aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:40:30 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 04:40:30 +0000
commit5cfe40f9661bf28654e0435a4e1df7236842c73e (patch)
tree1da983d133e257f271d173abf98d3f982c3d8d79
parentdc05e7abe54ff0f34907963332fbf37156995710 (diff)
parent18fb1f5bb1984f60136ccda658ed4aef25e3417b (diff)
downloadlibavc-android14-mainline-adservices-release.tar.gz
Snap for 10453563 from 18fb1f5bb1984f60136ccda658ed4aef25e3417b to mainline-adservices-releaseaml_ads_341517040aml_ads_341413000aml_ads_341316030aml_ads_341131050aml_ads_341027030aml_ads_340915050android14-mainline-adservices-release
Change-Id: I488a832875a84833f3b444c22b48470fb7cff265
-rw-r--r--.clang-format200
-rw-r--r--.github/workflows/cifuzz.yml24
-rw-r--r--.github/workflows/cmake.yml23
-rw-r--r--Android.bp640
-rw-r--r--CMakeLists.txt24
-rw-r--r--LICENSE187
-rw-r--r--METADATA16
-rw-r--r--cmake/utils.cmake4
-rw-r--r--common/arm/svc/isvc_intra_sampling_neon.c485
-rw-r--r--common/arm/svc/isvc_iquant_itrans_recon_neon.c1783
-rw-r--r--common/arm/svc/isvc_mem_fns_neon.c151
-rw-r--r--common/arm/svc/isvc_resi_trans_quant_neon.c1085
-rw-r--r--common/common.cmake1
-rw-r--r--common/ih264_buf_mgr.c33
-rw-r--r--common/ih264_buf_mgr.h3
-rw-r--r--common/ih264_cabac_tables.h9
-rw-r--r--common/ih264_debug.h1
-rw-r--r--common/ih264_defs.h106
-rw-r--r--common/ih264_resi_trans_quant.c61
-rw-r--r--common/ih264_size_defs.h2
-rw-r--r--common/ih264_structs.h183
-rw-r--r--common/ih264_trans_macros.h7
-rw-r--r--common/ithread.c2
-rw-r--r--common/mvc/imvc_defs.h114
-rw-r--r--common/mvc/imvc_structs.h164
-rw-r--r--common/riscv/ih264_platform_macros.h (renamed from common/mips/ih264_platform_macros.h)14
-rw-r--r--common/svc/isvc_cabac_tables.c6542
-rw-r--r--common/svc/isvc_cabac_tables.h57
-rw-r--r--common/svc/isvc_common_tables.c81
-rw-r--r--common/svc/isvc_common_tables.h50
-rw-r--r--common/svc/isvc_defs.h88
-rw-r--r--common/svc/isvc_inter_pred_filters.h219
-rw-r--r--common/svc/isvc_intra_resample.c3257
-rw-r--r--common/svc/isvc_intra_resample.h251
-rw-r--r--common/svc/isvc_iquant_itrans_recon.c1094
-rw-r--r--common/svc/isvc_macros.h37
-rw-r--r--common/svc/isvc_mem_fns.c317
-rw-r--r--common/svc/isvc_mem_fns.h109
-rw-r--r--common/svc/isvc_resi_trans_quant.c840
-rw-r--r--common/svc/isvc_structs.h335
-rw-r--r--common/svc/isvc_trans_quant_itrans_iquant.h253
-rw-r--r--common/svccommon.cmake39
-rw-r--r--common/x86/svc/isvc_intra_resample_sse42.c658
-rw-r--r--common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c548
-rw-r--r--common/x86/svc/isvc_iquant_itrans_recon_sse42.c2849
-rw-r--r--common/x86/svc/isvc_iquant_itrans_recon_ssse3.c1291
-rw-r--r--common/x86/svc/isvc_mem_fns_sse42.c157
-rw-r--r--common/x86/svc/isvc_mem_fns_ssse3.c435
-rw-r--r--common/x86/svc/isvc_padding_ssse3.c294
-rw-r--r--common/x86/svc/isvc_resi_trans_quant_sse42.c1881
-rw-r--r--decoder/arm/svc/isvcd_function_selector.c107
-rw-r--r--decoder/arm/svc/isvcd_function_selector_neon.c136
-rw-r--r--decoder/arm/svc/isvcd_intra_resamp_neon.c1548
-rw-r--r--decoder/arm/svc/isvcd_iquant_itrans_neon.c960
-rw-r--r--decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c1308
-rw-r--r--decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c1422
-rw-r--r--decoder/arm/svc/isvcd_pred_residual_recon_neon.c1694
-rw-r--r--decoder/arm/svc/isvcd_residual_resamp_neon.c1599
-rw-r--r--decoder/ih264d.h222
-rw-r--r--decoder/ih264d_api.c276
-rw-r--r--decoder/ih264d_api_utils.h72
-rw-r--r--decoder/ih264d_error_handler.h6
-rw-r--r--decoder/ih264d_parse_bslice.c20
-rw-r--r--decoder/ih264d_parse_headers.c39
-rw-r--r--decoder/ih264d_parse_islice.c3
-rw-r--r--decoder/ih264d_parse_pslice.c20
-rw-r--r--decoder/ih264d_parse_slice.c17
-rw-r--r--decoder/ih264d_sei.c374
-rw-r--r--decoder/ih264d_sei.h189
-rw-r--r--decoder/ih264d_vui.h2
-rw-r--r--decoder/ivd.h13
-rw-r--r--decoder/mvc/imvcd.h279
-rw-r--r--decoder/mvc/imvcd_api.c1599
-rw-r--r--decoder/mvc/imvcd_api_utils.c393
-rw-r--r--decoder/mvc/imvcd_api_utils.h58
-rw-r--r--decoder/mvc/imvcd_defs.h39
-rw-r--r--decoder/mvc/imvcd_dpb_manager.c2203
-rw-r--r--decoder/mvc/imvcd_dpb_manager.h220
-rw-r--r--decoder/mvc/imvcd_error_handler.c421
-rw-r--r--decoder/mvc/imvcd_error_handler.h39
-rw-r--r--decoder/mvc/imvcd_nalu_parser.c870
-rw-r--r--decoder/mvc/imvcd_nalu_parser.h37
-rw-r--r--decoder/mvc/imvcd_slice_functions.c2398
-rw-r--r--decoder/mvc/imvcd_slice_functions.h36
-rw-r--r--decoder/mvc/imvcd_structs.h234
-rw-r--r--decoder/mvc/imvcd_utils.c1140
-rw-r--r--decoder/mvc/imvcd_utils.h121
-rw-r--r--decoder/mvc/libmvcdec.cmake61
-rw-r--r--decoder/riscv/ih264d_function_selector.c (renamed from decoder/mips/ih264d_function_selector.c)0
-rw-r--r--decoder/riscv/svc/isvcd_function_selector.c81
-rw-r--r--decoder/svc/isvcd.h831
-rw-r--r--decoder/svc/isvcd_api.c7291
-rw-r--r--decoder/svc/isvcd_api.h57
-rw-r--r--decoder/svc/isvcd_cabac.c148
-rw-r--r--decoder/svc/isvcd_cabac.h48
-rw-r--r--decoder/svc/isvcd_cabac_init_tables.c6529
-rw-r--r--decoder/svc/isvcd_compute_bs.c965
-rw-r--r--decoder/svc/isvcd_deblocking.h58
-rw-r--r--decoder/svc/isvcd_defs.h120
-rw-r--r--decoder/svc/isvcd_function_selector.h48
-rw-r--r--decoder/svc/isvcd_function_selector_generic.c158
-rw-r--r--decoder/svc/isvcd_ii_pred.c681
-rw-r--r--decoder/svc/isvcd_ii_pred.h139
-rw-r--r--decoder/svc/isvcd_intra_resamp.c5120
-rw-r--r--decoder/svc/isvcd_intra_resamp.h631
-rw-r--r--decoder/svc/isvcd_iquant_itrans.c714
-rw-r--r--decoder/svc/isvcd_iquant_itrans.h73
-rw-r--r--decoder/svc/isvcd_iquant_itrans_residual.c809
-rw-r--r--decoder/svc/isvcd_iquant_itrans_residual.h78
-rw-r--r--decoder/svc/isvcd_iquant_itrans_residual_recon.c908
-rw-r--r--decoder/svc/isvcd_iquant_itrans_residual_recon.h76
-rw-r--r--decoder/svc/isvcd_mb_utils.c364
-rw-r--r--decoder/svc/isvcd_mb_utils.h51
-rw-r--r--decoder/svc/isvcd_mode_mv_resamp.c3211
-rw-r--r--decoder/svc/isvcd_mode_mv_resamp.h170
-rw-r--r--decoder/svc/isvcd_nal.c1256
-rw-r--r--decoder/svc/isvcd_nal.h216
-rw-r--r--decoder/svc/isvcd_nal_parse.c2434
-rw-r--r--decoder/svc/isvcd_nal_parse.h108
-rw-r--r--decoder/svc/isvcd_nal_parse_structs.h371
-rw-r--r--decoder/svc/isvcd_nal_structs.h291
-rw-r--r--decoder/svc/isvcd_parse_cavlc.c288
-rw-r--r--decoder/svc/isvcd_parse_cavlc.h65
-rw-r--r--decoder/svc/isvcd_parse_ebslice.c2161
-rw-r--r--decoder/svc/isvcd_parse_eislice.c2103
-rw-r--r--decoder/svc/isvcd_parse_epslice.c3501
-rw-r--r--decoder/svc/isvcd_parse_headers.c1874
-rw-r--r--decoder/svc/isvcd_parse_headers.h58
-rw-r--r--decoder/svc/isvcd_parse_slice.c2768
-rw-r--r--decoder/svc/isvcd_parse_slice.h110
-rw-r--r--decoder/svc/isvcd_pred_residual_recon.c541
-rw-r--r--decoder/svc/isvcd_pred_residual_recon.h86
-rw-r--r--decoder/svc/isvcd_process_ebslice.c619
-rw-r--r--decoder/svc/isvcd_process_ebslice.h64
-rw-r--r--decoder/svc/isvcd_process_epslice.c2291
-rw-r--r--decoder/svc/isvcd_process_epslice.h110
-rw-r--r--decoder/svc/isvcd_resamp_svc.c4304
-rw-r--r--decoder/svc/isvcd_resamp_svc.h570
-rw-r--r--decoder/svc/isvcd_residual_resamp.c2649
-rw-r--r--decoder/svc/isvcd_residual_resamp.h238
-rw-r--r--decoder/svc/isvcd_structs.h724
-rw-r--r--decoder/svc/isvcd_tables.h53
-rw-r--r--decoder/svc/isvcd_thread_compute_bs.c319
-rw-r--r--decoder/svc/isvcd_thread_compute_bs.h43
-rw-r--r--decoder/svc/isvcd_thread_parse_decode.c608
-rw-r--r--decoder/svc/isvcd_thread_parse_decode.h46
-rw-r--r--decoder/svc/isvcd_utils.c908
-rw-r--r--decoder/svc/isvcd_utils.h63
-rw-r--r--decoder/svc/isvcd_vui.c118
-rw-r--r--decoder/svc/isvcd_vui.h67
-rw-r--r--decoder/svc/libsvcdec.cmake102
-rw-r--r--decoder/x86/svc/isvcd_function_selector.c85
-rw-r--r--decoder/x86/svc/isvcd_function_selector_sse42.c141
-rw-r--r--decoder/x86/svc/isvcd_intra_resamp_sse42.c1925
-rw-r--r--decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c1879
-rw-r--r--decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c1678
-rw-r--r--decoder/x86/svc/isvcd_iquant_itrans_sse42.c1465
-rw-r--r--decoder/x86/svc/isvcd_pred_residual_recon_sse42.c1466
-rw-r--r--decoder/x86/svc/isvcd_residual_resamp_sse42.c1546
-rw-r--r--encoder/arm/svc/isvce_downscaler_neon.c927
-rw-r--r--encoder/arm/svc/isvce_function_selector.c157
-rw-r--r--encoder/arm/svc/isvce_function_selector_a9q.c270
-rw-r--r--encoder/arm/svc/isvce_function_selector_av8.c278
-rw-r--r--encoder/arm/svc/isvce_platform_macros.h139
-rw-r--r--encoder/arm/svc/isvce_rc_utils_neon.c625
-rw-r--r--encoder/arm/svc/isvce_residual_pred_neon.c666
-rw-r--r--encoder/ih264e.h72
-rw-r--r--encoder/ih264e_api.c140
-rw-r--r--encoder/ih264e_defs.h3
-rw-r--r--encoder/ih264e_encode.c56
-rw-r--r--encoder/ih264e_encode_header.c10
-rw-r--r--encoder/ih264e_error.h6
-rw-r--r--encoder/ih264e_master.h17
-rw-r--r--encoder/ih264e_process.c10
-rw-r--r--encoder/ih264e_sei.c108
-rw-r--r--encoder/ih264e_sei.h23
-rw-r--r--encoder/ih264e_structs.h35
-rw-r--r--encoder/ih264e_utils.c81
-rw-r--r--encoder/irc_rate_control_api_structs.h9
-rw-r--r--encoder/ive2.h3
-rw-r--r--encoder/libavcenc.cmake3
-rw-r--r--encoder/psnr.c65
-rw-r--r--encoder/psnr.h30
-rw-r--r--encoder/riscv/ih264e_function_selector.c (renamed from encoder/mips/ih264e_function_selector.c)1
-rw-r--r--encoder/riscv/ih264e_platform_macros.h (renamed from encoder/mips/ih264e_platform_macros.h)1
-rw-r--r--encoder/riscv/ime_platform_macros.h (renamed from encoder/mips/ime_platform_macros.h)0
-rw-r--r--encoder/riscv/svc/isvce_function_selector.c82
-rw-r--r--encoder/riscv/svc/isvce_platform_macros.h104
-rw-r--r--encoder/svc/irc_svc_rate_control_api.c116
-rw-r--r--encoder/svc/irc_svc_rate_control_api.h46
-rw-r--r--encoder/svc/isvce.h1023
-rw-r--r--encoder/svc/isvce_api.c6052
-rw-r--r--encoder/svc/isvce_cabac.c759
-rw-r--r--encoder/svc/isvce_cabac.h380
-rw-r--r--encoder/svc/isvce_cabac_encode.c2374
-rw-r--r--encoder/svc/isvce_cabac_init.c215
-rw-r--r--encoder/svc/isvce_cabac_structs.h142
-rw-r--r--encoder/svc/isvce_cabac_utils.h88
-rw-r--r--encoder/svc/isvce_cavlc.c2021
-rw-r--r--encoder/svc/isvce_cavlc.h126
-rw-r--r--encoder/svc/isvce_core_coding.c2367
-rw-r--r--encoder/svc/isvce_core_coding.h125
-rw-r--r--encoder/svc/isvce_deblk.c1267
-rw-r--r--encoder/svc/isvce_deblk.h53
-rw-r--r--encoder/svc/isvce_defs.h345
-rw-r--r--encoder/svc/isvce_downscaler.c537
-rw-r--r--encoder/svc/isvce_downscaler.h205
-rw-r--r--encoder/svc/isvce_downscaler_private_defs.h124
-rw-r--r--encoder/svc/isvce_encode.c791
-rw-r--r--encoder/svc/isvce_encode.h41
-rw-r--r--encoder/svc/isvce_encode_header.c2127
-rw-r--r--encoder/svc/isvce_encode_header.h296
-rw-r--r--encoder/svc/isvce_error.h70
-rw-r--r--encoder/svc/isvce_fmt_conv.c145
-rw-r--r--encoder/svc/isvce_fmt_conv.h48
-rw-r--r--encoder/svc/isvce_function_selector_generic.c314
-rw-r--r--encoder/svc/isvce_globals.c48
-rw-r--r--encoder/svc/isvce_globals.h44
-rw-r--r--encoder/svc/isvce_ibl_eval.c1378
-rw-r--r--encoder/svc/isvce_ibl_eval.h105
-rw-r--r--encoder/svc/isvce_ibl_private_defs.h94
-rw-r--r--encoder/svc/isvce_ilp_mv.c737
-rw-r--r--encoder/svc/isvce_ilp_mv.h115
-rw-r--r--encoder/svc/isvce_ilp_mv_private_defs.h68
-rw-r--r--encoder/svc/isvce_ilp_mv_utils.h111
-rw-r--r--encoder/svc/isvce_interface_structs.h116
-rw-r--r--encoder/svc/isvce_intra_modes_eval.c2334
-rw-r--r--encoder/svc/isvce_intra_modes_eval.h361
-rw-r--r--encoder/svc/isvce_mc.c480
-rw-r--r--encoder/svc/isvce_mc.h87
-rw-r--r--encoder/svc/isvce_me.c2924
-rw-r--r--encoder/svc/isvce_me.h381
-rw-r--r--encoder/svc/isvce_mode_stat_visualiser.c191
-rw-r--r--encoder/svc/isvce_mode_stat_visualiser.h72
-rw-r--r--encoder/svc/isvce_nalu_stat_aggregator.c124
-rw-r--r--encoder/svc/isvce_nalu_stat_aggregator.h99
-rw-r--r--encoder/svc/isvce_pred_structs.h156
-rw-r--r--encoder/svc/isvce_process.c2787
-rw-r--r--encoder/svc/isvce_process.h285
-rw-r--r--encoder/svc/isvce_rate_control.c716
-rw-r--r--encoder/svc/isvce_rate_control.h330
-rw-r--r--encoder/svc/isvce_rc_mem_interface.c325
-rw-r--r--encoder/svc/isvce_rc_mem_interface.h77
-rw-r--r--encoder/svc/isvce_rc_utils.c286
-rw-r--r--encoder/svc/isvce_rc_utils.h134
-rw-r--r--encoder/svc/isvce_rc_utils_private_defs.h52
-rw-r--r--encoder/svc/isvce_res_pred_private_defs.h124
-rw-r--r--encoder/svc/isvce_residual_pred.c1950
-rw-r--r--encoder/svc/isvce_residual_pred.h97
-rw-r--r--encoder/svc/isvce_structs.h2584
-rw-r--r--encoder/svc/isvce_sub_pic_rc.c906
-rw-r--r--encoder/svc/isvce_sub_pic_rc.h131
-rw-r--r--encoder/svc/isvce_sub_pic_rc_private_defs.h256
-rw-r--r--encoder/svc/isvce_utils.c4547
-rw-r--r--encoder/svc/isvce_utils.h237
-rw-r--r--encoder/svc/libsvcenc.cmake127
-rw-r--r--encoder/x86/svc/isvce_downscaler_sse42.c652
-rw-r--r--encoder/x86/svc/isvce_function_selector.c136
-rw-r--r--encoder/x86/svc/isvce_function_selector_sse42.c169
-rw-r--r--encoder/x86/svc/isvce_function_selector_ssse3.c182
-rw-r--r--encoder/x86/svc/isvce_platform_macros.h119
-rw-r--r--encoder/x86/svc/isvce_rc_utils_sse42.c450
-rw-r--r--encoder/x86/svc/isvce_residual_pred_sse42.c735
-rw-r--r--fuzzer/Android.bp91
-rw-r--r--fuzzer/README.md15
-rw-r--r--fuzzer/avc_dec_fuzzer.cpp38
-rw-r--r--fuzzer/avc_enc_fuzzer.cpp37
-rw-r--r--fuzzer/mvc_dec_fuzzer.cmake2
-rw-r--r--fuzzer/mvc_dec_fuzzer.cpp416
-rwxr-xr-xfuzzer/ossfuzz.sh8
-rw-r--r--fuzzer/svc_dec_fuzzer.cmake2
-rw-r--r--fuzzer/svc_dec_fuzzer.cpp449
-rw-r--r--fuzzer/svc_enc_fuzzer.cmake2
-rw-r--r--fuzzer/svc_enc_fuzzer.cpp1343
-rw-r--r--libavc_blocklist.txt1
-rw-r--r--test/Android.bp86
-rw-r--r--test/decoder/avcdec.cmake1
-rw-r--r--test/decoder/main.c109
-rw-r--r--test/encoder/app.h9
-rw-r--r--test/encoder/avcenc.cmake1
-rw-r--r--test/encoder/main.c185
-rw-r--r--test/mvcdec/dec.cfg12
-rw-r--r--test/mvcdec/main.c1544
-rw-r--r--test/mvcdec/mvcdec.cmake4
-rw-r--r--test/svcdec/dec.cfg13
-rw-r--r--test/svcdec/main.c3441
-rw-r--r--test/svcdec/svcdec.cmake4
-rw-r--r--test/svcenc/app.h417
-rw-r--r--test/svcenc/enc.cfg47
-rw-r--r--test/svcenc/input.c300
-rw-r--r--test/svcenc/main.c3253
-rw-r--r--test/svcenc/output.c95
-rw-r--r--test/svcenc/psnr.c245
-rw-r--r--test/svcenc/psnr.h58
-rw-r--r--test/svcenc/recon.c215
-rw-r--r--test/svcenc/svcenc.cmake12
296 files changed, 185502 insertions, 340 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..287f57a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,200 @@
+---
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveMacros: None
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: None
+AlignEscapedNewlines: Left
+AlignOperands: Align
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: WithoutElse
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros:
+ - __capability
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterCaseLabel: true
+ AfterClass: false
+ AfterControlStatement: Always
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ AfterExternBlock: true
+ BeforeCatch: true
+ BeforeElse: true
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: true
+BreakBeforeBraces: Allman
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 100
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: true
+DisableFormat: false
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+StatementAttributeLikeMacros:
+ - Q_EMIT
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^<ext/.*\.h>'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '.*'
+ Priority: 3
+ SortPriority: 0
+ CaseSensitive: false
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IncludeIsMainSourceRegex: ''
+IndentCaseLabels: true
+IndentCaseBlocks: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentExternBlock: AfterExternBlock
+IndentRequires: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Never
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PenaltyIndentedWhitespace: 0
+PointerAlignment: Right
+RawStringFormats:
+ - Language: Cpp
+ Delimiters:
+ - cc
+ - CC
+ - cpp
+ - Cpp
+ - CPP
+ - 'c++'
+ - 'C++'
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ - Language: TextProto
+ Delimiters:
+ - pb
+ - PB
+ - proto
+ - PROTO
+ EnclosingFunctions:
+ - EqualsProto
+ - EquivToProto
+ - PARSE_PARTIAL_TEXT_PROTO
+ - PARSE_TEST_PROTO
+ - PARSE_TEXT_PROTO
+ - ParseTextOrDie
+ - ParseTextProtoOrDie
+ - ParseTestProto
+ - ParsePartialTestProto
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ReflowComments: true
+SortIncludes: false
+SortJavaStaticImport: Before
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: true
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: Never
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+BitFieldColonSpacing: Both
+Standard: Auto
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 4
+UseCRLF: false
+UseTab: Never
+WhitespaceSensitiveMacros:
+ - STRINGIZE
+ - PP_STRINGIZE
+ - BOOST_PP_STRINGIZE
+ - NS_SWIFT_NAME
+ - CF_SWIFT_NAME
+...
+
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
new file mode 100644
index 0000000..91fa5ed
--- /dev/null
+++ b/.github/workflows/cifuzz.yml
@@ -0,0 +1,24 @@
+name: CIFuzz
+on: [pull_request]
+jobs:
+ Fuzzing:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build Fuzzers
+ id: build
+ uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'libavc'
+ language: c++
+ - name: Run Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'libavc'
+ language: c++
+ fuzz-seconds: 600
+ - name: Upload Crash
+ uses: actions/upload-artifact@v3
+ if: failure() && steps.build.outcome == 'success'
+ with:
+ name: artifacts
+ path: ./out/artifacts
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
new file mode 100644
index 0000000..b3e7e40
--- /dev/null
+++ b/.github/workflows/cmake.yml
@@ -0,0 +1,23 @@
+name: CMake
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+
+env:
+ BUILD_TYPE: Release
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Configure CMake
+ run: cmake -B ${{github.workspace}}/out -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_MVC=1 -DENABLE_SVC=1
+
+ - name: Build
+ run: cmake --build ${{github.workspace}}/out --config ${{env.BUILD_TYPE}}
diff --git a/Android.bp b/Android.bp
index e9efbe5..2e11831 100644
--- a/Android.bp
+++ b/Android.bp
@@ -25,6 +25,39 @@ cc_library_headers {
}
cc_library_headers {
+ name: "libmvcdec_headers",
+ export_include_dirs: [
+ "decoder",
+ "decoder/mvc",
+ "common",
+ "common/mvc",
+ ],
+ min_sdk_version: "29",
+}
+
+cc_library_headers {
+ name: "libsvcenc_headers",
+ export_include_dirs: [
+ "common",
+ "common/svc",
+ "encoder",
+ "encoder/svc",
+ ],
+ min_sdk_version: "29",
+}
+
+cc_library_headers {
+ name: "libsvcdec_headers",
+ export_include_dirs: [
+ "common",
+ "common/svc",
+ "decoder",
+ "decoder/svc",
+ ],
+ min_sdk_version: "29",
+}
+
+cc_library_headers {
name: "libavcenc_headers",
export_include_dirs: [
"common",
@@ -33,15 +66,102 @@ cc_library_headers {
min_sdk_version: "29",
}
-cc_library_static {
- name: "libavcdec",
+cc_defaults {
+ name: "libavc_enc_defaults",
vendor_available: true,
host_supported: true,
shared_libs: [
"liblog",
"libcutils",
],
+ cflags: [
+ "-DNDEBUG",
+ "-UHP_PL",
+ "-DN_MB_ENABLE",
+ "-fPIC",
+ "-O3",
+ "-Wall",
+ "-Werror",
+ "-Wno-error=constant-conversion",
+ ],
+ arch: {
+ arm: {
+ local_include_dirs: [
+ "common/arm",
+ "encoder/arm",
+ ],
+
+ cflags: [
+ "-DARM",
+ // These will be overriden by armv7_a_neon
+ "-DDISABLE_NEON",
+ ],
+
+ neon: {
+ cflags: [
+ "-UDISABLE_NEON",
+ ],
+ },
+ },
+ arm64: {
+ cflags: [
+ "-DARMV8",
+ "-DARM",
+ ],
+ local_include_dirs: [
+ "common/arm",
+ "common/armv8",
+ "encoder/arm",
+ "encoder/armv8",
+ ],
+ },
+
+ riscv64: {
+ local_include_dirs: [
+ "common/riscv",
+ "encoder/riscv",
+ ],
+ },
+
+ x86: {
+ cflags: [
+ "-DX86",
+ "-msse4.2",
+ ],
+
+ local_include_dirs: [
+ "encoder/x86",
+ "common/x86",
+ ],
+ },
+
+ x86_64: {
+ cflags: [
+ "-DX86",
+ "-msse4.2",
+ ],
+
+ local_include_dirs: [
+ "encoder/x86",
+ "common/x86",
+ ],
+ },
+ },
+
+ sanitize: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
+ blocklist: "libavc_blocklist.txt",
+ },
+}
+
+cc_defaults {
+ name: "libavc_dec_defaults",
cflags: [
"-fPIC",
"-O3",
@@ -52,6 +172,93 @@ cc_library_static {
// #KEEP_THREAD_ACTIVE is experimental
"-UKEEP_THREADS_ACTIVE",
],
+ vendor_available: true,
+ host_supported: true,
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ ],
+
+ arch: {
+ arm: {
+ local_include_dirs: [
+ "decoder/arm",
+ "common/arm",
+ ],
+ cflags: [
+ "-DARM",
+ // These will be overriden by armv7_a_neon
+ "-DDISABLE_NEON",
+ "-DDEFAULT_ARCH=D_ARCH_ARM_NONEON",
+ ],
+
+ neon: {
+ cflags: [
+ "-UDISABLE_NEON",
+ "-UDEFAULT_ARCH",
+ "-DDEFAULT_ARCH=D_ARCH_ARM_A9Q",
+ ],
+ },
+ },
+
+ arm64: {
+ cflags: [
+ "-DARMV8",
+ "-DARM",
+ "-DDEFAULT_ARCH=D_ARCH_ARMV8_GENERIC",
+ ],
+ local_include_dirs: [
+ "decoder/arm",
+ "common/armv8",
+ ],
+ },
+
+ riscv64: {
+ local_include_dirs: [
+ "common/riscv",
+ ],
+ },
+
+ x86: {
+ cflags: [
+ "-DX86",
+ "-msse4.2",
+ "-DDEFAULT_ARCH=D_ARCH_X86_SSE42",
+ ],
+
+ local_include_dirs: [
+ "decoder/x86",
+ "common/x86",
+ ],
+ },
+
+ x86_64: {
+ cflags: [
+ "-DX86",
+ "-msse4.2",
+ "-DDEFAULT_ARCH=D_ARCH_X86_SSE42",
+ ],
+
+ local_include_dirs: [
+ "decoder/x86",
+ "common/x86",
+ ],
+ },
+ },
+
+ sanitize: {
+ integer_overflow: true,
+ misc_undefined: ["bounds"],
+ cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
+ },
+}
+
+cc_library_static {
+ name: "libavcdec",
+ defaults: ["libavc_dec_defaults"],
export_include_dirs: [
"common",
@@ -106,24 +313,11 @@ cc_library_static {
arch: {
arm: {
- local_include_dirs: [
- "decoder/arm",
- "common/arm",
- ],
-
srcs: [
"decoder/arm/ih264d_function_selector.c",
"common/arm/ih264_arm_memory_barrier.s",
],
- cflags: [
- "-DARM",
-
- // These will be overriden by armv7_a_neon
- "-DDISABLE_NEON",
- "-DDEFAULT_ARCH=D_ARCH_ARM_NONEON",
- ],
-
neon: {
srcs: [
"decoder/arm/ih264d_function_selector_a9q.c",
@@ -151,25 +345,10 @@ cc_library_static {
"common/arm/ih264_iquant_itrans_recon_dc_a9.s",
"common/arm/ih264_ihadamard_scaling_a9.s",
],
- cflags: [
- "-UDISABLE_NEON",
- "-UDEFAULT_ARCH",
- "-DDEFAULT_ARCH=D_ARCH_ARM_A9Q",
- ],
},
},
arm64: {
- cflags: [
- "-DARMV8",
- "-DARM",
- "-DDEFAULT_ARCH=D_ARCH_ARMV8_GENERIC",
- ],
- local_include_dirs: [
- "decoder/arm",
- "common/armv8",
- ],
-
srcs: [
"decoder/arm/ih264d_function_selector.c",
"decoder/arm/ih264d_function_selector_av8.c",
@@ -199,18 +378,16 @@ cc_library_static {
],
},
- x86: {
- cflags: [
- "-DX86",
- "-msse4.2",
- "-DDEFAULT_ARCH=D_ARCH_X86_SSE42",
- ],
-
+ riscv64: {
local_include_dirs: [
- "decoder/x86",
- "common/x86",
+ "common/riscv",
+ ],
+ srcs: [
+ "decoder/riscv/ih264d_function_selector.c",
],
+ },
+ x86: {
srcs: [
"decoder/x86/ih264d_function_selector.c",
"decoder/x86/ih264d_function_selector_sse42.c",
@@ -231,17 +408,6 @@ cc_library_static {
},
x86_64: {
- cflags: [
- "-DX86",
- "-msse4.2",
- "-DDEFAULT_ARCH=D_ARCH_X86_SSE42",
- ],
-
- local_include_dirs: [
- "decoder/x86",
- "common/x86",
- ],
-
srcs: [
"decoder/x86/ih264d_function_selector.c",
"decoder/x86/ih264d_function_selector_sse42.c",
@@ -263,12 +429,6 @@ cc_library_static {
},
sanitize: {
- integer_overflow: true,
- misc_undefined: ["bounds"],
- cfi: true,
- config: {
- cfi_assembly_support: true,
- },
blocklist: "libavc_blocklist.txt",
},
apex_available: [
@@ -279,25 +439,33 @@ cc_library_static {
}
cc_library_static {
- name: "libavcenc",
- vendor_available: true,
- host_supported: true,
- shared_libs: [
- "liblog",
- "libcutils",
+ name: "libmvcdec",
+ defaults: ["libavc_dec_defaults"],
+ whole_static_libs: [
+ "libavcdec",
],
- cflags: [
- "-DNDEBUG",
- "-UHP_PL",
- "-DN_MB_ENABLE",
- "-fPIC",
+ export_include_dirs: [
+ "decoder",
+ "decoder/mvc",
+ "common",
+ "common/mvc",
+ ],
- "-O3",
- "-Wall",
- "-Werror",
- "-Wno-error=constant-conversion",
+ srcs: [
+ "decoder/mvc/imvcd_api.c",
+ "decoder/mvc/imvcd_api_utils.c",
+ "decoder/mvc/imvcd_dpb_manager.c",
+ "decoder/mvc/imvcd_error_handler.c",
+ "decoder/mvc/imvcd_nalu_parser.c",
+ "decoder/mvc/imvcd_slice_functions.c",
+ "decoder/mvc/imvcd_utils.c",
],
+}
+
+cc_library_static {
+ name: "libavcenc",
+ defaults: ["libavc_enc_defaults"],
export_include_dirs: [
"common",
@@ -361,27 +529,16 @@ cc_library_static {
"encoder/ime.c",
"encoder/ime_distortion_metrics.c",
"encoder/ih264e_sei.c",
+ "encoder/psnr.c",
],
arch: {
arm: {
- local_include_dirs: [
- "encoder/arm",
- "common/arm",
- ],
-
srcs: [
"encoder/arm/ih264e_function_selector.c",
"common/arm/ih264_arm_memory_barrier.s",
],
- cflags: [
- "-DARM",
-
- // This will be overriden by armv7_a_neon
- "-DDISABLE_NEON",
- ],
-
neon: {
srcs: [
"encoder/arm/ih264e_function_selector_a9q.c",
@@ -409,25 +566,10 @@ cc_library_static {
"encoder/arm/ih264e_fmt_conv.s",
"encoder/arm/ime_distortion_metrics_a9q.s",
],
-
- cflags: [
- "-UDISABLE_NEON",
- ],
},
},
arm64: {
- cflags: [
- "-DARMV8",
- "-DARM",
- ],
-
- local_include_dirs: [
- "encoder/arm",
- "encoder/armv8",
- "common/armv8",
- ],
-
srcs: [
"encoder/arm/ih264e_function_selector.c",
"encoder/arm/ih264e_function_selector_av8.c",
@@ -454,17 +596,13 @@ cc_library_static {
],
},
- x86: {
- cflags: [
- "-DX86",
- "-msse4.2",
- ],
-
- local_include_dirs: [
- "encoder/x86",
- "common/x86",
+ riscv64: {
+ srcs: [
+ "encoder/riscv/ih264e_function_selector.c",
],
+ },
+ x86: {
srcs: [
"encoder/x86/ih264e_function_selector.c",
"encoder/x86/ih264e_function_selector_sse42.c",
@@ -490,16 +628,6 @@ cc_library_static {
},
x86_64: {
- cflags: [
- "-DX86",
- "-msse4.2",
- ],
-
- local_include_dirs: [
- "encoder/x86",
- "common/x86",
- ],
-
srcs: [
"encoder/x86/ih264e_function_selector.c",
"encoder/x86/ih264e_function_selector_sse42.c",
@@ -525,15 +653,6 @@ cc_library_static {
},
},
- sanitize: {
- integer_overflow: true,
- misc_undefined: ["bounds"],
- cfi: true,
- config: {
- cfi_assembly_support: true,
- },
- blocklist: "libavc_blocklist.txt",
- },
apex_available: [
"//apex_available:platform", //due to libstagefright_soft_avcenc
"com.android.media.swcodec",
@@ -541,4 +660,273 @@ cc_library_static {
min_sdk_version: "29",
}
+cc_library_static {
+ name: "libsvcenc",
+ defaults: ["libavc_enc_defaults"],
+ whole_static_libs: [
+ "libavcenc",
+ ],
+
+ export_include_dirs: [
+ "common",
+ "common/svc",
+ "encoder",
+ "encoder/svc",
+ ],
+
+ srcs: [
+ "common/svc/isvc_cabac_tables.c",
+ "common/svc/isvc_common_tables.c",
+ "common/svc/isvc_intra_resample.c",
+ "common/svc/isvc_iquant_itrans_recon.c",
+ "common/svc/isvc_mem_fns.c",
+ "common/svc/isvc_resi_trans_quant.c",
+ "encoder/svc/irc_svc_rate_control_api.c",
+ "encoder/svc/isvce_api.c",
+ "encoder/svc/isvce_cabac.c",
+ "encoder/svc/isvce_cabac_encode.c",
+ "encoder/svc/isvce_cabac_init.c",
+ "encoder/svc/isvce_cavlc.c",
+ "encoder/svc/isvce_core_coding.c",
+ "encoder/svc/isvce_deblk.c",
+ "encoder/svc/isvce_downscaler.c",
+ "encoder/svc/isvce_encode.c",
+ "encoder/svc/isvce_encode_header.c",
+ "encoder/svc/isvce_fmt_conv.c",
+ "encoder/svc/isvce_function_selector_generic.c",
+ "encoder/svc/isvce_globals.c",
+ "encoder/svc/isvce_ibl_eval.c",
+ "encoder/svc/isvce_ilp_mv.c",
+ "encoder/svc/isvce_intra_modes_eval.c",
+ "encoder/svc/isvce_mc.c",
+ "encoder/svc/isvce_me.c",
+ "encoder/svc/isvce_mode_stat_visualiser.c",
+ "encoder/svc/isvce_nalu_stat_aggregator.c",
+ "encoder/svc/isvce_process.c",
+ "encoder/svc/isvce_rate_control.c",
+ "encoder/svc/isvce_rc_mem_interface.c",
+ "encoder/svc/isvce_rc_utils.c",
+ "encoder/svc/isvce_residual_pred.c",
+ "encoder/svc/isvce_sub_pic_rc.c",
+ "encoder/svc/isvce_utils.c",
+ ],
+
+ arch: {
+ arm: {
+ local_include_dirs: [
+ "common/arm/svc",
+ "encoder/arm/svc",
+ ],
+
+ srcs: [
+ "encoder/arm/svc/isvce_function_selector.c",
+ ],
+
+ neon: {
+ srcs: [
+ "encoder/arm/svc/isvce_function_selector_a9q.c",
+ "common/arm/svc/isvc_intra_sampling_neon.c",
+ "common/arm/svc/isvc_iquant_itrans_recon_neon.c",
+ "common/arm/svc/isvc_mem_fns_neon.c",
+ "common/arm/svc/isvc_resi_trans_quant_neon.c",
+ "encoder/arm/svc/isvce_downscaler_neon.c",
+ "encoder/arm/svc/isvce_rc_utils_neon.c",
+ "encoder/arm/svc/isvce_residual_pred_neon.c",
+ ],
+ },
+ },
+
+ arm64: {
+ local_include_dirs: [
+ "common/arm/svc",
+ "encoder/arm/svc",
+ ],
+
+ srcs: [
+ "encoder/arm/svc/isvce_function_selector.c",
+ "encoder/arm/svc/isvce_function_selector_av8.c",
+ "common/arm/svc/isvc_intra_sampling_neon.c",
+ "common/arm/svc/isvc_iquant_itrans_recon_neon.c",
+ "common/arm/svc/isvc_mem_fns_neon.c",
+ "common/arm/svc/isvc_resi_trans_quant_neon.c",
+ "encoder/arm/svc/isvce_downscaler_neon.c",
+ "encoder/arm/svc/isvce_rc_utils_neon.c",
+ "encoder/arm/svc/isvce_residual_pred_neon.c",
+ ],
+ },
+
+ riscv64: {
+ local_include_dirs: [
+ "encoder/riscv/svc",
+ ],
+
+ srcs: [
+ "encoder/riscv/svc/isvce_function_selector.c",
+ ],
+ },
+
+ x86: {
+ local_include_dirs: [
+ "encoder/x86/svc",
+ "common/x86/svc",
+ ],
+
+ srcs: [
+ "common/x86/svc/isvc_intra_resample_sse42.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_sse42.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_ssse3.c",
+ "common/x86/svc/isvc_mem_fns_sse42.c",
+ "common/x86/svc/isvc_mem_fns_ssse3.c",
+ "common/x86/svc/isvc_padding_ssse3.c",
+ "common/x86/svc/isvc_resi_trans_quant_sse42.c",
+ "encoder/x86/svc/isvce_downscaler_sse42.c",
+ "encoder/x86/svc/isvce_function_selector.c",
+ "encoder/x86/svc/isvce_function_selector_sse42.c",
+ "encoder/x86/svc/isvce_function_selector_ssse3.c",
+ "encoder/x86/svc/isvce_rc_utils_sse42.c",
+ "encoder/x86/svc/isvce_residual_pred_sse42.c",
+ ],
+ },
+
+ x86_64: {
+ local_include_dirs: [
+ "encoder/x86/svc",
+ "common/x86/svc",
+ ],
+
+ srcs: [
+ "common/x86/svc/isvc_intra_resample_sse42.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_sse42.c",
+ "common/x86/svc/isvc_iquant_itrans_recon_ssse3.c",
+ "common/x86/svc/isvc_mem_fns_sse42.c",
+ "common/x86/svc/isvc_mem_fns_ssse3.c",
+ "common/x86/svc/isvc_padding_ssse3.c",
+ "common/x86/svc/isvc_resi_trans_quant_sse42.c",
+ "encoder/x86/svc/isvce_downscaler_sse42.c",
+ "encoder/x86/svc/isvce_function_selector.c",
+ "encoder/x86/svc/isvce_function_selector_sse42.c",
+ "encoder/x86/svc/isvce_function_selector_ssse3.c",
+ "encoder/x86/svc/isvce_rc_utils_sse42.c",
+ "encoder/x86/svc/isvce_residual_pred_sse42.c",
+ ],
+ },
+ },
+}
+
+cc_library_static {
+ name: "libsvcdec",
+ defaults: ["libavc_dec_defaults"],
+ whole_static_libs: [
+ "libavcdec",
+ ],
+
+ export_include_dirs: [
+ "decoder",
+ "decoder/svc",
+ "common",
+ "common/svc",
+ ],
+
+ srcs: [
+ "decoder/svc/isvcd_ii_pred.c",
+ "decoder/svc/isvcd_intra_resamp.c",
+ "decoder/svc/isvcd_iquant_itrans.c",
+ "decoder/svc/isvcd_iquant_itrans_residual.c",
+ "decoder/svc/isvcd_iquant_itrans_residual_recon.c",
+ "decoder/svc/isvcd_mode_mv_resamp.c",
+ "decoder/svc/isvcd_pred_residual_recon.c",
+ "decoder/svc/isvcd_residual_resamp.c",
+ "decoder/svc/isvcd_api.c",
+ "decoder/svc/isvcd_cabac.c",
+ "decoder/svc/isvcd_cabac_init_tables.c",
+ "decoder/svc/isvcd_compute_bs.c",
+ "decoder/svc/isvcd_function_selector_generic.c",
+ "decoder/svc/isvcd_mb_utils.c",
+ "decoder/svc/isvcd_nal.c",
+ "decoder/svc/isvcd_nal_parse.c",
+ "decoder/svc/isvcd_parse_cavlc.c",
+ "decoder/svc/isvcd_parse_ebslice.c",
+ "decoder/svc/isvcd_parse_eislice.c",
+ "decoder/svc/isvcd_parse_epslice.c",
+ "decoder/svc/isvcd_parse_headers.c",
+ "decoder/svc/isvcd_parse_slice.c",
+ "decoder/svc/isvcd_process_ebslice.c",
+ "decoder/svc/isvcd_process_epslice.c",
+ "decoder/svc/isvcd_thread_compute_bs.c",
+ "decoder/svc/isvcd_thread_parse_decode.c",
+ "decoder/svc/isvcd_utils.c",
+ "decoder/svc/isvcd_vui.c",
+ ],
+
+ arch: {
+ arm: {
+ srcs: [
+ "decoder/arm/svc/isvcd_function_selector.c",
+ ],
+
+ neon: {
+ srcs: [
+ "decoder/arm/svc/isvcd_function_selector_neon.c",
+ "decoder/arm/svc/isvcd_intra_resamp_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c",
+ "decoder/arm/svc/isvcd_pred_residual_recon_neon.c",
+ "decoder/arm/svc/isvcd_residual_resamp_neon.c",
+ ],
+ },
+ },
+
+ arm64: {
+ srcs: [
+ "decoder/arm/svc/isvcd_function_selector.c",
+ "decoder/arm/svc/isvcd_function_selector_neon.c",
+ "decoder/arm/svc/isvcd_intra_resamp_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c",
+ "decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c",
+ "decoder/arm/svc/isvcd_pred_residual_recon_neon.c",
+ "decoder/arm/svc/isvcd_residual_resamp_neon.c",
+ ],
+ },
+
+ riscv64: {
+ local_include_dirs: [
+ "decoder/riscv/svc",
+ ],
+
+ srcs: [
+ "decoder/riscv/svc/isvcd_function_selector.c",
+ ],
+ },
+ x86: {
+ srcs: [
+ "decoder/x86/svc/isvcd_function_selector.c",
+ "decoder/x86/svc/isvcd_function_selector_sse42.c",
+ "decoder/x86/svc/isvcd_intra_resamp_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_sse42.c",
+ "decoder/x86/svc/isvcd_pred_residual_recon_sse42.c",
+ "decoder/x86/svc/isvcd_residual_resamp_sse42.c",
+ ],
+ },
+
+ x86_64: {
+ srcs: [
+ "decoder/x86/svc/isvcd_function_selector.c",
+ "decoder/x86/svc/isvcd_function_selector_sse42.c",
+ "decoder/x86/svc/isvcd_intra_resamp_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c",
+ "decoder/x86/svc/isvcd_iquant_itrans_sse42.c",
+ "decoder/x86/svc/isvcd_pred_residual_recon_sse42.c",
+ "decoder/x86/svc/isvcd_residual_resamp_sse42.c",
+ ],
+ },
+ },
+}
+
subdirs = ["test"]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6caee5c..9f04b12 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,8 @@ enable_language(ASM)
set(AVC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
set(AVC_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+option(ENABLE_MVC "Enables svcenc and svcdec builds" OFF)
+option(ENABLE_SVC "Enables svcenc and svcdec builds" OFF)
if("${AVC_ROOT}" STREQUAL "${AVC_CONFIG_DIR}")
message(
@@ -36,10 +38,32 @@ libavc_set_link_libraries()
include("${AVC_ROOT}/common/common.cmake")
include("${AVC_ROOT}/decoder/libavcdec.cmake")
+if (${ENABLE_MVC})
+ include("${AVC_ROOT}/decoder/mvc/libmvcdec.cmake")
+endif()
include("${AVC_ROOT}/encoder/libavcenc.cmake")
+if (${ENABLE_SVC})
+ include("${AVC_ROOT}/common/svccommon.cmake")
+ include("${AVC_ROOT}/encoder/svc/libsvcenc.cmake")
+ include("${AVC_ROOT}/decoder/svc/libsvcdec.cmake")
+endif()
include("${AVC_ROOT}/test/decoder/avcdec.cmake")
+if (${ENABLE_MVC})
+ include("${AVC_ROOT}/test/mvcdec/mvcdec.cmake")
+endif()
include("${AVC_ROOT}/test/encoder/avcenc.cmake")
+if (${ENABLE_SVC})
+ include("${AVC_ROOT}/test/svcenc/svcenc.cmake")
+ include("${AVC_ROOT}/test/svcdec/svcdec.cmake")
+endif()
include("${AVC_ROOT}/fuzzer/avc_dec_fuzzer.cmake")
+if (${ENABLE_MVC})
+ include("${AVC_ROOT}/fuzzer/mvc_dec_fuzzer.cmake")
+endif()
include("${AVC_ROOT}/fuzzer/avc_enc_fuzzer.cmake")
+if (${ENABLE_SVC})
+ include("${AVC_ROOT}/fuzzer/svc_enc_fuzzer.cmake")
+ include("${AVC_ROOT}/fuzzer/svc_dec_fuzzer.cmake")
+endif()
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..9a8974d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,187 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright (c) 2015, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/METADATA b/METADATA
index d97975c..5a2a651 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,19 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update libavc
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
+name: "libavc"
+description: "Android fork of the libavc library."
third_party {
+ url {
+ type: GIT
+ value: "https://github.com/ittiam-systems/libavc.git"
+ }
+ version: "v1.1.1"
license_type: NOTICE
+ last_upgrade_date {
+ year: 2023
+ month: 3
+ day: 15
+ }
}
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
index 85ada3b..468e9d1 100644
--- a/cmake/utils.cmake
+++ b/cmake/utils.cmake
@@ -1,4 +1,5 @@
include(CheckCXXCompilerFlag)
+set(CMAKE_C_STANDARD 90)
# Adds compiler options for all targets
function(libavc_add_compile_options)
@@ -9,6 +10,7 @@ function(libavc_add_compile_options)
else()
add_compile_options(-msse4.2 -mno-avx)
endif()
+ add_compile_options(-Wdeclaration-after-statement)
set(CMAKE_REQUIRED_FLAGS -fsanitize=fuzzer-no-link)
check_cxx_compiler_flag(-fsanitize=fuzzer-no-link
@@ -32,8 +34,6 @@ endfunction()
# Adds defintions for all targets
function(libavc_add_definitions)
- add_definitions(-DPROFILE_ENABLE -DMD5_DISABLE)
-
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
add_definitions(-DARMV8 -DDEFAULT_ARCH=D_ARCH_ARMV8_GENERIC)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch32")
diff --git a/common/arm/svc/isvc_intra_sampling_neon.c b/common/arm/svc/isvc_intra_sampling_neon.c
new file mode 100644
index 0000000..661a21e
--- /dev/null
+++ b/common/arm/svc/isvc_intra_sampling_neon.c
@@ -0,0 +1,485 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ * *******************************************************************************
+ * * @file
+ * isvc_intra_sampling_neon.c
+ *
+ * @brief
+ * neon variants of intra sampling functions used by IBL mode
+ *
+ * *******************************************************************************
+ */
+
+#include <arm_neon.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_intra_resample.h"
+
+void isvc_interpolate_base_luma_dyadic_neon(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_y;
+ WORD16 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp = pu1_inp_buf;
+ UWORD8 *pu1_out = pu1_out_buf;
+ WORD16 *pi2_tmp = pi2_tmp_filt_buf;
+
+ int16x4_t i4_rslt_vert_16x4_1, i4_rslt_vert_16x4_2;
+ uint8x8_t i4_samp_vert_8x8_0, i4_samp_vert_8x8_1, i4_samp_vert_8x8_2, i4_samp_vert_8x8_3;
+ int16x8_t i4_rslt_vert_16x8_0, i4_rslt_vert_16x8_2;
+
+ /* Horizontal interpolation */
+ int32x4_t i4_rslt_horz_r0_1, i4_rslt_horz_r1_1, i4_rslt_horz_r0_2, i4_rslt_horz_r1_2;
+ uint16x4_t i4_rslt_horz_r0_1_tmp, i4_rslt_horz_r1_1_tmp, i4_rslt_horz_r0_2_tmp,
+ i4_rslt_horz_r1_2_tmp;
+ uint16x8_t rslt_16x8_t_1, rslt_16x8_t_2;
+
+ int16x4_t i4_samp_horz_16x4_0, i4_samp_horz_16x4_1, i4_samp_horz_16x4_2, i4_samp_horz_16x4_3,
+ i4_samp_horz_16x4_4;
+ int16x4_t i4_samp_horz_16x4_5, i4_samp_horz_16x4_6, i4_samp_horz_16x4_7, i4_samp_horz_16x4_8;
+ int16_t i4_coeff_c0 = -3;
+ int16_t i4_coeff_c1 = 28;
+ int16_t i4_coeff_c2 = 8;
+ int16_t i4_coeff_c3 = -1;
+ int32x4x2_t i4_rslt_horz_r0_tmp32, i4_rslt_horz_r1_tmp32;
+ int32x4_t const_512_32x4 = vdupq_n_s32(512);
+
+ /* Filter coefficient values for phase 4 */
+ i4_coeff_0 = -3;
+ i4_coeff_1 = 28;
+ i4_coeff_2 = 8;
+ i4_coeff_3 = -1;
+
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+
+ /* Vertical interpolation */
+ {
+ /* First 64 bits*/
+ i4_samp_vert_8x8_0 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_1 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_2 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_3);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_0);
+
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_0);
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_0);
+ i4_rslt_vert_16x8_0 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_0,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_0,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_0,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_3);
+
+ i4_rslt_vert_16x8_2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_3);
+ i4_rslt_vert_16x8_2 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_2,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_2);
+ i4_rslt_vert_16x8_2 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_2,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_1);
+ i4_rslt_vert_16x8_2 =
+ vmlaq_n_s16(i4_rslt_vert_16x8_2,
+ vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_0);
+
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_0));
+ pi2_tmp += i4_filt_stride;
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_2));
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ }
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_0);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_3);
+
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_0));
+ }
+
+ {
+ /* Remaining 32 bits */
+ pu1_inp = pu1_inp_buf + 8;
+ pi2_tmp = pi2_tmp_filt_buf + 8;
+
+ i4_samp_vert_8x8_0 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_1 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_2 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x4_1 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_3);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))),
+ i4_coeff_2);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))),
+ i4_coeff_1);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))),
+ i4_coeff_0);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+
+ i4_rslt_vert_16x4_1 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_0);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))), i4_coeff_1);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))), i4_coeff_2);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))), i4_coeff_3);
+
+ i4_rslt_vert_16x4_2 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_3);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))), i4_coeff_2);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))), i4_coeff_1);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))), i4_coeff_0);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ pi2_tmp += i4_filt_stride;
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_2));
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ }
+
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const UWORD8 *) pu1_inp);
+
+ i4_rslt_vert_16x4_1 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_0);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))),
+ i4_coeff_1);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))),
+ i4_coeff_2);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))),
+ i4_coeff_3);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ }
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ i4_samp_horz_16x4_0 = vld1_s16(pi2_tmp);
+ i4_samp_horz_16x4_1 = vld1_s16(pi2_tmp + 1);
+ i4_samp_horz_16x4_2 = vld1_s16(pi2_tmp + 2);
+ i4_samp_horz_16x4_3 = vld1_s16(pi2_tmp + 3);
+ i4_samp_horz_16x4_4 = vld1_s16(pi2_tmp + 4);
+ i4_samp_horz_16x4_5 = vld1_s16(pi2_tmp + 5);
+ i4_samp_horz_16x4_6 = vld1_s16(pi2_tmp + 6);
+ i4_samp_horz_16x4_7 = vld1_s16(pi2_tmp + 7);
+ i4_samp_horz_16x4_8 = vld1_s16(pi2_tmp + 8);
+
+ i4_rslt_horz_r0_1 =
+ vmull_n_s16(i4_samp_horz_16x4_0, i4_coeff_c3); /* a0c3 a1c3 a2c3 a3c3 */
+ i4_rslt_horz_r0_1 =
+ vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_1,
+ i4_coeff_c2); /* a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 */
+ i4_rslt_horz_r0_1 = vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_2, i4_coeff_c1);
+ i4_rslt_horz_r0_1 = vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_3, i4_coeff_c0);
+ /* i4_rslt_horz_r0_1 : contains res at even pos:0,2,4,6 */
+
+ i4_rslt_horz_r1_1 =
+ vmull_n_s16(i4_samp_horz_16x4_1, i4_coeff_c0); /* a0c0 a1c0 a2c0 a3c0 */
+ i4_rslt_horz_r1_1 =
+ vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_2,
+ i4_coeff_c1); /* a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 */
+ i4_rslt_horz_r1_1 = vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_3, i4_coeff_c2);
+ i4_rslt_horz_r1_1 = vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_4, i4_coeff_c3);
+ /* i4_rslt_horz_r1_1 : contains res at odd pos:1,3,5,7 */
+
+ i4_rslt_horz_r0_2 =
+ vmull_n_s16(i4_samp_horz_16x4_4, i4_coeff_c3); /* a0c3 a1c3 a2c3 a3c3 */
+ i4_rslt_horz_r0_2 =
+ vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_5,
+ i4_coeff_c2); /* a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 */
+ i4_rslt_horz_r0_2 = vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_6, i4_coeff_c1);
+ i4_rslt_horz_r0_2 = vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_7, i4_coeff_c0);
+ /* i4_rslt_horz_r0_1 : contains res at even pos:8,10,12,14 */
+
+ i4_rslt_horz_r1_2 =
+ vmull_n_s16(i4_samp_horz_16x4_5, i4_coeff_c0); /* a0c0 a1c0 a2c0 a3c0 */
+ i4_rslt_horz_r1_2 =
+ vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_6,
+ i4_coeff_c1); /* a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 */
+ i4_rslt_horz_r1_2 = vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_7, i4_coeff_c2);
+ i4_rslt_horz_r1_2 = vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_8, i4_coeff_c3);
+ /* i4_rslt_horz_r1_1 : contains res at odd pos:1,3,5,7 */
+
+ i4_rslt_horz_r0_tmp32 = vzipq_s32(i4_rslt_horz_r0_1, i4_rslt_horz_r1_1);
+ i4_rslt_horz_r1_tmp32 = vzipq_s32(i4_rslt_horz_r0_2, i4_rslt_horz_r1_2);
+
+ i4_rslt_horz_r0_1 = vaddq_s32(i4_rslt_horz_r0_tmp32.val[0], const_512_32x4);
+ i4_rslt_horz_r1_1 = vaddq_s32(i4_rslt_horz_r0_tmp32.val[1], const_512_32x4);
+ i4_rslt_horz_r0_2 = vaddq_s32(i4_rslt_horz_r1_tmp32.val[0], const_512_32x4);
+ i4_rslt_horz_r1_2 = vaddq_s32(i4_rslt_horz_r1_tmp32.val[1], const_512_32x4);
+
+ i4_rslt_horz_r0_1_tmp = vqshrun_n_s32(i4_rslt_horz_r0_1, 10);
+ i4_rslt_horz_r1_1_tmp = vqshrun_n_s32(i4_rslt_horz_r1_1, 10);
+
+ i4_rslt_horz_r0_2_tmp = vqshrun_n_s32(i4_rslt_horz_r0_2, 10);
+ i4_rslt_horz_r1_2_tmp = vqshrun_n_s32(i4_rslt_horz_r1_2, 10);
+
+ rslt_16x8_t_1 = vcombine_u16(i4_rslt_horz_r0_1_tmp, i4_rslt_horz_r1_1_tmp);
+ rslt_16x8_t_2 = vcombine_u16(i4_rslt_horz_r0_2_tmp, i4_rslt_horz_r1_2_tmp);
+
+ vst1_u8(pu1_out, vqmovn_u16(rslt_16x8_t_1));
+ vst1_u8(pu1_out + 8, vqmovn_u16(rslt_16x8_t_2));
+
+ pu1_out += i4_out_stride;
+ pi2_tmp += i4_filt_stride;
+ }
+}
+
+void isvc_horz_interpol_chroma_dyadic_neon(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ UWORD8 *pu1_out = pu1_out_buf;
+ WORD16 *pi2_tmp = pi2_tmp_filt_buf;
+ WORD32 i4_filt_stride = 6;
+ WORD32 i4_dst_stride = i4_out_stride;
+
+ int16x8_t i4_samp_horz_16x8_r0_0, i4_samp_horz_16x8_r0_1, i4_samp_horz_16x8_r0_2;
+ int16x8_t i4_samp_horz_16x8_r1_0, i4_samp_horz_16x8_r1_1, i4_samp_horz_16x8_r1_2;
+ int16x8_t i4_rslt_horz_r0_1, i4_rslt_horz_r0_2;
+ int16x8_t i4_rslt_horz_r1_1, i4_rslt_horz_r1_2;
+
+ int16x8x2_t temp_horz_16x8_r0;
+ int16x8x2_t temp_horz_16x8_r1;
+ int16x8_t final_horz_16x8_r0_1;
+ int16x8_t final_horz_16x8_r1_1;
+
+ uint8x16_t i4_out_horz_8x16_r0, i4_out_horz_8x16_r1;
+ uint8x16_t chroma_mask_8x16 = vreinterpretq_u8_u16(vdupq_n_u16(0x00ff));
+
+ i4_coeff_0 = 16 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 16 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_horz_16x8_r0_0 = vld1q_s16(pi2_tmp); /* a0 a1 a2 a3 a4 a5 a6 a7 */
+ i4_samp_horz_16x8_r0_1 = vld1q_s16(pi2_tmp + 1); /* a1 a2 a3 a4 */
+ i4_samp_horz_16x8_r0_2 = vld1q_s16(pi2_tmp + 2); /* a2 a3 a4 a5 */
+
+ i4_samp_horz_16x8_r1_0 = vld1q_s16(pi2_tmp + i4_filt_stride);
+ i4_samp_horz_16x8_r1_1 = vld1q_s16(pi2_tmp + i4_filt_stride + 1);
+ i4_samp_horz_16x8_r1_2 = vld1q_s16(pi2_tmp + (i4_filt_stride + 2));
+
+ i4_rslt_horz_r0_1 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_0, i4_coeff_0); /* a0c0 a1c0 a2c0 a3c0 */
+ i4_rslt_horz_r0_2 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_1, i4_coeff_2); /* a1c2 a2c2 a3c2 a4c2 */
+
+ i4_rslt_horz_r0_1 = vmlaq_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x8_r0_1,
+ i4_coeff_1); /* a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 */
+ i4_rslt_horz_r0_2 = vmlaq_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x8_r0_2,
+ i4_coeff_3); /* a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3 */
+
+ i4_rslt_horz_r1_1 = vmulq_n_s16(i4_samp_horz_16x8_r1_0, i4_coeff_0);
+ i4_rslt_horz_r1_2 = vmulq_n_s16(i4_samp_horz_16x8_r1_1, i4_coeff_2);
+
+ i4_rslt_horz_r1_1 = vmlaq_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x8_r1_1, i4_coeff_1);
+ i4_rslt_horz_r1_2 = vmlaq_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x8_r1_2, i4_coeff_3);
+
+ temp_horz_16x8_r0 = vzipq_s16(i4_rslt_horz_r0_1, i4_rslt_horz_r0_2);
+ temp_horz_16x8_r1 = vzipq_s16(i4_rslt_horz_r1_1, i4_rslt_horz_r1_2);
+
+ final_horz_16x8_r0_1 = temp_horz_16x8_r0.val[0];
+ final_horz_16x8_r1_1 = temp_horz_16x8_r1.val[0];
+
+ final_horz_16x8_r0_1 = vrshrq_n_s16(final_horz_16x8_r0_1, 8);
+ final_horz_16x8_r1_1 = vrshrq_n_s16(final_horz_16x8_r1_1, 8);
+
+ i4_out_horz_8x16_r0 = vld1q_u8(pu1_out);
+ i4_out_horz_8x16_r1 = vld1q_u8(pu1_out + i4_dst_stride);
+
+ i4_out_horz_8x16_r0 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r0_1),
+ i4_out_horz_8x16_r0);
+ i4_out_horz_8x16_r1 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r1_1),
+ i4_out_horz_8x16_r1);
+
+ vst1q_u8(pu1_out, i4_out_horz_8x16_r0);
+ vst1q_u8(pu1_out + i4_dst_stride, i4_out_horz_8x16_r1);
+
+ /* Incrementing ptr */
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_out += (i4_dst_stride << 1);
+ }
+}
+
+void isvc_vert_interpol_chroma_dyadic_neon(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_src_stride = DYADIC_REF_W_C;
+ UWORD8 *pu1_inp = pu1_inp_buf;
+ WORD16 *pi2_tmp = pi2_tmp_filt_buf;
+
+ uint8x8_t i4_samp_vert_8x8_r0, i4_samp_vert_8x8_r1, i4_samp_vert_8x8_r2, i4_samp_vert_8x8_r3,
+ i4_samp_vert_8x8_r4, i4_samp_vert_8x8_r5;
+
+ int16x8_t i4_rslt_vert_16x8_r0, i4_rslt_vert_16x8_r1, i4_rslt_vert_16x8_r2,
+ i4_rslt_vert_16x8_r3, i4_rslt_vert_16x8_r4, i4_rslt_vert_16x8_r5, i4_rslt_vert_16x8_r6,
+ i4_rslt_vert_16x8_r7;
+
+ i4_coeff_0 = 16 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 16 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ /* Vertical interpolation */
+ i4_samp_vert_8x8_r0 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r1 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r2 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r3 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r4 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r5 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x8_r0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_0);
+ i4_rslt_vert_16x8_r0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_1);
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_r0);
+
+ i4_rslt_vert_16x8_r1 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_2);
+ i4_rslt_vert_16x8_r1 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r1, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 6, i4_rslt_vert_16x8_r1);
+
+ i4_rslt_vert_16x8_r2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_0);
+ i4_rslt_vert_16x8_r2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 12, i4_rslt_vert_16x8_r2);
+
+ i4_rslt_vert_16x8_r3 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_2);
+ i4_rslt_vert_16x8_r3 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r3, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 18, i4_rslt_vert_16x8_r3);
+
+ i4_rslt_vert_16x8_r4 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_0);
+ i4_rslt_vert_16x8_r4 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r4, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 24, i4_rslt_vert_16x8_r4);
+
+ i4_rslt_vert_16x8_r5 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_2);
+ i4_rslt_vert_16x8_r5 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r5, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 30, i4_rslt_vert_16x8_r5);
+
+ i4_rslt_vert_16x8_r6 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_0);
+ i4_rslt_vert_16x8_r6 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r6, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 36, i4_rslt_vert_16x8_r6);
+
+ i4_rslt_vert_16x8_r7 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_2);
+ i4_rslt_vert_16x8_r7 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r7, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r5)), i4_coeff_3);
+ vst1_s16(pi2_tmp + 42, vget_low_s16(i4_rslt_vert_16x8_r7));
+ vst1q_lane_s16(pi2_tmp + 46, i4_rslt_vert_16x8_r7, 4);
+ vst1q_lane_s16(pi2_tmp + 47, i4_rslt_vert_16x8_r7, 5);
+}
diff --git a/common/arm/svc/isvc_iquant_itrans_recon_neon.c b/common/arm/svc/isvc_iquant_itrans_recon_neon.c
new file mode 100644
index 0000000..270adde
--- /dev/null
+++ b/common/arm/svc/isvc_iquant_itrans_recon_neon.c
@@ -0,0 +1,1783 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ * *******************************************************************************
+ * * @file
+ * isvc_iquant_itrans_recon_neon.c
+ *
+ * @brief
+ * neon variants of inverse transform and quantization functions
+ *
+ * *******************************************************************************
+ */
+#include <arm_neon.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+void isvc_iquant_itrans_recon_4x4_neon(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd01_in, resd23_in;
+ int16x8_t pred01_in, pred23_in;
+ uint8x8_t pred01_un, pred23_un;
+
+ int16x8_t pos_255_16x8 = vdupq_n_s16(((WORD16) UINT8_MAX));
+ int16x8_t neg_255_16x8 = vdupq_n_s16(-((WORD16) UINT8_MAX));
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(i4_iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ resd01_in = vcombine_s16(x0_16x4, x1_16x4);
+ resd23_in = vcombine_s16(x2_16x4, x3_16x4);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ resd01_in = vmaxq_s16(resd01_in, neg_255_16x8);
+ resd23_in = vmaxq_s16(resd23_in, neg_255_16x8);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ resd01_in = vminq_s16(resd01_in, pos_255_16x8);
+ resd23_in = vminq_s16(resd23_in, pos_255_16x8);
+
+ /* Load pred */
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ pred01_in = vcombine_s16(vget_low_s16(pred0), vget_low_s16(pred1));
+ pred23_in = vcombine_s16(vget_low_s16(pred2), vget_low_s16(pred3));
+
+ /* Out pixel = pred + res */
+ pred01_in = vaddq_s16(pred01_in, resd01_in);
+ pred23_in = vaddq_s16(pred23_in, resd23_in);
+
+ /* Convert to 8 bit unsigned with saturation */
+ pred01_un = vqmovun_s16(pred01_in);
+ pred23_un = vqmovun_s16(pred23_in);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred01_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred01_un), 1);
+ vst1_lane_u32((uint32_t *) (pu1_out + (i4_out_stride << 1)), vreinterpret_u32_u8(pred23_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + ((i4_out_stride << 1) + i4_out_stride)),
+ vreinterpret_u32_u8(pred23_un), 1);
+}
+
+void isvc_iquant_itrans_recon_4x4_with_res_output_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd01_in, resd23_in;
+ int16x8_t pred01_in, pred23_in;
+ uint8x8_t pred01_un, pred23_un;
+
+ int16x4_t pos_255_16x4 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255_16x4 = vdup_n_s16(-((WORD16) UINT8_MAX));
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(i4_iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ x0_16x4 = vmax_s16(x0_16x4, neg_255_16x4);
+ x1_16x4 = vmax_s16(x1_16x4, neg_255_16x4);
+ x2_16x4 = vmax_s16(x2_16x4, neg_255_16x4);
+ x3_16x4 = vmax_s16(x3_16x4, neg_255_16x4);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ x0_16x4 = vmin_s16(x0_16x4, pos_255_16x4);
+ x1_16x4 = vmin_s16(x1_16x4, pos_255_16x4);
+ x2_16x4 = vmin_s16(x2_16x4, pos_255_16x4);
+ x3_16x4 = vmin_s16(x3_16x4, pos_255_16x4);
+
+ vst1_s16(pi2_res, x0_16x4);
+ vst1_s16(pi2_res + i4_res_stride, x1_16x4);
+ vst1_s16(pi2_res + (i4_res_stride << 1), x2_16x4);
+ vst1_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, x3_16x4);
+
+ resd01_in = vcombine_s16(x0_16x4, x1_16x4);
+ resd23_in = vcombine_s16(x2_16x4, x3_16x4);
+
+ /* Load pred */
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ pred01_in = vcombine_s16(vget_low_s16(pred0), vget_low_s16(pred1));
+ pred23_in = vcombine_s16(vget_low_s16(pred2), vget_low_s16(pred3));
+
+ /* Out pixel = pred + res */
+ pred01_in = vaddq_s16(pred01_in, resd01_in);
+ pred23_in = vaddq_s16(pred23_in, resd23_in);
+
+ /* Convert to 8 bit unsigned with saturation */
+ pred01_un = vqmovun_s16(pred01_in);
+ pred23_un = vqmovun_s16(pred23_in);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred01_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred01_un), 1);
+ vst1_lane_u32((uint32_t *) (pu1_out + (i4_out_stride << 1)), vreinterpret_u32_u8(pred23_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + ((i4_out_stride << 1) + i4_out_stride)),
+ vreinterpret_u32_u8(pred23_un), 1);
+}
+
+void isvc_iquant_itrans_recon_4x4_with_res_accumulate_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x4_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd01_in, resd23_in;
+ int16x8_t pred01_in, pred23_in;
+ uint8x8_t pred01_un, pred23_un;
+
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ int16x4_t pos_255 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255 = vdup_n_s16(-((WORD16) UINT8_MAX));
+
+ UNUSED(u1_res_accumulate);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(i4_iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ /* Accumulating Res */
+
+ /* Load Res pred */
+ resd0_in = vld1_s16((int16_t *) pi2_res_pred);
+ resd1_in = vld1_s16((int16_t *) pi2_res_pred + i4_res_pred_stride);
+ resd2_in = vld1_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 2));
+ resd3_in = vld1_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 3));
+
+ /* Add res pred with res obtained */
+ resd0_in = vadd_s16(resd0_in, x0_16x4);
+ resd1_in = vadd_s16(resd1_in, x1_16x4);
+ resd2_in = vadd_s16(resd2_in, x2_16x4);
+ resd3_in = vadd_s16(resd3_in, x3_16x4);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ resd0_in = vmax_s16(resd0_in, neg_255);
+ resd1_in = vmax_s16(resd1_in, neg_255);
+ resd2_in = vmax_s16(resd2_in, neg_255);
+ resd3_in = vmax_s16(resd3_in, neg_255);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ resd0_in = vmin_s16(resd0_in, pos_255);
+ resd1_in = vmin_s16(resd1_in, pos_255);
+ resd2_in = vmin_s16(resd2_in, pos_255);
+ resd3_in = vmin_s16(resd3_in, pos_255);
+
+ vst1_s16(pi2_res, resd0_in);
+ vst1_s16(pi2_res + i4_res_stride, resd1_in);
+ vst1_s16(pi2_res + (i4_res_stride << 1), resd2_in);
+ vst1_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resd3_in);
+
+ resd01_in = vcombine_s16(resd0_in, resd1_in);
+ resd23_in = vcombine_s16(resd2_in, resd3_in);
+
+ /* Load pred */
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ pred01_in = vcombine_s16(vget_low_s16(pred0), vget_low_s16(pred1));
+ pred23_in = vcombine_s16(vget_low_s16(pred2), vget_low_s16(pred3));
+
+ /* Out pixel = pred + res */
+ pred01_in = vaddq_s16(pred01_in, resd01_in);
+ pred23_in = vaddq_s16(pred23_in, resd23_in);
+
+ /* Convert to 8 bit unsigned with saturation */
+ pred01_un = vqmovun_s16(pred01_in);
+ pred23_un = vqmovun_s16(pred23_in);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred01_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred01_un), 1);
+ vst1_lane_u32((uint32_t *) (pu1_out + (i4_out_stride << 1)), vreinterpret_u32_u8(pred23_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + ((i4_out_stride << 1) + i4_out_stride)),
+ vreinterpret_u32_u8(pred23_un), 1);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD16 i2_rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t rec0, rec1, rec2, rec3;
+ uint8x8_t rec0_un, rec1_un, rec2_un, rec3_un;
+ uint8x8_t out0, out1, out2, out3;
+
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+
+ int16x4_t pos_255_16x4 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255_16x4 = vdup_n_s16(-((WORD16) UINT8_MAX));
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ int32x4_t rnd_fact = vdupq_n_s32(i2_rnd_factor);
+
+ UNUSED(i4_iq_start_idx);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ x0_16x4 = vmax_s16(x0_16x4, neg_255_16x4);
+ x1_16x4 = vmax_s16(x1_16x4, neg_255_16x4);
+ x2_16x4 = vmax_s16(x2_16x4, neg_255_16x4);
+ x3_16x4 = vmax_s16(x3_16x4, neg_255_16x4);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ x0_16x4 = vmin_s16(x0_16x4, pos_255_16x4);
+ x1_16x4 = vmin_s16(x1_16x4, pos_255_16x4);
+ x2_16x4 = vmin_s16(x2_16x4, pos_255_16x4);
+ x3_16x4 = vmin_s16(x3_16x4, pos_255_16x4);
+
+ x0_16x8 = vreinterpretq_s16_s32(vmovl_s16(x0_16x4));
+ x1_16x8 = vreinterpretq_s16_s32(vmovl_s16(x1_16x4));
+ x2_16x8 = vreinterpretq_s16_s32(vmovl_s16(x2_16x4));
+ x3_16x8 = vreinterpretq_s16_s32(vmovl_s16(x3_16x4));
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = pred + res */
+ rec0 = vaddq_s16(pred0, x0_16x8);
+ rec1 = vaddq_s16(pred1, x1_16x8);
+ rec2 = vaddq_s16(pred2, x2_16x8);
+ rec3 = vaddq_s16(pred3, x3_16x8);
+
+ out0 = vld1_u8(pu1_out);
+ out1 = vld1_u8(pu1_out + i4_out_stride);
+ out2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ out3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ /* Convert to 8 bit unsigned with saturation */
+ rec0_un = vqmovun_s16(rec0);
+ rec1_un = vqmovun_s16(rec1);
+ rec2_un = vqmovun_s16(rec2);
+ rec3_un = vqmovun_s16(rec3);
+
+ /* Store in alternate postions */
+ out0 = vbsl_u8(chroma_mask_8x8, rec0_un, out0);
+ out1 = vbsl_u8(chroma_mask_8x8, rec1_un, out1);
+ out2 = vbsl_u8(chroma_mask_8x8, rec2_un, out2);
+ out3 = vbsl_u8(chroma_mask_8x8, rec3_un, out3);
+
+ vst1_u8((pu1_out), out0);
+ vst1_u8((pu1_out + i4_out_stride), out1);
+ vst1_u8((pu1_out + (i4_out_stride << 1)), out2);
+ vst1_u8((pu1_out + ((i4_out_stride << 1) + i4_out_stride)), out3);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_with_res_output_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD16 i2_rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t rec0, rec1, rec2, rec3;
+ uint8x8_t rec0_un, rec1_un, rec2_un, rec3_un;
+ uint8x8_t out0, out1, out2, out3;
+ int16x8_t resout0, resout1, resout2, resout3;
+
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+ uint16x8_t chroma_mask_16x8 = {0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000};
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ int32x4_t rnd_fact = vdupq_n_s32(i2_rnd_factor);
+ int16x4_t pos_255_16x4 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255_16x4 = vdup_n_s16(-((WORD16) UINT8_MAX));
+
+ UNUSED(i4_iq_start_idx);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ x0_16x4 = vmax_s16(x0_16x4, neg_255_16x4);
+ x1_16x4 = vmax_s16(x1_16x4, neg_255_16x4);
+ x2_16x4 = vmax_s16(x2_16x4, neg_255_16x4);
+ x3_16x4 = vmax_s16(x3_16x4, neg_255_16x4);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ x0_16x4 = vmin_s16(x0_16x4, pos_255_16x4);
+ x1_16x4 = vmin_s16(x1_16x4, pos_255_16x4);
+ x2_16x4 = vmin_s16(x2_16x4, pos_255_16x4);
+ x3_16x4 = vmin_s16(x3_16x4, pos_255_16x4);
+
+ resout0 = vld1q_s16(pi2_res);
+ resout1 = vld1q_s16(pi2_res + i4_res_stride);
+ resout2 = vld1q_s16(pi2_res + i4_res_stride * 2);
+ resout3 = vld1q_s16(pi2_res + i4_res_stride * 3);
+
+ x0_16x8 = vreinterpretq_s16_s32(vmovl_s16(x0_16x4));
+ x1_16x8 = vreinterpretq_s16_s32(vmovl_s16(x1_16x4));
+ x2_16x8 = vreinterpretq_s16_s32(vmovl_s16(x2_16x4));
+ x3_16x8 = vreinterpretq_s16_s32(vmovl_s16(x3_16x4));
+
+ /* Storing res in alternate positions */
+ resout0 = vbslq_s16(chroma_mask_16x8, x0_16x8, resout0);
+ resout1 = vbslq_s16(chroma_mask_16x8, x1_16x8, resout1);
+ resout2 = vbslq_s16(chroma_mask_16x8, x2_16x8, resout2);
+ resout3 = vbslq_s16(chroma_mask_16x8, x3_16x8, resout3);
+
+ vst1q_s16(pi2_res, resout0);
+ vst1q_s16(pi2_res + i4_res_stride, resout1);
+ vst1q_s16(pi2_res + (i4_res_stride << 1), resout2);
+ vst1q_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resout3);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = pred + res */
+ rec0 = vaddq_s16(pred0, x0_16x8);
+ rec1 = vaddq_s16(pred1, x1_16x8);
+ rec2 = vaddq_s16(pred2, x2_16x8);
+ rec3 = vaddq_s16(pred3, x3_16x8);
+
+ out0 = vld1_u8(pu1_out);
+ out1 = vld1_u8(pu1_out + i4_out_stride);
+ out2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ out3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ /* Convert to 8 bit unsigned with saturation */
+ rec0_un = vqmovun_s16(rec0);
+ rec1_un = vqmovun_s16(rec1);
+ rec2_un = vqmovun_s16(rec2);
+ rec3_un = vqmovun_s16(rec3);
+
+ /* Store output pixels in alternate positions */
+ out0 = vbsl_u8(chroma_mask_8x8, rec0_un, out0);
+ out1 = vbsl_u8(chroma_mask_8x8, rec1_un, out1);
+ out2 = vbsl_u8(chroma_mask_8x8, rec2_un, out2);
+ out3 = vbsl_u8(chroma_mask_8x8, rec3_un, out3);
+
+ vst1_u8((pu1_out), out0);
+ vst1_u8((pu1_out + i4_out_stride), out1);
+ vst1_u8((pu1_out + (i4_out_stride << 1)), out2);
+ vst1_u8((pu1_out + ((i4_out_stride << 1) + i4_out_stride)), out3);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_with_res_accumulate_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD16 i2_rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t rec0, rec1, rec2, rec3;
+ uint8x8_t rec0_un, rec1_un, rec2_un, rec3_un;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd1_in_mask, resd2_in_mask, resd3_in_mask;
+ uint8x8_t out0, out1, out2, out3;
+ int16x8_t resout0, resout1, resout2, resout3;
+ int16x8_t pos_255 = vdupq_n_s16(((WORD16) UINT8_MAX));
+ int16x8_t neg_255 = vdupq_n_s16(-((WORD16) UINT8_MAX));
+
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+ uint16x8_t chroma_mask_16x8 = {0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000};
+
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ int32x4_t rnd_fact = vdupq_n_s32(i2_rnd_factor);
+
+ int16x8_t resd0_in_mask = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
+
+ UNUSED(i4_iq_start_idx);
+ UNUSED(u1_res_accumulate);
+
+ resd1_in_mask = resd0_in_mask;
+ resd2_in_mask = resd0_in_mask;
+ resd3_in_mask = resd0_in_mask;
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4);
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4);
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4);
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ /* row 0 to row 3 */
+ xx0_16x4x2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx1_16x4x2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ x0_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vzip_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Store Horz transform output into temp */
+ vst1_s16(pi2_tmp, x0_16x4);
+ vst1_s16(pi2_tmp + 4, x1_16x4);
+ vst1_s16(pi2_tmp + 8, x2_16x4);
+ vst1_s16(pi2_tmp + 12, x3_16x4);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1);
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4);
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4);
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4);
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4);
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4);
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4);
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ resd0_in = vld1q_s16((int16_t *) pi2_res_pred);
+ resd1_in = vld1q_s16((int16_t *) pi2_res_pred + i4_res_pred_stride);
+ resd2_in = vld1q_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 3));
+
+ /* Mask alternate values */
+ resd0_in_mask = vbslq_s16(chroma_mask_16x8, resd0_in, resd0_in_mask);
+ resd1_in_mask = vbslq_s16(chroma_mask_16x8, resd1_in, resd1_in_mask);
+ resd2_in_mask = vbslq_s16(chroma_mask_16x8, resd2_in, resd2_in_mask);
+ resd3_in_mask = vbslq_s16(chroma_mask_16x8, resd3_in, resd3_in_mask);
+
+ x0_16x8 = vreinterpretq_s16_s32(vmovl_s16(x0_16x4));
+ x1_16x8 = vreinterpretq_s16_s32(vmovl_s16(x1_16x4));
+ x2_16x8 = vreinterpretq_s16_s32(vmovl_s16(x2_16x4));
+ x3_16x8 = vreinterpretq_s16_s32(vmovl_s16(x3_16x4));
+
+ resd0_in = vaddq_s16(resd0_in_mask, x0_16x8);
+ resd1_in = vaddq_s16(resd1_in_mask, x1_16x8);
+ resd2_in = vaddq_s16(resd2_in_mask, x2_16x8);
+ resd3_in = vaddq_s16(resd3_in_mask, x3_16x8);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ resd0_in = vmaxq_s16(resd0_in, neg_255);
+ resd1_in = vmaxq_s16(resd1_in, neg_255);
+ resd2_in = vmaxq_s16(resd2_in, neg_255);
+ resd3_in = vmaxq_s16(resd3_in, neg_255);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ resd0_in = vminq_s16(resd0_in, pos_255);
+ resd1_in = vminq_s16(resd1_in, pos_255);
+ resd2_in = vminq_s16(resd2_in, pos_255);
+ resd3_in = vminq_s16(resd3_in, pos_255);
+
+ resout0 = vld1q_s16(pi2_res);
+ resout1 = vld1q_s16(pi2_res + i4_res_stride);
+ resout2 = vld1q_s16(pi2_res + i4_res_stride * 2);
+ resout3 = vld1q_s16(pi2_res + i4_res_stride * 3);
+
+ /* Store res in aternate positions */
+ resout0 = vbslq_s16(chroma_mask_16x8, resd0_in, resout0);
+ resout1 = vbslq_s16(chroma_mask_16x8, resd1_in, resout1);
+ resout2 = vbslq_s16(chroma_mask_16x8, resd2_in, resout2);
+ resout3 = vbslq_s16(chroma_mask_16x8, resd3_in, resout3);
+
+ vst1q_s16(pi2_res, resout0);
+ vst1q_s16(pi2_res + i4_res_stride, resout1);
+ vst1q_s16(pi2_res + (i4_res_stride << 1), resout2);
+ vst1q_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resout3);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (i4_pred_stride * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = pred + res */
+ rec0 = vaddq_s16(pred0, resout0);
+ rec1 = vaddq_s16(pred1, resout1);
+ rec2 = vaddq_s16(pred2, resout2);
+ rec3 = vaddq_s16(pred3, resout3);
+
+ out0 = vld1_u8(pu1_out);
+ out1 = vld1_u8(pu1_out + i4_out_stride);
+ out2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ out3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ /* Convert to 8 bit unsigned with saturation */
+ rec0_un = vqmovun_s16(rec0);
+ rec1_un = vqmovun_s16(rec1);
+ rec2_un = vqmovun_s16(rec2);
+ rec3_un = vqmovun_s16(rec3);
+
+ /* Store output pixels in alternate positions */
+ out0 = vbsl_u8(chroma_mask_8x8, rec0_un, out0);
+ out1 = vbsl_u8(chroma_mask_8x8, rec1_un, out1);
+ out2 = vbsl_u8(chroma_mask_8x8, rec2_un, out2);
+ out3 = vbsl_u8(chroma_mask_8x8, rec3_un, out3);
+
+ vst1_u8((pu1_out), out0);
+ vst1_u8((pu1_out + i4_out_stride), out1);
+ vst1_u8((pu1_out + (i4_out_stride << 1)), out2);
+ vst1_u8((pu1_out + ((i4_out_stride << 1) + i4_out_stride)), out3);
+}
+
+void isvc_iquant_itrans_recon_4x4_dc_neon(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ if(i4_iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_src[0];
+ }
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = Res + pred */
+ pred0 = vaddq_s16(pred0, temp_0);
+ pred1 = vaddq_s16(pred1, temp_0);
+ pred2 = vaddq_s16(pred2, temp_0);
+ pred3 = vaddq_s16(pred3, temp_0);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred0_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred1_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride * 2), vreinterpret_u32_u8(pred2_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride * 3), vreinterpret_u32_u8(pred3_in), 0);
+}
+
+void isvc_iquant_itrans_recon_4x4_dc_with_res_output_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ WORD16 i2_it_out;
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ int16x4_t residue_res;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ if(i4_iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_src[0];
+ }
+
+ i2_it_out = ((i4_iq_out_temp + 32) >> 6);
+ temp_0 = vdupq_n_s16(i2_it_out);
+ residue_res = vdup_n_s16(isvc_get_residue(i2_it_out, 0, 0));
+
+ vst1_s16(pi2_res, residue_res);
+ vst1_s16(pi2_res + i4_res_stride, residue_res);
+ vst1_s16(pi2_res + (i4_res_stride << 1), residue_res);
+ vst1_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, residue_res);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = Res + pred */
+ pred0 = vaddq_s16(pred0, temp_0);
+ pred1 = vaddq_s16(pred1, temp_0);
+ pred2 = vaddq_s16(pred2, temp_0);
+ pred3 = vaddq_s16(pred3, temp_0);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred0_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred1_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride * 2), vreinterpret_u32_u8(pred2_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride * 3), vreinterpret_u32_u8(pred3_in), 0);
+}
+
+void isvc_iquant_itrans_recon_4x4_dc_with_res_accumulate_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ WORD32 i4_iq_out_temp;
+ int16x4_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t pred01_in, pred23_in;
+ uint8x8_t pred01_un, pred23_un;
+
+ int16x4_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd01_in, resd23_in;
+ int16x4_t pos_255 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255 = vdup_n_s16(-((WORD16) UINT8_MAX));
+
+ UNUSED(pi2_tmp);
+ UNUSED(u1_res_accumulate);
+
+ if(i4_iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_src[0];
+ }
+
+ temp_0 = vdup_n_s16((i4_iq_out_temp + 32) >> 6);
+
+ resd0_in = vld1_s16((int16_t *) pi2_res_pred);
+ resd1_in = vld1_s16((int16_t *) pi2_res_pred + i4_res_pred_stride);
+ resd2_in = vld1_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 2));
+ resd3_in = vld1_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 3));
+
+ /* Add res pred to the res obtained */
+ resd0_in = vadd_s16(resd0_in, temp_0);
+ resd1_in = vadd_s16(resd1_in, temp_0);
+ resd2_in = vadd_s16(resd2_in, temp_0);
+ resd3_in = vadd_s16(resd3_in, temp_0);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ resd0_in = vmax_s16(resd0_in, neg_255);
+ resd1_in = vmax_s16(resd1_in, neg_255);
+ resd2_in = vmax_s16(resd2_in, neg_255);
+ resd3_in = vmax_s16(resd3_in, neg_255);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ resd0_in = vmin_s16(resd0_in, pos_255);
+ resd1_in = vmin_s16(resd1_in, pos_255);
+ resd2_in = vmin_s16(resd2_in, pos_255);
+ resd3_in = vmin_s16(resd3_in, pos_255);
+
+ vst1_s16(pi2_res, resd0_in);
+ vst1_s16(pi2_res + i4_res_stride, resd1_in);
+ vst1_s16(pi2_res + (i4_res_stride << 1), resd2_in);
+ vst1_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resd3_in);
+
+ resd01_in = vcombine_s16(resd0_in, resd1_in);
+ resd23_in = vcombine_s16(resd2_in, resd3_in);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ pred01_in = vcombine_s16(vget_low_s16(pred0), vget_low_s16(pred1));
+ pred23_in = vcombine_s16(vget_low_s16(pred2), vget_low_s16(pred3));
+
+ /* Out pixel = Res + pred */
+ pred01_in = vaddq_s16(pred01_in, resd01_in);
+ pred23_in = vaddq_s16(pred23_in, resd23_in);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred01_un = vqmovun_s16(pred01_in);
+ pred23_un = vqmovun_s16(pred23_in);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred01_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + i4_out_stride), vreinterpret_u32_u8(pred01_un), 1);
+ vst1_lane_u32((uint32_t *) (pu1_out + (i4_out_stride << 1)), vreinterpret_u32_u8(pred23_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + ((i4_out_stride << 1) + i4_out_stride)),
+ vreinterpret_u32_u8(pred23_un), 1);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_dc_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ uint8x8_t i4_out_horz_8x8_r0, i4_out_horz_8x8_r1, i4_out_horz_8x8_r2, i4_out_horz_8x8_r3;
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ i4_iq_out_temp = pi2_dc_src[0];
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = Res + pred */
+ pred0 = vaddq_s16(pred0, temp_0);
+ pred1 = vaddq_s16(pred1, temp_0);
+ pred2 = vaddq_s16(pred2, temp_0);
+ pred3 = vaddq_s16(pred3, temp_0);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + i4_out_stride);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ /* Store out pixels in alternate positions */
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 3), i4_out_horz_8x8_r3);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_output_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD16 i2_it_out;
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0, residue_res;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resout0, resout1, resout2, resout3;
+
+ uint8x8_t i4_out_horz_8x8_r0, i4_out_horz_8x8_r1, i4_out_horz_8x8_r2, i4_out_horz_8x8_r3;
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+ uint16x8_t chroma_mask_16x8 = {0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000};
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ i4_iq_out_temp = pi2_dc_src[0];
+
+ i2_it_out = ((i4_iq_out_temp + 32) >> 6);
+ temp_0 = vdupq_n_s16(i2_it_out);
+ residue_res = vdupq_n_s16(isvc_get_residue(i2_it_out, 0, 0));
+
+ resout0 = vld1q_s16(pi2_res);
+ resout1 = vld1q_s16(pi2_res + i4_res_stride);
+ resout2 = vld1q_s16(pi2_res + i4_res_stride * 2);
+ resout3 = vld1q_s16(pi2_res + i4_res_stride * 3);
+
+ /* Store res in alternate positions */
+ resout0 = vbslq_s16(chroma_mask_16x8, residue_res, resout0);
+ resout1 = vbslq_s16(chroma_mask_16x8, residue_res, resout1);
+ resout2 = vbslq_s16(chroma_mask_16x8, residue_res, resout2);
+ resout3 = vbslq_s16(chroma_mask_16x8, residue_res, resout3);
+
+ vst1q_s16(pi2_res, resout0);
+ vst1q_s16(pi2_res + i4_res_stride, resout1);
+ vst1q_s16(pi2_res + (i4_res_stride << 1), resout2);
+ vst1q_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resout3);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = Res + pred */
+ pred0 = vaddq_s16(pred0, temp_0);
+ pred1 = vaddq_s16(pred1, temp_0);
+ pred2 = vaddq_s16(pred2, temp_0);
+ pred3 = vaddq_s16(pred3, temp_0);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ /* Store out pixels in alternate positions */
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + i4_out_stride);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 3), i4_out_horz_8x8_r3);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_accumulate_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resout0, resout1, resout2, resout3;
+ int16x8_t resd1_in_mask, resd2_in_mask, resd3_in_mask;
+ uint8x8_t out0, out1, out2, out3;
+ int16x8_t pos_255 = vdupq_n_s16(((WORD16) UINT8_MAX));
+ int16x8_t neg_255 = vdupq_n_s16(-((WORD16) UINT8_MAX));
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+ uint16x8_t chroma_mask_16x8 = {0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000};
+
+ int16x8_t resd0_in_mask = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(u1_res_accumulate);
+
+ resd1_in_mask = resd0_in_mask;
+ resd2_in_mask = resd0_in_mask;
+ resd3_in_mask = resd0_in_mask;
+
+ i4_iq_out_temp = pi2_dc_src[0];
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+
+ resd0_in = vld1q_s16((int16_t *) pi2_res_pred);
+ resd1_in = vld1q_s16((int16_t *) pi2_res_pred + i4_res_pred_stride);
+ resd2_in = vld1q_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_res_pred + (i4_res_pred_stride * 3));
+
+ /* Mask alternate values of res pred */
+ resd0_in_mask = vbslq_s16(chroma_mask_16x8, resd0_in, resd0_in_mask);
+ resd1_in_mask = vbslq_s16(chroma_mask_16x8, resd1_in, resd1_in_mask);
+ resd2_in_mask = vbslq_s16(chroma_mask_16x8, resd2_in, resd2_in_mask);
+ resd3_in_mask = vbslq_s16(chroma_mask_16x8, resd3_in, resd3_in_mask);
+
+ /* Add res pred to res obtained */
+ resd0_in = vaddq_s16(resd0_in_mask, temp_0);
+ resd1_in = vaddq_s16(resd1_in_mask, temp_0);
+ resd2_in = vaddq_s16(resd2_in_mask, temp_0);
+ resd3_in = vaddq_s16(resd3_in_mask, temp_0);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ resd0_in = vmaxq_s16(resd0_in, neg_255);
+ resd1_in = vmaxq_s16(resd1_in, neg_255);
+ resd2_in = vmaxq_s16(resd2_in, neg_255);
+ resd3_in = vmaxq_s16(resd3_in, neg_255);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ resd0_in = vminq_s16(resd0_in, pos_255);
+ resd1_in = vminq_s16(resd1_in, pos_255);
+ resd2_in = vminq_s16(resd2_in, pos_255);
+ resd3_in = vminq_s16(resd3_in, pos_255);
+
+ resout0 = vld1q_s16(pi2_res);
+ resout1 = vld1q_s16(pi2_res + i4_res_stride);
+ resout2 = vld1q_s16(pi2_res + i4_res_stride * 2);
+ resout3 = vld1q_s16(pi2_res + i4_res_stride * 3);
+
+ /* Store res in alternate positions */
+ resout0 = vbslq_s16(chroma_mask_16x8, resd0_in, resout0);
+ resout1 = vbslq_s16(chroma_mask_16x8, resd1_in, resout1);
+ resout2 = vbslq_s16(chroma_mask_16x8, resd2_in, resout2);
+ resout3 = vbslq_s16(chroma_mask_16x8, resd3_in, resout3);
+
+ vst1q_s16(pi2_res, resout0);
+ vst1q_s16(pi2_res + i4_res_stride, resout1);
+ vst1q_s16(pi2_res + (i4_res_stride << 1), resout2);
+ vst1q_s16(pi2_res + (i4_res_stride << 1) + i4_res_stride, resout3);
+
+ pred0_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred1_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred2_in = vld1_u8(pu1_pred);
+ pu1_pred = pu1_pred + i4_pred_stride;
+ pred3_in = vld1_u8(pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ /* Out pixel = Res + pred */
+ pred0 = vaddq_s16(pred0, resout0);
+ pred1 = vaddq_s16(pred1, resout1);
+ pred2 = vaddq_s16(pred2, resout2);
+ pred3 = vaddq_s16(pred3, resout3);
+
+ /* Convert to unsigned 8 bit with saturation */
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ out0 = vld1_u8(pu1_out);
+ out1 = vld1_u8(pu1_out + i4_out_stride);
+ out2 = vld1_u8(pu1_out + i4_out_stride * 2);
+ out3 = vld1_u8(pu1_out + i4_out_stride * 3);
+
+ /* Store out pixels in alternate positions */
+ out0 = vbsl_u8(chroma_mask_8x8, pred0_in, out0);
+ out1 = vbsl_u8(chroma_mask_8x8, pred1_in, out1);
+ out2 = vbsl_u8(chroma_mask_8x8, pred2_in, out2);
+ out3 = vbsl_u8(chroma_mask_8x8, pred3_in, out3);
+
+ vst1_u8((uint8_t *) (pu1_out), out0);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride), out1);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 2), out2);
+ vst1_u8((uint8_t *) (pu1_out + i4_out_stride * 3), out3);
+}
diff --git a/common/arm/svc/isvc_mem_fns_neon.c b/common/arm/svc/isvc_mem_fns_neon.c
new file mode 100644
index 0000000..f2cf448
--- /dev/null
+++ b/common/arm/svc/isvc_mem_fns_neon.c
@@ -0,0 +1,151 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ * *******************************************************************************
+ * * @file
+ * isvc_mem_fns_av8.c
+ *
+ * @brief
+ * armv8 variants of
+ * functions used for memory operations
+ *
+ * *******************************************************************************
+ */
+#include <arm_neon.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_mem_fns.h"
+
+void isvc_memset_2d_neon(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 u1_val, WORD32 i4_blk_wd,
+ WORD32 i4_blk_ht)
+{
+ if(i4_blk_wd == 4)
+ {
+ vst1_lane_u32((UWORD32 *) pu1_dst, vreinterpret_u32_u8(vdup_n_u8(u1_val)), 0);
+ pu1_dst += i4_dst_stride;
+
+ vst1_lane_u32((UWORD32 *) pu1_dst, vreinterpret_u32_u8(vdup_n_u8(u1_val)), 0);
+ pu1_dst += i4_dst_stride;
+
+ vst1_lane_u32((UWORD32 *) pu1_dst, vreinterpret_u32_u8(vdup_n_u8(u1_val)), 0);
+ pu1_dst += i4_dst_stride;
+
+ vst1_lane_u32((UWORD32 *) pu1_dst, vreinterpret_u32_u8(vdup_n_u8(u1_val)), 0);
+ }
+ else if(i4_blk_wd == 8)
+ {
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ vst1_u8(pu1_dst, vdup_n_u8(u1_val));
+ }
+ else if((i4_blk_wd % 16 == 0) && (i4_blk_ht % 16 == 0))
+ {
+ WORD32 i, j;
+ UWORD8 *pu1_dst_col_ptr, *pu1_dst_row_ptr;
+ WORD32 i4_width_by_16 = i4_blk_wd / 16;
+ WORD32 i4_height_by_16 = i4_blk_ht / 16;
+
+ for(i = 0; i < i4_height_by_16; i++)
+ {
+ pu1_dst_row_ptr = pu1_dst + i * 16 * i4_dst_stride;
+ for(j = 0; j < i4_width_by_16; j++)
+ {
+ pu1_dst_col_ptr = pu1_dst_row_ptr + (j << 4);
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ vst1q_u8(&pu1_dst_col_ptr[0], vdupq_n_u8(u1_val));
+ }
+ }
+ }
+ else
+ {
+ WORD32 i;
+
+ for(i = 0; i < i4_blk_ht; i++)
+ {
+ memset(pu1_dst, u1_val, i4_blk_wd);
+ pu1_dst += i4_dst_stride;
+ }
+ }
+}
diff --git a/common/arm/svc/isvc_resi_trans_quant_neon.c b/common/arm/svc/isvc_resi_trans_quant_neon.c
new file mode 100644
index 0000000..4179cb2
--- /dev/null
+++ b/common/arm/svc/isvc_resi_trans_quant_neon.c
@@ -0,0 +1,1085 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ * *******************************************************************************
+ * * @file
+ * isvc_resi_trans_quant_neon.c
+ *
+ * @brief
+ * neon variants of forward transform and quantization functions
+ *
+ * *******************************************************************************
+ */
+
+#include <arm_neon.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+void isvc_resi_trans_quant_4x4_neon(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out,
+ UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ uint8x8_t src0, src1, src2, src3;
+ uint8x8_t pred0, pred1, pred2, pred3;
+ uint8x8_t temp0_u8x8, temp1_u8x8;
+ uint16x4_t temp0_u16x4, temp1_u16x4, temp2_u16x4, temp3_u16x4;
+ uint16x4_t scale_mat0_16x4, scale_mat1_16x4, scale_mat2_16x4, scale_mat3_16x4;
+ uint16x4_t threshold0_16x4, threshold1_16x4, threshold2_16x4, threshold3_16x4;
+ uint16x4_t thresholdmask0_16x4, thresholdmask1_16x4, thresholdmask2_16x4, thresholdmask3_16x4;
+ int16x4_t res0_16x4, res1_16x4, res2_16x4, res3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int16x4_t temp0_16x4, temp1_16x4, temp2_16x4, temp3_16x4;
+ uint16x8_t res0_16x8, res1_16x8, res2_16x8, res3_16x8;
+ uint16x8_t temp0_u16x8, temp1_u16x8;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int32x4_t tx0_32x4, tx1_32x4, tx2_32x4, tx3_32x4;
+
+ int32x4_t rnd_factor_32x4 = vdupq_n_s32(u4_round_factor);
+ int32x4_t qbits_32x4 = vdupq_n_s32(u4_qbits);
+ int16x4_t zeros_16x4 = vdup_n_s16(0);
+
+ UNUSED(ps_upsampled_res);
+ UNUSED(u1_use_upsampled_res);
+
+ threshold0_16x4 = vld1_u16(pu2_threshold_matrix);
+ threshold1_16x4 = vld1_u16(pu2_threshold_matrix + 4);
+ threshold2_16x4 = vld1_u16(pu2_threshold_matrix + 8);
+ threshold3_16x4 = vld1_u16(pu2_threshold_matrix + 12);
+
+ scale_mat0_16x4 = vld1_u16(pu2_scale_matrix);
+ scale_mat1_16x4 = vld1_u16(pu2_scale_matrix + 4);
+ scale_mat2_16x4 = vld1_u16(pu2_scale_matrix + 8);
+ scale_mat3_16x4 = vld1_u16(pu2_scale_matrix + 12);
+
+ src0 = vld1_u8(&pu1_src[0 * i4_src_stride]);
+ src1 = vld1_u8(&pu1_src[1 * i4_src_stride]);
+ src2 = vld1_u8(&pu1_src[2 * i4_src_stride]);
+ src3 = vld1_u8(&pu1_src[3 * i4_src_stride]);
+
+ pred0 = vld1_u8(&pu1_pred[0 * i4_pred_stride]);
+ pred1 = vld1_u8(&pu1_pred[1 * i4_pred_stride]);
+ pred2 = vld1_u8(&pu1_pred[2 * i4_pred_stride]);
+ pred3 = vld1_u8(&pu1_pred[3 * i4_pred_stride]);
+
+ /* calculate res = src - pred */
+ res0_16x8 = vsubl_u8(src0, pred0);
+ res1_16x8 = vsubl_u8(src1, pred1);
+ res2_16x8 = vsubl_u8(src2, pred2);
+ res3_16x8 = vsubl_u8(src3, pred3);
+
+ res0_16x4 = vreinterpret_s16_u16(vget_low_u16(res0_16x8));
+ res1_16x4 = vreinterpret_s16_u16(vget_low_u16(res1_16x8));
+ res2_16x4 = vreinterpret_s16_u16(vget_low_u16(res2_16x8));
+ res3_16x4 = vreinterpret_s16_u16(vget_low_u16(res3_16x8));
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ /* Matrix transpose */
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(res0_16x4, res1_16x4);
+ xx1_16x4x2 = vtrn_s16(res2_16x4, res3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(xx2_16x4, temp0_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* Matrix transpose */
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(x0_16x4, x1_16x4);
+ xx1_16x4x2 = vtrn_s16(x2_16x4, x3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Vertical Transformation */
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(temp0_16x4, xx2_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* get the first 16 bits from the register */
+ *pi2_dc_out = vget_lane_s16(x0_16x4, 0);
+
+ xx0_16x4 = vabs_s16(x0_16x4);
+ xx1_16x4 = vabs_s16(x1_16x4);
+ xx2_16x4 = vabs_s16(x2_16x4);
+ xx3_16x4 = vabs_s16(x3_16x4);
+
+ /* compare with zero for getting sign */
+ temp0_u16x4 = vcgt_s16(x0_16x4, zeros_16x4);
+ temp1_u16x4 = vcgt_s16(x1_16x4, zeros_16x4);
+ temp2_u16x4 = vcgt_s16(x2_16x4, zeros_16x4);
+ temp3_u16x4 = vcgt_s16(x3_16x4, zeros_16x4);
+
+ /* compare with zero for thresholding */
+ thresholdmask0_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold0_16x4), xx0_16x4);
+ thresholdmask1_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold1_16x4), xx1_16x4);
+ thresholdmask2_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold2_16x4), xx2_16x4);
+ thresholdmask3_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold3_16x4), xx3_16x4);
+
+ /* Multiply abs values obtained with scaling matrix */
+ tx0_32x4 = vmull_s16(xx0_16x4, vreinterpret_s16_u16(scale_mat0_16x4));
+ tx1_32x4 = vmull_s16(xx1_16x4, vreinterpret_s16_u16(scale_mat1_16x4));
+ tx2_32x4 = vmull_s16(xx2_16x4, vreinterpret_s16_u16(scale_mat2_16x4));
+ tx3_32x4 = vmull_s16(xx3_16x4, vreinterpret_s16_u16(scale_mat3_16x4));
+
+ tx0_32x4 = vaddq_s32(tx0_32x4, rnd_factor_32x4);
+ tx1_32x4 = vaddq_s32(tx1_32x4, rnd_factor_32x4);
+ tx2_32x4 = vaddq_s32(tx2_32x4, rnd_factor_32x4);
+ tx3_32x4 = vaddq_s32(tx3_32x4, rnd_factor_32x4);
+
+ qbits_32x4 = vnegq_s32(qbits_32x4);
+
+ tx0_32x4 = vshlq_s32(tx0_32x4, qbits_32x4);
+ tx1_32x4 = vshlq_s32(tx1_32x4, qbits_32x4);
+ tx2_32x4 = vshlq_s32(tx2_32x4, qbits_32x4);
+ tx3_32x4 = vshlq_s32(tx3_32x4, qbits_32x4);
+
+ /* Convertion to 16 bits signed */
+ temp0_16x4 = vmovn_s32(tx0_32x4);
+ temp1_16x4 = vmovn_s32(tx1_32x4);
+ temp2_16x4 = vmovn_s32(tx2_32x4);
+ temp3_16x4 = vmovn_s32(tx3_32x4);
+
+ x0_16x4 = vneg_s16(temp0_16x4);
+ x1_16x4 = vneg_s16(temp1_16x4);
+ x2_16x4 = vneg_s16(temp2_16x4);
+ x3_16x4 = vneg_s16(temp3_16x4);
+
+ /* Restore sign */
+ x0_16x4 = vbsl_s16(temp0_u16x4, temp0_16x4, x0_16x4);
+ x1_16x4 = vbsl_s16(temp1_u16x4, temp1_16x4, x1_16x4);
+ x2_16x4 = vbsl_s16(temp2_u16x4, temp2_16x4, x2_16x4);
+ x3_16x4 = vbsl_s16(temp3_u16x4, temp3_16x4, x3_16x4);
+
+ xx0_16x4 = vbsl_s16(thresholdmask0_16x4, zeros_16x4, x0_16x4);
+ xx1_16x4 = vbsl_s16(thresholdmask1_16x4, zeros_16x4, x1_16x4);
+ xx2_16x4 = vbsl_s16(thresholdmask2_16x4, zeros_16x4, x2_16x4);
+ xx3_16x4 = vbsl_s16(thresholdmask3_16x4, zeros_16x4, x3_16x4);
+
+ /* Store Quantized outputs */
+ vst1_s16(&pi2_out[0 * i4_out_stride], xx0_16x4);
+ vst1_s16(&pi2_out[1 * i4_out_stride], xx1_16x4);
+ vst1_s16(&pi2_out[2 * i4_out_stride], xx2_16x4);
+ vst1_s16(&pi2_out[3 * i4_out_stride], xx3_16x4);
+
+ /* NNZ calculation */
+
+ temp0_u16x4 = vceq_s16(xx0_16x4, zeros_16x4);
+ temp1_u16x4 = vceq_s16(xx1_16x4, zeros_16x4);
+ temp2_u16x4 = vceq_s16(xx2_16x4, zeros_16x4);
+ temp3_u16x4 = vceq_s16(xx3_16x4, zeros_16x4);
+
+ temp0_u16x8 = vcombine_u16(temp0_u16x4, temp2_u16x4);
+ temp1_u16x8 = vcombine_u16(temp1_u16x4, temp3_u16x4);
+
+ /* Convertion to 8 bit unsigned */
+ temp0_u8x8 = vmovn_u16(temp0_u16x8);
+ temp1_u8x8 = vmovn_u16(temp1_u16x8);
+
+ temp0_u8x8 = vshr_n_u8(temp0_u8x8, 7);
+ temp1_u8x8 = vshr_n_u8(temp1_u8x8, 7);
+
+ temp0_u8x8 = vadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+
+ *pu1_nnz = 16 - vget_lane_u8(temp0_u8x8, 0);
+}
+
+void isvc_resi_trans_quant_4x4_with_residual_sub_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res, resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? (WORD16 *) ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ uint8x8_t src0, src1, src2, src3;
+ uint8x8_t pred0, pred1, pred2, pred3;
+ uint8x8_t temp0_u8x8, temp1_u8x8;
+ uint16x4_t temp0_u16x4, temp1_u16x4, temp2_u16x4, temp3_u16x4;
+ uint16x4_t scale_mat0_16x4, scale_mat1_16x4, scale_mat2_16x4, scale_mat3_16x4;
+ uint16x4_t threshold0_16x4, threshold1_16x4, threshold2_16x4, threshold3_16x4;
+ uint16x4_t thresholdmask0_16x4, thresholdmask1_16x4, thresholdmask2_16x4, thresholdmask3_16x4;
+ int16x4_t upres0_16x4, upres1_16x4, upres2_16x4, upres3_16x4;
+ int16x4_t res0_16x4, res1_16x4, res2_16x4, res3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int16x4_t temp0_16x4, temp1_16x4, temp2_16x4, temp3_16x4;
+ uint16x8_t res0_16x8, res1_16x8, res2_16x8, res3_16x8;
+ uint16x8_t temp0_u16x8, temp1_u16x8;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int32x4_t tx0_32x4, tx1_32x4, tx2_32x4, tx3_32x4;
+
+ int32x4_t rnd_factor_32x4 = vdupq_n_s32(u4_round_factor);
+ int32x4_t qbits_32x4 = vdupq_n_s32(u4_qbits);
+ int16x4_t zeros_16x4 = vdup_n_s16(0);
+ int16x4_t pos_255_16x4 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255_16x4 = vdup_n_s16(-((WORD16) UINT8_MAX));
+
+ UNUSED(u1_use_upsampled_res);
+
+ threshold0_16x4 = vld1_u16(pu2_threshold_matrix);
+ threshold1_16x4 = vld1_u16(pu2_threshold_matrix + 4);
+ threshold2_16x4 = vld1_u16(pu2_threshold_matrix + 8);
+ threshold3_16x4 = vld1_u16(pu2_threshold_matrix + 12);
+
+ scale_mat0_16x4 = vld1_u16(pu2_scale_matrix);
+ scale_mat1_16x4 = vld1_u16(pu2_scale_matrix + 4);
+ scale_mat2_16x4 = vld1_u16(pu2_scale_matrix + 8);
+ scale_mat3_16x4 = vld1_u16(pu2_scale_matrix + 12);
+
+ src0 = vld1_u8(&pu1_src[0 * i4_src_stride]);
+ src1 = vld1_u8(&pu1_src[1 * i4_src_stride]);
+ src2 = vld1_u8(&pu1_src[2 * i4_src_stride]);
+ src3 = vld1_u8(&pu1_src[3 * i4_src_stride]);
+
+ pred0 = vld1_u8(&pu1_pred[0 * i4_pred_stride]);
+ pred1 = vld1_u8(&pu1_pred[1 * i4_pred_stride]);
+ pred2 = vld1_u8(&pu1_pred[2 * i4_pred_stride]);
+ pred3 = vld1_u8(&pu1_pred[3 * i4_pred_stride]);
+
+ /* calculate res = src - pred */
+ res0_16x8 = vsubl_u8(src0, pred0);
+ res1_16x8 = vsubl_u8(src1, pred1);
+ res2_16x8 = vsubl_u8(src2, pred2);
+ res3_16x8 = vsubl_u8(src3, pred3);
+
+ res0_16x4 = vreinterpret_s16_u16(vget_low_u16(res0_16x8));
+ res1_16x4 = vreinterpret_s16_u16(vget_low_u16(res1_16x8));
+ res2_16x4 = vreinterpret_s16_u16(vget_low_u16(res2_16x8));
+ res3_16x4 = vreinterpret_s16_u16(vget_low_u16(res3_16x8));
+
+ /* Load upsampled res */
+ upres0_16x4 = vld1_s16(&pi2_upsampled_res[0 * i4_upsampled_res_stride]);
+ upres1_16x4 = vld1_s16(&pi2_upsampled_res[1 * i4_upsampled_res_stride]);
+ upres2_16x4 = vld1_s16(&pi2_upsampled_res[2 * i4_upsampled_res_stride]);
+ upres3_16x4 = vld1_s16(&pi2_upsampled_res[3 * i4_upsampled_res_stride]);
+
+ /* subtract upsampled res from (src - pred) to obtain final res */
+ res0_16x4 = vsub_s16(res0_16x4, upres0_16x4);
+ res1_16x4 = vsub_s16(res1_16x4, upres1_16x4);
+ res2_16x4 = vsub_s16(res2_16x4, upres2_16x4);
+ res3_16x4 = vsub_s16(res3_16x4, upres3_16x4);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ res0_16x4 = vmax_s16(res0_16x4, neg_255_16x4);
+ res1_16x4 = vmax_s16(res1_16x4, neg_255_16x4);
+ res2_16x4 = vmax_s16(res2_16x4, neg_255_16x4);
+ res3_16x4 = vmax_s16(res3_16x4, neg_255_16x4);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ res0_16x4 = vmin_s16(res0_16x4, pos_255_16x4);
+ res1_16x4 = vmin_s16(res1_16x4, pos_255_16x4);
+ res2_16x4 = vmin_s16(res2_16x4, pos_255_16x4);
+ res3_16x4 = vmin_s16(res3_16x4, pos_255_16x4);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ /* Matrix transpose */
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(res0_16x4, res1_16x4);
+ xx1_16x4x2 = vtrn_s16(res2_16x4, res3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(xx2_16x4, temp0_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* Matrix transpose */
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(x0_16x4, x1_16x4);
+ xx1_16x4x2 = vtrn_s16(x2_16x4, x3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Vertical Transformation */
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(temp0_16x4, xx2_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* get the first 16 bits from the register */
+ *pi2_dc_out = vget_lane_s16(x0_16x4, 0);
+
+ xx0_16x4 = vabs_s16(x0_16x4);
+ xx1_16x4 = vabs_s16(x1_16x4);
+ xx2_16x4 = vabs_s16(x2_16x4);
+ xx3_16x4 = vabs_s16(x3_16x4);
+
+ /* compare with zero for getting sign */
+ temp0_u16x4 = vcgt_s16(x0_16x4, zeros_16x4);
+ temp1_u16x4 = vcgt_s16(x1_16x4, zeros_16x4);
+ temp2_u16x4 = vcgt_s16(x2_16x4, zeros_16x4);
+ temp3_u16x4 = vcgt_s16(x3_16x4, zeros_16x4);
+
+ /* compare with zero for thresholding */
+ thresholdmask0_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold0_16x4), xx0_16x4);
+ thresholdmask1_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold1_16x4), xx1_16x4);
+ thresholdmask2_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold2_16x4), xx2_16x4);
+ thresholdmask3_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold3_16x4), xx3_16x4);
+
+ /* Multiply abs values obtained with scaling matrix */
+ tx0_32x4 = vmull_s16(xx0_16x4, vreinterpret_s16_u16(scale_mat0_16x4));
+ tx1_32x4 = vmull_s16(xx1_16x4, vreinterpret_s16_u16(scale_mat1_16x4));
+ tx2_32x4 = vmull_s16(xx2_16x4, vreinterpret_s16_u16(scale_mat2_16x4));
+ tx3_32x4 = vmull_s16(xx3_16x4, vreinterpret_s16_u16(scale_mat3_16x4));
+
+ tx0_32x4 = vaddq_s32(tx0_32x4, rnd_factor_32x4);
+ tx1_32x4 = vaddq_s32(tx1_32x4, rnd_factor_32x4);
+ tx2_32x4 = vaddq_s32(tx2_32x4, rnd_factor_32x4);
+ tx3_32x4 = vaddq_s32(tx3_32x4, rnd_factor_32x4);
+
+ qbits_32x4 = vnegq_s32(qbits_32x4);
+
+ tx0_32x4 = vshlq_s32(tx0_32x4, qbits_32x4);
+ tx1_32x4 = vshlq_s32(tx1_32x4, qbits_32x4);
+ tx2_32x4 = vshlq_s32(tx2_32x4, qbits_32x4);
+ tx3_32x4 = vshlq_s32(tx3_32x4, qbits_32x4);
+
+ /* Convertion to 16 bits signed */
+ temp0_16x4 = vmovn_s32(tx0_32x4);
+ temp1_16x4 = vmovn_s32(tx1_32x4);
+ temp2_16x4 = vmovn_s32(tx2_32x4);
+ temp3_16x4 = vmovn_s32(tx3_32x4);
+
+ x0_16x4 = vneg_s16(temp0_16x4);
+ x1_16x4 = vneg_s16(temp1_16x4);
+ x2_16x4 = vneg_s16(temp2_16x4);
+ x3_16x4 = vneg_s16(temp3_16x4);
+
+ /* Restore sign */
+ x0_16x4 = vbsl_s16(temp0_u16x4, temp0_16x4, x0_16x4);
+ x1_16x4 = vbsl_s16(temp1_u16x4, temp1_16x4, x1_16x4);
+ x2_16x4 = vbsl_s16(temp2_u16x4, temp2_16x4, x2_16x4);
+ x3_16x4 = vbsl_s16(temp3_u16x4, temp3_16x4, x3_16x4);
+
+ xx0_16x4 = vbsl_s16(thresholdmask0_16x4, zeros_16x4, x0_16x4);
+ xx1_16x4 = vbsl_s16(thresholdmask1_16x4, zeros_16x4, x1_16x4);
+ xx2_16x4 = vbsl_s16(thresholdmask2_16x4, zeros_16x4, x2_16x4);
+ xx3_16x4 = vbsl_s16(thresholdmask3_16x4, zeros_16x4, x3_16x4);
+
+ /* Store Quantized outputs */
+ vst1_s16(&pi2_out[0 * i4_out_stride], xx0_16x4);
+ vst1_s16(&pi2_out[1 * i4_out_stride], xx1_16x4);
+ vst1_s16(&pi2_out[2 * i4_out_stride], xx2_16x4);
+ vst1_s16(&pi2_out[3 * i4_out_stride], xx3_16x4);
+
+ /* NNZ calculation */
+
+ temp0_u16x4 = vceq_s16(xx0_16x4, zeros_16x4);
+ temp1_u16x4 = vceq_s16(xx1_16x4, zeros_16x4);
+ temp2_u16x4 = vceq_s16(xx2_16x4, zeros_16x4);
+ temp3_u16x4 = vceq_s16(xx3_16x4, zeros_16x4);
+
+ temp0_u16x8 = vcombine_u16(temp0_u16x4, temp2_u16x4);
+ temp1_u16x8 = vcombine_u16(temp1_u16x4, temp3_u16x4);
+
+ /* Convertion to 8 bit unsigned */
+ temp0_u8x8 = vmovn_u16(temp0_u16x8);
+ temp1_u8x8 = vmovn_u16(temp1_u16x8);
+
+ temp0_u8x8 = vshr_n_u8(temp0_u8x8, 7);
+ temp1_u8x8 = vshr_n_u8(temp1_u8x8, 7);
+
+ temp0_u8x8 = vadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+
+ *pu1_nnz = 16 - vget_lane_u8(temp0_u8x8, 0);
+}
+
+void isvc_resi_trans_quant_chroma_4x4_neon(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out,
+ UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ uint8x8_t src0, src1, src2, src3;
+ uint8x8_t pred0, pred1, pred2, pred3;
+ uint8x8x2_t tmp0, tmp1, tmp2, tmp3;
+ uint8x8_t temp0_u8x8, temp1_u8x8;
+ uint16x4_t temp0_u16x4, temp1_u16x4, temp2_u16x4, temp3_u16x4;
+ uint16x4_t scale_mat0_16x4, scale_mat1_16x4, scale_mat2_16x4, scale_mat3_16x4;
+ uint16x4_t threshold0_16x4, threshold1_16x4, threshold2_16x4, threshold3_16x4;
+ uint16x4_t thresholdmask0_16x4, thresholdmask1_16x4, thresholdmask2_16x4, thresholdmask3_16x4;
+ int16x4_t res0_16x4, res1_16x4, res2_16x4, res3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int16x4_t temp0_16x4, temp1_16x4, temp2_16x4, temp3_16x4;
+ uint16x8_t res0_16x8, res1_16x8, res2_16x8, res3_16x8;
+ uint16x8_t temp0_u16x8, temp1_u16x8;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int32x4_t tx0_32x4, tx1_32x4, tx2_32x4, tx3_32x4;
+
+ int32x4_t rnd_factor_32x4 = vdupq_n_s32(u4_round_factor);
+ int32x4_t qbits_32x4 = vdupq_n_s32(u4_qbits);
+ int16x4_t zeros_16x4 = vdup_n_s16(0);
+
+ UNUSED(ps_upsampled_res);
+ UNUSED(u1_use_upsampled_res);
+
+ threshold0_16x4 = vld1_u16(pu2_threshold_matrix);
+ threshold1_16x4 = vld1_u16(pu2_threshold_matrix + 4);
+ threshold2_16x4 = vld1_u16(pu2_threshold_matrix + 8);
+ threshold3_16x4 = vld1_u16(pu2_threshold_matrix + 12);
+
+ scale_mat0_16x4 = vld1_u16(pu2_scale_matrix);
+ scale_mat1_16x4 = vld1_u16(pu2_scale_matrix + 4);
+ scale_mat2_16x4 = vld1_u16(pu2_scale_matrix + 8);
+ scale_mat3_16x4 = vld1_u16(pu2_scale_matrix + 12);
+
+ src0 = vld1_u8(&pu1_src[0 * i4_src_stride]);
+ src1 = vld1_u8(&pu1_src[1 * i4_src_stride]);
+ src2 = vld1_u8(&pu1_src[2 * i4_src_stride]);
+ src3 = vld1_u8(&pu1_src[3 * i4_src_stride]);
+
+ /* deinterleaving source buffer */
+ tmp0 = vuzp_u8(src0, src0);
+ tmp1 = vuzp_u8(src1, src1);
+ tmp2 = vuzp_u8(src2, src2);
+ tmp3 = vuzp_u8(src3, src3);
+
+ src0 = tmp0.val[0];
+ src1 = tmp1.val[0];
+ src2 = tmp2.val[0];
+ src3 = tmp3.val[0];
+
+ pred0 = vld1_u8(&pu1_pred[0 * i4_pred_stride]);
+ pred1 = vld1_u8(&pu1_pred[1 * i4_pred_stride]);
+ pred2 = vld1_u8(&pu1_pred[2 * i4_pred_stride]);
+ pred3 = vld1_u8(&pu1_pred[3 * i4_pred_stride]);
+
+ /* deinterleaving pred buffer */
+ tmp0 = vuzp_u8(pred0, pred0);
+ tmp1 = vuzp_u8(pred1, pred1);
+ tmp2 = vuzp_u8(pred2, pred2);
+ tmp3 = vuzp_u8(pred3, pred3);
+
+ pred0 = tmp0.val[0];
+ pred1 = tmp1.val[0];
+ pred2 = tmp2.val[0];
+ pred3 = tmp3.val[0];
+
+ /* calculate res = src - pred */
+ res0_16x8 = vsubl_u8(src0, pred0);
+ res1_16x8 = vsubl_u8(src1, pred1);
+ res2_16x8 = vsubl_u8(src2, pred2);
+ res3_16x8 = vsubl_u8(src3, pred3);
+
+ res0_16x4 = vreinterpret_s16_u16(vget_low_u16(res0_16x8));
+ res1_16x4 = vreinterpret_s16_u16(vget_low_u16(res1_16x8));
+ res2_16x4 = vreinterpret_s16_u16(vget_low_u16(res2_16x8));
+ res3_16x4 = vreinterpret_s16_u16(vget_low_u16(res3_16x8));
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ /* Matrix transpose */
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(res0_16x4, res1_16x4);
+ xx1_16x4x2 = vtrn_s16(res2_16x4, res3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(xx2_16x4, temp0_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* Matrix transpose */
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(x0_16x4, x1_16x4);
+ xx1_16x4x2 = vtrn_s16(x2_16x4, x3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Vertical Transformation */
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(temp0_16x4, xx2_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* get the first 16 bits from the register */
+ *pi2_dc_out = vget_lane_s16(x0_16x4, 0);
+
+ xx0_16x4 = vabs_s16(x0_16x4);
+ xx1_16x4 = vabs_s16(x1_16x4);
+ xx2_16x4 = vabs_s16(x2_16x4);
+ xx3_16x4 = vabs_s16(x3_16x4);
+
+ /* compare with zero for getting sign */
+ temp0_u16x4 = vcgt_s16(x0_16x4, zeros_16x4);
+ temp1_u16x4 = vcgt_s16(x1_16x4, zeros_16x4);
+ temp2_u16x4 = vcgt_s16(x2_16x4, zeros_16x4);
+ temp3_u16x4 = vcgt_s16(x3_16x4, zeros_16x4);
+
+ /* compare with zero for thresholding */
+ thresholdmask0_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold0_16x4), xx0_16x4);
+ thresholdmask1_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold1_16x4), xx1_16x4);
+ thresholdmask2_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold2_16x4), xx2_16x4);
+ thresholdmask3_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold3_16x4), xx3_16x4);
+
+ /* Multiply abs values obtained with scaling matrix */
+ tx0_32x4 = vmull_s16(xx0_16x4, vreinterpret_s16_u16(scale_mat0_16x4));
+ tx1_32x4 = vmull_s16(xx1_16x4, vreinterpret_s16_u16(scale_mat1_16x4));
+ tx2_32x4 = vmull_s16(xx2_16x4, vreinterpret_s16_u16(scale_mat2_16x4));
+ tx3_32x4 = vmull_s16(xx3_16x4, vreinterpret_s16_u16(scale_mat3_16x4));
+
+ tx0_32x4 = vaddq_s32(tx0_32x4, rnd_factor_32x4);
+ tx1_32x4 = vaddq_s32(tx1_32x4, rnd_factor_32x4);
+ tx2_32x4 = vaddq_s32(tx2_32x4, rnd_factor_32x4);
+ tx3_32x4 = vaddq_s32(tx3_32x4, rnd_factor_32x4);
+
+ qbits_32x4 = vnegq_s32(qbits_32x4);
+
+ tx0_32x4 = vshlq_s32(tx0_32x4, qbits_32x4);
+ tx1_32x4 = vshlq_s32(tx1_32x4, qbits_32x4);
+ tx2_32x4 = vshlq_s32(tx2_32x4, qbits_32x4);
+ tx3_32x4 = vshlq_s32(tx3_32x4, qbits_32x4);
+
+ /* Convertion to 16 bits signed */
+ temp0_16x4 = vmovn_s32(tx0_32x4);
+ temp1_16x4 = vmovn_s32(tx1_32x4);
+ temp2_16x4 = vmovn_s32(tx2_32x4);
+ temp3_16x4 = vmovn_s32(tx3_32x4);
+
+ x0_16x4 = vneg_s16(temp0_16x4);
+ x1_16x4 = vneg_s16(temp1_16x4);
+ x2_16x4 = vneg_s16(temp2_16x4);
+ x3_16x4 = vneg_s16(temp3_16x4);
+
+ /* Restore sign */
+ x0_16x4 = vbsl_s16(temp0_u16x4, temp0_16x4, x0_16x4);
+ x1_16x4 = vbsl_s16(temp1_u16x4, temp1_16x4, x1_16x4);
+ x2_16x4 = vbsl_s16(temp2_u16x4, temp2_16x4, x2_16x4);
+ x3_16x4 = vbsl_s16(temp3_u16x4, temp3_16x4, x3_16x4);
+
+ /* Thresholding */
+ xx0_16x4 = vbsl_s16(thresholdmask0_16x4, zeros_16x4, x0_16x4);
+ xx1_16x4 = vbsl_s16(thresholdmask1_16x4, zeros_16x4, x1_16x4);
+ xx2_16x4 = vbsl_s16(thresholdmask2_16x4, zeros_16x4, x2_16x4);
+ xx3_16x4 = vbsl_s16(thresholdmask3_16x4, zeros_16x4, x3_16x4);
+
+ /* Store Quantized outputs */
+ vst1_s16(&pi2_out[0 * i4_out_stride], xx0_16x4);
+ vst1_s16(&pi2_out[1 * i4_out_stride], xx1_16x4);
+ vst1_s16(&pi2_out[2 * i4_out_stride], xx2_16x4);
+ vst1_s16(&pi2_out[3 * i4_out_stride], xx3_16x4);
+
+ /* NNZ calculation */
+
+ temp0_u16x4 = vceq_s16(xx0_16x4, zeros_16x4);
+ temp1_u16x4 = vceq_s16(xx1_16x4, zeros_16x4);
+ temp2_u16x4 = vceq_s16(xx2_16x4, zeros_16x4);
+ temp3_u16x4 = vceq_s16(xx3_16x4, zeros_16x4);
+
+ temp0_u16x8 = vcombine_u16(temp0_u16x4, temp2_u16x4);
+ temp1_u16x8 = vcombine_u16(temp1_u16x4, temp3_u16x4);
+
+ /* Convertion to 8 bit unsigned */
+ temp0_u8x8 = vmovn_u16(temp0_u16x8);
+ temp1_u8x8 = vmovn_u16(temp1_u16x8);
+
+ temp0_u8x8 = vshr_n_u8(temp0_u8x8, 7);
+ temp1_u8x8 = vshr_n_u8(temp1_u8x8, 7);
+
+ temp0_u8x8 = vadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+
+ *pu1_nnz = 16 - vget_lane_u8(temp0_u8x8, 0);
+}
+
+void isvc_resi_trans_quant_chroma_4x4_with_residual_sub_neon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res, resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? (WORD16 *) ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ uint8x8_t src0, src1, src2, src3;
+ uint8x8_t pred0, pred1, pred2, pred3;
+ uint8x8x2_t tmp0, tmp1, tmp2, tmp3;
+ uint8x8_t temp0_u8x8, temp1_u8x8;
+ uint16x4_t temp0_u16x4, temp1_u16x4, temp2_u16x4, temp3_u16x4;
+ uint16x4_t scale_mat0_16x4, scale_mat1_16x4, scale_mat2_16x4, scale_mat3_16x4;
+ uint16x4_t threshold0_16x4, threshold1_16x4, threshold2_16x4, threshold3_16x4;
+ uint16x4_t thresholdmask0_16x4, thresholdmask1_16x4, thresholdmask2_16x4, thresholdmask3_16x4;
+ int16x4_t upres0_16x4, upres1_16x4, upres2_16x4, upres3_16x4;
+ int16x4_t res0_16x4, res1_16x4, res2_16x4, res3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4x2_t xx0_16x4x2, xx1_16x4x2;
+ int16x4_t temp0_16x4, temp1_16x4, temp2_16x4, temp3_16x4;
+ uint16x8_t res0_16x8, res1_16x8, res2_16x8, res3_16x8;
+ uint16x8_t temp0_u16x8, temp1_u16x8;
+ int32x2x2_t x0_32x2x2, x1_32x2x2;
+ int32x4_t tx0_32x4, tx1_32x4, tx2_32x4, tx3_32x4;
+
+ int32x4_t rnd_factor_32x4 = vdupq_n_s32(u4_round_factor);
+ int32x4_t qbits_32x4 = vdupq_n_s32(u4_qbits);
+ int16x4_t zeros_16x4 = vdup_n_s16(0);
+ int16x4_t pos_255_16x4 = vdup_n_s16(((WORD16) UINT8_MAX));
+ int16x4_t neg_255_16x4 = vdup_n_s16(-((WORD16) UINT8_MAX));
+
+ UNUSED(u1_use_upsampled_res);
+
+ threshold0_16x4 = vld1_u16(pu2_threshold_matrix);
+ threshold1_16x4 = vld1_u16(pu2_threshold_matrix + 4);
+ threshold2_16x4 = vld1_u16(pu2_threshold_matrix + 8);
+ threshold3_16x4 = vld1_u16(pu2_threshold_matrix + 12);
+
+ scale_mat0_16x4 = vld1_u16(pu2_scale_matrix);
+ scale_mat1_16x4 = vld1_u16(pu2_scale_matrix + 4);
+ scale_mat2_16x4 = vld1_u16(pu2_scale_matrix + 8);
+ scale_mat3_16x4 = vld1_u16(pu2_scale_matrix + 12);
+
+ src0 = vld1_u8(&pu1_src[0 * i4_src_stride]);
+ src1 = vld1_u8(&pu1_src[1 * i4_src_stride]);
+ src2 = vld1_u8(&pu1_src[2 * i4_src_stride]);
+ src3 = vld1_u8(&pu1_src[3 * i4_src_stride]);
+
+ /* deinterleaving source buffer */
+ tmp0 = vuzp_u8(src0, src0);
+ tmp1 = vuzp_u8(src1, src1);
+ tmp2 = vuzp_u8(src2, src2);
+ tmp3 = vuzp_u8(src3, src3);
+
+ src0 = tmp0.val[0];
+ src1 = tmp1.val[0];
+ src2 = tmp2.val[0];
+ src3 = tmp3.val[0];
+
+ pred0 = vld1_u8(&pu1_pred[0 * i4_pred_stride]);
+ pred1 = vld1_u8(&pu1_pred[1 * i4_pred_stride]);
+ pred2 = vld1_u8(&pu1_pred[2 * i4_pred_stride]);
+ pred3 = vld1_u8(&pu1_pred[3 * i4_pred_stride]);
+
+ /* deinterleaving pred buffer */
+ tmp0 = vuzp_u8(pred0, pred0);
+ tmp1 = vuzp_u8(pred1, pred1);
+ tmp2 = vuzp_u8(pred2, pred2);
+ tmp3 = vuzp_u8(pred3, pred3);
+
+ pred0 = tmp0.val[0];
+ pred1 = tmp1.val[0];
+ pred2 = tmp2.val[0];
+ pred3 = tmp3.val[0];
+
+ /* calculate res = src - pred */
+ res0_16x8 = vsubl_u8(src0, pred0);
+ res1_16x8 = vsubl_u8(src1, pred1);
+ res2_16x8 = vsubl_u8(src2, pred2);
+ res3_16x8 = vsubl_u8(src3, pred3);
+
+ res0_16x4 = vreinterpret_s16_u16(vget_low_u16(res0_16x8));
+ res1_16x4 = vreinterpret_s16_u16(vget_low_u16(res1_16x8));
+ res2_16x4 = vreinterpret_s16_u16(vget_low_u16(res2_16x8));
+ res3_16x4 = vreinterpret_s16_u16(vget_low_u16(res3_16x8));
+
+ /* Load upsampled res */
+ upres0_16x4 = vld1_s16(&pi2_upsampled_res[0 * i4_upsampled_res_stride]);
+ upres1_16x4 = vld1_s16(&pi2_upsampled_res[1 * i4_upsampled_res_stride]);
+ upres2_16x4 = vld1_s16(&pi2_upsampled_res[2 * i4_upsampled_res_stride]);
+ upres3_16x4 = vld1_s16(&pi2_upsampled_res[3 * i4_upsampled_res_stride]);
+
+ /* subtract upsampled res from (src - pred) to obtain final res */
+ res0_16x4 = vsub_s16(res0_16x4, upres0_16x4);
+ res1_16x4 = vsub_s16(res1_16x4, upres1_16x4);
+ res2_16x4 = vsub_s16(res2_16x4, upres2_16x4);
+ res3_16x4 = vsub_s16(res3_16x4, upres3_16x4);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ res0_16x4 = vmax_s16(res0_16x4, neg_255_16x4);
+ res1_16x4 = vmax_s16(res1_16x4, neg_255_16x4);
+ res2_16x4 = vmax_s16(res2_16x4, neg_255_16x4);
+ res3_16x4 = vmax_s16(res3_16x4, neg_255_16x4);
+
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ res0_16x4 = vmin_s16(res0_16x4, pos_255_16x4);
+ res1_16x4 = vmin_s16(res1_16x4, pos_255_16x4);
+ res2_16x4 = vmin_s16(res2_16x4, pos_255_16x4);
+ res3_16x4 = vmin_s16(res3_16x4, pos_255_16x4);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ /* Matrix transpose */
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(res0_16x4, res1_16x4);
+ xx1_16x4x2 = vtrn_s16(res2_16x4, res3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(xx2_16x4, temp0_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* Matrix transpose */
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ xx0_16x4x2 = vtrn_s16(x0_16x4, x1_16x4);
+ xx1_16x4x2 = vtrn_s16(x2_16x4, x3_16x4);
+ x0_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[0]), vreinterpret_s32_s16(xx1_16x4x2.val[0]));
+ x1_32x2x2 =
+ vtrn_s32(vreinterpret_s32_s16(xx0_16x4x2.val[1]), vreinterpret_s32_s16(xx1_16x4x2.val[1]));
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[0]);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[0]);
+ x2_16x4 = vreinterpret_s16_s32(x0_32x2x2.val[1]);
+ x3_16x4 = vreinterpret_s16_s32(x1_32x2x2.val[1]);
+
+ /* Vertical Transformation */
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4);
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4);
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4);
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4);
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx3_16x4, 1);
+ x1_16x4 = vadd_s16(temp0_16x4, xx2_16x4);
+
+ x2_16x4 = vsub_s16(xx0_16x4, xx1_16x4);
+ temp0_16x4 = vshl_n_s16(xx2_16x4, 1);
+ x3_16x4 = vsub_s16(xx3_16x4, temp0_16x4);
+
+ /* get the first 16 bits from the register */
+ *pi2_dc_out = vget_lane_s16(x0_16x4, 0);
+
+ xx0_16x4 = vabs_s16(x0_16x4);
+ xx1_16x4 = vabs_s16(x1_16x4);
+ xx2_16x4 = vabs_s16(x2_16x4);
+ xx3_16x4 = vabs_s16(x3_16x4);
+
+ /* compare with zero for getting sign */
+ temp0_u16x4 = vcgt_s16(x0_16x4, zeros_16x4);
+ temp1_u16x4 = vcgt_s16(x1_16x4, zeros_16x4);
+ temp2_u16x4 = vcgt_s16(x2_16x4, zeros_16x4);
+ temp3_u16x4 = vcgt_s16(x3_16x4, zeros_16x4);
+
+ thresholdmask0_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold0_16x4), xx0_16x4);
+ thresholdmask1_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold1_16x4), xx1_16x4);
+ thresholdmask2_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold2_16x4), xx2_16x4);
+ thresholdmask3_16x4 = vcgt_s16(vreinterpret_s16_u16(threshold3_16x4), xx3_16x4);
+
+ /* Multiply abs values obtained with scaling matrix */
+ tx0_32x4 = vmull_s16(xx0_16x4, vreinterpret_s16_u16(scale_mat0_16x4));
+ tx1_32x4 = vmull_s16(xx1_16x4, vreinterpret_s16_u16(scale_mat1_16x4));
+ tx2_32x4 = vmull_s16(xx2_16x4, vreinterpret_s16_u16(scale_mat2_16x4));
+ tx3_32x4 = vmull_s16(xx3_16x4, vreinterpret_s16_u16(scale_mat3_16x4));
+
+ tx0_32x4 = vaddq_s32(tx0_32x4, rnd_factor_32x4);
+ tx1_32x4 = vaddq_s32(tx1_32x4, rnd_factor_32x4);
+ tx2_32x4 = vaddq_s32(tx2_32x4, rnd_factor_32x4);
+ tx3_32x4 = vaddq_s32(tx3_32x4, rnd_factor_32x4);
+
+ qbits_32x4 = vnegq_s32(qbits_32x4);
+
+ tx0_32x4 = vshlq_s32(tx0_32x4, qbits_32x4);
+ tx1_32x4 = vshlq_s32(tx1_32x4, qbits_32x4);
+ tx2_32x4 = vshlq_s32(tx2_32x4, qbits_32x4);
+ tx3_32x4 = vshlq_s32(tx3_32x4, qbits_32x4);
+
+ /* Convertion to 16 bits signed */
+ temp0_16x4 = vmovn_s32(tx0_32x4);
+ temp1_16x4 = vmovn_s32(tx1_32x4);
+ temp2_16x4 = vmovn_s32(tx2_32x4);
+ temp3_16x4 = vmovn_s32(tx3_32x4);
+
+ x0_16x4 = vneg_s16(temp0_16x4);
+ x1_16x4 = vneg_s16(temp1_16x4);
+ x2_16x4 = vneg_s16(temp2_16x4);
+ x3_16x4 = vneg_s16(temp3_16x4);
+
+ /* Restore sign */
+ x0_16x4 = vbsl_s16(temp0_u16x4, temp0_16x4, x0_16x4);
+ x1_16x4 = vbsl_s16(temp1_u16x4, temp1_16x4, x1_16x4);
+ x2_16x4 = vbsl_s16(temp2_u16x4, temp2_16x4, x2_16x4);
+ x3_16x4 = vbsl_s16(temp3_u16x4, temp3_16x4, x3_16x4);
+
+ xx0_16x4 = vbsl_s16(thresholdmask0_16x4, zeros_16x4, x0_16x4);
+ xx1_16x4 = vbsl_s16(thresholdmask1_16x4, zeros_16x4, x1_16x4);
+ xx2_16x4 = vbsl_s16(thresholdmask2_16x4, zeros_16x4, x2_16x4);
+ xx3_16x4 = vbsl_s16(thresholdmask3_16x4, zeros_16x4, x3_16x4);
+
+ /* Store Quantized outputs */
+ vst1_s16(&pi2_out[0 * i4_out_stride], xx0_16x4);
+ vst1_s16(&pi2_out[1 * i4_out_stride], xx1_16x4);
+ vst1_s16(&pi2_out[2 * i4_out_stride], xx2_16x4);
+ vst1_s16(&pi2_out[3 * i4_out_stride], xx3_16x4);
+
+ /* NNZ calculation */
+
+ temp0_u16x4 = vceq_s16(xx0_16x4, zeros_16x4);
+ temp1_u16x4 = vceq_s16(xx1_16x4, zeros_16x4);
+ temp2_u16x4 = vceq_s16(xx2_16x4, zeros_16x4);
+ temp3_u16x4 = vceq_s16(xx3_16x4, zeros_16x4);
+
+ temp0_u16x8 = vcombine_u16(temp0_u16x4, temp2_u16x4);
+ temp1_u16x8 = vcombine_u16(temp1_u16x4, temp3_u16x4);
+
+ /* Convertion to 8 bit unsigned */
+ temp0_u8x8 = vmovn_u16(temp0_u16x8);
+ temp1_u8x8 = vmovn_u16(temp1_u16x8);
+
+ temp0_u8x8 = vshr_n_u8(temp0_u8x8, 7);
+ temp1_u8x8 = vshr_n_u8(temp1_u8x8, 7);
+
+ temp0_u8x8 = vadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+ temp0_u8x8 = vpadd_u8(temp0_u8x8, temp1_u8x8);
+
+ *pu1_nnz = 16 - vget_lane_u8(temp0_u8x8, 0);
+}
diff --git a/common/common.cmake b/common/common.cmake
index a8e599b..47ca54b 100644
--- a/common/common.cmake
+++ b/common/common.cmake
@@ -24,6 +24,7 @@ list(
"${AVC_ROOT}/common/ithread.c")
include_directories(${AVC_ROOT}/common)
+include_directories(${AVC_ROOT}/common/mvc)
# arm/x86 sources
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
diff --git a/common/ih264_buf_mgr.c b/common/ih264_buf_mgr.c
index ea4333e..0b5a596 100644
--- a/common/ih264_buf_mgr.c
+++ b/common/ih264_buf_mgr.c
@@ -261,6 +261,39 @@ void *ih264_buf_mgr_init(void *pv_buf)
return ps_buf_mgr;
}
+/**
+*******************************************************************************
+*
+* @brief
+* Buffer manager reset function.
+*
+* @par Description:
+* resets the buffer manager structure
+*
+* @param[in] ps_buf_mgr
+* Pointer to the buffer manager
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+void ih264_buf_mgr_reset(void *pv_buf_mgr)
+{
+ WORD32 id;
+ buf_mgr_t *ps_buf_mgr;
+
+ ps_buf_mgr = (buf_mgr_t *) pv_buf_mgr;
+
+ for(id = 0; id < BUF_MGR_MAX_CNT; id++)
+ {
+ ps_buf_mgr->au4_status[id] = 0;
+ }
+
+ return;
+}
/**
*******************************************************************************
diff --git a/common/ih264_buf_mgr.h b/common/ih264_buf_mgr.h
index 52efa70..fe9c53d 100644
--- a/common/ih264_buf_mgr.h
+++ b/common/ih264_buf_mgr.h
@@ -82,6 +82,9 @@ WORD32 ih264_buf_mgr_size(void);
//Free buffer manager
IH264_ERROR_T ih264_buf_mgr_free(buf_mgr_t *ps_buf_mgr);
+// Reset the buffer manager
+void ih264_buf_mgr_reset(void *pv_buf_mgr);
+
// Initializes the buffer API structure
void *ih264_buf_mgr_init(void *pv_buf);
diff --git a/common/ih264_cabac_tables.h b/common/ih264_cabac_tables.h
index dd2fd35..5cddc45 100644
--- a/common/ih264_cabac_tables.h
+++ b/common/ih264_cabac_tables.h
@@ -141,10 +141,15 @@ typedef enum
LAST_SIGNIFICANT_COEFF_FLAG_8X8_FRAME = 417,
COEFF_ABS_LEVEL_MINUS1_8X8 = 426,
SIGNIFICANT_COEFF_FLAG_8X8_FIELD = 436,
- LAST_SIGNIFICANT_COEFF_FLAG_8X8_FIELD = 451
+ LAST_SIGNIFICANT_COEFF_FLAG_8X8_FIELD = 451,
-} cabac_table_num_t;
+ /* SVC related CABAC offsets */
+ BASE_MODE_FLAG = 460,
+ MOTION_PREDICTION_FLAG_L0 = 463,
+ MOTION_PREDICTION_FLAG_L1 = 464,
+ RESIDUAL_PREDICTION_FLAG = 465,
+} cabac_table_num_t;
/**
******************************************************************************
diff --git a/common/ih264_debug.h b/common/ih264_debug.h
index 96ff2a7..63d5c71 100644
--- a/common/ih264_debug.h
+++ b/common/ih264_debug.h
@@ -38,6 +38,7 @@
#ifndef _IH264_DEBUG_H_
#define _IH264_DEBUG_H_
+#include <assert.h>
#if DEBUG_PRINT
diff --git a/common/ih264_defs.h b/common/ih264_defs.h
index d9fea26..62b2783 100644
--- a/common/ih264_defs.h
+++ b/common/ih264_defs.h
@@ -135,6 +135,9 @@ enum
ISLICE = 2,
SPSLICE = 3,
SISLICE = 4,
+ EPSLICE = 5,
+ EBSLICE = 6,
+ EISLICE = 7,
MAXSLICE_TYPE,
};
@@ -144,27 +147,28 @@ enum
* @brief Defines the set of possible nal unit types
******************************************************************************
*/
-enum
+typedef enum NAL_UNIT_TYPE_T
{
- NAL_UNSPEC_0 = 0,
- NAL_SLICE_NON_IDR = 1,
- NAL_SLICE_DPA = 2,
- NAL_SLICE_DPB = 3,
- NAL_SLICE_DPC = 4,
- NAL_SLICE_IDR = 5,
- NAL_SEI = 6,
- NAL_SPS = 7,
- NAL_PPS = 8,
- NAL_AUD = 9,
- NAL_EOSEQ = 10,
- NAL_EOSTR = 11,
- NAL_FILLER = 12,
- NAL_SPSE = 13,
- NAL_RES_18 = 14,
- NAL_AUX_PIC = 19,
- NAL_RES_23 = 20,
- NAL_UNSPEC_31 = 24,
-};
+ NAL_UNSPEC_0 = 0,
+ NAL_SLICE_NON_IDR = 1,
+ NAL_SLICE_DPA = 2,
+ NAL_SLICE_DPB = 3,
+ NAL_SLICE_DPC = 4,
+ NAL_SLICE_IDR = 5,
+ NAL_SEI = 6,
+ NAL_SPS = 7,
+ NAL_PPS = 8,
+ NAL_AUD = 9,
+ NAL_EOSEQ = 10,
+ NAL_EOSTR = 11,
+ NAL_FILLER = 12,
+ NAL_SPSE = 13,
+ NAL_PREFIX = 14,
+ NAL_SUBSET_SPS = 15,
+ NAL_AUX_PIC = 19,
+ NAL_CODED_SLICE_EXTENSION = 20,
+ NAL_UNSPEC_31 = 24,
+} NAL_UNIT_TYPE_T;
/**
******************************************************************************
@@ -261,27 +265,29 @@ typedef enum
*/
typedef enum
{
- I16x16 = 0,
- I4x4 = 1,
- I8x8 = 2,
- P16x16 = 3,
- P16x8 = 4,
- P8x16 = 5,
- P8x8 = 6,
- PSKIP = 7,
- IPCM = 8,
- B16x16 = 9,
- BSKIP = 10,
- BDIRECT = 11,
+ INVALID_MB_TYPE = -1,
+ I16x16 = 0,
+ I4x4 = 1,
+ I8x8 = 2,
+ P16x16 = 3,
+ P16x8 = 4,
+ P8x16 = 5,
+ P8x8 = 6,
+ PSKIP = 7,
+ IPCM = 8,
+ B16x16 = 9,
+ BSKIP = 10,
+ BDIRECT = 11,
+ BASE_MODE = 12,
MAX_MBTYPES,
-}MBTYPES_T;
+} MBTYPES_T;
/* Pred Modes */
enum
{
BLOCK_TYPE_INTER_MB = 0,
BLOCK_TYPE_INTRA_MB = 1,
- BLOCK_TYPE_SKIP_MB = 2
+ BLOCK_TYPE_SKIP_MB = 2
};
/* Prediction list */
@@ -521,9 +527,16 @@ typedef enum
/* Number of max TU in a MB row */
#define MAX_TU_IN_MB_ROW ((MB_SIZE / MIN_TU_SIZE))
+#define MIN_TU_IN_MB_ROW ((MB_SIZE / MAX_TU_SIZE))
+
/* Number of max PU in a CTb row */
#define MAX_PU_IN_MB_ROW ((MB_SIZE / MIN_PU_SIZE))
+#define MAX_TU_IN_MB_COL MAX_TU_IN_MB_ROW
+
+#define MIN_TU_IN_MB_COL MIN_TU_IN_MB_ROW
+
+#define MAX_PU_IN_MB_COL MAX_PU_IN_MB_ROW
/* Number of max PU in a MB */
/*****************************************************************************/
@@ -537,7 +550,11 @@ typedef enum
#define MAX_TU_IN_MB ((MB_SIZE / MIN_TU_SIZE) * \
(MB_SIZE / MIN_TU_SIZE))
+#define MIN_TU_IN_MB (MIN_TU_IN_MB_ROW * MIN_TU_IN_MB_COL)
+
+#define NUM_4x4_IN_8x8 4
+#define NUM_COEFFS_IN_MIN_TU (MIN_TU_SIZE * MIN_TU_SIZE)
/**
* Maximum transform depths
@@ -754,4 +771,25 @@ typedef enum
#define CCV_PRIMARIES_Y_UPPER_LIMIT 5000000
#define CCV_PRIMARIES_Y_LOWER_LIMIT -5000000
+#define RSD_MAX 255
+#define RSD_MIN -255
+#define CLIP_RSD(x) CLIP3(RSD_MIN, RSD_MAX, (x))
+
+#define SII_MAX_SUB_LAYERS 8
+#define SII_SUB_LAYER_IDX 0
+#define SHUTTER_INTERVAL_INFO_PRESENT_FLAG 1
+#define SII_TIME_SCALE 24000000
+#define FIXED_SHUTTER_INTERVAL_WITHIN_CVS_FLAG 0
+#define SII_NUM_UNITS_IN_SHUTTER_INTERVAL 480000
+#define SII_MAX_SUB_LAYERS_MINUS1 (SII_MAX_SUB_LAYERS - 1)
+#define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_HFR 480000
+#define SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_SFR 240000
+
+/*
+ * @brief Below macros related to film grain characteristics SEI
+ */
+#define SEI_FGC_NUM_COLOUR_COMPONENTS 3
+#define SEI_FGC_MAX_NUM_MODEL_VALUES 6
+#define SEI_FGC_MAX_NUM_INTENSITY_INTERVALS 256
+
#endif /* IH264_DEFS_H_ */
diff --git a/common/ih264_resi_trans_quant.c b/common/ih264_resi_trans_quant.c
index cf1d43c..a17b078 100644
--- a/common/ih264_resi_trans_quant.c
+++ b/common/ih264_resi_trans_quant.c
@@ -123,8 +123,7 @@ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src,
{
UWORD32 i;
WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
- WORD32 i4_value, i4_sign;
- UWORD32 u4_abs_value;
+ WORD32 i4_value;
WORD16 *pi2_out_tmp = pi2_out;
UWORD32 u4_nonzero_coeff = 0;
@@ -178,22 +177,22 @@ void ih264_resi_trans_quant_4x4(UWORD8 *pu1_src,
(*pi2_alt_dc_addr) = i4_value;
}
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, u4_nonzero_coeff);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits, u4_nonzero_coeff);
pi2_out_tmp[0] = i4_value;
i4_value = (x3 << 1) + x2;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[4], pu2_scale_matrix[4], u4_round_factor, u4_qbits, u4_nonzero_coeff);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[4], pu2_scale_matrix[4], u4_round_factor, u4_qbits, u4_nonzero_coeff);
pi2_out_tmp[4] = i4_value;
i4_value = x0 - x1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits, u4_nonzero_coeff);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits, u4_nonzero_coeff);
pi2_out_tmp[8] = i4_value;
i4_value = x3 - (x2 << 1);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[12], pu2_scale_matrix[12], u4_round_factor, u4_qbits, u4_nonzero_coeff);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[12], pu2_scale_matrix[12], u4_round_factor, u4_qbits, u4_nonzero_coeff);
pi2_out_tmp[12] = i4_value;
pi2_out_tmp ++;
@@ -271,8 +270,7 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src,
{
UWORD32 i;
WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
- WORD32 i4_value, i4_sign;
- UWORD32 u4_abs_value;
+ WORD32 i4_value;
WORD16 *pi2_out_tmp = pi2_out;
UWORD32 u4_nonzero_coeff = 0;
@@ -326,25 +324,25 @@ void ih264_resi_trans_quant_chroma_4x4(UWORD8 *pu1_src,
*pu1_dc_alt_addr = i4_value;
}
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[0] = i4_value;
i4_value = (x3 << 1) + x2;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[4],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[4],
pu2_scale_matrix[4], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[4] = i4_value;
i4_value = x0 - x1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[8],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[8],
pu2_scale_matrix[8], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[8] = i4_value;
i4_value = x3 - (x2 << 1);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[12],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[12],
pu2_scale_matrix[12], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[12] = i4_value;
@@ -420,8 +418,6 @@ void ih264_hadamard_quant_4x4(WORD16 *pi2_src,
{
WORD32 i;
WORD32 x0,x1,x2,x3,x4,x5,x6,x7,i4_value;
- UWORD32 u4_abs_value;
- WORD32 i4_sign;
*pu1_nnz = 0;
@@ -463,22 +459,22 @@ void ih264_hadamard_quant_4x4(WORD16 *pi2_src,
i4_value = (x0 + x1) >> 1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]);
pi2_dst[0] = i4_value;
i4_value = (x3 + x2) >> 1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]);
pi2_dst[4] = i4_value;
i4_value = (x0 - x1) >> 1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]);
pi2_dst[8] = i4_value;
i4_value = (x3 - x2) >> 1;
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits, pu1_nnz[0]);
pi2_dst[12] = i4_value;
@@ -548,8 +544,7 @@ void ih264_hadamard_quant_2x2_uv(WORD16 *pi2_src,
UWORD8 *pu1_nnz)
{
WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
- WORD32 i4_value, i4_sign, plane;
- UWORD32 u4_abs_value;
+ WORD32 i4_value, plane;
for(plane = 0; plane < 2; plane++)
{
@@ -568,25 +563,25 @@ void ih264_hadamard_quant_2x2_uv(WORD16 *pi2_src,
/* Vertical transform and quantization */
i4_value = (x0 + x2);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
pu1_nnz[plane]);
pi2_dst[0] = i4_value;
i4_value = (x0 - x2);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
pu1_nnz[plane]);
pi2_dst[2] = i4_value;
i4_value = (x1 - x3);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
pu1_nnz[plane]);
pi2_dst[3] = i4_value;
i4_value = (x1 + x3);
- FWD_QUANT(i4_value, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
pu1_nnz[plane]);
pi2_dst[1] = i4_value;
@@ -660,8 +655,6 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src,
UWORD32 i;
WORD32 a0, a1, a2, a3, a4, a5, a6, a7;
WORD32 r0, r1, r2, r3, r4, r5, r6, r7;
- WORD32 i4_sign;
- UWORD32 u4_abs_value;
UWORD32 u4_nonzero_coeff = 0;
UNUSED(pu1_dc_alt_addr);
@@ -765,42 +758,42 @@ void ih264_resi_trans_quant_8x8(UWORD8 *pu1_src,
r5 = a6 - (a5>>2);
r7 = (a4>>2) - a7;
- FWD_QUANT(r0, u4_abs_value, i4_sign, pu2_threshold_matrix[0],
+ FWD_QUANT(r0, pu2_threshold_matrix[0],
pu2_scale_matrix[0], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[0] = r0;
- FWD_QUANT(r1, u4_abs_value, i4_sign, pu2_threshold_matrix[8],
+ FWD_QUANT(r1, pu2_threshold_matrix[8],
pu2_scale_matrix[8], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[8] = r1;
- FWD_QUANT(r2, u4_abs_value, i4_sign, pu2_threshold_matrix[16],
+ FWD_QUANT(r2, pu2_threshold_matrix[16],
pu2_scale_matrix[16], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[16] = r2;
- FWD_QUANT(r3, u4_abs_value, i4_sign, pu2_threshold_matrix[24],
+ FWD_QUANT(r3, pu2_threshold_matrix[24],
pu2_scale_matrix[24], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[24] = r3;
- FWD_QUANT(r4, u4_abs_value, i4_sign, pu2_threshold_matrix[32],
+ FWD_QUANT(r4, pu2_threshold_matrix[32],
pu2_scale_matrix[32], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[32] = r4;
- FWD_QUANT(r5, u4_abs_value, i4_sign, pu2_threshold_matrix[40],
+ FWD_QUANT(r5, pu2_threshold_matrix[40],
pu2_scale_matrix[40], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[40] = r5;
- FWD_QUANT(r6, u4_abs_value, i4_sign, pu2_threshold_matrix[48],
+ FWD_QUANT(r6, pu2_threshold_matrix[48],
pu2_scale_matrix[48], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[48] = r6;
- FWD_QUANT(r7, u4_abs_value, i4_sign, pu2_threshold_matrix[56],
+ FWD_QUANT(r7, pu2_threshold_matrix[56],
pu2_scale_matrix[56], u4_round_factor, u4_qbits,
u4_nonzero_coeff);
pi2_out_tmp[56] = r7;
diff --git a/common/ih264_size_defs.h b/common/ih264_size_defs.h
index e2a8b76..4555647 100644
--- a/common/ih264_size_defs.h
+++ b/common/ih264_size_defs.h
@@ -44,6 +44,8 @@
/*Width of a 4x4 block*/
#define SUB_BLK_WIDTH_4x4 4
+#define SUB_BLK_HEIGHT_4x4 4
+
/*Width of an 8x8 block*/
#define SUB_BLK_WIDTH_8x8 8
diff --git a/common/ih264_structs.h b/common/ih264_structs.h
index d1eaeac..7699451 100644
--- a/common/ih264_structs.h
+++ b/common/ih264_structs.h
@@ -1867,6 +1867,169 @@ typedef struct
UWORD32 u4_ccv_avg_luminance_value;
}sei_ccv_params_t;
+/**
+ * Structure to hold FGC SEI
+ */
+typedef struct
+{
+ /**
+ * Flag to control the presence of FGC SEI params
+ */
+ UWORD8 u1_film_grain_characteristics_cancel_flag;
+
+ /**
+ * Specifies the pic order count
+ */
+ WORD32 i4_poc;
+
+ /**
+ * Specifies IDR pic ID
+ */
+ UWORD32 u4_idr_pic_id;
+
+ /**
+ * Specifies film grain model for simulation
+ */
+ UWORD8 u1_film_grain_model_id;
+
+ /**
+ * Specifies separate color format for decoded samples and grain
+ */
+ UWORD8 u1_separate_colour_description_present_flag;
+
+ /**
+ * Specifies the bit depth used for the luma component
+ */
+ UWORD8 u1_film_grain_bit_depth_luma_minus8;
+
+ /**
+ * Specifies the bit depth used for the Cb and Cr components
+ */
+ UWORD8 u1_film_grain_bit_depth_chroma_minus8;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_full_range_flag;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_colour_primaries;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_transfer_characteristics;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_matrix_coefficients;
+
+ /**
+ * identifies the blending mode used to blend the simulated film grain with the decoded images
+ */
+ UWORD8 u1_blending_mode_id;
+
+ /**
+ * Specifies a scale factor used in the film grain characterization equations
+ */
+ UWORD8 u1_log2_scale_factor;
+
+ /**
+ * Indicates whether film grain is modelled or not on the colour component
+ */
+ UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of intensity intervals for which
+ * a specific set of model values has been estimated
+ */
+ UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of model values present for each intensity interval in which
+ * the film grain has been modelled
+ */
+ UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the lower bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Specifies the upper bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Represents each one of the model values present for
+ * the colour component and intensity interval
+ */
+ WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]
+ [SEI_FGC_MAX_NUM_MODEL_VALUES];
+
+ /**
+ * Specifies the persistence of the film grain characteristics SEI message
+ */
+ UWORD32 u4_film_grain_characteristics_repetition_period;
+
+} sei_fgc_params_t;
+
+/**
+ * Structure to hold shutter interval info SEI
+ */
+typedef struct
+{
+ /**
+ * specifies if the sei sii is enabled
+ */
+ UWORD8 u1_shutter_interval_info_present_flag;
+
+ /**
+ * specifies the shutter interval temporal sub-layer index
+ * of the current picture
+ */
+ UWORD32 u4_sii_sub_layer_idx;
+
+ /**
+ * specify the number of time units that pass in one second
+ */
+ UWORD32 u4_sii_time_scale;
+
+ /**
+ * specifies that the indicated shutter interval is the same for all
+ * pictures in the coded video sequence
+ */
+ UWORD8 u1_fixed_shutter_interval_within_cvs_flag;
+
+ /**
+ * specifies the the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the indicated shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 u4_sii_num_units_in_shutter_interval;
+
+ /**
+ * sii_max_sub_layers_minus1 plus 1 specifies the maximum number of
+ * shutter interval temporal sub-layers indexes that may be present
+ * in the coded video sequence
+ */
+ UWORD8 u1_sii_max_sub_layers_minus1;
+
+ /*
+ * specifies the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 au4_sub_layer_num_units_in_shutter_interval[SII_MAX_SUB_LAYERS];
+} sei_sii_params_t;
/**
* Structure to hold SEI parameters Info
@@ -1912,6 +2075,26 @@ typedef struct
* CCV parameters
*/
sei_ccv_params_t s_sei_ccv_params;
+
+ /**
+ * film grain characteristics info present flag
+ */
+ UWORD8 u1_sei_fgc_params_present_flag;
+
+ /*
+ * Film grain parameters
+ */
+ sei_fgc_params_t s_sei_fgc_params;
+
+ /**
+ * shutter interval info present flag
+ */
+ UWORD8 u1_sei_sii_params_present_flag;
+
+ /*
+ * Shutter Interval Info parameters
+ */
+ sei_sii_params_t s_sei_sii_params;
} sei_params_t;
diff --git a/common/ih264_trans_macros.h b/common/ih264_trans_macros.h
index f114d0e..79e3aa3 100644
--- a/common/ih264_trans_macros.h
+++ b/common/ih264_trans_macros.h
@@ -51,8 +51,10 @@
* h264 specification
******************************************************************************
*/
-#define FWD_QUANT(i4_value, u4_abs_value, i4_sign, threshold, scale, rndfactor, qbits, u4_nnz) \
+#define FWD_QUANT(i4_value, threshold, scale, rndfactor, qbits, u4_nnz) \
{\
+ WORD32 i4_sign;\
+ UWORD32 u4_abs_value;\
if (i4_value < 0)\
{\
u4_abs_value = -i4_value;\
@@ -72,7 +74,8 @@
u4_abs_value *= scale;\
u4_abs_value += rndfactor;\
u4_abs_value >>= qbits;\
- i4_value = u4_abs_value * i4_sign;\
+ i4_value = u4_abs_value;\
+ if (i4_sign == -1) i4_value = -i4_value;\
if (i4_value)\
{\
u4_nnz++;\
diff --git a/common/ithread.c b/common/ithread.c
index e7f63ad..d45bfed 100644
--- a/common/ithread.c
+++ b/common/ithread.c
@@ -82,8 +82,8 @@ WORD32 ithread_create(void *thread_handle, void *attribute, void *strt, void *ar
WORD32 ithread_join(void *thread_handle, void ** val_ptr)
{
- UNUSED(val_ptr);
pthread_t *pthread_handle = (pthread_t *)thread_handle;
+ UNUSED(val_ptr);
return pthread_join(*pthread_handle, NULL);
}
diff --git a/common/mvc/imvc_defs.h b/common/mvc/imvc_defs.h
new file mode 100644
index 0000000..c7e0705
--- /dev/null
+++ b/common/mvc/imvc_defs.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _IMVC_DEFS_H_
+#define _IMVC_DEFS_H_
+
+#define MAX_NUM_VIEWS 6
+
+#define LOG2_MAX_NUM_VIEWS 3
+
+#define MAX_NUM_IVP_REFS MAX_NUM_VIEWS
+
+#define MAX_NUM_LEVEL_VALUES_SIGNALLED 1
+
+#define MAX_NUM_OPERATING_POINTS 1
+
+#define MULTIVIEW_HIGH_PROFILE_IDC 118
+
+#define NUM_OF_ZERO_BYTES_BEFORE_START_CODE 2
+
+#define EMULATION_PREVENTION_BYTE 0x03
+
+#define MIN_H264_QP 0
+
+#define MAX_H264_QP 51
+
+#define NUM_SP_COMPONENTS 2
+
+#define NUM_COMPONENTS 3
+
+#define FORCEINLINE __attribute__((always_inline)) inline
+
+typedef void *FT_ALIGNED_ALLOC(void *pv_mem_ctxt, WORD32 i4_alignment, WORD32 i4_size);
+
+typedef void FT_ALIGNED_FREE(void *pv_mem_ctxt, void *pv_buf);
+
+typedef enum COMPONENT_TYPES_T
+{
+ Y = 0,
+ UV = 1,
+ U = 1,
+ V = 2,
+} COMPONENT_TYPES_T;
+
+typedef enum AVC_EXT_NALU_ID_T
+{
+ UNSPEC_0 = 0,
+
+ SLICE_NON_IDR = 1,
+
+ SLICE_DPA = 2,
+
+ SLICE_DPB = 3,
+
+ SLICE_DPC = 4,
+
+ SLICE_IDR = 5,
+
+ SEI = 6,
+
+ SPS = 7,
+
+ PPS = 8,
+
+ AUD = 9,
+
+ EOSEQ = 10,
+
+ EOSTR = 11,
+
+ FILLER = 12,
+
+ SPSE = 13,
+
+ PREFIX_NAL = 14,
+
+ SUBSET_SPS = 15,
+
+ AUX_PIC = 19,
+
+ CODED_SLICE_EXTENSION = 20,
+
+ UNSPEC_31 = 24
+
+} AVC_EXT_NALU_ID_T;
+
+typedef enum SLICE_TYPES_T
+{
+ PSLICE = 0,
+ BSLICE = 1,
+ ISLICE = 2,
+ SPSLICE = 3,
+ SISLICE = 4,
+ MAXSLICE_TYPE,
+} SLICE_TYPES_T;
+
+#endif
diff --git a/common/mvc/imvc_structs.h b/common/mvc/imvc_structs.h
new file mode 100644
index 0000000..faf3ff9
--- /dev/null
+++ b/common/mvc/imvc_structs.h
@@ -0,0 +1,164 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _IMVC_STRUCTS_H_
+#define _IMVC_STRUCTS_H_
+
+#include "ih264_typedefs.h"
+#include "imvc_defs.h"
+
+typedef struct nalu_mvc_ext_t
+{
+ UWORD8 u1_non_idr_flag;
+
+ UWORD8 u1_priority_id;
+
+ UWORD16 u2_view_id;
+
+ UWORD8 u1_temporal_id;
+
+ UWORD8 u1_anchor_pic_flag;
+
+ UWORD8 u1_inter_view_flag;
+
+} nalu_mvc_ext_t;
+
+typedef struct mvc_ivp_ref_data_t
+{
+ UWORD8 u1_num_refs;
+
+ UWORD16 au2_ref_view_ids[MAX_NUM_IVP_REFS];
+
+} mvc_ivp_ref_data_t;
+
+typedef struct mvc_op_data_t
+{
+ UWORD8 u1_temporal_id;
+
+ UWORD16 u2_num_ops;
+
+ UWORD16 u2_num_target_views;
+
+ UWORD16 au2_target_view_ids[MAX_NUM_VIEWS];
+
+ /* Counter for num target views and views each target is dependent on */
+ UWORD16 u2_num_views;
+
+} mvc_op_data_t;
+
+typedef struct mvc_level_info_t
+{
+ UWORD32 u4_level_idc;
+
+ mvc_op_data_t as_mvc_op_data[MAX_NUM_OPERATING_POINTS];
+
+} mvc_level_info_t;
+
+typedef struct sps_mvc_ext_t
+{
+ UWORD16 u2_num_views;
+
+ UWORD16 au2_view_ids[MAX_NUM_VIEWS];
+
+ /* 0 => L0; 1 => L1 */
+ mvc_ivp_ref_data_t as_anchor_ref_data[2][MAX_NUM_VIEWS];
+
+ /* 0 => L0; 1 => L1 */
+ mvc_ivp_ref_data_t as_non_anchor_ref_data[2][MAX_NUM_VIEWS];
+
+ UWORD8 u1_num_level_values_signalled;
+
+ mvc_level_info_t as_mvc_level_info[MAX_NUM_LEVEL_VALUES_SIGNALLED];
+
+} sps_mvc_ext_t;
+
+typedef struct mvc_vui_ext_t
+{
+ UWORD16 u2_vui_mvc_num_ops;
+
+ UWORD8 u1_vui_mvc_temporal_id[MAX_NUM_OPERATING_POINTS];
+
+ UWORD16 u2_vui_mvc_num_target_output_views[MAX_NUM_OPERATING_POINTS];
+
+ UWORD16 u2_vui_mvc_view_id[MAX_NUM_OPERATING_POINTS][MAX_NUM_VIEWS];
+
+ UWORD8 u1_vui_mvc_timing_info_present_flag[MAX_NUM_OPERATING_POINTS];
+
+ UWORD32 u4_vui_mvc_num_units_in_tick[MAX_NUM_OPERATING_POINTS];
+
+ UWORD32 u4_vui_mvc_time_scale[MAX_NUM_OPERATING_POINTS];
+
+ UWORD8 u1_vui_mvc_fixed_frame_rate_flag[MAX_NUM_OPERATING_POINTS];
+
+ UWORD8 u1_vui_mvc_nal_hrd_parameters_present_flag[MAX_NUM_OPERATING_POINTS];
+
+ UWORD8 u1_vui_mvc_vcl_hrd_parameters_present_flag[MAX_NUM_OPERATING_POINTS];
+
+ UWORD8 u1_vui_mvc_low_delay_hrd_flag[MAX_NUM_OPERATING_POINTS];
+
+ UWORD8 u1_vui_mvc_pic_struct_present_flag[MAX_NUM_OPERATING_POINTS];
+
+} mvc_vui_ext_t;
+
+typedef struct buffer_container_t
+{
+ void *pv_data;
+
+ WORD32 i4_data_stride;
+
+} buffer_container_t;
+
+typedef struct yuv_buf_props_t
+{
+ buffer_container_t as_component_bufs[NUM_COMPONENTS];
+
+ UWORD8 u1_bit_depth;
+
+ UWORD16 u2_width;
+
+ UWORD16 u2_height;
+
+} yuv_buf_props_t;
+
+typedef struct iv_mvc_yuv_buf_t
+{
+ yuv_buf_props_t as_view_buf_props[MAX_NUM_VIEWS];
+
+} iv_mvc_yuv_buf_t;
+
+typedef struct coordinates_t
+{
+ WORD32 i4_abscissa;
+
+ WORD32 i4_ordinate;
+} coordinates_t;
+
+typedef struct offsets_t
+{
+ UWORD16 u2_top_offset;
+
+ UWORD16 u2_bottom_offset;
+
+ UWORD16 u2_left_offset;
+
+ UWORD16 u2_right_offset;
+} offsets_t;
+
+#endif
diff --git a/common/mips/ih264_platform_macros.h b/common/riscv/ih264_platform_macros.h
index fa0ba61..2b0b0d1 100644
--- a/common/mips/ih264_platform_macros.h
+++ b/common/riscv/ih264_platform_macros.h
@@ -67,13 +67,9 @@
#define SHL_NEG(val,shift) ((shift<0)?(val>>(-shift)):(val<<shift))
-#define ITT_BIG_ENDIAN(x) ((x << 24)) | \
- ((x & 0x0000ff00) << 8) | \
- ((x & 0x00ff0000) >> 8) | \
- ((UWORD32)x >> 24);
+#define ITT_BIG_ENDIAN(x) __builtin_bswap32(x)
-
-#define NOP(nop_cnt) {UWORD32 nop_i; for (nop_i = 0; nop_i < nop_cnt; nop_i++);}
+#define NOP(nop_cnt) {UWORD32 nop_i; for (nop_i = 0; nop_i < nop_cnt; nop_i++) asm("nop");}
#define PLD(a)
@@ -102,11 +98,9 @@ static __inline UWORD32 CTZ(UWORD32 u4_word)
}
}
-#define DATA_SYNC()
-
-#define INLINE
+#define DATA_SYNC() __sync_synchronize()
-#define PREFETCH(ptr, type)
+#define INLINE inline
#define MEM_ALIGN8 __attribute__ ((aligned (8)))
#define MEM_ALIGN16 __attribute__ ((aligned (16)))
diff --git a/common/svc/isvc_cabac_tables.c b/common/svc/isvc_cabac_tables.c
new file mode 100644
index 0000000..6893fc2
--- /dev/null
+++ b/common/svc/isvc_cabac_tables.c
@@ -0,0 +1,6542 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvc_cabac_tables.c
+*
+* @brief
+* This file contains H264 cabac tables for init contexts, rlps and
+* cabac state transitions
+*
+* @author
+* Ittiam
+*
+* @par List of Tables
+* - gau4_isvc_cabac_table[][]
+* - gau1_isvc_cabac_ctxt_init_table[][][]
+*
+******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvc_cabac_tables.h"
+
+/*****************************************************************************/
+/* CABAC TABLES */
+/*****************************************************************************/
+/*combined table :guc_RTAB,NextStateLPS,NextStateMPS
+ input(combined_state):
+ bits 0-5: state
+ bits 6:mps
+ output
+ bits 0-7:rangeTabLPS
+ bits 8-14 :combined_next_state_if_mps
+ bits 15 -21:combined_next_state_if_lps
+
+ */
+const UWORD32 (*gau4_isvc_cabac_table)[4] = gau4_ih264_cabac_table;
+
+/*****************************************************************************/
+/* Global Variable Initialization */
+/*****************************************************************************/
+/* This table has been derived using equation 9.5 and table 9.11 from the */
+/* spec. The formulae have been reproduced below - */
+/*
+ preCtxState = Clip3( 1, 126, ( ( m * Clip3( 0, 51, SliceQPY ) ) >> 4 ) + n )
+ if( preCtxState <= 63 ) {
+ pStateIdx = 63 - preCtxState
+ valMPS = 0
+ } else {
+ pStateIdx = preCtxState - 64
+ valMPS = 1
+ }
+ gau1_isvc_cabac_ctxt_init_table[I|P][SliceQPY][Idx] = (pStateIdx + (valMPS << 7));
+*/
+/* 'm', and 'n' are listed for each index in table 9.11 */
+const UWORD8
+ gau1_isvc_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_SVC_CABAC_CTXTS] =
+
+ {
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, 54, 14, 118,
+ 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, 67, 90, 104, 126, 104, 67, 78,
+ 65, 1, 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, 94, 9,
+ 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0, 83, 86, 97, 72,
+ 22, 1, 18, 78, 96, 126, 98, 101, 67, 82, 94, 83, 110, 91, 102, 93, 126,
+ 92, 89, 96, 108, 17, 65, 6, 93, 74, 92, 87, 126, 9, 3, 4, 69, 15,
+ 68, 69, 88, 85, 78, 75, 77, 9, 13, 68, 13, 21, 81, 0, 70, 67, 6,
+ 76, 28, 64, 2, 28, 38, 39, 34, 27, 93, 73, 73, 17, 14, 100, 10, 10,
+ 10, 2, 7, 7, 0, 3, 1, 6, 69, 6, 24, 12, 68, 64, 2, 0, 13,
+ 24, 19, 11, 15, 3, 4, 4, 30, 19, 20, 78, 3, 69, 35, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18,
+ 27, 10, 82, 8, 78, 17, 32, 84, 56, 62, 60, 59, 62, 62, 57, 57, 54,
+ 44, 36, 33, 43, 29, 70, 67, 4, 67, 33, 31, 28, 34, 32, 25, 20, 22,
+ 0, 4, 64, 94, 89, 108, 76, 19, 18, 11, 64, 4, 70, 75, 82, 102, 77,
+ 39, 21, 15, 8, 4, 71, 83, 87, 119, 5, 34, 27, 25, 20, 8, 5, 64,
+ 74, 90, 70, 34, 32, 21, 4, 5, 72, 81, 97, 5, 58, 49, 45, 36, 23,
+ 5, 70, 79, 85, 62, 106, 106, 87, 114, 110, 98, 110, 106, 103, 107, 108, 112,
+ 96, 95, 91, 93, 94, 86, 67, 80, 85, 70, 3, 5, 2, 13, 13, 14, 9,
+ 22, 17, 12, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, 64, 69, 4,
+ 70, 19, 32, 20, 10, 29, 25, 11, 23, 31, 19, 25, 13, 6, 20, 52, 49,
+ 52, 52, 54, 62, 62, 62, 62, 62, 62, 62, 62, 62, 34, 62, 62, 62, 62,
+ 62, 62, 54, 37, 36, 6, 82, 75, 97, 125, 62, 62, 62, 57, 55, 53, 41,
+ 44, 31, 32, 22, 19, 16, 65, 71, 3, 0, 65, 39, 43, 40, 31, 40, 39,
+ 23, 31, 34, 21, 6, 10, 2, 86, 23, 12, 4, 79, 71, 69, 70, 66, 68,
+ 73, 69, 70, 67, 1, 70, 66, 65, 0, 62, 62, 62, 62, 62, 60, 54, 36,
+ 4, 66, 28, 21, 18, 15, 7, 3, 1, 66, 76, 85, 81, 77, 81, 80, 73,
+ 74, 83, 71, 67, 2, 66, 66, 4, 4, 62, 62, 62, 62, 61, 57, 46, 29,
+ 1, 75, 65, 4, 67, 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, 62, 54, 14, 115,
+ 6, 77, 64, 1, 14, 72, 12, 65, 20, 62, 68, 91, 104, 124, 102, 67, 77,
+ 64, 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5, 75, 93, 9,
+ 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0, 82, 86, 97, 71,
+ 22, 1, 18, 77, 95, 124, 96, 99, 65, 80, 92, 82, 108, 89, 100, 92, 125,
+ 91, 88, 95, 107, 18, 64, 7, 92, 73, 91, 86, 124, 9, 3, 4, 69, 16,
+ 68, 68, 87, 84, 77, 74, 76, 9, 13, 67, 13, 21, 80, 0, 69, 67, 6,
+ 75, 28, 64, 2, 28, 37, 39, 34, 27, 92, 72, 72, 17, 14, 99, 10, 10,
+ 10, 3, 7, 7, 1, 4, 2, 6, 68, 6, 24, 12, 68, 64, 2, 0, 13,
+ 23, 19, 11, 15, 4, 5, 4, 29, 19, 20, 77, 3, 69, 35, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18,
+ 27, 10, 81, 8, 77, 17, 31, 83, 55, 62, 59, 58, 61, 62, 56, 56, 52,
+ 43, 35, 32, 41, 28, 71, 67, 4, 67, 32, 30, 27, 33, 31, 24, 19, 21,
+ 0, 4, 64, 93, 88, 107, 75, 20, 18, 11, 0, 5, 69, 74, 81, 100, 76,
+ 39, 21, 15, 8, 5, 70, 82, 86, 117, 5, 35, 28, 25, 20, 9, 5, 64,
+ 73, 89, 70, 35, 32, 21, 4, 6, 71, 80, 96, 5, 58, 49, 45, 36, 23,
+ 5, 69, 78, 84, 62, 105, 105, 86, 112, 108, 97, 108, 104, 101, 105, 106, 110,
+ 95, 94, 90, 92, 92, 85, 67, 79, 84, 69, 3, 5, 2, 13, 13, 13, 8,
+ 22, 17, 13, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, 64, 68, 5,
+ 70, 19, 32, 20, 10, 29, 25, 12, 23, 30, 19, 25, 13, 6, 19, 52, 49,
+ 52, 51, 53, 62, 62, 62, 62, 62, 62, 62, 62, 62, 33, 62, 62, 62, 62,
+ 62, 62, 53, 36, 35, 6, 81, 74, 95, 122, 62, 62, 62, 56, 53, 52, 40,
+ 42, 30, 31, 21, 18, 15, 66, 71, 3, 0, 66, 38, 42, 39, 30, 39, 38,
+ 22, 30, 33, 20, 5, 9, 1, 86, 23, 12, 4, 78, 70, 68, 69, 65, 67,
+ 71, 68, 69, 66, 3, 68, 65, 0, 2, 62, 62, 62, 62, 62, 58, 51, 34,
+ 2, 65, 29, 22, 19, 16, 8, 4, 2, 65, 75, 84, 80, 76, 80, 78, 71,
+ 73, 82, 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 58, 54, 43, 26,
+ 64, 75, 65, 4, 66, 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, 61, 54, 14, 113,
+ 6, 76, 0, 1, 13, 72, 11, 66, 19, 60, 70, 92, 105, 121, 101, 67, 76,
+ 0, 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5, 75, 92, 9,
+ 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0, 81, 86, 97, 71,
+ 21, 1, 18, 77, 95, 122, 94, 97, 64, 78, 91, 81, 107, 88, 99, 91, 123,
+ 91, 88, 95, 106, 18, 64, 7, 91, 73, 90, 86, 123, 9, 3, 4, 69, 16,
+ 68, 68, 87, 84, 77, 74, 76, 9, 13, 67, 13, 21, 80, 0, 69, 67, 6,
+ 75, 27, 64, 2, 27, 36, 38, 33, 26, 91, 72, 72, 16, 13, 99, 9, 10,
+ 10, 3, 7, 7, 2, 4, 2, 6, 68, 6, 23, 12, 69, 64, 2, 64, 13,
+ 22, 19, 11, 14, 4, 5, 4, 28, 19, 19, 77, 3, 70, 34, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 17,
+ 26, 9, 81, 8, 77, 16, 30, 83, 53, 62, 57, 56, 59, 60, 54, 54, 50,
+ 41, 33, 30, 39, 26, 72, 67, 4, 68, 31, 29, 26, 32, 29, 23, 18, 20,
+ 64, 3, 65, 93, 88, 106, 75, 20, 18, 11, 0, 5, 69, 74, 81, 99, 75,
+ 39, 21, 15, 8, 5, 70, 81, 85, 115, 5, 35, 28, 25, 20, 9, 5, 64,
+ 73, 88, 70, 35, 32, 21, 4, 6, 71, 80, 95, 5, 57, 48, 44, 35, 23,
+ 5, 69, 78, 84, 62, 104, 104, 85, 111, 107, 96, 107, 103, 100, 104, 105, 108,
+ 94, 93, 90, 91, 91, 85, 68, 79, 83, 69, 3, 4, 2, 12, 12, 12, 7,
+ 21, 17, 13, 14, 10, 21, 16, 8, 21, 18, 13, 10, 13, 0, 64, 68, 5,
+ 70, 18, 31, 19, 10, 28, 24, 12, 22, 29, 19, 25, 12, 5, 17, 51, 48,
+ 51, 50, 52, 62, 62, 62, 62, 62, 62, 62, 62, 62, 32, 62, 62, 62, 62,
+ 62, 62, 51, 35, 34, 6, 80, 74, 94, 120, 60, 60, 62, 54, 51, 50, 38,
+ 40, 29, 29, 20, 16, 14, 67, 72, 2, 0, 67, 37, 41, 37, 28, 37, 36,
+ 21, 28, 31, 19, 4, 8, 0, 87, 22, 11, 3, 78, 70, 68, 68, 65, 66,
+ 70, 67, 68, 65, 4, 67, 64, 1, 3, 62, 62, 62, 62, 60, 55, 48, 31,
+ 0, 65, 29, 22, 19, 16, 9, 4, 2, 65, 75, 84, 80, 75, 80, 77, 70,
+ 73, 81, 69, 65, 3, 65, 64, 4, 4, 62, 62, 62, 60, 55, 50, 39, 23,
+ 67, 75, 65, 4, 66, 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, 60, 54, 14, 111,
+ 6, 75, 1, 1, 12, 72, 10, 67, 19, 58, 71, 93, 105, 118, 100, 67, 75,
+ 1, 1, 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, 75, 92, 9,
+ 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, 0, 81, 86, 97, 70,
+ 20, 1, 18, 77, 95, 120, 92, 96, 1, 76, 90, 80, 105, 87, 98, 90, 121,
+ 90, 88, 94, 105, 18, 64, 7, 91, 73, 90, 85, 121, 9, 2, 3, 70, 16,
+ 68, 68, 86, 84, 76, 74, 75, 9, 13, 67, 13, 20, 80, 0, 69, 67, 6,
+ 75, 26, 64, 2, 26, 35, 37, 32, 25, 91, 71, 72, 15, 13, 98, 9, 10,
+ 10, 3, 7, 7, 3, 4, 2, 6, 67, 6, 22, 12, 70, 64, 2, 64, 12,
+ 21, 19, 11, 13, 4, 5, 4, 26, 19, 18, 77, 3, 70, 33, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 16, 9, 9, 5, 0, 11, 5, 9, 10, 7, 16,
+ 25, 9, 81, 7, 77, 15, 28, 83, 52, 62, 55, 54, 57, 58, 52, 52, 48,
+ 39, 32, 29, 37, 24, 73, 67, 4, 68, 30, 28, 25, 30, 28, 21, 17, 19,
+ 65, 3, 65, 93, 88, 106, 74, 20, 18, 11, 0, 5, 69, 74, 80, 98, 75,
+ 39, 21, 15, 8, 6, 69, 80, 84, 113, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 88, 70, 35, 32, 20, 4, 6, 71, 80, 94, 5, 57, 48, 43, 34, 23,
+ 5, 69, 77, 83, 62, 103, 103, 85, 110, 106, 95, 105, 102, 99, 103, 103, 107,
+ 94, 92, 90, 91, 89, 85, 68, 79, 83, 69, 2, 4, 2, 11, 11, 11, 6,
+ 21, 16, 13, 13, 10, 21, 15, 8, 20, 18, 12, 10, 12, 0, 65, 68, 5,
+ 71, 18, 31, 18, 10, 27, 24, 12, 21, 28, 18, 24, 11, 5, 16, 50, 47,
+ 51, 49, 51, 61, 62, 62, 62, 62, 62, 62, 62, 62, 31, 62, 62, 62, 62,
+ 62, 62, 49, 34, 33, 6, 79, 74, 93, 118, 58, 58, 62, 52, 49, 48, 37,
+ 38, 27, 28, 19, 15, 12, 68, 73, 2, 64, 68, 36, 39, 36, 26, 35, 34,
+ 19, 27, 29, 17, 3, 6, 65, 88, 21, 10, 2, 78, 69, 68, 68, 64, 66,
+ 69, 66, 67, 64, 5, 66, 0, 3, 4, 62, 62, 62, 62, 58, 52, 45, 28,
+ 65, 64, 30, 23, 20, 16, 10, 5, 2, 64, 74, 84, 79, 75, 79, 76, 69,
+ 73, 81, 69, 65, 3, 64, 0, 4, 4, 62, 62, 62, 57, 52, 46, 35, 19,
+ 69, 75, 65, 4, 65, 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, 58, 54, 14, 108,
+ 5, 74, 1, 1, 11, 72, 9, 68, 18, 56, 73, 94, 106, 115, 99, 67, 74,
+ 1, 1, 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, 75, 91, 8,
+ 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0, 80, 87, 97, 70,
+ 19, 1, 18, 77, 95, 119, 91, 94, 2, 75, 89, 79, 104, 85, 97, 89, 119,
+ 90, 87, 94, 104, 18, 64, 7, 90, 73, 89, 85, 120, 8, 2, 3, 70, 16,
+ 68, 68, 86, 84, 76, 74, 75, 9, 12, 67, 13, 20, 80, 0, 69, 67, 6,
+ 75, 26, 65, 2, 26, 34, 36, 31, 24, 90, 71, 72, 14, 12, 98, 8, 10,
+ 9, 3, 7, 7, 4, 5, 2, 5, 67, 5, 21, 11, 71, 64, 2, 65, 12,
+ 20, 18, 10, 13, 5, 5, 4, 25, 18, 17, 77, 3, 71, 33, 23, 19, 14,
+ 17, 19, 12, 16, 23, 1, 16, 9, 9, 5, 64, 11, 5, 9, 10, 7, 16,
+ 24, 8, 81, 7, 77, 14, 27, 83, 50, 62, 53, 52, 55, 56, 50, 50, 46,
+ 37, 30, 27, 34, 22, 74, 67, 3, 69, 29, 27, 24, 29, 26, 20, 16, 17,
+ 65, 2, 66, 93, 88, 105, 74, 20, 18, 11, 0, 5, 69, 74, 80, 97, 74,
+ 39, 21, 15, 8, 6, 69, 80, 84, 111, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 87, 70, 35, 31, 20, 4, 6, 71, 80, 94, 5, 56, 47, 42, 33, 23,
+ 5, 69, 77, 83, 62, 102, 102, 84, 108, 105, 94, 104, 100, 98, 101, 102, 105,
+ 93, 92, 89, 90, 88, 84, 69, 79, 82, 69, 2, 3, 1, 10, 10, 10, 5,
+ 20, 16, 13, 13, 9, 20, 15, 8, 19, 17, 12, 9, 11, 64, 65, 68, 5,
+ 71, 17, 30, 17, 10, 26, 23, 12, 20, 27, 18, 24, 10, 4, 14, 49, 47,
+ 50, 48, 49, 60, 62, 62, 62, 62, 62, 62, 62, 62, 29, 62, 62, 62, 62,
+ 62, 62, 47, 33, 31, 6, 78, 73, 92, 116, 57, 56, 60, 51, 47, 46, 35,
+ 36, 26, 26, 17, 13, 11, 69, 74, 1, 64, 69, 34, 38, 34, 25, 33, 32,
+ 18, 25, 27, 16, 2, 5, 66, 88, 20, 10, 1, 78, 69, 67, 67, 64, 65,
+ 68, 66, 66, 0, 6, 65, 1, 4, 5, 62, 62, 62, 61, 55, 49, 42, 25,
+ 68, 64, 30, 23, 20, 17, 10, 5, 3, 64, 74, 83, 79, 74, 79, 75, 68,
+ 73, 80, 68, 64, 3, 64, 1, 4, 4, 62, 62, 61, 54, 49, 42, 31, 16,
+ 72, 75, 65, 4, 65, 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, 57, 54, 14, 106,
+ 5, 73, 2, 1, 11, 71, 8, 69, 18, 54, 75, 95, 106, 112, 97, 67, 73,
+ 2, 1, 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, 75, 90, 8,
+ 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, 80, 87, 97, 69,
+ 18, 1, 18, 76, 95, 117, 89, 93, 4, 73, 87, 78, 103, 84, 96, 88, 117,
+ 89, 87, 93, 103, 18, 64, 7, 90, 73, 89, 84, 118, 8, 2, 3, 70, 16,
+ 68, 67, 85, 84, 76, 74, 74, 9, 12, 67, 13, 20, 79, 0, 68, 67, 6,
+ 75, 25, 65, 2, 25, 33, 36, 30, 23, 89, 70, 72, 13, 12, 97, 8, 10,
+ 9, 3, 7, 7, 5, 5, 2, 5, 67, 5, 20, 11, 72, 64, 2, 65, 11,
+ 19, 18, 10, 12, 5, 5, 4, 24, 18, 16, 77, 3, 71, 32, 23, 19, 14,
+ 17, 19, 12, 16, 23, 1, 16, 9, 9, 5, 64, 11, 5, 8, 10, 7, 15,
+ 23, 8, 81, 6, 77, 13, 26, 83, 49, 61, 52, 51, 53, 54, 48, 48, 44,
+ 35, 28, 25, 32, 21, 75, 67, 3, 69, 28, 26, 23, 28, 25, 18, 15, 16,
+ 66, 2, 66, 93, 88, 105, 74, 20, 18, 11, 0, 5, 68, 73, 79, 96, 74,
+ 39, 21, 15, 8, 6, 68, 79, 83, 109, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 86, 70, 36, 31, 19, 4, 6, 71, 80, 93, 5, 56, 46, 41, 32, 23,
+ 5, 69, 77, 82, 62, 101, 101, 83, 107, 104, 93, 103, 99, 97, 100, 100, 103,
+ 92, 91, 89, 90, 87, 84, 69, 78, 81, 69, 1, 3, 1, 10, 9, 9, 4,
+ 19, 15, 13, 12, 9, 20, 15, 8, 18, 16, 12, 9, 10, 64, 65, 68, 5,
+ 71, 16, 30, 17, 10, 25, 22, 12, 19, 26, 17, 23, 9, 3, 12, 48, 46,
+ 50, 47, 48, 58, 62, 62, 62, 62, 62, 62, 62, 62, 28, 62, 62, 62, 62,
+ 62, 61, 45, 32, 30, 6, 77, 73, 91, 114, 55, 55, 58, 49, 45, 44, 34,
+ 34, 25, 24, 16, 11, 9, 70, 75, 1, 64, 70, 33, 36, 32, 23, 32, 31,
+ 16, 24, 26, 14, 1, 4, 67, 89, 20, 9, 0, 77, 68, 67, 67, 0, 64,
+ 67, 65, 65, 1, 8, 64, 2, 5, 7, 62, 62, 62, 58, 53, 46, 39, 22,
+ 70, 64, 31, 24, 21, 17, 11, 5, 3, 0, 73, 83, 79, 73, 78, 74, 67,
+ 72, 79, 68, 64, 3, 0, 2, 4, 4, 62, 62, 58, 51, 46, 39, 27, 12,
+ 75, 75, 65, 4, 65, 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, 56, 54, 14, 104,
+ 5, 73, 3, 1, 10, 71, 7, 70, 17, 53, 76, 96, 107, 109, 96, 67, 73,
+ 3, 1, 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, 74, 90, 8,
+ 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, 79, 87, 97, 69,
+ 18, 0, 18, 76, 94, 115, 87, 91, 5, 71, 86, 77, 101, 83, 95, 88, 116,
+ 89, 87, 93, 103, 19, 64, 7, 89, 72, 88, 84, 117, 8, 1, 2, 71, 16,
+ 68, 67, 85, 84, 75, 74, 74, 9, 12, 66, 13, 19, 79, 0, 68, 67, 6,
+ 75, 24, 65, 2, 24, 32, 35, 30, 23, 89, 70, 72, 13, 11, 97, 7, 10,
+ 9, 3, 7, 7, 5, 5, 2, 5, 66, 5, 19, 11, 72, 65, 2, 66, 11,
+ 18, 18, 10, 11, 5, 5, 4, 22, 18, 15, 77, 3, 72, 31, 23, 18, 14,
+ 17, 19, 12, 16, 23, 1, 15, 9, 8, 5, 64, 10, 4, 8, 9, 6, 14,
+ 22, 7, 81, 6, 76, 12, 24, 83, 47, 59, 50, 49, 51, 52, 46, 46, 42,
+ 33, 27, 24, 30, 19, 76, 67, 3, 70, 27, 25, 22, 26, 23, 17, 14, 15,
+ 67, 1, 67, 93, 88, 104, 73, 20, 18, 11, 1, 5, 68, 73, 79, 95, 73,
+ 38, 21, 15, 8, 7, 68, 78, 82, 107, 5, 36, 28, 25, 20, 11, 5, 64,
+ 72, 86, 70, 36, 31, 19, 4, 6, 70, 79, 92, 5, 55, 46, 40, 32, 23,
+ 5, 68, 76, 82, 62, 101, 100, 83, 106, 103, 92, 101, 98, 96, 99, 99, 102,
+ 92, 90, 89, 89, 85, 84, 70, 78, 81, 69, 1, 2, 1, 9, 8, 8, 3,
+ 19, 15, 13, 12, 8, 19, 14, 8, 18, 16, 11, 9, 10, 64, 66, 68, 5,
+ 72, 16, 29, 16, 9, 24, 22, 13, 19, 25, 17, 23, 9, 3, 11, 47, 45,
+ 49, 46, 47, 57, 62, 62, 62, 62, 62, 62, 62, 61, 27, 62, 62, 62, 62,
+ 62, 59, 43, 31, 29, 6, 76, 73, 89, 111, 53, 53, 56, 47, 43, 42, 32,
+ 32, 23, 23, 15, 10, 8, 71, 76, 0, 65, 71, 32, 35, 31, 21, 30, 29,
+ 15, 22, 24, 13, 64, 2, 69, 90, 19, 8, 64, 77, 68, 67, 66, 0, 64,
+ 65, 64, 64, 2, 9, 1, 3, 7, 8, 62, 62, 60, 56, 50, 44, 36, 20,
+ 72, 0, 31, 24, 21, 17, 12, 6, 3, 0, 73, 83, 78, 73, 78, 73, 66,
+ 72, 79, 67, 0, 3, 0, 3, 4, 4, 62, 62, 56, 48, 42, 35, 24, 9,
+ 77, 75, 65, 4, 64, 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, 54, 54, 14, 101,
+ 4, 72, 3, 1, 9, 71, 6, 71, 17, 51, 78, 97, 107, 106, 95, 67, 72,
+ 3, 1, 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, 74, 89, 7,
+ 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, 79, 87, 97, 68,
+ 17, 0, 18, 76, 94, 114, 85, 90, 7, 69, 85, 76, 100, 81, 94, 87, 114,
+ 88, 86, 92, 102, 19, 64, 7, 89, 72, 88, 83, 115, 7, 1, 2, 71, 16,
+ 68, 67, 84, 84, 75, 74, 73, 9, 11, 66, 13, 19, 79, 0, 68, 67, 6,
+ 75, 24, 65, 2, 24, 31, 34, 29, 22, 88, 69, 72, 12, 11, 96, 7, 10,
+ 8, 3, 7, 7, 6, 6, 2, 5, 66, 5, 18, 11, 73, 65, 2, 66, 10,
+ 17, 17, 10, 11, 6, 5, 4, 21, 17, 14, 77, 3, 72, 31, 23, 18, 14,
+ 17, 19, 12, 16, 23, 1, 15, 9, 8, 5, 64, 10, 4, 7, 9, 6, 14,
+ 21, 7, 81, 5, 76, 11, 23, 83, 46, 57, 48, 47, 49, 50, 44, 44, 40,
+ 31, 25, 22, 27, 17, 77, 67, 2, 70, 26, 24, 21, 25, 22, 15, 13, 14,
+ 67, 1, 67, 93, 88, 104, 73, 20, 18, 11, 1, 5, 68, 73, 78, 94, 73,
+ 38, 21, 15, 8, 7, 67, 77, 82, 105, 5, 36, 28, 25, 20, 11, 5, 64,
+ 72, 85, 70, 36, 30, 18, 4, 6, 70, 79, 92, 5, 55, 45, 39, 31, 23,
+ 5, 68, 76, 81, 62, 100, 99, 82, 104, 102, 91, 100, 96, 95, 97, 97, 100,
+ 91, 89, 88, 89, 84, 83, 70, 78, 80, 69, 0, 2, 0, 8, 7, 7, 2,
+ 18, 14, 13, 11, 8, 19, 14, 8, 17, 15, 11, 8, 9, 64, 66, 68, 5,
+ 72, 15, 29, 15, 9, 23, 21, 13, 18, 24, 16, 22, 8, 2, 9, 46, 45,
+ 49, 45, 45, 55, 62, 62, 62, 62, 62, 62, 62, 59, 25, 62, 62, 62, 62,
+ 62, 56, 41, 30, 28, 6, 75, 72, 88, 109, 52, 51, 54, 46, 41, 40, 31,
+ 30, 22, 21, 13, 8, 6, 72, 77, 0, 65, 72, 30, 33, 29, 20, 28, 27,
+ 13, 21, 22, 11, 65, 1, 70, 90, 18, 8, 65, 77, 67, 66, 66, 1, 0,
+ 64, 0, 0, 3, 10, 2, 4, 8, 9, 62, 61, 58, 53, 48, 41, 33, 17,
+ 74, 0, 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, 77, 72, 65,
+ 72, 78, 67, 0, 3, 1, 4, 4, 4, 62, 62, 53, 45, 39, 31, 20, 5,
+ 80, 75, 65, 4, 64, 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, 53, 54, 14, 99, 4,
+ 71, 4, 1, 8, 71, 5, 73, 16, 49, 80, 98, 108, 104, 94, 67, 71, 4, 1,
+ 83, 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, 89, 7, 71, 79, 88,
+ 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, 78, 88, 97, 68, 16, 0, 18, 76,
+ 94, 112, 84, 88, 8, 68, 84, 75, 99, 80, 93, 86, 112, 88, 86, 92, 101, 19,
+ 64, 7, 88, 72, 87, 83, 114, 7, 0, 1, 72, 16, 68, 67, 84, 84, 75, 74,
+ 73, 8, 11, 66, 13, 18, 79, 0, 68, 67, 5, 75, 23, 66, 2, 23, 29, 33,
+ 28, 21, 88, 69, 72, 11, 10, 96, 6, 9, 8, 3, 7, 7, 7, 6, 2, 4,
+ 66, 4, 17, 10, 74, 65, 2, 67, 10, 16, 17, 9, 10, 6, 5, 4, 19, 17,
+ 13, 77, 3, 73, 30, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 7, 8, 5, 13, 20, 6, 81, 5, 76, 10, 21, 83, 44, 55, 46,
+ 45, 47, 47, 42, 42, 38, 29, 23, 20, 25, 15, 78, 67, 2, 71, 25, 22, 19,
+ 23, 20, 14, 11, 12, 68, 0, 68, 93, 88, 103, 73, 20, 18, 11, 1, 5, 68,
+ 73, 78, 93, 72, 38, 21, 15, 8, 7, 67, 77, 81, 104, 5, 36, 28, 25, 19,
+ 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, 79, 91, 5, 54, 44, 38,
+ 30, 22, 5, 68, 76, 81, 62, 99, 98, 82, 103, 101, 91, 99, 95, 94, 96, 96,
+ 99, 91, 89, 88, 88, 83, 83, 71, 78, 80, 69, 0, 1, 0, 7, 6, 5, 1,
+ 17, 14, 13, 11, 7, 18, 13, 7, 16, 14, 10, 8, 8, 65, 67, 68, 5, 73,
+ 14, 28, 14, 9, 22, 20, 13, 17, 23, 16, 22, 7, 1, 7, 45, 44, 48, 43,
+ 44, 54, 62, 62, 62, 62, 62, 62, 62, 56, 24, 62, 62, 62, 62, 61, 54, 39,
+ 28, 26, 6, 75, 72, 87, 107, 50, 49, 52, 44, 38, 38, 29, 28, 20, 19, 12,
+ 6, 5, 73, 78, 64, 66, 73, 29, 32, 27, 18, 26, 25, 12, 19, 20, 10, 66,
+ 64, 72, 91, 17, 7, 66, 77, 67, 66, 65, 1, 0, 0, 0, 1, 4, 11, 3,
+ 5, 9, 10, 61, 59, 56, 51, 45, 38, 30, 14, 77, 0, 32, 25, 22, 18, 13,
+ 6, 4, 1, 72, 82, 78, 72, 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4,
+ 3, 62, 61, 51, 42, 36, 27, 16, 2, 83, 75, 66, 3, 64, 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, 52, 54, 14, 97, 4,
+ 70, 5, 1, 8, 70, 4, 74, 15, 47, 81, 99, 109, 101, 92, 67, 70, 5, 1,
+ 82, 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, 88, 7, 71, 79, 88,
+ 0, 71, 71, 77, 68, 5, 22, 0, 0, 0, 77, 88, 97, 68, 15, 0, 18, 75,
+ 94, 110, 82, 86, 9, 66, 82, 74, 97, 79, 91, 85, 110, 88, 86, 92, 100, 19,
+ 64, 7, 87, 72, 86, 82, 113, 7, 0, 1, 72, 16, 68, 66, 83, 83, 74, 74,
+ 73, 8, 11, 66, 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 28, 33,
+ 27, 20, 87, 69, 71, 10, 9, 96, 5, 9, 8, 4, 7, 7, 8, 6, 2, 4,
+ 65, 4, 17, 10, 75, 65, 2, 68, 10, 15, 17, 9, 9, 6, 5, 4, 18, 17,
+ 13, 77, 3, 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 7, 8, 5, 12, 20, 6, 81, 5, 76, 9, 20, 83, 42, 54, 45,
+ 44, 45, 45, 41, 41, 36, 27, 22, 19, 23, 14, 79, 67, 2, 72, 24, 21, 18,
+ 22, 19, 13, 10, 11, 69, 64, 69, 93, 87, 102, 72, 21, 18, 11, 1, 6, 67,
+ 72, 77, 92, 71, 38, 21, 15, 8, 8, 67, 76, 80, 102, 5, 36, 28, 25, 19,
+ 12, 5, 64, 72, 84, 70, 37, 30, 18, 4, 7, 70, 79, 90, 5, 54, 44, 38,
+ 29, 22, 5, 68, 75, 80, 62, 98, 97, 81, 102, 99, 90, 97, 94, 92, 95, 95,
+ 97, 90, 88, 88, 87, 81, 83, 72, 77, 79, 69, 0, 0, 0, 7, 5, 4, 0,
+ 17, 14, 13, 11, 7, 17, 13, 7, 15, 14, 10, 8, 7, 65, 67, 67, 6, 73,
+ 14, 27, 14, 9, 22, 20, 13, 16, 22, 16, 22, 6, 1, 6, 45, 43, 47, 42,
+ 43, 53, 60, 60, 62, 62, 62, 62, 62, 54, 23, 62, 62, 62, 62, 58, 52, 38,
+ 27, 25, 6, 74, 72, 86, 105, 48, 48, 50, 42, 36, 37, 28, 26, 19, 18, 11,
+ 5, 4, 74, 78, 64, 66, 74, 28, 31, 26, 16, 25, 24, 11, 18, 19, 9, 67,
+ 65, 73, 92, 17, 6, 66, 76, 67, 66, 64, 2, 1, 1, 1, 2, 5, 13, 4,
+ 6, 11, 12, 60, 58, 54, 49, 42, 35, 27, 11, 79, 1, 32, 25, 23, 18, 14,
+ 7, 4, 2, 71, 82, 77, 71, 77, 70, 1, 71, 77, 65, 2, 3, 2, 5, 4,
+ 3, 62, 59, 49, 40, 33, 24, 12, 64, 85, 75, 66, 3, 0, 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, 50, 54, 14, 94, 3,
+ 69, 5, 1, 7, 70, 3, 75, 15, 45, 83, 100, 109, 98, 91, 67, 69, 5, 1,
+ 82, 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, 87, 6, 71, 79, 88,
+ 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, 77, 88, 97, 67, 14, 0, 18, 75,
+ 94, 109, 80, 85, 11, 64, 81, 73, 96, 77, 90, 84, 108, 87, 85, 91, 99, 19,
+ 64, 7, 87, 72, 86, 82, 111, 6, 0, 1, 72, 16, 68, 66, 83, 83, 74, 74,
+ 72, 8, 10, 66, 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 27, 32,
+ 26, 19, 86, 68, 71, 9, 9, 95, 5, 9, 7, 4, 7, 7, 9, 7, 2, 4,
+ 65, 4, 16, 10, 76, 65, 2, 68, 9, 14, 16, 9, 9, 7, 5, 4, 17, 16,
+ 12, 77, 3, 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 6, 8, 5, 12, 19, 5, 81, 4, 76, 8, 19, 83, 41, 52, 43,
+ 42, 43, 43, 39, 39, 34, 25, 20, 17, 20, 12, 80, 67, 1, 72, 23, 20, 17,
+ 21, 17, 11, 9, 10, 69, 64, 69, 93, 87, 102, 72, 21, 18, 11, 1, 6, 67,
+ 72, 77, 91, 71, 38, 21, 15, 8, 8, 66, 75, 80, 100, 5, 36, 28, 25, 19,
+ 12, 5, 64, 72, 83, 70, 37, 29, 17, 4, 7, 70, 79, 90, 5, 53, 43, 37,
+ 28, 22, 5, 68, 75, 80, 62, 97, 96, 80, 100, 98, 89, 96, 92, 91, 93, 93,
+ 95, 89, 87, 87, 87, 80, 82, 72, 77, 78, 69, 64, 0, 64, 6, 4, 3, 64,
+ 16, 13, 13, 10, 6, 17, 13, 7, 14, 13, 10, 7, 6, 65, 67, 67, 6, 73,
+ 13, 27, 13, 9, 21, 19, 13, 15, 21, 15, 21, 5, 0, 4, 44, 43, 47, 41,
+ 41, 51, 58, 58, 62, 62, 62, 62, 62, 52, 21, 59, 62, 59, 62, 56, 49, 36,
+ 26, 24, 6, 73, 71, 85, 103, 47, 46, 48, 41, 34, 35, 26, 24, 18, 16, 9,
+ 3, 2, 75, 79, 65, 66, 75, 26, 29, 24, 15, 23, 22, 9, 16, 17, 7, 68,
+ 66, 74, 92, 16, 6, 67, 76, 66, 65, 64, 2, 2, 2, 2, 3, 6, 14, 5,
+ 7, 12, 13, 60, 56, 52, 46, 40, 32, 24, 8, 81, 1, 33, 26, 23, 19, 15,
+ 7, 5, 2, 71, 81, 77, 70, 76, 69, 2, 71, 76, 65, 2, 3, 2, 6, 4,
+ 3, 62, 57, 46, 37, 30, 20, 8, 68, 88, 75, 66, 3, 0, 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, 49, 54, 14, 92, 3,
+ 69, 6, 1, 6, 70, 2, 76, 14, 44, 84, 101, 110, 95, 90, 67, 69, 6, 1,
+ 81, 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, 87, 6, 71, 78, 88,
+ 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 18, 75,
+ 93, 107, 78, 83, 12, 1, 80, 72, 94, 76, 89, 84, 107, 87, 85, 91, 99, 20,
+ 64, 7, 86, 71, 85, 81, 110, 6, 64, 0, 73, 16, 68, 66, 82, 83, 73, 74,
+ 72, 8, 10, 65, 13, 17, 78, 0, 67, 67, 5, 74, 21, 66, 2, 21, 26, 31,
+ 26, 19, 86, 68, 71, 9, 8, 95, 4, 9, 7, 4, 7, 7, 9, 7, 2, 4,
+ 64, 4, 15, 10, 76, 66, 2, 69, 9, 13, 16, 9, 8, 7, 5, 4, 15, 16,
+ 11, 77, 3, 75, 28, 22, 17, 14, 17, 18, 11, 16, 22, 0, 13, 9, 7, 4,
+ 65, 8, 2, 6, 7, 4, 11, 18, 5, 81, 4, 75, 7, 17, 83, 39, 50, 41,
+ 40, 41, 41, 37, 37, 32, 23, 19, 16, 18, 10, 81, 67, 1, 73, 22, 19, 16,
+ 19, 16, 10, 8, 9, 70, 65, 70, 93, 87, 101, 71, 21, 18, 11, 2, 6, 67,
+ 72, 76, 90, 70, 37, 21, 15, 8, 9, 66, 74, 79, 98, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 83, 70, 37, 29, 17, 4, 7, 69, 78, 89, 5, 53, 43, 36,
+ 28, 22, 5, 67, 74, 79, 62, 97, 95, 80, 99, 97, 88, 94, 91, 90, 92, 92,
+ 94, 89, 86, 87, 86, 78, 82, 73, 77, 78, 69, 64, 64, 64, 5, 3, 2, 65,
+ 16, 13, 13, 10, 6, 16, 12, 7, 14, 13, 9, 7, 6, 65, 68, 67, 6, 74,
+ 13, 26, 12, 8, 20, 19, 14, 15, 20, 15, 21, 5, 0, 3, 43, 42, 46, 40,
+ 40, 50, 56, 56, 61, 60, 62, 62, 60, 49, 20, 57, 62, 56, 62, 53, 47, 34,
+ 25, 23, 6, 72, 71, 83, 100, 45, 44, 46, 39, 32, 33, 25, 22, 16, 15, 8,
+ 2, 1, 76, 80, 65, 67, 76, 25, 28, 23, 13, 21, 20, 8, 15, 15, 6, 70,
+ 68, 76, 93, 15, 5, 68, 76, 66, 65, 0, 3, 2, 4, 3, 4, 7, 15, 7,
+ 8, 14, 14, 59, 55, 50, 44, 37, 30, 21, 6, 83, 2, 33, 26, 24, 19, 16,
+ 8, 5, 3, 70, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, 3, 7, 4,
+ 3, 62, 55, 44, 34, 26, 16, 5, 71, 90, 75, 66, 3, 1, 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, 48, 54, 14, 90, 3,
+ 68, 7, 1, 5, 70, 1, 77, 14, 42, 86, 102, 110, 92, 89, 67, 68, 7, 1,
+ 81, 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, 86, 6, 72, 78, 88,
+ 2, 70, 71, 76, 66, 5, 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 18, 75,
+ 93, 105, 77, 82, 14, 2, 79, 71, 93, 75, 88, 83, 105, 86, 85, 90, 98, 20,
+ 64, 7, 86, 71, 85, 81, 108, 6, 64, 0, 73, 16, 68, 66, 82, 83, 73, 74,
+ 71, 8, 10, 65, 13, 17, 78, 0, 67, 67, 5, 74, 20, 67, 2, 20, 25, 30,
+ 25, 18, 85, 67, 71, 8, 8, 94, 4, 9, 7, 4, 7, 7, 10, 7, 2, 3,
+ 64, 3, 14, 9, 77, 66, 2, 69, 8, 12, 16, 8, 7, 7, 5, 4, 14, 16,
+ 10, 77, 3, 75, 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4,
+ 66, 8, 2, 5, 7, 4, 10, 17, 4, 81, 3, 75, 6, 16, 83, 38, 48, 39,
+ 38, 39, 39, 35, 35, 30, 21, 17, 14, 16, 8, 82, 67, 1, 73, 21, 18, 15,
+ 18, 14, 8, 7, 7, 71, 65, 70, 93, 87, 101, 71, 21, 18, 11, 2, 6, 67,
+ 72, 76, 89, 70, 37, 21, 15, 8, 9, 65, 74, 78, 96, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 82, 70, 37, 29, 16, 4, 7, 69, 78, 88, 5, 52, 42, 35,
+ 27, 22, 5, 67, 74, 79, 62, 96, 94, 79, 98, 96, 87, 93, 90, 89, 91, 90,
+ 92, 88, 86, 87, 86, 77, 82, 73, 77, 77, 69, 65, 64, 64, 4, 2, 1, 66,
+ 15, 12, 13, 9, 5, 16, 12, 7, 13, 12, 9, 7, 5, 66, 68, 67, 6, 74,
+ 12, 26, 11, 8, 19, 18, 14, 14, 19, 14, 20, 4, 64, 1, 42, 41, 46, 39,
+ 39, 48, 54, 54, 59, 57, 62, 62, 57, 47, 19, 54, 62, 53, 58, 50, 44, 32,
+ 24, 21, 6, 71, 71, 82, 98, 43, 42, 44, 37, 30, 31, 23, 20, 15, 13, 7,
+ 0, 64, 77, 81, 66, 67, 77, 24, 26, 21, 11, 19, 18, 6, 13, 13, 4, 71,
+ 69, 77, 94, 14, 4, 69, 76, 65, 65, 0, 3, 3, 5, 3, 5, 8, 16, 8,
+ 9, 15, 15, 59, 53, 48, 41, 35, 27, 18, 3, 86, 2, 34, 27, 24, 19, 16,
+ 8, 5, 3, 70, 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3, 8, 4,
+ 3, 61, 53, 41, 31, 23, 12, 1, 75, 93, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, 46, 54, 14, 87, 2,
+ 67, 7, 1, 5, 69, 0, 78, 13, 40, 88, 103, 111, 89, 87, 67, 67, 7, 1,
+ 81, 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5, 72, 78, 88,
+ 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, 75, 89, 97, 66, 12, 64, 18, 74,
+ 93, 104, 75, 80, 15, 4, 77, 70, 92, 73, 87, 82, 103, 86, 84, 90, 97, 20,
+ 64, 7, 85, 71, 84, 80, 107, 5, 64, 0, 73, 16, 68, 65, 81, 83, 73, 74,
+ 71, 8, 9, 65, 13, 17, 77, 0, 66, 67, 5, 74, 20, 67, 2, 20, 24, 30,
+ 24, 17, 84, 67, 71, 7, 7, 94, 3, 9, 6, 4, 7, 7, 11, 8, 2, 3,
+ 64, 3, 13, 9, 78, 66, 2, 70, 8, 11, 15, 8, 7, 8, 5, 4, 13, 15,
+ 9, 77, 3, 76, 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4,
+ 66, 8, 2, 5, 7, 4, 10, 16, 4, 81, 3, 75, 5, 15, 83, 36, 46, 38,
+ 37, 37, 37, 33, 33, 28, 19, 15, 12, 13, 7, 83, 67, 0, 74, 20, 17, 14,
+ 17, 13, 7, 6, 6, 71, 66, 71, 93, 87, 100, 71, 21, 18, 11, 2, 6, 66,
+ 71, 75, 88, 69, 37, 21, 15, 8, 9, 65, 73, 78, 94, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 81, 70, 38, 28, 16, 4, 7, 69, 78, 88, 5, 52, 41, 34,
+ 26, 22, 5, 67, 74, 78, 62, 95, 93, 78, 96, 95, 86, 92, 88, 88, 89, 89,
+ 90, 87, 85, 86, 85, 76, 81, 74, 76, 76, 69, 65, 65, 65, 4, 1, 0, 67,
+ 14, 12, 13, 9, 5, 15, 12, 7, 12, 11, 9, 6, 4, 66, 68, 67, 6, 74,
+ 11, 25, 11, 8, 18, 17, 14, 13, 18, 14, 20, 3, 65, 64, 41, 41, 45, 38,
+ 37, 47, 52, 52, 57, 55, 62, 61, 54, 45, 17, 51, 62, 50, 54, 48, 42, 30,
+ 23, 20, 6, 70, 70, 81, 96, 42, 41, 42, 36, 28, 29, 22, 18, 14, 11, 5,
+ 65, 65, 78, 82, 66, 67, 78, 22, 25, 19, 10, 18, 17, 5, 12, 12, 3, 72,
+ 70, 78, 94, 14, 4, 70, 75, 65, 64, 1, 4, 4, 6, 4, 6, 9, 18, 9,
+ 10, 16, 17, 58, 51, 46, 39, 32, 24, 15, 0, 88, 2, 34, 27, 25, 20, 17,
+ 8, 6, 4, 69, 80, 76, 68, 75, 66, 5, 70, 74, 0, 4, 3, 4, 9, 4,
+ 3, 59, 51, 39, 28, 20, 9, 66, 78, 96, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, 45, 54, 14, 85, 2,
+ 66, 8, 1, 4, 69, 64, 79, 13, 38, 89, 104, 111, 86, 86, 67, 66, 8, 1,
+ 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 18, 74,
+ 93, 102, 73, 79, 17, 6, 76, 69, 90, 72, 86, 81, 101, 85, 84, 89, 96, 20,
+ 64, 7, 85, 71, 84, 80, 105, 5, 65, 64, 74, 16, 68, 65, 81, 83, 72, 74,
+ 70, 8, 9, 65, 13, 16, 77, 0, 66, 67, 5, 74, 19, 67, 2, 19, 23, 29,
+ 23, 16, 84, 66, 71, 6, 7, 93, 3, 9, 6, 4, 7, 7, 12, 8, 2, 3,
+ 0, 3, 12, 9, 79, 66, 2, 70, 7, 10, 15, 8, 6, 8, 5, 4, 11, 15,
+ 8, 77, 3, 76, 26, 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4,
+ 66, 7, 1, 4, 6, 3, 9, 15, 3, 81, 2, 75, 4, 13, 83, 35, 44, 36,
+ 35, 35, 35, 31, 31, 26, 17, 14, 11, 11, 5, 84, 67, 0, 74, 19, 16, 13,
+ 15, 11, 5, 5, 5, 72, 66, 71, 93, 87, 100, 70, 21, 18, 11, 2, 6, 66,
+ 71, 75, 87, 69, 37, 21, 15, 8, 10, 64, 72, 77, 92, 5, 37, 28, 25, 19,
+ 14, 5, 64, 71, 81, 70, 38, 28, 15, 4, 7, 69, 78, 87, 5, 51, 41, 33,
+ 25, 22, 5, 67, 73, 78, 62, 94, 92, 78, 95, 94, 85, 90, 87, 87, 88, 87,
+ 89, 87, 84, 86, 85, 74, 81, 74, 76, 76, 69, 66, 65, 65, 3, 0, 64, 68,
+ 14, 11, 13, 8, 4, 15, 11, 7, 11, 11, 8, 6, 3, 66, 69, 67, 6, 75,
+ 11, 25, 10, 8, 17, 17, 14, 12, 17, 13, 19, 2, 65, 65, 40, 40, 45, 37,
+ 36, 45, 50, 50, 55, 52, 60, 59, 51, 42, 16, 48, 62, 47, 50, 45, 39, 28,
+ 22, 19, 6, 69, 70, 80, 94, 40, 39, 40, 34, 26, 27, 20, 16, 12, 10, 4,
+ 66, 67, 79, 83, 67, 68, 79, 21, 23, 18, 8, 16, 15, 3, 10, 10, 1, 73,
+ 72, 80, 95, 13, 3, 71, 75, 64, 64, 1, 4, 4, 7, 5, 7, 10, 19, 10,
+ 11, 18, 18, 58, 50, 44, 36, 30, 21, 12, 66, 90, 3, 35, 28, 25, 20, 18,
+ 9, 6, 4, 69, 80, 75, 68, 74, 65, 6, 70, 74, 0, 4, 3, 4, 10, 4,
+ 3, 58, 49, 36, 25, 17, 5, 70, 82, 98, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, 54, 14, 83, 2,
+ 65, 9, 1, 3, 69, 65, 80, 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1,
+ 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 18, 74,
+ 93, 100, 71, 77, 18, 8, 75, 68, 89, 71, 85, 80, 99, 85, 84, 89, 95, 20,
+ 64, 7, 84, 71, 83, 79, 104, 5, 65, 64, 74, 16, 68, 65, 80, 83, 72, 74,
+ 70, 8, 9, 65, 13, 16, 77, 0, 66, 67, 5, 74, 18, 67, 2, 18, 22, 28,
+ 22, 15, 83, 66, 71, 5, 6, 93, 2, 9, 6, 4, 7, 7, 13, 8, 2, 3,
+ 0, 3, 11, 9, 80, 66, 2, 71, 7, 9, 15, 8, 5, 8, 5, 4, 10, 15,
+ 7, 77, 3, 77, 25, 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4,
+ 66, 7, 1, 4, 6, 3, 8, 14, 3, 81, 2, 75, 3, 12, 83, 33, 42, 34,
+ 33, 33, 33, 29, 29, 24, 15, 12, 9, 9, 3, 85, 67, 0, 75, 18, 15, 12,
+ 14, 10, 4, 4, 4, 73, 67, 72, 93, 87, 99, 70, 21, 18, 11, 2, 6, 66,
+ 71, 74, 86, 68, 37, 21, 15, 8, 10, 64, 71, 76, 90, 5, 37, 28, 25, 19,
+ 14, 5, 64, 71, 80, 70, 38, 28, 15, 4, 7, 69, 78, 86, 5, 51, 40, 32,
+ 24, 22, 5, 67, 73, 77, 62, 93, 91, 77, 94, 93, 84, 89, 86, 86, 87, 86,
+ 87, 86, 83, 86, 84, 73, 81, 75, 76, 75, 69, 66, 66, 65, 2, 64, 65, 69,
+ 13, 11, 13, 8, 4, 14, 11, 7, 10, 10, 8, 6, 2, 66, 69, 67, 6, 75,
+ 10, 24, 9, 8, 16, 16, 14, 11, 16, 13, 19, 1, 66, 67, 39, 39, 44, 36,
+ 35, 44, 48, 48, 53, 50, 57, 56, 48, 40, 15, 45, 59, 44, 46, 42, 37, 26,
+ 21, 18, 6, 68, 70, 79, 92, 38, 37, 38, 32, 24, 25, 19, 14, 11, 8, 3,
+ 68, 68, 80, 84, 67, 68, 80, 20, 22, 16, 6, 14, 13, 2, 9, 8, 0, 74,
+ 73, 81, 96, 12, 2, 72, 75, 64, 64, 2, 5, 5, 8, 6, 8, 11, 20, 11,
+ 12, 19, 19, 57, 48, 42, 34, 27, 18, 9, 69, 92, 3, 35, 28, 26, 20, 19,
+ 9, 6, 5, 68, 80, 75, 67, 74, 64, 7, 70, 73, 1, 5, 3, 5, 11, 4,
+ 3, 57, 47, 34, 22, 14, 1, 74, 85, 101, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, 53, 14, 81, 1, 65,
+ 9, 0, 2, 69, 67, 82, 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0, 80, 78,
+ 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, 78, 88, 3, 69, 70,
+ 75, 65, 4, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 18, 74, 93, 99, 70, 76,
+ 19, 9, 74, 67, 88, 70, 84, 80, 98, 85, 84, 89, 95, 20, 64, 7, 84, 71, 83,
+ 79, 103, 4, 66, 65, 75, 16, 68, 65, 80, 83, 72, 74, 70, 7, 8, 65, 12, 15,
+ 77, 64, 66, 67, 4, 74, 17, 68, 1, 17, 20, 27, 21, 14, 83, 66, 71, 4, 5,
+ 93, 1, 8, 5, 4, 7, 7, 13, 8, 2, 2, 0, 2, 10, 8, 81, 67, 1, 72,
+ 6, 8, 14, 7, 4, 8, 5, 4, 8, 14, 6, 77, 3, 78, 24, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 7, 13, 2, 81,
+ 1, 75, 2, 10, 83, 31, 40, 32, 31, 31, 30, 27, 27, 22, 13, 10, 7, 6, 1,
+ 87, 68, 64, 76, 17, 13, 10, 12, 8, 2, 2, 2, 74, 68, 73, 93, 87, 99, 70,
+ 21, 18, 11, 2, 6, 66, 71, 74, 85, 68, 36, 21, 15, 8, 10, 64, 71, 76, 89,
+ 4, 37, 28, 24, 18, 14, 5, 64, 71, 80, 70, 38, 27, 14, 3, 7, 69, 78, 86,
+ 5, 50, 39, 31, 23, 21, 5, 67, 73, 77, 62, 93, 90, 77, 93, 92, 84, 88, 85,
+ 85, 86, 85, 86, 86, 83, 86, 84, 72, 81, 76, 76, 75, 69, 67, 67, 66, 1, 65,
+ 67, 71, 12, 10, 13, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, 70, 67, 6,
+ 76, 9, 23, 8, 7, 15, 15, 14, 10, 14, 12, 18, 0, 67, 69, 38, 38, 43, 34,
+ 33, 42, 46, 46, 50, 47, 54, 53, 45, 37, 13, 42, 55, 41, 41, 39, 34, 24, 19,
+ 16, 6, 68, 70, 78, 90, 36, 35, 36, 30, 21, 23, 17, 11, 9, 6, 1, 70, 70,
+ 81, 85, 68, 69, 82, 18, 20, 14, 4, 12, 11, 0, 7, 6, 65, 76, 75, 83, 97,
+ 11, 1, 73, 75, 64, 64, 2, 5, 5, 9, 6, 9, 11, 21, 12, 13, 20, 20, 56,
+ 46, 39, 31, 24, 15, 5, 72, 95, 3, 35, 28, 26, 20, 19, 9, 6, 5, 68, 80,
+ 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, 5, 11, 4, 2, 55, 44, 31, 19, 10,
+ 66, 78, 89, 104, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, 53, 14, 78, 1, 64,
+ 10, 0, 2, 68, 68, 83, 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0, 79, 76,
+ 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, 77, 88, 4, 68, 69,
+ 74, 64, 4, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 18, 73, 92, 97, 68, 74,
+ 21, 11, 72, 66, 86, 68, 82, 79, 96, 84, 83, 88, 94, 21, 0, 8, 83, 70, 82,
+ 78, 101, 4, 66, 65, 75, 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, 15,
+ 76, 64, 65, 67, 4, 73, 17, 68, 1, 17, 19, 27, 21, 14, 82, 65, 70, 4, 5,
+ 92, 1, 8, 5, 5, 7, 7, 14, 9, 3, 2, 1, 2, 10, 8, 81, 67, 1, 72,
+ 6, 7, 14, 7, 4, 9, 6, 4, 7, 14, 6, 76, 3, 78, 24, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 7, 13, 2, 80,
+ 1, 74, 2, 9, 82, 30, 39, 31, 30, 29, 28, 26, 26, 20, 12, 9, 6, 4, 0,
+ 88, 68, 64, 76, 16, 12, 9, 11, 7, 1, 1, 1, 74, 68, 73, 92, 86, 98, 69,
+ 22, 18, 11, 3, 7, 65, 70, 73, 83, 67, 36, 21, 15, 8, 11, 0, 70, 75, 87,
+ 4, 38, 29, 24, 18, 15, 5, 64, 70, 79, 70, 39, 27, 14, 3, 8, 68, 77, 85,
+ 5, 50, 39, 31, 23, 21, 5, 66, 72, 76, 62, 92, 89, 76, 91, 90, 83, 86, 83,
+ 83, 84, 83, 84, 85, 82, 85, 83, 70, 80, 76, 75, 74, 68, 67, 67, 66, 1, 65,
+ 68, 72, 12, 10, 14, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, 70, 66, 7,
+ 76, 9, 23, 8, 7, 15, 15, 15, 10, 13, 12, 18, 0, 67, 70, 38, 38, 43, 33,
+ 32, 41, 44, 44, 48, 45, 52, 51, 43, 35, 12, 40, 52, 38, 37, 37, 32, 23, 18,
+ 15, 6, 67, 69, 76, 87, 35, 34, 35, 29, 19, 22, 16, 9, 8, 5, 0, 71, 71,
+ 82, 85, 68, 69, 83, 17, 19, 13, 3, 11, 10, 64, 6, 5, 66, 77, 76, 84, 97,
+ 11, 1, 73, 74, 0, 0, 3, 6, 6, 11, 7, 10, 12, 23, 14, 14, 22, 22, 56,
+ 45, 37, 29, 22, 13, 2, 74, 97, 4, 36, 29, 27, 21, 20, 10, 7, 6, 67, 79,
+ 74, 66, 73, 2, 10, 69, 72, 2, 6, 4, 6, 12, 4, 2, 54, 42, 29, 17, 7,
+ 69, 81, 92, 106, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, 53, 14, 76, 1, 0,
+ 11, 0, 1, 68, 69, 84, 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0, 79, 75,
+ 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, 77, 88, 4, 68, 69,
+ 74, 64, 4, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 18, 73, 92, 95, 66, 72,
+ 22, 13, 71, 65, 85, 67, 81, 78, 94, 84, 83, 88, 93, 21, 0, 8, 82, 70, 81,
+ 78, 100, 4, 66, 65, 75, 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, 15,
+ 76, 64, 65, 67, 4, 73, 16, 68, 1, 16, 18, 26, 20, 13, 81, 65, 70, 3, 4,
+ 92, 0, 8, 5, 5, 7, 7, 15, 9, 3, 2, 1, 2, 9, 8, 82, 67, 1, 73,
+ 6, 6, 14, 7, 3, 9, 6, 4, 6, 14, 5, 76, 3, 79, 23, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 6, 12, 1, 80,
+ 1, 74, 1, 8, 82, 28, 37, 29, 28, 27, 26, 24, 24, 18, 10, 7, 4, 2, 65,
+ 89, 68, 64, 77, 15, 11, 8, 10, 5, 0, 0, 0, 75, 69, 74, 92, 86, 97, 69,
+ 22, 18, 11, 3, 7, 65, 70, 73, 82, 66, 36, 21, 15, 8, 11, 0, 69, 74, 85,
+ 4, 38, 29, 24, 18, 15, 5, 64, 70, 78, 70, 39, 27, 14, 3, 8, 68, 77, 84,
+ 5, 49, 38, 30, 22, 21, 5, 66, 72, 76, 62, 91, 88, 75, 90, 89, 82, 85, 82,
+ 82, 83, 82, 82, 84, 81, 85, 82, 69, 80, 77, 75, 73, 68, 67, 68, 66, 0, 66,
+ 69, 73, 11, 10, 14, 7, 2, 12, 10, 6, 8, 8, 7, 5, 0, 67, 70, 66, 7,
+ 76, 8, 22, 7, 7, 14, 14, 15, 9, 12, 12, 18, 64, 68, 72, 37, 37, 42, 32,
+ 31, 40, 42, 42, 46, 43, 49, 48, 40, 33, 11, 37, 49, 35, 33, 34, 30, 21, 17,
+ 14, 6, 66, 69, 75, 85, 33, 32, 33, 27, 17, 20, 14, 7, 7, 3, 64, 73, 72,
+ 83, 86, 69, 69, 84, 16, 18, 11, 1, 9, 8, 65, 4, 3, 67, 78, 77, 85, 98,
+ 10, 0, 74, 74, 0, 0, 4, 6, 7, 12, 8, 11, 13, 24, 15, 15, 23, 23, 55,
+ 43, 35, 27, 19, 10, 64, 77, 99, 4, 36, 29, 27, 21, 21, 10, 7, 6, 67, 79,
+ 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6, 13, 4, 2, 53, 40, 27, 14, 4,
+ 73, 85, 95, 109, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, 53, 14, 74, 1, 1,
+ 12, 0, 0, 68, 70, 85, 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0, 78, 74,
+ 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, 77, 88, 5, 68, 69,
+ 74, 0, 4, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 18, 73, 92, 93, 64, 71,
+ 24, 15, 70, 64, 83, 66, 80, 77, 92, 83, 83, 87, 92, 21, 0, 8, 82, 70, 81,
+ 77, 98, 4, 67, 66, 76, 17, 68, 64, 78, 82, 70, 73, 68, 7, 8, 64, 12, 14,
+ 76, 64, 65, 67, 4, 73, 15, 68, 1, 15, 17, 25, 19, 12, 81, 64, 70, 2, 4,
+ 91, 0, 8, 5, 5, 7, 7, 16, 9, 3, 2, 2, 2, 8, 8, 83, 67, 1, 73,
+ 5, 5, 14, 7, 2, 9, 6, 4, 4, 14, 4, 76, 3, 79, 22, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 10, 9, 6, 3, 67, 5, 64, 2, 4, 1, 5, 11, 1, 80,
+ 0, 74, 0, 6, 82, 27, 35, 27, 26, 25, 24, 22, 22, 16, 8, 6, 3, 0, 67,
+ 90, 68, 64, 77, 14, 10, 7, 8, 4, 65, 64, 64, 76, 69, 74, 92, 86, 97, 68,
+ 22, 18, 11, 3, 7, 65, 70, 72, 81, 66, 36, 21, 15, 8, 12, 1, 68, 73, 83,
+ 4, 38, 29, 24, 18, 16, 5, 64, 70, 78, 70, 39, 27, 13, 3, 8, 68, 77, 83,
+ 5, 49, 38, 29, 21, 21, 5, 66, 71, 75, 62, 90, 87, 75, 89, 88, 81, 83, 81,
+ 81, 82, 80, 81, 84, 80, 85, 82, 67, 80, 77, 75, 73, 68, 68, 68, 66, 64, 67,
+ 70, 74, 11, 9, 14, 6, 2, 12, 9, 6, 7, 8, 6, 5, 64, 67, 71, 66, 7,
+ 77, 8, 22, 6, 7, 13, 14, 15, 8, 11, 11, 17, 65, 68, 73, 36, 36, 42, 31,
+ 30, 38, 40, 40, 44, 40, 47, 46, 37, 30, 10, 34, 46, 32, 29, 31, 27, 19, 16,
+ 13, 6, 65, 69, 74, 83, 31, 30, 31, 25, 15, 18, 13, 5, 5, 2, 65, 74, 74,
+ 84, 87, 69, 70, 85, 15, 16, 10, 64, 7, 6, 67, 3, 1, 69, 79, 79, 87, 99,
+ 9, 64, 75, 74, 1, 0, 4, 7, 7, 13, 9, 12, 14, 25, 16, 16, 25, 24, 55,
+ 42, 33, 24, 17, 7, 67, 80, 101, 5, 37, 30, 28, 21, 22, 11, 7, 7, 66, 79,
+ 73, 65, 72, 4, 12, 69, 71, 3, 7, 4, 7, 14, 4, 2, 52, 38, 24, 11, 1,
+ 77, 89, 99, 111, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, 53, 14, 71, 0, 2,
+ 12, 0, 64, 68, 71, 86, 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, 73,
+ 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, 77, 88, 5, 67, 69,
+ 73, 0, 4, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 18, 73, 92, 92, 0, 69,
+ 25, 16, 69, 0, 82, 64, 79, 76, 90, 83, 82, 87, 91, 21, 0, 8, 81, 70, 80,
+ 77, 97, 3, 67, 66, 76, 17, 68, 64, 78, 82, 70, 73, 68, 7, 7, 64, 12, 14,
+ 76, 64, 65, 67, 4, 73, 15, 69, 1, 15, 16, 24, 18, 11, 80, 64, 70, 1, 3,
+ 91, 64, 8, 4, 5, 7, 7, 17, 10, 3, 1, 2, 1, 7, 7, 84, 67, 1, 74,
+ 5, 4, 13, 6, 2, 10, 6, 4, 3, 13, 3, 76, 3, 80, 22, 21, 16, 14, 17,
+ 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, 64, 2, 4, 1, 5, 10, 0, 80,
+ 0, 74, 64, 5, 82, 25, 33, 25, 24, 23, 22, 20, 20, 14, 6, 4, 1, 66, 69,
+ 91, 68, 65, 78, 13, 9, 6, 7, 2, 66, 65, 66, 76, 70, 75, 92, 86, 96, 68,
+ 22, 18, 11, 3, 7, 65, 70, 72, 80, 65, 36, 21, 15, 8, 12, 1, 68, 73, 81,
+ 4, 38, 29, 24, 18, 16, 5, 64, 70, 77, 70, 39, 26, 13, 3, 8, 68, 77, 83,
+ 5, 48, 37, 28, 20, 21, 5, 66, 71, 75, 62, 89, 86, 74, 87, 87, 80, 82, 79,
+ 80, 80, 79, 79, 83, 80, 84, 81, 66, 79, 78, 75, 72, 68, 68, 69, 67, 65, 68,
+ 71, 75, 10, 9, 14, 6, 1, 11, 9, 6, 6, 7, 6, 4, 65, 68, 71, 66, 7,
+ 77, 7, 21, 5, 7, 12, 13, 15, 7, 10, 11, 17, 66, 69, 75, 35, 36, 41, 30,
+ 28, 37, 38, 38, 42, 38, 44, 43, 34, 28, 8, 31, 42, 29, 25, 29, 25, 17, 15,
+ 11, 6, 64, 68, 73, 81, 30, 28, 29, 24, 13, 16, 11, 3, 4, 0, 67, 76, 75,
+ 85, 88, 70, 70, 86, 13, 15, 8, 65, 5, 4, 68, 1, 64, 70, 80, 80, 88, 99,
+ 8, 64, 76, 74, 1, 1, 5, 7, 8, 14, 9, 13, 15, 26, 17, 17, 26, 25, 54,
+ 40, 31, 22, 14, 4, 70, 83, 104, 5, 37, 30, 28, 22, 22, 11, 8, 7, 66, 78,
+ 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7, 15, 4, 2, 50, 36, 22, 8, 65,
+ 81, 93, 102, 114, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, 53, 14, 69, 0,
+ 3, 13, 0, 64, 67, 72, 87, 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0,
+ 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, 77, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 18, 72,
+ 92, 90, 2, 68, 27, 18, 67, 1, 81, 0, 78, 75, 88, 82, 82, 86, 90, 21,
+ 0, 8, 81, 70, 80, 76, 95, 3, 67, 66, 76, 17, 68, 0, 77, 82, 70, 73,
+ 67, 7, 7, 64, 12, 14, 75, 64, 64, 67, 4, 73, 14, 69, 1, 14, 15, 24,
+ 17, 10, 79, 0, 70, 0, 3, 90, 64, 8, 4, 5, 7, 7, 18, 10, 3, 1,
+ 2, 1, 6, 7, 85, 67, 1, 74, 4, 3, 13, 6, 1, 10, 6, 4, 2, 13,
+ 2, 76, 3, 80, 21, 21, 16, 14, 17, 17, 10, 16, 19, 64, 10, 9, 6, 3,
+ 68, 5, 64, 1, 4, 1, 4, 9, 0, 80, 64, 74, 65, 4, 82, 24, 31, 24,
+ 23, 21, 20, 18, 18, 12, 4, 2, 64, 68, 70, 92, 68, 65, 78, 12, 8, 5,
+ 6, 1, 68, 66, 67, 77, 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 64,
+ 69, 71, 79, 65, 36, 21, 15, 8, 12, 2, 67, 72, 79, 4, 38, 29, 24, 18,
+ 16, 5, 64, 70, 76, 70, 40, 26, 12, 3, 8, 68, 77, 82, 5, 48, 36, 27,
+ 19, 21, 5, 66, 71, 74, 62, 88, 85, 73, 86, 86, 79, 81, 78, 79, 79, 77,
+ 77, 82, 79, 84, 81, 65, 79, 78, 74, 71, 68, 69, 69, 67, 65, 69, 72, 76,
+ 9, 8, 14, 5, 1, 11, 9, 6, 5, 6, 6, 4, 66, 68, 71, 66, 7, 77,
+ 6, 21, 5, 7, 11, 12, 15, 6, 9, 10, 16, 67, 70, 77, 34, 35, 41, 29,
+ 27, 35, 36, 36, 40, 35, 41, 41, 31, 26, 7, 28, 39, 26, 21, 26, 22, 15,
+ 14, 10, 6, 0, 68, 72, 79, 28, 27, 27, 22, 11, 14, 10, 1, 3, 65, 68,
+ 78, 77, 86, 89, 70, 70, 87, 12, 13, 6, 67, 4, 3, 70, 0, 65, 72, 81,
+ 81, 89, 100, 8, 65, 77, 73, 2, 1, 5, 8, 9, 15, 10, 14, 16, 28, 18,
+ 18, 27, 27, 54, 38, 29, 19, 12, 1, 73, 86, 106, 5, 38, 31, 29, 22, 23,
+ 11, 8, 8, 65, 78, 73, 0, 71, 6, 14, 68, 69, 4, 8, 4, 8, 16, 4,
+ 2, 49, 34, 19, 5, 68, 84, 97, 106, 117, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, 53, 14, 67, 0,
+ 3, 14, 0, 65, 67, 73, 88, 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0,
+ 77, 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, 76, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 18, 72,
+ 91, 88, 4, 66, 28, 20, 66, 2, 79, 1, 77, 75, 87, 82, 82, 86, 90, 22,
+ 0, 8, 80, 69, 79, 76, 94, 3, 68, 67, 77, 17, 68, 0, 77, 82, 69, 73,
+ 67, 7, 7, 0, 12, 13, 75, 64, 64, 67, 4, 73, 13, 69, 1, 13, 14, 23,
+ 17, 10, 79, 0, 70, 0, 2, 90, 65, 8, 4, 5, 7, 7, 18, 10, 3, 1,
+ 3, 1, 5, 7, 85, 68, 1, 75, 4, 2, 13, 6, 0, 10, 6, 4, 0, 13,
+ 1, 76, 3, 81, 20, 21, 15, 14, 17, 17, 10, 16, 19, 64, 9, 9, 5, 3,
+ 68, 4, 65, 1, 3, 0, 3, 8, 64, 80, 64, 73, 66, 2, 82, 22, 29, 22,
+ 21, 19, 18, 16, 16, 10, 2, 1, 65, 70, 72, 93, 68, 65, 79, 11, 7, 4,
+ 4, 64, 69, 67, 68, 78, 71, 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64,
+ 69, 71, 78, 64, 35, 21, 15, 8, 13, 2, 66, 71, 77, 4, 39, 29, 24, 18,
+ 17, 5, 64, 69, 76, 70, 40, 26, 12, 3, 8, 67, 76, 81, 5, 47, 36, 26,
+ 19, 21, 5, 65, 70, 74, 62, 88, 84, 73, 85, 85, 78, 79, 77, 78, 78, 76,
+ 76, 82, 78, 84, 80, 0, 79, 79, 74, 71, 68, 69, 70, 67, 66, 70, 73, 77,
+ 9, 8, 14, 5, 0, 10, 8, 6, 5, 6, 5, 4, 66, 68, 72, 66, 7, 78,
+ 6, 20, 4, 6, 10, 12, 16, 6, 8, 10, 16, 67, 70, 78, 33, 34, 40, 28,
+ 26, 34, 34, 34, 38, 33, 39, 38, 28, 23, 6, 26, 36, 23, 17, 23, 20, 13,
+ 13, 9, 6, 1, 68, 70, 76, 26, 25, 25, 20, 9, 12, 8, 64, 1, 66, 69,
+ 79, 78, 87, 90, 71, 71, 88, 11, 12, 5, 69, 2, 1, 71, 65, 67, 73, 83,
+ 83, 91, 101, 7, 66, 78, 73, 2, 1, 6, 8, 9, 17, 11, 15, 17, 29, 20,
+ 19, 29, 28, 53, 37, 27, 17, 9, 64, 76, 88, 108, 6, 38, 31, 29, 22, 24,
+ 12, 8, 8, 65, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8, 17, 4,
+ 2, 48, 32, 17, 2, 72, 88, 100, 109, 119, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, 53, 14, 64, 64,
+ 4, 14, 0, 66, 67, 74, 89, 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0,
+ 77, 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 18, 72,
+ 91, 87, 6, 65, 30, 22, 65, 3, 78, 3, 76, 74, 85, 81, 81, 85, 89, 22,
+ 0, 8, 80, 69, 79, 75, 92, 2, 68, 67, 77, 17, 68, 0, 76, 82, 69, 73,
+ 66, 7, 6, 0, 12, 13, 75, 64, 64, 67, 4, 73, 13, 69, 1, 13, 13, 22,
+ 16, 9, 78, 1, 70, 64, 2, 89, 65, 8, 3, 5, 7, 7, 19, 11, 3, 1,
+ 3, 1, 4, 7, 86, 68, 1, 75, 3, 1, 12, 6, 0, 11, 6, 4, 64, 12,
+ 0, 76, 3, 81, 20, 21, 15, 14, 17, 17, 10, 16, 19, 64, 9, 9, 5, 3,
+ 68, 4, 65, 0, 3, 0, 3, 7, 64, 80, 65, 73, 67, 1, 82, 21, 27, 20,
+ 19, 17, 16, 14, 14, 8, 0, 64, 67, 73, 74, 94, 68, 66, 79, 10, 6, 3,
+ 3, 65, 71, 68, 69, 78, 71, 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64,
+ 69, 70, 77, 64, 35, 21, 15, 8, 13, 3, 65, 71, 75, 4, 39, 29, 24, 18,
+ 17, 5, 64, 69, 75, 70, 40, 25, 11, 3, 8, 67, 76, 81, 5, 47, 35, 25,
+ 18, 21, 5, 65, 70, 73, 62, 87, 83, 72, 83, 84, 77, 78, 75, 77, 76, 74,
+ 74, 81, 77, 83, 80, 1, 78, 79, 74, 70, 68, 70, 70, 68, 67, 71, 74, 78,
+ 8, 7, 14, 4, 0, 10, 8, 6, 4, 5, 5, 3, 67, 68, 72, 66, 7, 78,
+ 5, 20, 3, 6, 9, 11, 16, 5, 7, 9, 15, 68, 71, 80, 32, 34, 40, 27,
+ 24, 32, 32, 32, 36, 30, 36, 36, 25, 21, 4, 23, 32, 20, 13, 21, 17, 11,
+ 12, 8, 6, 2, 67, 69, 74, 25, 23, 23, 19, 7, 10, 7, 66, 0, 68, 71,
+ 81, 80, 88, 91, 71, 71, 89, 9, 10, 3, 70, 0, 64, 73, 66, 69, 75, 84,
+ 84, 92, 101, 6, 66, 79, 73, 3, 2, 6, 9, 10, 18, 12, 16, 18, 30, 21,
+ 20, 30, 29, 53, 35, 25, 14, 7, 67, 79, 91, 110, 6, 39, 32, 30, 23, 25,
+ 12, 9, 9, 64, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9, 18, 4,
+ 2, 46, 30, 14, 64, 75, 92, 104, 113, 122, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, 53, 14, 1, 64,
+ 5, 15, 0, 67, 67, 75, 91, 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0,
+ 77, 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 18, 72,
+ 91, 85, 7, 0, 31, 23, 64, 4, 77, 4, 75, 73, 83, 81, 81, 85, 88, 22,
+ 0, 8, 79, 69, 78, 75, 91, 2, 69, 68, 78, 17, 68, 0, 76, 82, 69, 73,
+ 66, 6, 6, 0, 12, 12, 75, 64, 64, 67, 3, 73, 12, 70, 1, 12, 11, 21,
+ 15, 8, 78, 1, 70, 65, 1, 89, 66, 7, 3, 5, 7, 7, 20, 11, 3, 0,
+ 3, 0, 3, 6, 87, 68, 1, 76, 3, 0, 12, 5, 64, 11, 6, 4, 66, 12,
+ 64, 76, 3, 82, 19, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 0, 2, 64, 2, 6, 65, 80, 65, 73, 68, 64, 82, 19, 25, 18,
+ 17, 15, 13, 12, 12, 6, 65, 66, 69, 75, 76, 95, 68, 66, 80, 9, 4, 1,
+ 1, 67, 72, 70, 71, 79, 72, 77, 92, 86, 94, 67, 22, 18, 11, 4, 7, 64,
+ 69, 70, 76, 0, 35, 21, 15, 8, 13, 3, 65, 70, 74, 4, 39, 29, 24, 17,
+ 17, 5, 64, 69, 75, 70, 40, 25, 11, 3, 8, 67, 76, 80, 5, 46, 34, 24,
+ 17, 20, 5, 65, 70, 73, 62, 86, 82, 72, 82, 83, 77, 77, 74, 76, 75, 73,
+ 73, 81, 77, 83, 79, 2, 78, 80, 74, 70, 68, 70, 71, 68, 68, 72, 76, 79,
+ 7, 7, 14, 4, 64, 9, 7, 5, 3, 4, 4, 3, 68, 69, 73, 66, 7, 79,
+ 4, 19, 2, 6, 8, 10, 16, 4, 6, 9, 15, 69, 72, 82, 31, 33, 39, 25,
+ 23, 31, 30, 30, 33, 28, 33, 33, 22, 18, 3, 20, 29, 17, 9, 18, 15, 9,
+ 10, 6, 6, 2, 67, 68, 72, 23, 21, 21, 17, 4, 8, 5, 68, 65, 70, 72,
+ 83, 81, 89, 92, 72, 72, 90, 8, 9, 1, 72, 65, 66, 74, 68, 71, 76, 85,
+ 86, 94, 102, 5, 67, 80, 73, 3, 2, 7, 9, 10, 19, 12, 17, 19, 31, 22,
+ 21, 31, 30, 52, 33, 23, 12, 4, 70, 82, 94, 113, 6, 39, 32, 30, 23, 25,
+ 12, 9, 9, 64, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, 18, 4,
+ 1, 45, 28, 12, 67, 78, 96, 108, 116, 125, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, 53, 14, 3, 64,
+ 6, 16, 0, 67, 66, 76, 92, 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0,
+ 76, 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, 76, 88,
+ 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 18, 71,
+ 91, 83, 9, 2, 32, 25, 1, 5, 75, 5, 73, 72, 81, 81, 81, 85, 87, 22,
+ 0, 8, 78, 69, 77, 74, 90, 2, 69, 68, 78, 17, 68, 1, 75, 81, 68, 73,
+ 66, 6, 6, 0, 12, 12, 74, 64, 0, 67, 3, 72, 11, 70, 1, 11, 10, 21,
+ 14, 7, 77, 1, 69, 66, 0, 89, 67, 7, 3, 6, 7, 7, 21, 11, 3, 0,
+ 4, 0, 3, 6, 88, 68, 1, 77, 3, 64, 12, 5, 65, 11, 6, 4, 67, 12,
+ 64, 76, 3, 83, 18, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 0, 2, 64, 1, 6, 65, 80, 65, 73, 69, 65, 82, 17, 24, 17,
+ 16, 13, 11, 11, 11, 4, 67, 67, 70, 77, 77, 96, 68, 66, 81, 8, 3, 0,
+ 0, 68, 73, 71, 72, 80, 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0,
+ 68, 69, 75, 1, 35, 21, 15, 8, 14, 3, 64, 69, 72, 4, 39, 29, 24, 17,
+ 18, 5, 64, 69, 74, 70, 41, 25, 11, 3, 9, 67, 76, 79, 5, 46, 34, 24,
+ 16, 20, 5, 65, 69, 72, 62, 85, 81, 71, 81, 81, 76, 75, 73, 74, 74, 72,
+ 71, 80, 76, 83, 78, 4, 78, 81, 73, 69, 68, 70, 72, 68, 68, 73, 77, 80,
+ 7, 7, 14, 4, 64, 8, 7, 5, 2, 4, 4, 3, 69, 69, 73, 65, 8, 79,
+ 4, 18, 2, 6, 8, 10, 16, 3, 5, 9, 15, 70, 72, 83, 31, 32, 38, 24,
+ 22, 30, 28, 28, 31, 26, 31, 30, 20, 16, 2, 17, 26, 14, 5, 15, 13, 8,
+ 9, 5, 6, 3, 67, 67, 70, 21, 20, 19, 15, 2, 7, 4, 70, 66, 71, 73,
+ 84, 82, 90, 92, 72, 72, 91, 7, 8, 0, 74, 66, 67, 75, 69, 72, 77, 86,
+ 87, 95, 103, 5, 68, 80, 72, 3, 2, 8, 10, 11, 20, 13, 18, 20, 33, 23,
+ 22, 33, 32, 51, 32, 21, 10, 1, 73, 85, 97, 115, 7, 39, 32, 31, 23, 26,
+ 13, 9, 10, 0, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, 10, 19, 4,
+ 1, 44, 26, 10, 69, 81, 99, 112, 119, 126, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, 53, 14, 6, 65,
+ 7, 16, 0, 68, 66, 77, 93, 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0,
+ 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, 76, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 71,
+ 91, 82, 11, 3, 34, 27, 2, 6, 74, 7, 72, 71, 79, 80, 80, 84, 86, 22,
+ 0, 8, 78, 69, 77, 74, 88, 1, 69, 68, 78, 17, 68, 1, 75, 81, 68, 73,
+ 65, 6, 5, 0, 12, 12, 74, 64, 0, 67, 3, 72, 11, 70, 1, 11, 9, 20,
+ 13, 6, 76, 2, 69, 67, 0, 88, 67, 7, 2, 6, 7, 7, 22, 12, 3, 0,
+ 4, 0, 2, 6, 89, 68, 1, 77, 2, 65, 11, 5, 65, 12, 6, 4, 68, 11,
+ 65, 76, 3, 83, 18, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 64, 2, 64, 1, 5, 66, 80, 66, 73, 70, 66, 82, 16, 22, 15,
+ 14, 11, 9, 9, 9, 2, 69, 69, 72, 80, 79, 97, 68, 67, 81, 7, 2, 64,
+ 64, 70, 75, 72, 73, 80, 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0,
+ 68, 69, 74, 1, 35, 21, 15, 8, 14, 4, 0, 69, 70, 4, 39, 29, 24, 17,
+ 18, 5, 64, 69, 73, 70, 41, 24, 10, 3, 9, 67, 76, 79, 5, 45, 33, 23,
+ 15, 20, 5, 65, 69, 72, 62, 84, 80, 70, 79, 80, 75, 74, 71, 73, 72, 70,
+ 69, 79, 75, 82, 78, 5, 77, 81, 73, 68, 68, 71, 72, 69, 69, 74, 78, 81,
+ 6, 6, 14, 3, 65, 8, 7, 5, 1, 3, 4, 2, 70, 69, 73, 65, 8, 79,
+ 3, 18, 1, 6, 7, 9, 16, 2, 4, 8, 14, 71, 73, 85, 30, 32, 38, 23,
+ 20, 28, 26, 26, 29, 23, 28, 28, 17, 14, 0, 14, 22, 11, 1, 13, 10, 6,
+ 8, 4, 6, 4, 66, 66, 68, 20, 18, 17, 14, 0, 5, 2, 72, 67, 73, 75,
+ 86, 84, 91, 93, 73, 72, 92, 5, 6, 65, 75, 68, 69, 77, 71, 74, 79, 87,
+ 88, 96, 103, 4, 68, 81, 72, 4, 3, 8, 10, 12, 21, 14, 19, 21, 34, 24,
+ 23, 34, 33, 51, 30, 19, 7, 64, 76, 88, 100, 117, 7, 40, 33, 31, 24, 27,
+ 13, 10, 10, 0, 76, 71, 3, 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4,
+ 1, 42, 24, 7, 72, 84, 103, 116, 123, 126, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, 53, 14, 8, 65,
+ 7, 17, 0, 69, 66, 78, 94, 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0,
+ 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, 75, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 71,
+ 90, 80, 13, 5, 35, 29, 3, 7, 72, 8, 71, 71, 78, 80, 80, 84, 86, 23,
+ 0, 8, 77, 68, 76, 73, 87, 1, 70, 69, 79, 17, 68, 1, 74, 81, 67, 73,
+ 65, 6, 5, 1, 12, 11, 74, 64, 0, 67, 3, 72, 10, 70, 1, 10, 8, 19,
+ 13, 6, 76, 2, 69, 67, 64, 88, 68, 7, 2, 6, 7, 7, 22, 12, 3, 0,
+ 5, 0, 1, 6, 89, 69, 1, 78, 2, 66, 11, 5, 66, 12, 6, 4, 70, 11,
+ 66, 76, 3, 84, 17, 20, 14, 14, 17, 16, 9, 16, 18, 65, 7, 9, 4, 2,
+ 69, 2, 67, 64, 1, 65, 0, 4, 66, 80, 66, 72, 71, 68, 82, 14, 20, 13,
+ 12, 9, 7, 7, 7, 0, 71, 70, 73, 82, 81, 98, 68, 67, 82, 6, 1, 65,
+ 66, 71, 76, 73, 74, 81, 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0,
+ 68, 68, 73, 2, 34, 21, 15, 8, 15, 4, 1, 68, 68, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 73, 70, 41, 24, 10, 3, 9, 66, 75, 78, 5, 45, 33, 22,
+ 15, 20, 5, 64, 68, 71, 62, 84, 79, 70, 78, 79, 74, 72, 70, 72, 71, 69,
+ 68, 79, 74, 82, 77, 7, 77, 82, 73, 68, 68, 71, 73, 69, 70, 75, 79, 82,
+ 6, 6, 14, 3, 65, 7, 6, 5, 1, 3, 3, 2, 70, 69, 74, 65, 8, 80,
+ 3, 17, 0, 5, 6, 9, 17, 2, 3, 8, 14, 71, 73, 86, 29, 31, 37, 22,
+ 19, 27, 24, 24, 27, 21, 26, 25, 14, 11, 64, 12, 19, 8, 66, 10, 8, 4,
+ 7, 3, 6, 5, 66, 64, 65, 18, 16, 15, 12, 65, 3, 1, 74, 69, 74, 76,
+ 87, 85, 92, 94, 73, 73, 93, 4, 5, 66, 77, 70, 71, 78, 72, 76, 80, 89,
+ 90, 98, 104, 3, 69, 82, 72, 4, 3, 9, 11, 12, 23, 15, 20, 22, 35, 26,
+ 24, 36, 34, 50, 29, 17, 5, 67, 78, 91, 102, 119, 8, 40, 33, 32, 24, 28,
+ 14, 10, 11, 1, 76, 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4,
+ 1, 41, 22, 5, 75, 88, 107, 119, 126, 126, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, 53, 14, 10, 65,
+ 8, 18, 0, 70, 66, 79, 95, 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0,
+ 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, 75, 88,
+ 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 18, 71,
+ 90, 78, 14, 6, 37, 30, 4, 8, 71, 9, 70, 70, 76, 79, 80, 83, 85, 23,
+ 0, 8, 77, 68, 76, 73, 85, 1, 70, 69, 79, 17, 68, 1, 74, 81, 67, 73,
+ 64, 6, 5, 1, 12, 11, 74, 64, 0, 67, 3, 72, 9, 71, 1, 9, 7, 18,
+ 12, 5, 75, 3, 69, 68, 64, 87, 68, 7, 2, 6, 7, 7, 23, 12, 3, 64,
+ 5, 64, 0, 5, 90, 69, 1, 78, 1, 67, 11, 4, 67, 12, 6, 4, 71, 11,
+ 67, 76, 3, 84, 16, 20, 14, 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2,
+ 70, 2, 67, 65, 1, 65, 64, 3, 67, 80, 67, 72, 72, 69, 82, 13, 18, 11,
+ 10, 7, 5, 5, 5, 65, 73, 72, 75, 84, 83, 99, 68, 67, 82, 5, 0, 66,
+ 67, 73, 78, 74, 76, 82, 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0,
+ 68, 68, 72, 2, 34, 21, 15, 8, 15, 5, 1, 67, 66, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 72, 70, 41, 24, 9, 3, 9, 66, 75, 77, 5, 44, 32, 21,
+ 14, 20, 5, 64, 68, 71, 62, 83, 78, 69, 77, 78, 73, 71, 69, 71, 70, 67,
+ 66, 78, 74, 82, 77, 8, 77, 82, 73, 67, 68, 72, 73, 69, 71, 76, 80, 83,
+ 5, 5, 14, 2, 66, 7, 6, 5, 0, 2, 3, 2, 71, 70, 74, 65, 8, 80,
+ 2, 17, 64, 5, 5, 8, 17, 1, 2, 7, 13, 72, 74, 88, 28, 30, 37, 21,
+ 18, 25, 22, 22, 25, 18, 23, 23, 11, 9, 65, 9, 16, 5, 70, 7, 5, 2,
+ 6, 1, 6, 6, 66, 0, 0, 16, 14, 13, 10, 67, 1, 64, 76, 70, 76, 77,
+ 89, 87, 93, 95, 74, 73, 94, 3, 3, 68, 79, 72, 73, 80, 74, 78, 82, 90,
+ 91, 99, 105, 2, 70, 83, 72, 5, 3, 9, 11, 13, 24, 15, 21, 23, 36, 27,
+ 25, 37, 35, 50, 27, 15, 2, 69, 81, 94, 105, 122, 8, 41, 34, 32, 24, 28,
+ 14, 10, 11, 1, 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11, 22, 4,
+ 1, 40, 20, 2, 78, 91, 111, 123, 126, 126, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, 53, 14, 13, 66,
+ 9, 18, 0, 70, 65, 80, 96, 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0,
+ 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 18, 70,
+ 90, 77, 16, 8, 38, 32, 6, 9, 70, 11, 69, 69, 74, 79, 79, 83, 84, 23,
+ 0, 8, 76, 68, 75, 72, 84, 0, 70, 69, 79, 17, 68, 2, 73, 81, 67, 73,
+ 64, 6, 4, 1, 12, 11, 73, 64, 1, 67, 3, 72, 9, 71, 1, 9, 6, 18,
+ 11, 4, 74, 3, 69, 69, 65, 87, 69, 7, 1, 6, 7, 7, 24, 13, 3, 64,
+ 5, 64, 64, 5, 91, 69, 1, 79, 1, 68, 10, 4, 67, 13, 6, 4, 72, 10,
+ 68, 76, 3, 85, 16, 20, 14, 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2,
+ 70, 2, 67, 65, 1, 65, 64, 2, 67, 80, 67, 72, 73, 70, 82, 11, 16, 10,
+ 9, 5, 3, 3, 3, 67, 75, 74, 77, 87, 84, 100, 68, 68, 83, 4, 64, 67,
+ 68, 74, 79, 75, 77, 82, 75, 80, 92, 85, 91, 65, 23, 18, 11, 5, 8, 1,
+ 67, 67, 71, 3, 34, 21, 15, 8, 15, 5, 2, 67, 64, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 71, 70, 42, 23, 9, 3, 9, 66, 75, 77, 5, 44, 31, 20,
+ 13, 20, 5, 64, 68, 70, 62, 82, 77, 68, 75, 77, 72, 70, 67, 70, 68, 66,
+ 64, 77, 73, 81, 76, 9, 76, 83, 72, 66, 68, 72, 74, 70, 71, 77, 81, 84,
+ 4, 5, 14, 2, 66, 6, 6, 5, 64, 1, 3, 1, 72, 70, 74, 65, 8, 80,
+ 1, 16, 64, 5, 4, 7, 17, 0, 1, 7, 13, 73, 75, 90, 27, 30, 36, 20,
+ 16, 24, 20, 20, 23, 16, 20, 20, 8, 7, 67, 6, 12, 2, 74, 5, 3, 0,
+ 5, 0, 6, 7, 65, 1, 2, 15, 13, 11, 9, 69, 64, 65, 78, 71, 78, 79,
+ 91, 88, 94, 96, 74, 73, 95, 1, 2, 70, 80, 73, 74, 81, 75, 79, 83, 91,
+ 92, 100, 105, 2, 70, 84, 71, 5, 4, 10, 12, 14, 25, 16, 22, 24, 38, 28,
+ 26, 38, 37, 49, 25, 13, 0, 72, 84, 97, 108, 124, 8, 41, 34, 33, 25, 29,
+ 14, 11, 12, 2, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, 12, 23, 4,
+ 1, 38, 18, 0, 81, 94, 114, 126, 126, 126, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, 53, 14, 15, 66,
+ 10, 19, 0, 71, 65, 81, 97, 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0,
+ 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 18, 70,
+ 90, 75, 18, 9, 40, 34, 7, 10, 68, 12, 68, 68, 72, 78, 79, 82, 83, 23,
+ 0, 8, 76, 68, 75, 72, 82, 0, 71, 70, 80, 17, 68, 2, 73, 81, 66, 73,
+ 0, 6, 4, 1, 12, 10, 73, 64, 1, 67, 3, 72, 8, 71, 1, 8, 5, 17,
+ 10, 3, 74, 4, 69, 70, 65, 86, 69, 7, 1, 6, 7, 7, 25, 13, 3, 64,
+ 6, 64, 65, 5, 92, 69, 1, 79, 0, 69, 10, 4, 68, 13, 6, 4, 74, 10,
+ 69, 76, 3, 85, 15, 20, 14, 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2,
+ 70, 1, 68, 66, 0, 66, 65, 1, 68, 80, 68, 72, 74, 72, 82, 10, 14, 8,
+ 7, 3, 1, 1, 1, 69, 77, 75, 78, 89, 86, 101, 68, 68, 83, 3, 65, 68,
+ 70, 76, 81, 76, 78, 83, 75, 80, 92, 85, 91, 64, 23, 18, 11, 5, 8, 1,
+ 67, 67, 70, 3, 34, 21, 15, 8, 16, 6, 3, 66, 1, 4, 40, 29, 24, 17,
+ 20, 5, 64, 68, 71, 70, 42, 23, 8, 3, 9, 66, 75, 76, 5, 43, 31, 19,
+ 12, 20, 5, 64, 67, 70, 62, 81, 76, 68, 74, 76, 71, 68, 66, 69, 67, 64,
+ 0, 77, 72, 81, 76, 11, 76, 83, 72, 66, 68, 73, 74, 70, 72, 78, 82, 85,
+ 4, 4, 14, 1, 67, 6, 5, 5, 65, 1, 2, 1, 73, 70, 75, 65, 8, 81,
+ 1, 16, 65, 5, 3, 7, 17, 64, 0, 6, 12, 74, 75, 91, 26, 29, 36, 19,
+ 15, 22, 18, 18, 21, 13, 18, 18, 5, 4, 68, 3, 9, 64, 78, 2, 0, 65,
+ 4, 64, 6, 8, 65, 2, 4, 13, 11, 9, 7, 71, 66, 67, 80, 73, 79, 80,
+ 92, 90, 95, 97, 75, 74, 96, 0, 0, 71, 82, 75, 76, 83, 77, 81, 85, 92,
+ 94, 102, 106, 1, 71, 85, 71, 6, 4, 10, 12, 14, 26, 17, 23, 25, 39, 29,
+ 27, 40, 38, 49, 24, 11, 66, 74, 87, 100, 111, 126, 9, 42, 35, 33, 25, 30,
+ 15, 11, 12, 2, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, 4, 12, 24, 4,
+ 1, 37, 16, 66, 84, 97, 118, 126, 126, 126, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, 53, 14, 17, 66,
+ 11, 20, 0, 72, 65, 82, 98, 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0,
+ 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 18, 70,
+ 90, 73, 20, 11, 41, 36, 8, 11, 67, 13, 67, 67, 70, 78, 79, 82, 82, 23,
+ 0, 8, 75, 68, 74, 71, 81, 0, 71, 70, 80, 17, 68, 2, 72, 81, 66, 73,
+ 0, 6, 4, 1, 12, 10, 73, 64, 1, 67, 3, 72, 7, 71, 1, 7, 4, 16,
+ 9, 2, 73, 4, 69, 71, 66, 86, 70, 7, 1, 6, 7, 7, 26, 13, 3, 64,
+ 6, 64, 66, 5, 93, 69, 1, 80, 0, 70, 10, 4, 69, 13, 6, 4, 75, 10,
+ 70, 76, 3, 86, 14, 20, 14, 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2,
+ 70, 1, 68, 66, 0, 66, 66, 0, 68, 80, 68, 72, 75, 73, 82, 8, 12, 6,
+ 5, 1, 64, 64, 64, 71, 79, 77, 80, 91, 88, 102, 68, 68, 84, 2, 66, 69,
+ 71, 77, 82, 77, 79, 84, 76, 81, 92, 85, 90, 64, 23, 18, 11, 5, 8, 1,
+ 67, 66, 69, 4, 34, 21, 15, 8, 16, 6, 4, 65, 3, 4, 40, 29, 24, 17,
+ 20, 5, 64, 68, 70, 70, 42, 23, 8, 3, 9, 66, 75, 75, 5, 43, 30, 18,
+ 11, 20, 5, 64, 67, 69, 62, 80, 75, 67, 73, 75, 70, 67, 65, 68, 66, 0,
+ 2, 76, 71, 81, 75, 12, 76, 84, 72, 65, 68, 73, 75, 70, 73, 79, 83, 86,
+ 3, 4, 14, 1, 67, 5, 5, 5, 66, 0, 2, 1, 74, 70, 75, 65, 8, 81,
+ 0, 15, 66, 5, 2, 6, 17, 65, 64, 6, 12, 75, 76, 93, 25, 28, 35, 18,
+ 14, 21, 16, 16, 19, 11, 15, 15, 2, 2, 69, 0, 6, 67, 82, 64, 65, 67,
+ 3, 65, 6, 9, 65, 3, 6, 11, 9, 7, 5, 73, 68, 68, 82, 74, 81, 81,
+ 94, 91, 96, 98, 75, 74, 97, 64, 64, 73, 84, 77, 78, 84, 78, 83, 86, 93,
+ 95, 103, 107, 0, 72, 86, 71, 6, 4, 11, 13, 15, 27, 18, 24, 26, 40, 30,
+ 28, 41, 39, 48, 22, 9, 68, 77, 90, 103, 114, 126, 9, 42, 35, 34, 25, 31,
+ 15, 11, 13, 3, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, 4, 13, 25, 4,
+ 1, 36, 14, 68, 87, 100, 122, 126, 126, 126, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, 52, 14, 19, 67,
+ 11, 20, 64, 73, 65, 84, 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, 64,
+ 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, 77, 75, 88,
+ 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 18, 70,
+ 90, 72, 21, 12, 42, 37, 9, 12, 66, 14, 66, 67, 69, 78, 79, 82, 82, 23,
+ 0, 8, 75, 68, 74, 71, 80, 64, 72, 71, 81, 17, 68, 2, 72, 81, 66, 73,
+ 0, 5, 3, 1, 11, 9, 73, 65, 1, 67, 2, 72, 6, 72, 0, 6, 2, 15,
+ 8, 1, 73, 4, 69, 72, 67, 86, 71, 6, 0, 6, 7, 7, 26, 13, 3, 65,
+ 6, 65, 67, 4, 94, 70, 0, 81, 64, 71, 9, 3, 70, 13, 6, 4, 77, 9,
+ 71, 76, 3, 87, 13, 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1,
+ 71, 0, 69, 67, 64, 67, 67, 64, 69, 80, 69, 72, 76, 75, 82, 6, 10, 4,
+ 3, 64, 67, 66, 66, 73, 81, 79, 82, 94, 90, 104, 69, 69, 85, 1, 68, 71,
+ 73, 79, 84, 79, 81, 85, 77, 82, 92, 85, 90, 64, 23, 18, 11, 5, 8, 1,
+ 67, 66, 68, 4, 33, 21, 15, 8, 16, 6, 4, 65, 4, 3, 40, 29, 23, 16,
+ 20, 5, 64, 68, 70, 70, 42, 22, 7, 2, 9, 66, 75, 75, 5, 42, 29, 17,
+ 10, 19, 5, 64, 67, 69, 62, 80, 74, 67, 72, 74, 70, 66, 64, 67, 65, 1,
+ 3, 76, 71, 81, 75, 13, 76, 85, 72, 65, 68, 74, 76, 71, 74, 80, 85, 88,
+ 2, 3, 14, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, 71, 76, 65, 8, 82,
+ 64, 14, 67, 4, 1, 5, 17, 66, 66, 5, 11, 76, 77, 95, 24, 27, 34, 16,
+ 12, 19, 14, 14, 16, 8, 12, 12, 64, 64, 71, 66, 2, 70, 87, 67, 68, 69,
+ 1, 67, 6, 9, 65, 4, 8, 9, 7, 5, 3, 76, 70, 70, 85, 76, 83, 83,
+ 96, 93, 97, 99, 76, 75, 99, 66, 66, 75, 86, 79, 80, 86, 80, 85, 88, 95,
+ 97, 105, 108, 64, 73, 87, 71, 6, 4, 11, 13, 15, 28, 18, 25, 26, 41, 31,
+ 29, 42, 40, 47, 20, 6, 71, 80, 93, 107, 117, 126, 9, 42, 35, 34, 25, 31,
+ 15, 11, 13, 3, 75, 69, 6, 67, 17, 26, 66, 0, 10, 14, 4, 13, 25, 4,
+ 0, 34, 11, 71, 90, 104, 126, 126, 126, 126, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, 52, 14, 22, 67,
+ 12, 21, 64, 73, 64, 85, 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, 64,
+ 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 18, 69,
+ 89, 70, 23, 14, 44, 39, 11, 13, 64, 16, 64, 66, 67, 77, 78, 81, 81, 24,
+ 1, 9, 74, 67, 73, 70, 78, 64, 72, 71, 81, 18, 68, 3, 71, 80, 65, 72,
+ 1, 5, 3, 2, 11, 9, 72, 65, 2, 67, 2, 71, 6, 72, 0, 6, 1, 15,
+ 8, 1, 72, 5, 68, 72, 67, 85, 71, 6, 0, 7, 7, 7, 27, 14, 4, 65,
+ 7, 65, 67, 4, 94, 70, 0, 81, 64, 72, 9, 3, 70, 14, 7, 4, 78, 9,
+ 71, 75, 3, 87, 13, 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1,
+ 71, 0, 69, 67, 64, 67, 67, 64, 69, 79, 69, 71, 76, 76, 81, 5, 9, 3,
+ 2, 66, 69, 67, 67, 75, 82, 80, 83, 96, 91, 105, 69, 69, 85, 0, 69, 72,
+ 74, 80, 85, 80, 82, 85, 77, 82, 91, 84, 89, 0, 24, 18, 11, 6, 9, 2,
+ 66, 65, 66, 5, 33, 21, 15, 8, 17, 7, 5, 64, 6, 3, 41, 30, 23, 16,
+ 21, 5, 64, 67, 69, 70, 43, 22, 7, 2, 10, 65, 74, 74, 5, 42, 29, 17,
+ 10, 19, 5, 0, 66, 68, 62, 79, 73, 66, 70, 72, 69, 64, 1, 65, 0, 3,
+ 5, 75, 70, 80, 74, 15, 75, 85, 71, 64, 67, 74, 76, 71, 74, 80, 86, 89,
+ 2, 3, 15, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, 71, 76, 64, 9, 82,
+ 64, 14, 67, 4, 1, 5, 18, 66, 67, 5, 11, 76, 77, 96, 24, 27, 34, 15,
+ 11, 18, 12, 12, 14, 6, 10, 10, 66, 66, 72, 68, 64, 73, 91, 69, 70, 70,
+ 0, 68, 6, 10, 64, 6, 11, 8, 6, 4, 2, 78, 71, 71, 87, 77, 84, 84,
+ 97, 94, 98, 99, 76, 75, 100, 67, 67, 76, 87, 80, 81, 87, 81, 86, 89, 96,
+ 98, 106, 108, 64, 73, 87, 70, 7, 5, 12, 14, 16, 30, 19, 26, 27, 43, 33,
+ 30, 44, 42, 47, 19, 4, 73, 82, 95, 110, 119, 126, 10, 43, 36, 35, 26, 32,
+ 16, 12, 14, 4, 74, 68, 7, 66, 19, 28, 65, 1, 11, 15, 5, 14, 26, 4,
+ 0, 33, 9, 73, 92, 107, 126, 126, 126, 126, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, 52, 14, 24,
+ 67, 13, 22, 64, 74, 64, 86, 102, 1, 2, 122, 124, 123, 34, 2, 69, 13,
+ 22, 64, 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, 64,
+ 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 18, 69, 89, 68, 25, 16, 45, 41, 12, 14, 0, 17, 0, 65, 65,
+ 77, 78, 81, 80, 24, 1, 9, 73, 67, 72, 70, 77, 64, 72, 71, 81, 18,
+ 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, 9, 72, 65, 2, 67, 2,
+ 71, 5, 72, 0, 5, 0, 14, 7, 0, 71, 5, 68, 73, 68, 85, 72, 6,
+ 0, 7, 7, 7, 28, 14, 4, 65, 7, 65, 68, 4, 95, 70, 0, 82, 64,
+ 73, 9, 3, 71, 14, 7, 4, 79, 9, 72, 75, 3, 88, 12, 19, 13, 14,
+ 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, 71, 0, 69, 67, 64, 67, 68,
+ 65, 70, 79, 69, 71, 77, 77, 81, 3, 7, 1, 0, 68, 71, 69, 69, 77,
+ 84, 82, 85, 98, 93, 106, 69, 69, 86, 64, 70, 73, 75, 82, 86, 81, 83,
+ 86, 78, 83, 91, 84, 88, 0, 24, 18, 11, 6, 9, 2, 66, 65, 65, 6,
+ 33, 21, 15, 8, 17, 7, 6, 0, 8, 3, 41, 30, 23, 16, 21, 5, 64,
+ 67, 68, 70, 43, 22, 7, 2, 10, 65, 74, 73, 5, 41, 28, 16, 9, 19,
+ 5, 0, 66, 68, 62, 78, 72, 65, 69, 71, 68, 0, 2, 64, 1, 4, 7,
+ 74, 69, 80, 73, 16, 75, 86, 71, 0, 67, 74, 77, 71, 75, 81, 87, 90,
+ 1, 3, 15, 0, 69, 3, 4, 4, 68, 65, 1, 0, 76, 71, 76, 64, 9,
+ 82, 65, 13, 68, 4, 0, 4, 18, 67, 68, 5, 11, 77, 78, 98, 23, 26,
+ 33, 14, 10, 17, 10, 10, 12, 4, 7, 7, 69, 68, 73, 71, 67, 76, 95,
+ 72, 72, 72, 64, 69, 6, 11, 64, 7, 13, 6, 4, 2, 0, 80, 73, 73,
+ 89, 78, 86, 85, 99, 95, 99, 100, 77, 75, 101, 68, 68, 78, 89, 82, 83,
+ 88, 83, 88, 90, 97, 99, 107, 109, 65, 74, 88, 70, 7, 5, 13, 14, 17,
+ 31, 20, 27, 28, 44, 34, 31, 45, 43, 46, 17, 2, 75, 85, 98, 113, 122,
+ 126, 10, 43, 36, 35, 26, 33, 16, 12, 14, 4, 74, 68, 8, 66, 20, 29,
+ 65, 2, 12, 16, 5, 14, 27, 4, 0, 32, 7, 75, 95, 110, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, 18, 52, 14, 26,
+ 67, 14, 23, 64, 75, 64, 87, 103, 1, 0, 123, 125, 123, 37, 3, 69, 14,
+ 23, 64, 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, 64,
+ 77, 74, 88, 12, 0, 65, 69, 7, 3, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 18, 69, 89, 66, 27, 17, 47, 43, 13, 15, 2, 18, 1, 64, 0,
+ 76, 78, 80, 79, 24, 1, 9, 73, 67, 72, 69, 75, 64, 73, 72, 82, 18,
+ 68, 3, 70, 80, 64, 72, 2, 5, 3, 2, 11, 8, 72, 65, 2, 67, 2,
+ 71, 4, 72, 0, 4, 64, 13, 6, 64, 71, 6, 68, 74, 68, 84, 72, 6,
+ 0, 7, 7, 7, 29, 14, 4, 65, 8, 65, 69, 4, 96, 70, 0, 82, 65,
+ 74, 9, 3, 72, 14, 7, 4, 81, 9, 73, 75, 3, 88, 11, 19, 13, 14,
+ 17, 15, 8, 16, 16, 66, 4, 9, 3, 1, 71, 64, 70, 68, 65, 68, 69,
+ 66, 70, 79, 70, 71, 78, 79, 81, 2, 5, 64, 65, 70, 73, 71, 71, 79,
+ 86, 83, 86, 100, 95, 107, 69, 69, 86, 65, 71, 74, 77, 83, 88, 82, 84,
+ 87, 78, 83, 91, 84, 88, 1, 24, 18, 11, 6, 9, 2, 66, 64, 64, 6,
+ 33, 21, 15, 8, 18, 8, 7, 1, 10, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 68, 70, 43, 22, 6, 2, 10, 65, 74, 72, 5, 41, 28, 15, 8, 19,
+ 5, 0, 65, 67, 62, 77, 71, 65, 68, 70, 67, 2, 3, 0, 2, 6, 8,
+ 74, 68, 80, 73, 18, 75, 86, 71, 0, 67, 75, 77, 71, 76, 82, 88, 91,
+ 1, 2, 15, 64, 69, 3, 3, 4, 69, 65, 0, 0, 77, 71, 77, 64, 9,
+ 83, 65, 13, 69, 4, 64, 4, 18, 68, 69, 4, 10, 78, 78, 99, 22, 25,
+ 33, 13, 9, 15, 8, 8, 10, 1, 5, 5, 72, 71, 74, 74, 70, 79, 99,
+ 75, 75, 74, 65, 70, 6, 12, 64, 8, 15, 4, 2, 0, 65, 82, 75, 74,
+ 91, 80, 87, 86, 100, 97, 100, 101, 77, 76, 102, 69, 70, 79, 91, 84, 85,
+ 90, 84, 90, 92, 98, 101, 109, 110, 66, 75, 89, 70, 8, 5, 13, 15, 17,
+ 32, 21, 28, 29, 45, 35, 32, 47, 44, 46, 16, 0, 78, 87, 101, 116, 125,
+ 126, 11, 44, 37, 36, 26, 34, 17, 12, 15, 5, 74, 67, 8, 65, 21, 30,
+ 65, 2, 12, 16, 5, 15, 28, 4, 0, 31, 5, 78, 98, 113, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, 16, 52, 14, 29,
+ 68, 15, 23, 64, 76, 64, 88, 104, 0, 65, 125, 126, 124, 40, 4, 69, 15,
+ 23, 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5, 69, 71, 65,
+ 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 18, 69, 89, 65, 28, 19, 48, 44, 14, 16, 3, 20, 2, 0, 2,
+ 76, 77, 80, 78, 24, 1, 9, 72, 67, 71, 69, 74, 65, 73, 72, 82, 18,
+ 68, 3, 70, 80, 64, 72, 2, 5, 2, 2, 11, 8, 72, 65, 2, 67, 2,
+ 71, 4, 73, 0, 4, 65, 12, 5, 65, 70, 6, 68, 75, 69, 84, 73, 6,
+ 64, 7, 7, 7, 30, 15, 4, 66, 8, 66, 70, 3, 97, 70, 0, 83, 65,
+ 75, 8, 2, 72, 15, 7, 4, 82, 8, 74, 75, 3, 89, 11, 19, 13, 14,
+ 17, 15, 8, 16, 15, 66, 4, 9, 3, 1, 72, 64, 70, 68, 65, 68, 69,
+ 67, 71, 79, 70, 71, 79, 80, 81, 0, 3, 66, 67, 72, 75, 73, 73, 81,
+ 88, 85, 88, 103, 97, 108, 69, 70, 87, 66, 72, 75, 78, 85, 89, 83, 86,
+ 87, 79, 84, 91, 84, 87, 1, 24, 18, 11, 6, 9, 2, 66, 64, 0, 7,
+ 33, 21, 15, 8, 18, 8, 7, 1, 12, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 67, 70, 43, 21, 6, 2, 10, 65, 74, 72, 5, 40, 27, 14, 7, 19,
+ 5, 0, 65, 67, 62, 76, 70, 64, 66, 69, 66, 3, 5, 1, 4, 7, 10,
+ 73, 68, 79, 72, 19, 74, 87, 71, 1, 67, 75, 78, 72, 77, 83, 89, 92,
+ 0, 2, 15, 64, 70, 2, 3, 4, 70, 66, 0, 64, 78, 72, 77, 64, 9,
+ 83, 66, 12, 70, 4, 65, 3, 18, 69, 70, 4, 10, 79, 79, 101, 21, 25,
+ 32, 12, 7, 14, 6, 6, 8, 64, 2, 2, 75, 73, 76, 77, 74, 82, 103,
+ 77, 77, 76, 66, 72, 6, 13, 0, 9, 17, 3, 0, 65, 66, 84, 77, 76,
+ 93, 81, 89, 88, 102, 98, 101, 102, 78, 76, 103, 71, 71, 81, 92, 86, 87,
+ 91, 86, 92, 93, 99, 102, 110, 110, 67, 75, 90, 70, 8, 6, 14, 15, 18,
+ 33, 21, 29, 30, 46, 36, 33, 48, 45, 45, 14, 65, 80, 90, 104, 119, 126,
+ 126, 11, 44, 37, 36, 27, 34, 17, 13, 15, 5, 73, 67, 9, 65, 22, 31,
+ 65, 3, 13, 17, 5, 15, 29, 4, 0, 29, 3, 80, 101, 116, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, 52, 14, 31,
+ 68, 16, 24, 64, 76, 0, 89, 105, 0, 67, 126, 126, 124, 43, 6, 69, 16,
+ 24, 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, 5, 69, 70, 65,
+ 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0, 1, 95, 97, 8,
+ 71, 68, 18, 68, 89, 0, 30, 20, 50, 46, 16, 17, 4, 21, 3, 1, 4,
+ 75, 77, 79, 77, 24, 1, 9, 72, 67, 71, 68, 72, 65, 73, 72, 82, 18,
+ 68, 4, 69, 80, 64, 72, 3, 5, 2, 2, 11, 8, 71, 65, 3, 67, 2,
+ 71, 3, 73, 0, 3, 66, 12, 4, 66, 69, 7, 68, 76, 69, 83, 73, 6,
+ 64, 7, 7, 7, 31, 15, 4, 66, 8, 66, 71, 3, 98, 70, 0, 83, 66,
+ 76, 8, 2, 73, 15, 7, 4, 83, 8, 75, 75, 3, 89, 10, 19, 13, 14,
+ 17, 15, 8, 16, 15, 66, 4, 9, 3, 1, 72, 64, 70, 69, 65, 68, 70,
+ 68, 71, 79, 71, 71, 80, 81, 81, 64, 1, 67, 68, 74, 77, 75, 75, 83,
+ 90, 87, 90, 105, 98, 109, 69, 70, 87, 67, 73, 76, 79, 86, 91, 84, 87,
+ 88, 79, 84, 91, 84, 87, 1, 24, 18, 11, 6, 9, 3, 65, 0, 1, 7,
+ 33, 21, 15, 8, 18, 9, 8, 2, 14, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 66, 70, 44, 21, 5, 2, 10, 65, 74, 71, 5, 40, 26, 13, 6, 19,
+ 5, 0, 65, 66, 62, 75, 69, 0, 65, 68, 65, 4, 6, 2, 5, 9, 12,
+ 72, 67, 79, 72, 20, 74, 87, 70, 2, 67, 76, 78, 72, 77, 84, 90, 93,
+ 64, 1, 15, 65, 70, 2, 3, 4, 71, 67, 0, 64, 79, 72, 77, 64, 9,
+ 83, 67, 12, 70, 4, 66, 2, 18, 70, 71, 3, 9, 80, 80, 103, 20, 24,
+ 32, 11, 6, 12, 4, 4, 6, 67, 64, 0, 78, 75, 77, 80, 77, 85, 107,
+ 80, 80, 78, 67, 73, 6, 14, 0, 10, 19, 1, 64, 67, 68, 86, 79, 77,
+ 95, 82, 91, 89, 104, 100, 102, 103, 78, 76, 104, 72, 73, 83, 94, 87, 88,
+ 93, 87, 93, 95, 100, 103, 111, 111, 67, 76, 91, 69, 9, 6, 14, 16, 19,
+ 34, 22, 30, 31, 48, 37, 34, 49, 47, 45, 12, 67, 83, 92, 107, 122, 126,
+ 126, 11, 45, 38, 37, 27, 35, 17, 13, 16, 6, 73, 67, 10, 64, 23, 32,
+ 64, 4, 13, 17, 5, 16, 30, 4, 0, 28, 1, 83, 104, 119, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, 52, 14, 33,
+ 68, 16, 25, 64, 77, 0, 90, 106, 64, 68, 126, 126, 125, 46, 7, 69, 16,
+ 25, 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, 5, 68, 70, 65,
+ 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0, 2, 95, 97, 8,
+ 71, 69, 18, 68, 88, 2, 32, 22, 51, 48, 17, 18, 6, 22, 4, 1, 5,
+ 75, 77, 79, 77, 25, 1, 9, 71, 66, 70, 68, 71, 65, 74, 73, 83, 18,
+ 68, 4, 69, 80, 0, 72, 3, 5, 2, 3, 11, 7, 71, 65, 3, 67, 2,
+ 71, 2, 73, 0, 2, 67, 11, 4, 66, 69, 7, 68, 76, 70, 83, 74, 6,
+ 64, 7, 7, 7, 31, 15, 4, 66, 9, 66, 72, 3, 98, 71, 0, 84, 66,
+ 77, 8, 2, 74, 15, 7, 4, 85, 8, 76, 75, 3, 90, 9, 19, 12, 14,
+ 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, 65, 71, 69, 66, 69, 71,
+ 69, 72, 79, 71, 70, 81, 83, 81, 66, 64, 69, 70, 76, 79, 77, 77, 85,
+ 92, 88, 91, 107, 100, 110, 69, 70, 88, 68, 74, 77, 81, 88, 92, 85, 88,
+ 89, 80, 85, 91, 84, 86, 2, 24, 18, 11, 7, 9, 3, 65, 0, 2, 8,
+ 32, 21, 15, 8, 19, 9, 9, 3, 16, 3, 42, 30, 23, 16, 23, 5, 64,
+ 66, 66, 70, 44, 21, 5, 2, 10, 64, 73, 70, 5, 39, 26, 12, 6, 19,
+ 5, 1, 64, 66, 62, 75, 68, 0, 64, 67, 64, 6, 7, 3, 6, 10, 13,
+ 72, 66, 79, 71, 22, 74, 88, 70, 2, 67, 76, 79, 72, 78, 85, 91, 94,
+ 64, 1, 15, 65, 71, 1, 2, 4, 71, 67, 64, 64, 79, 72, 78, 64, 9,
+ 84, 67, 11, 71, 3, 67, 2, 19, 70, 72, 3, 9, 80, 80, 104, 19, 23,
+ 31, 10, 5, 11, 2, 2, 4, 69, 66, 66, 81, 78, 78, 82, 80, 88, 111,
+ 83, 82, 80, 68, 74, 6, 15, 0, 12, 22, 64, 66, 69, 70, 88, 81, 79,
+ 97, 84, 92, 90, 105, 101, 103, 104, 79, 77, 105, 73, 74, 84, 96, 89, 90,
+ 94, 89, 95, 96, 102, 105, 113, 112, 68, 77, 92, 69, 9, 6, 15, 16, 19,
+ 36, 23, 31, 32, 49, 39, 35, 51, 48, 44, 11, 69, 85, 95, 109, 125, 126,
+ 126, 12, 45, 38, 37, 27, 36, 18, 13, 16, 6, 73, 66, 10, 64, 24, 33,
+ 64, 4, 14, 18, 5, 16, 31, 4, 0, 27, 64, 85, 107, 123, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, 52, 14, 36,
+ 69, 17, 25, 64, 78, 0, 91, 107, 64, 70, 126, 126, 125, 49, 8, 69, 17,
+ 25, 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5, 68, 69, 66,
+ 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0, 2, 95, 97, 9,
+ 72, 69, 18, 68, 88, 3, 34, 23, 53, 50, 18, 19, 7, 24, 5, 2, 7,
+ 74, 76, 78, 76, 25, 1, 9, 71, 66, 70, 67, 69, 66, 74, 73, 83, 18,
+ 68, 4, 68, 80, 0, 72, 4, 5, 1, 3, 11, 7, 71, 65, 3, 67, 2,
+ 71, 2, 73, 0, 2, 68, 10, 3, 67, 68, 8, 68, 77, 70, 82, 74, 6,
+ 65, 7, 7, 7, 32, 16, 4, 66, 9, 66, 73, 3, 99, 71, 0, 84, 67,
+ 78, 7, 2, 74, 16, 7, 4, 86, 7, 77, 75, 3, 90, 9, 19, 12, 14,
+ 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, 65, 71, 70, 66, 69, 71,
+ 70, 72, 79, 72, 70, 82, 84, 81, 67, 66, 71, 72, 78, 81, 79, 79, 87,
+ 94, 90, 93, 110, 102, 111, 69, 71, 88, 69, 75, 78, 82, 89, 94, 86, 89,
+ 89, 80, 85, 91, 84, 86, 2, 24, 18, 11, 7, 9, 3, 65, 1, 3, 8,
+ 32, 21, 15, 8, 19, 10, 10, 3, 18, 3, 42, 30, 23, 16, 23, 5, 64,
+ 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 70, 5, 39, 25, 11, 5, 19,
+ 5, 1, 64, 65, 62, 74, 67, 1, 1, 66, 0, 7, 9, 4, 8, 12, 15,
+ 71, 65, 78, 71, 23, 73, 88, 70, 3, 67, 77, 79, 73, 79, 86, 92, 95,
+ 65, 0, 15, 66, 71, 1, 2, 4, 72, 68, 64, 65, 80, 72, 78, 64, 9,
+ 84, 68, 11, 72, 3, 68, 1, 19, 71, 73, 2, 8, 81, 81, 106, 18, 23,
+ 31, 9, 3, 9, 0, 0, 2, 72, 69, 68, 84, 80, 80, 85, 84, 91, 115,
+ 85, 85, 82, 69, 75, 6, 16, 1, 13, 24, 65, 68, 71, 71, 90, 83, 80,
+ 99, 85, 94, 92, 107, 103, 104, 105, 79, 77, 106, 75, 76, 86, 97, 91, 92,
+ 96, 90, 97, 98, 103, 106, 114, 112, 69, 77, 93, 69, 10, 7, 15, 17, 20,
+ 37, 24, 32, 33, 50, 40, 36, 52, 49, 44, 9, 71, 88, 97, 112, 126, 126,
+ 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, 66, 11, 0, 25, 34,
+ 64, 5, 14, 18, 5, 17, 32, 4, 0, 25, 66, 88, 110, 126, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, 52, 14, 38,
+ 69, 18, 26, 64, 79, 0, 92, 109, 65, 72, 126, 126, 126, 51, 9, 69, 18,
+ 26, 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5, 68, 69, 66,
+ 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0, 3, 96, 97, 9,
+ 73, 69, 18, 68, 88, 5, 35, 25, 54, 51, 19, 20, 8, 25, 6, 3, 9,
+ 74, 76, 78, 75, 25, 1, 9, 70, 66, 69, 67, 68, 66, 75, 74, 84, 18,
+ 68, 4, 68, 80, 0, 72, 4, 4, 1, 3, 11, 6, 71, 65, 3, 67, 1,
+ 71, 1, 74, 0, 1, 70, 9, 2, 68, 68, 8, 68, 78, 71, 82, 75, 5,
+ 65, 7, 7, 7, 33, 16, 4, 67, 9, 67, 74, 2, 100, 71, 0, 85, 67,
+ 79, 7, 1, 75, 16, 7, 4, 88, 7, 78, 75, 3, 91, 8, 18, 12, 14,
+ 17, 14, 7, 16, 14, 67, 2, 9, 2, 0, 73, 66, 72, 70, 67, 70, 72,
+ 71, 73, 79, 72, 70, 83, 86, 81, 69, 68, 73, 74, 80, 84, 81, 81, 89,
+ 96, 92, 95, 112, 104, 112, 69, 71, 89, 70, 77, 80, 84, 91, 95, 88, 91,
+ 90, 81, 86, 91, 84, 85, 2, 24, 18, 11, 7, 9, 3, 65, 1, 4, 9,
+ 32, 21, 15, 8, 19, 10, 10, 4, 19, 3, 42, 30, 23, 15, 23, 5, 64,
+ 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 69, 5, 38, 24, 10, 4, 18,
+ 5, 1, 64, 65, 62, 73, 66, 1, 2, 65, 0, 8, 10, 5, 9, 13, 16,
+ 71, 65, 78, 70, 24, 73, 89, 70, 3, 67, 77, 80, 73, 80, 87, 94, 96,
+ 66, 0, 15, 66, 72, 0, 1, 3, 73, 69, 65, 65, 81, 73, 79, 64, 9,
+ 85, 69, 10, 73, 3, 69, 0, 19, 72, 74, 2, 8, 82, 82, 108, 17, 22,
+ 30, 7, 2, 8, 65, 65, 64, 74, 72, 71, 87, 83, 81, 88, 87, 94, 119,
+ 88, 87, 84, 71, 77, 6, 16, 1, 14, 26, 67, 70, 73, 73, 93, 85, 82,
+ 101, 87, 96, 93, 109, 104, 105, 106, 80, 78, 107, 76, 77, 88, 99, 93, 94,
+ 97, 92, 99, 99, 104, 108, 116, 113, 70, 78, 94, 69, 10, 7, 16, 17, 20,
+ 38, 24, 33, 34, 51, 41, 37, 53, 50, 43, 7, 73, 90, 100, 115, 126, 126,
+ 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, 66, 11, 0, 26, 35,
+ 64, 5, 15, 19, 5, 17, 32, 4, 64, 24, 68, 90, 113, 126, 126, 126, 126,
+ 126, 75, 70, 64, 11, 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, 52, 14,
+ 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, 74, 126, 126, 126, 54, 11,
+ 69, 19, 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5,
+ 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 18, 67, 88, 7, 37, 27, 55, 53, 21, 21,
+ 10, 26, 8, 4, 11, 74, 76, 78, 74, 25, 1, 9, 69, 66, 68, 66,
+ 67, 66, 75, 74, 84, 18, 68, 5, 67, 79, 1, 72, 4, 4, 1, 3,
+ 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 71, 9, 1, 69,
+ 67, 8, 67, 79, 72, 82, 76, 5, 65, 8, 7, 7, 34, 16, 4, 67,
+ 10, 67, 74, 2, 101, 71, 0, 86, 67, 80, 7, 1, 76, 16, 7, 4,
+ 89, 7, 78, 75, 3, 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67,
+ 2, 9, 2, 0, 73, 66, 72, 70, 67, 70, 73, 71, 73, 79, 72, 70,
+ 84, 87, 81, 71, 69, 74, 75, 82, 86, 82, 82, 91, 98, 93, 96, 114,
+ 105, 113, 69, 71, 90, 71, 78, 81, 85, 92, 96, 89, 92, 91, 82, 87,
+ 91, 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 5, 10, 32, 21,
+ 15, 8, 20, 10, 11, 5, 21, 3, 42, 30, 23, 15, 24, 5, 64, 66,
+ 64, 70, 45, 20, 4, 2, 11, 64, 73, 68, 5, 38, 24, 10, 3, 18,
+ 5, 1, 0, 64, 62, 72, 65, 2, 3, 0, 1, 10, 11, 7, 10, 14,
+ 18, 70, 64, 78, 69, 26, 73, 90, 69, 4, 67, 77, 81, 73, 80, 88,
+ 95, 97, 66, 0, 15, 66, 72, 64, 1, 3, 74, 69, 65, 65, 82, 73,
+ 79, 0, 10, 85, 69, 9, 73, 3, 69, 0, 19, 73, 75, 2, 8, 83,
+ 82, 109, 17, 21, 29, 6, 1, 7, 67, 67, 66, 76, 74, 74, 89, 85,
+ 82, 91, 90, 97, 123, 91, 89, 85, 72, 78, 6, 17, 1, 15, 28, 69,
+ 71, 75, 75, 95, 86, 83, 103, 88, 97, 94, 110, 105, 106, 106, 80, 78,
+ 108, 77, 78, 89, 101, 94, 95, 98, 93, 100, 100, 105, 109, 117, 114, 70,
+ 79, 94, 68, 10, 7, 17, 18, 21, 39, 25, 34, 35, 53, 42, 38, 55,
+ 52, 42, 6, 75, 92, 103, 118, 126, 126, 126, 13, 46, 39, 39, 28, 38,
+ 19, 14, 18, 8, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, 5, 18,
+ 33, 4, 64, 23, 70, 92, 115, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, 52, 14,
+ 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, 76, 126, 126, 126, 57, 12,
+ 69, 20, 27, 64, 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5,
+ 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 18, 67, 88, 8, 39, 28, 57, 55, 22, 22,
+ 11, 28, 9, 5, 13, 73, 75, 77, 73, 25, 1, 9, 69, 66, 68, 66,
+ 65, 67, 75, 74, 84, 18, 68, 5, 67, 79, 1, 72, 5, 4, 0, 3,
+ 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 72, 8, 0, 70,
+ 66, 9, 67, 80, 72, 81, 76, 5, 66, 8, 7, 7, 35, 17, 4, 67,
+ 10, 67, 75, 2, 102, 71, 0, 86, 68, 81, 6, 1, 76, 17, 7, 4,
+ 90, 6, 79, 75, 3, 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67,
+ 2, 9, 2, 0, 73, 66, 72, 71, 67, 70, 73, 72, 74, 79, 73, 70,
+ 85, 88, 81, 72, 71, 76, 77, 84, 88, 84, 84, 93, 100, 95, 98, 117,
+ 107, 114, 69, 72, 90, 72, 79, 82, 86, 94, 98, 90, 93, 91, 82, 87,
+ 91, 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 6, 10, 32, 21,
+ 15, 8, 20, 11, 12, 5, 23, 3, 42, 30, 23, 15, 24, 5, 64, 66,
+ 0, 70, 45, 19, 3, 2, 11, 64, 73, 68, 5, 37, 23, 9, 2, 18,
+ 5, 1, 0, 64, 62, 71, 64, 3, 5, 1, 2, 11, 13, 8, 12, 16,
+ 20, 69, 0, 77, 69, 27, 72, 90, 69, 5, 67, 78, 81, 74, 81, 89,
+ 96, 98, 67, 64, 15, 67, 73, 64, 1, 3, 75, 70, 65, 66, 83, 73,
+ 79, 0, 10, 85, 70, 9, 74, 3, 70, 64, 19, 74, 76, 1, 7, 84,
+ 83, 111, 16, 21, 29, 5, 64, 5, 69, 69, 68, 79, 77, 76, 92, 87,
+ 84, 94, 94, 100, 126, 93, 92, 87, 73, 79, 6, 18, 2, 16, 30, 70,
+ 73, 77, 76, 97, 88, 85, 105, 89, 99, 96, 112, 107, 107, 107, 81, 78,
+ 109, 79, 80, 91, 102, 96, 97, 100, 95, 102, 102, 106, 110, 118, 114, 71,
+ 79, 95, 68, 11, 8, 17, 18, 22, 40, 26, 35, 36, 54, 43, 39, 56,
+ 53, 42, 4, 77, 95, 105, 121, 126, 126, 126, 13, 47, 40, 39, 29, 39,
+ 19, 15, 18, 8, 71, 65, 13, 1, 28, 38, 0, 7, 16, 20, 5, 18,
+ 34, 4, 64, 21, 72, 95, 118, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, 52, 14,
+ 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, 77, 126, 126, 126, 60, 13,
+ 69, 20, 28, 64, 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5,
+ 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 18, 67, 87, 10, 41, 30, 58, 57, 23, 23,
+ 13, 29, 10, 5, 14, 73, 75, 77, 73, 26, 1, 9, 68, 65, 67, 65,
+ 64, 67, 76, 75, 85, 18, 68, 5, 66, 79, 2, 72, 5, 4, 0, 4,
+ 11, 5, 70, 65, 4, 67, 1, 70, 64, 74, 0, 64, 73, 7, 0, 70,
+ 66, 9, 67, 80, 73, 81, 77, 5, 66, 8, 7, 7, 35, 17, 4, 67,
+ 11, 67, 76, 2, 102, 72, 0, 87, 68, 82, 6, 1, 77, 17, 7, 4,
+ 92, 6, 80, 75, 3, 93, 6, 18, 11, 14, 17, 14, 7, 16, 14, 67,
+ 1, 9, 1, 0, 73, 67, 73, 71, 68, 71, 74, 73, 74, 79, 73, 69,
+ 86, 90, 81, 74, 73, 78, 79, 86, 90, 86, 86, 95, 102, 96, 99, 119,
+ 109, 115, 69, 72, 91, 73, 80, 83, 88, 95, 99, 91, 94, 92, 83, 88,
+ 91, 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 7, 11, 31, 21,
+ 15, 8, 21, 11, 13, 6, 25, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 0, 70, 45, 19, 3, 2, 11, 0, 72, 67, 5, 37, 23, 8, 2, 18,
+ 5, 2, 1, 0, 62, 71, 0, 3, 6, 2, 3, 13, 14, 9, 13, 17,
+ 21, 69, 1, 77, 68, 29, 72, 91, 69, 5, 67, 78, 82, 74, 82, 90,
+ 97, 99, 67, 64, 15, 67, 73, 65, 0, 3, 75, 70, 66, 66, 83, 73,
+ 80, 0, 10, 86, 70, 8, 75, 2, 71, 64, 20, 74, 77, 1, 7, 84,
+ 83, 112, 15, 20, 28, 4, 65, 4, 71, 71, 70, 81, 79, 79, 95, 90,
+ 85, 96, 97, 103, 126, 96, 94, 89, 74, 80, 6, 19, 2, 18, 33, 72,
+ 75, 79, 78, 99, 90, 86, 107, 91, 100, 97, 113, 108, 108, 108, 81, 79,
+ 110, 80, 81, 92, 104, 98, 99, 101, 96, 104, 103, 108, 112, 120, 115, 72,
+ 80, 96, 68, 11, 8, 18, 19, 22, 42, 27, 36, 37, 55, 45, 40, 58,
+ 54, 41, 3, 79, 97, 108, 123, 126, 126, 126, 14, 47, 40, 40, 29, 40,
+ 20, 15, 19, 9, 71, 64, 13, 1, 29, 39, 0, 7, 17, 21, 5, 19,
+ 35, 4, 64, 20, 74, 97, 121, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, 52, 14,
+ 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, 79, 126, 126, 126, 62, 14,
+ 69, 21, 29, 64, 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5,
+ 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 18, 67, 87, 12, 42, 31, 60, 58, 24, 24,
+ 14, 30, 11, 6, 16, 72, 75, 76, 72, 26, 1, 9, 68, 65, 67, 65,
+ 1, 67, 76, 75, 85, 18, 68, 5, 66, 79, 2, 72, 6, 4, 0, 4,
+ 11, 5, 70, 65, 4, 67, 1, 70, 65, 75, 0, 65, 74, 6, 64, 71,
+ 65, 10, 67, 81, 73, 80, 77, 5, 66, 8, 7, 7, 36, 17, 4, 68,
+ 11, 68, 77, 1, 103, 72, 0, 87, 69, 83, 6, 0, 78, 17, 7, 4,
+ 93, 6, 81, 75, 3, 93, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 1, 9, 1, 0, 74, 67, 73, 72, 68, 71, 75, 74, 75, 79, 74, 69,
+ 87, 91, 81, 75, 75, 80, 81, 88, 92, 88, 88, 97, 104, 98, 101, 121,
+ 111, 116, 69, 72, 91, 74, 81, 84, 89, 97, 101, 92, 96, 93, 83, 88,
+ 91, 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 8, 11, 31, 21,
+ 15, 8, 21, 12, 13, 7, 27, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 1, 70, 45, 19, 2, 2, 11, 0, 72, 66, 5, 36, 22, 7, 1, 18,
+ 5, 2, 1, 0, 62, 70, 1, 4, 7, 3, 4, 14, 15, 10, 14, 19,
+ 23, 68, 1, 77, 68, 30, 72, 91, 69, 6, 67, 79, 82, 74, 83, 91,
+ 98, 100, 68, 65, 15, 68, 74, 65, 0, 3, 76, 71, 66, 66, 84, 74,
+ 80, 0, 10, 86, 71, 8, 76, 2, 72, 65, 20, 75, 78, 0, 6, 85,
+ 84, 114, 14, 19, 28, 3, 66, 2, 73, 73, 72, 84, 82, 81, 98, 92,
+ 86, 99, 100, 106, 126, 99, 97, 91, 75, 82, 6, 20, 2, 19, 35, 74,
+ 77, 81, 80, 101, 92, 88, 109, 92, 102, 98, 115, 110, 109, 109, 82, 79,
+ 111, 81, 83, 94, 106, 100, 101, 103, 98, 106, 105, 109, 113, 121, 116, 73,
+ 81, 97, 68, 12, 8, 18, 19, 23, 43, 27, 37, 38, 56, 46, 41, 59,
+ 55, 41, 1, 81, 100, 110, 126, 126, 126, 126, 14, 48, 41, 40, 29, 40,
+ 20, 15, 19, 9, 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19,
+ 36, 4, 64, 19, 76, 100, 124, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, 52, 14,
+ 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, 81, 126, 126, 126, 62, 16,
+ 69, 22, 29, 64, 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 18, 66, 87, 13, 44, 33, 61, 60, 26, 25,
+ 15, 32, 12, 7, 18, 72, 74, 76, 71, 26, 1, 9, 67, 65, 66, 64,
+ 2, 68, 76, 75, 85, 18, 68, 6, 65, 79, 2, 72, 6, 4, 64, 4,
+ 11, 5, 69, 65, 5, 67, 1, 70, 65, 75, 0, 65, 75, 6, 65, 72,
+ 64, 10, 67, 82, 74, 80, 78, 5, 67, 8, 7, 7, 37, 18, 4, 68,
+ 11, 68, 78, 1, 104, 72, 0, 88, 69, 84, 5, 0, 78, 18, 7, 4,
+ 94, 5, 82, 75, 3, 94, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 1, 9, 1, 0, 74, 67, 73, 72, 68, 71, 75, 75, 75, 79, 74, 69,
+ 88, 92, 81, 77, 77, 81, 82, 90, 94, 90, 90, 99, 106, 100, 103, 124,
+ 112, 117, 69, 73, 92, 75, 82, 85, 90, 98, 102, 93, 97, 93, 84, 89,
+ 91, 83, 82, 4, 25, 18, 11, 8, 10, 5, 0, 4, 9, 12, 31, 21,
+ 15, 8, 21, 12, 14, 7, 29, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 2, 70, 46, 18, 2, 2, 11, 0, 72, 66, 5, 36, 21, 6, 0, 18,
+ 5, 2, 1, 1, 62, 69, 2, 5, 9, 4, 5, 15, 17, 11, 16, 20,
+ 25, 67, 2, 76, 67, 31, 71, 92, 68, 7, 67, 79, 83, 75, 83, 92,
+ 99, 101, 69, 65, 15, 68, 74, 66, 0, 3, 77, 72, 66, 67, 85, 74,
+ 80, 0, 10, 86, 72, 7, 76, 2, 73, 66, 20, 76, 79, 0, 6, 86,
+ 85, 116, 13, 19, 27, 2, 68, 1, 75, 75, 74, 86, 85, 84, 101, 94,
+ 88, 102, 104, 109, 126, 101, 99, 93, 76, 83, 6, 21, 3, 20, 37, 75,
+ 78, 83, 81, 103, 94, 89, 111, 93, 104, 100, 117, 111, 110, 110, 82, 79,
+ 112, 83, 84, 96, 107, 101, 102, 104, 99, 107, 106, 110, 114, 122, 116, 73,
+ 81, 98, 67, 12, 9, 19, 20, 24, 44, 28, 38, 39, 58, 47, 42, 60,
+ 57, 40, 64, 83, 102, 113, 126, 126, 126, 126, 14, 48, 41, 41, 30, 41,
+ 20, 16, 20, 10, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20,
+ 37, 4, 64, 17, 78, 102, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, 52, 14,
+ 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, 83, 126, 126, 126, 62, 17,
+ 69, 23, 30, 64, 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 18, 66, 87, 15, 46, 34, 62, 62, 27, 26,
+ 17, 33, 13, 8, 20, 71, 74, 75, 70, 26, 1, 9, 67, 65, 66, 64,
+ 4, 68, 77, 76, 86, 18, 68, 6, 65, 79, 3, 72, 7, 4, 64, 4,
+ 11, 4, 69, 65, 5, 67, 1, 70, 66, 75, 0, 66, 76, 5, 66, 73,
+ 64, 11, 67, 83, 74, 79, 78, 5, 67, 8, 7, 7, 38, 18, 4, 68,
+ 12, 68, 79, 1, 105, 72, 0, 88, 70, 85, 5, 0, 79, 18, 7, 4,
+ 96, 5, 83, 75, 3, 94, 4, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 0, 9, 1, 0, 74, 68, 74, 73, 69, 72, 76, 76, 76, 79, 75, 69,
+ 89, 94, 81, 78, 79, 83, 84, 92, 96, 92, 92, 101, 108, 101, 104, 126,
+ 114, 118, 69, 73, 92, 76, 83, 86, 92, 100, 104, 94, 98, 94, 84, 89,
+ 91, 83, 82, 5, 25, 18, 11, 8, 10, 5, 0, 4, 10, 12, 31, 21,
+ 15, 8, 22, 13, 15, 8, 31, 3, 43, 30, 23, 15, 26, 5, 64, 65,
+ 2, 70, 46, 18, 1, 2, 11, 0, 72, 65, 5, 35, 21, 5, 64, 18,
+ 5, 2, 2, 1, 62, 68, 3, 5, 10, 5, 6, 17, 18, 12, 17, 22,
+ 26, 67, 3, 76, 67, 33, 71, 92, 68, 7, 67, 80, 83, 75, 84, 93,
+ 100, 102, 69, 66, 15, 69, 75, 66, 64, 3, 78, 72, 67, 67, 86, 74,
+ 81, 0, 10, 87, 72, 7, 77, 2, 74, 66, 20, 77, 80, 64, 5, 87,
+ 85, 117, 12, 18, 27, 1, 69, 64, 77, 77, 76, 89, 87, 86, 104, 97,
+ 89, 105, 107, 112, 126, 104, 102, 95, 77, 84, 6, 22, 3, 21, 39, 77,
+ 80, 85, 83, 105, 96, 91, 113, 95, 105, 101, 118, 113, 111, 111, 83, 80,
+ 113, 84, 86, 97, 109, 103, 104, 106, 101, 109, 108, 111, 116, 124, 117, 74,
+ 82, 99, 67, 13, 9, 19, 20, 24, 45, 29, 39, 40, 59, 48, 43, 62,
+ 58, 40, 65, 85, 105, 115, 126, 126, 126, 126, 15, 49, 42, 41, 30, 42,
+ 21, 16, 20, 10, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20,
+ 38, 4, 64, 16, 80, 105, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, 2, 52, 14,
+ 54, 71, 24, 31, 64, 84, 2, 99, 116, 69, 85, 126, 126, 126, 62, 18,
+ 69, 24, 31, 64, 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5,
+ 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 18, 66, 87, 17, 48, 36, 62, 62, 28, 27,
+ 18, 34, 14, 9, 22, 71, 74, 75, 69, 26, 1, 9, 66, 65, 65, 0,
+ 5, 68, 77, 76, 86, 18, 68, 6, 64, 79, 3, 72, 7, 4, 64, 4,
+ 11, 4, 69, 65, 5, 67, 1, 70, 67, 75, 0, 67, 77, 4, 67, 74,
+ 0, 11, 67, 84, 75, 79, 79, 5, 67, 8, 7, 7, 39, 18, 4, 68,
+ 12, 68, 80, 1, 106, 72, 0, 89, 70, 86, 5, 0, 80, 18, 7, 4,
+ 97, 5, 84, 75, 3, 95, 3, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 0, 9, 1, 0, 74, 68, 74, 73, 69, 72, 77, 77, 76, 79, 75, 69,
+ 90, 95, 81, 80, 81, 85, 86, 94, 98, 94, 94, 103, 110, 103, 106, 126,
+ 116, 119, 69, 73, 93, 77, 84, 87, 93, 101, 105, 95, 99, 95, 85, 90,
+ 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, 11, 13, 31, 21,
+ 15, 8, 22, 13, 16, 9, 33, 3, 43, 30, 23, 15, 26, 5, 64, 65,
+ 3, 70, 46, 18, 1, 2, 11, 0, 72, 64, 5, 35, 20, 4, 65, 18,
+ 5, 2, 2, 2, 62, 67, 4, 6, 11, 6, 7, 18, 19, 13, 18, 23,
+ 28, 66, 4, 76, 66, 34, 71, 93, 68, 8, 67, 80, 84, 75, 85, 94,
+ 101, 103, 70, 66, 15, 69, 75, 67, 64, 3, 79, 73, 67, 67, 87, 74,
+ 81, 0, 10, 87, 73, 6, 78, 2, 75, 67, 20, 78, 81, 64, 5, 88,
+ 86, 119, 11, 17, 26, 0, 70, 65, 79, 79, 78, 91, 90, 89, 107, 99,
+ 90, 108, 110, 115, 126, 107, 104, 97, 78, 85, 6, 23, 3, 22, 41, 79,
+ 82, 87, 85, 107, 98, 92, 115, 96, 107, 102, 120, 114, 112, 112, 83, 80,
+ 114, 85, 87, 99, 111, 105, 106, 107, 102, 111, 109, 112, 117, 125, 118, 75,
+ 83, 100, 67, 13, 9, 20, 21, 25, 46, 30, 40, 41, 60, 49, 44, 62,
+ 59, 39, 67, 87, 107, 118, 126, 126, 126, 126, 15, 49, 42, 42, 30, 43,
+ 21, 16, 21, 11, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21,
+ 39, 4, 64, 15, 82, 107, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, 0, 51, 14,
+ 56, 72, 24, 31, 65, 85, 2, 101, 118, 70, 87, 126, 126, 126, 62, 19,
+ 70, 24, 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5,
+ 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 18, 66, 87, 18, 49, 37, 62, 62, 29, 28,
+ 19, 35, 15, 9, 23, 71, 74, 75, 69, 26, 1, 9, 66, 65, 65, 0,
+ 6, 69, 78, 77, 87, 18, 68, 6, 64, 79, 3, 72, 7, 3, 65, 4,
+ 10, 3, 69, 66, 5, 67, 0, 70, 68, 76, 64, 68, 79, 3, 68, 75,
+ 0, 11, 67, 85, 76, 79, 80, 4, 68, 8, 7, 7, 39, 18, 4, 69,
+ 12, 69, 81, 0, 107, 73, 64, 90, 71, 87, 4, 64, 81, 18, 7, 4,
+ 99, 4, 85, 75, 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 79, 76, 69,
+ 91, 97, 81, 82, 83, 87, 88, 96, 101, 96, 96, 105, 112, 105, 108, 126,
+ 118, 121, 70, 74, 94, 78, 86, 89, 95, 103, 107, 97, 101, 96, 86, 91,
+ 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, 12, 13, 30, 21,
+ 15, 8, 22, 13, 16, 9, 34, 2, 43, 30, 22, 14, 26, 5, 64, 65,
+ 3, 70, 46, 17, 0, 1, 11, 0, 72, 64, 5, 34, 19, 3, 66, 17,
+ 5, 2, 2, 2, 62, 67, 5, 6, 12, 7, 7, 19, 20, 14, 19, 24,
+ 29, 66, 4, 76, 66, 35, 71, 94, 68, 8, 67, 81, 85, 76, 86, 95,
+ 103, 105, 71, 67, 15, 70, 76, 68, 65, 2, 80, 74, 68, 68, 88, 75,
+ 82, 0, 10, 88, 74, 5, 79, 1, 76, 68, 20, 79, 83, 65, 4, 89,
+ 87, 121, 10, 16, 25, 65, 72, 67, 81, 81, 81, 94, 93, 92, 110, 102,
+ 92, 111, 114, 118, 126, 110, 107, 99, 80, 87, 6, 23, 3, 23, 43, 81,
+ 84, 89, 87, 110, 100, 94, 118, 98, 109, 104, 122, 116, 113, 113, 84, 81,
+ 116, 87, 89, 101, 113, 107, 108, 109, 104, 113, 111, 114, 119, 126, 119, 76,
+ 84, 101, 67, 13, 9, 20, 21, 25, 47, 30, 41, 41, 61, 50, 45, 62,
+ 60, 38, 69, 90, 110, 121, 126, 126, 126, 126, 15, 49, 42, 42, 30, 43,
+ 21, 16, 21, 11, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, 21,
+ 39, 4, 65, 13, 85, 110, 126, 126, 126, 126, 126, 126, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, 64, 51, 14,
+ 59, 72, 25, 32, 65, 85, 3, 102, 119, 70, 88, 126, 126, 126, 62, 21,
+ 70, 25, 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5,
+ 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 18, 65, 86, 20, 51, 39, 62, 62, 31, 29,
+ 21, 37, 17, 10, 25, 70, 73, 74, 68, 27, 2, 10, 65, 64, 64, 1,
+ 8, 69, 78, 77, 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5,
+ 10, 3, 68, 66, 6, 67, 0, 69, 68, 76, 64, 68, 80, 3, 68, 75,
+ 1, 12, 66, 85, 76, 78, 80, 4, 68, 9, 7, 7, 40, 19, 5, 69,
+ 13, 69, 81, 0, 107, 73, 64, 90, 71, 88, 4, 64, 81, 19, 8, 4,
+ 100, 4, 85, 74, 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 78, 76, 68,
+ 91, 98, 80, 83, 84, 88, 89, 98, 103, 97, 97, 107, 113, 106, 109, 126,
+ 119, 122, 70, 74, 94, 79, 87, 90, 96, 104, 108, 98, 102, 96, 86, 91,
+ 90, 82, 80, 6, 26, 18, 11, 9, 11, 6, 1, 6, 14, 14, 30, 21,
+ 15, 8, 23, 14, 17, 10, 36, 2, 44, 31, 22, 14, 27, 5, 64, 64,
+ 4, 70, 47, 17, 0, 1, 12, 1, 71, 0, 5, 34, 19, 3, 66, 17,
+ 5, 3, 3, 3, 62, 66, 6, 7, 14, 9, 8, 21, 22, 16, 21, 26,
+ 31, 65, 5, 75, 65, 37, 70, 94, 67, 9, 66, 81, 85, 76, 86, 95,
+ 104, 106, 71, 67, 16, 70, 76, 68, 65, 2, 80, 74, 68, 68, 88, 75,
+ 82, 1, 11, 88, 74, 5, 79, 1, 76, 68, 21, 79, 84, 65, 4, 89,
+ 87, 122, 10, 16, 25, 66, 73, 68, 83, 83, 83, 96, 95, 94, 112, 104,
+ 93, 113, 117, 121, 126, 112, 109, 100, 81, 88, 6, 24, 4, 25, 46, 82,
+ 85, 90, 88, 112, 101, 95, 120, 99, 110, 105, 123, 117, 114, 113, 84, 81,
+ 117, 88, 90, 102, 114, 108, 109, 110, 105, 114, 112, 115, 120, 126, 119, 76,
+ 84, 101, 66, 14, 10, 21, 22, 26, 49, 31, 42, 42, 62, 52, 46, 62,
+ 62, 38, 70, 92, 112, 123, 126, 126, 126, 126, 16, 50, 43, 43, 31, 44,
+ 22, 17, 22, 12, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, 22,
+ 40, 4, 65, 12, 87, 112, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, 65, 51, 14,
+ 61, 72, 26, 33, 65, 86, 3, 103, 120, 71, 90, 126, 126, 126, 62, 22,
+ 70, 26, 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 18, 65, 86, 22, 53, 41, 62, 62, 32, 30,
+ 22, 38, 18, 11, 27, 70, 73, 74, 67, 27, 2, 10, 64, 64, 0, 1,
+ 9, 69, 78, 77, 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5,
+ 10, 3, 68, 66, 6, 67, 0, 69, 69, 76, 64, 69, 81, 2, 69, 76,
+ 2, 12, 66, 86, 77, 78, 81, 4, 68, 9, 7, 7, 41, 19, 5, 69,
+ 13, 69, 82, 0, 108, 73, 64, 91, 71, 89, 4, 64, 82, 19, 8, 4,
+ 101, 4, 86, 74, 3, 97, 1, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 79, 79, 78, 78, 76, 68,
+ 92, 99, 80, 85, 86, 90, 91, 100, 105, 99, 99, 109, 115, 108, 111, 126,
+ 121, 123, 70, 74, 95, 80, 88, 91, 97, 106, 109, 99, 103, 97, 87, 92,
+ 90, 82, 79, 6, 26, 18, 11, 9, 11, 6, 1, 6, 15, 15, 30, 21,
+ 15, 8, 23, 14, 18, 11, 38, 2, 44, 31, 22, 14, 27, 5, 64, 64,
+ 5, 70, 47, 17, 0, 1, 12, 1, 71, 1, 5, 33, 18, 2, 67, 17,
+ 5, 3, 3, 3, 62, 65, 7, 8, 15, 10, 9, 22, 23, 17, 22, 27,
+ 33, 64, 6, 75, 64, 38, 70, 95, 67, 10, 66, 81, 86, 76, 87, 96,
+ 105, 107, 72, 67, 16, 70, 77, 69, 65, 2, 81, 75, 68, 68, 89, 75,
+ 82, 1, 11, 88, 75, 4, 80, 1, 77, 69, 21, 80, 85, 65, 4, 90,
+ 88, 124, 9, 15, 24, 67, 74, 69, 85, 85, 85, 98, 98, 97, 115, 106,
+ 94, 116, 120, 124, 126, 115, 111, 102, 82, 89, 6, 25, 4, 26, 48, 84,
+ 87, 92, 90, 114, 103, 97, 122, 100, 112, 106, 125, 118, 115, 114, 85, 81,
+ 118, 89, 91, 104, 116, 110, 111, 111, 107, 116, 113, 116, 121, 126, 120, 77,
+ 85, 102, 66, 14, 10, 22, 22, 27, 50, 32, 43, 43, 62, 53, 47, 62,
+ 62, 37, 72, 94, 114, 126, 126, 126, 126, 126, 16, 50, 43, 43, 31, 45,
+ 22, 17, 22, 12, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, 22,
+ 41, 4, 65, 11, 89, 114, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, 66, 51, 14,
+ 62, 72, 27, 34, 65, 87, 3, 104, 121, 71, 92, 126, 126, 126, 62, 23,
+ 70, 27, 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 18, 65, 86, 24, 55, 42, 62, 62, 33, 31,
+ 24, 39, 19, 12, 29, 69, 73, 73, 66, 27, 2, 10, 64, 64, 0, 2,
+ 11, 69, 79, 78, 88, 19, 68, 7, 1, 78, 5, 71, 9, 3, 65, 5,
+ 10, 2, 68, 66, 6, 67, 0, 69, 70, 76, 64, 70, 82, 1, 70, 77,
+ 2, 13, 66, 87, 77, 77, 81, 4, 68, 9, 7, 7, 42, 19, 5, 69,
+ 14, 69, 83, 0, 109, 73, 64, 91, 72, 90, 4, 64, 83, 19, 8, 4,
+ 103, 4, 87, 74, 3, 97, 0, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 65, 9, 0, 64, 75, 70, 76, 75, 71, 74, 80, 80, 78, 78, 77, 68,
+ 93, 101, 80, 86, 88, 92, 93, 102, 107, 101, 101, 111, 117, 109, 112, 126,
+ 123, 124, 70, 74, 95, 81, 89, 92, 99, 107, 111, 100, 104, 98, 87, 92,
+ 90, 82, 79, 7, 26, 18, 11, 9, 11, 6, 1, 7, 16, 15, 30, 21,
+ 15, 8, 24, 15, 19, 12, 40, 2, 44, 31, 22, 14, 28, 5, 64, 64,
+ 5, 70, 47, 17, 64, 1, 12, 1, 71, 2, 5, 33, 18, 1, 68, 17,
+ 5, 3, 4, 4, 62, 64, 8, 8, 16, 11, 10, 24, 24, 18, 23, 29,
+ 34, 64, 7, 75, 64, 40, 70, 95, 67, 10, 66, 82, 86, 76, 88, 97,
+ 106, 108, 72, 68, 16, 71, 77, 69, 66, 2, 82, 75, 69, 68, 90, 75,
+ 83, 1, 11, 89, 75, 4, 81, 1, 78, 69, 21, 81, 86, 66, 3, 91,
+ 88, 125, 8, 14, 24, 68, 75, 71, 87, 87, 87, 101, 100, 99, 118, 109,
+ 95, 119, 123, 126, 126, 118, 114, 104, 83, 90, 6, 26, 4, 27, 50, 86,
+ 89, 94, 92, 116, 105, 98, 124, 102, 113, 107, 126, 120, 116, 115, 85, 82,
+ 119, 90, 93, 105, 118, 112, 113, 113, 108, 118, 115, 117, 123, 126, 121, 78,
+ 86, 103, 66, 15, 10, 22, 23, 27, 51, 33, 44, 44, 62, 54, 48, 62,
+ 62, 37, 73, 96, 117, 126, 126, 126, 126, 126, 17, 51, 44, 44, 31, 46,
+ 23, 17, 23, 13, 69, 2, 18, 5, 38, 48, 2, 12, 21, 25, 6, 23,
+ 42, 4, 65, 10, 91, 117, 126, 126, 126, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 38, 62, 62, 54, 22,
+ 118, 65, 71, 79, 11, 13, 70, 9, 29, 41, 62, 61, 27, 69, 126, 101,
+ 76, 71, 79, 11, 69, 90, 11, 20, 69, 82, 96, 4, 75, 87, 100, 7,
+ 74, 85, 4, 81, 86, 95, 66, 77, 70, 86, 72, 2, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 48, 12, 80, 126, 91, 96, 81, 98, 102, 97,
+ 119, 99, 110, 102, 126, 80, 89, 94, 92, 24, 65, 84, 126, 73, 104, 91,
+ 126, 8, 7, 8, 2, 10, 68, 74, 88, 103, 91, 89, 92, 76, 87, 110,
+ 105, 78, 112, 99, 126, 126, 126, 126, 66, 78, 71, 72, 4, 8, 70, 75,
+ 89, 119, 75, 43, 41, 126, 9, 2, 5, 3, 2, 67, 84, 74, 65, 11,
+ 6, 2, 69, 70, 8, 71, 5, 2, 22, 38, 31, 20, 16, 19, 12, 17,
+ 25, 66, 25, 21, 29, 89, 18, 35, 32, 62, 62, 48, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 53, 62, 62, 62, 62, 62, 62, 62, 56, 62,
+ 62, 62, 27, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 53, 45,
+ 38, 22, 75, 72, 77, 28, 32, 28, 33, 18, 21, 18, 37, 9, 66, 7,
+ 73, 67, 116, 112, 71, 2, 10, 66, 77, 80, 84, 87, 126, 101, 24, 10,
+ 2, 75, 77, 91, 107, 111, 122, 76, 19, 11, 6, 5, 72, 69, 69, 74,
+ 86, 66, 29, 31, 32, 11, 8, 67, 73, 89, 11, 59, 55, 55, 44, 26,
+ 2, 73, 70, 78, 62, 126, 124, 110, 126, 124, 105, 121, 117, 102, 117, 116,
+ 122, 95, 100, 95, 111, 114, 89, 80, 82, 85, 81, 72, 64, 67, 7, 69,
+ 69, 69, 69, 67, 77, 64, 2, 67, 64, 6, 65, 66, 1, 12, 66, 71,
+ 75, 70, 72, 3, 26, 16, 28, 26, 22, 22, 15, 22, 22, 4, 13, 23,
+ 66, 13, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 54, 62, 62, 62, 62, 62, 62, 62, 62, 62, 49, 37, 26, 8, 65, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 43, 33, 19, 15, 14,
+ 18, 41, 41, 42, 43, 35, 39, 29, 21, 24, 13, 70, 9, 71, 83, 31,
+ 14, 9, 85, 81, 77, 81, 80, 73, 74, 83, 71, 67, 2, 66, 66, 4,
+ 4, 62, 62, 62, 62, 62, 60, 53, 36, 6, 71, 39, 27, 21, 11, 6,
+ 0, 65, 67, 82, 81, 76, 72, 78, 72, 68, 70, 76, 66, 1, 6, 2,
+ 3, 9, 5, 62, 62, 62, 62, 62, 60, 53, 36, 6, 75, 65, 4, 67,
+ 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 37, 61, 62, 55, 22,
+ 116, 65, 70, 78, 11, 13, 69, 9, 28, 40, 61, 58, 25, 70, 124, 100,
+ 75, 70, 78, 11, 69, 89, 11, 20, 68, 81, 95, 4, 75, 86, 99, 7,
+ 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 48, 12, 80, 124, 89, 94, 79, 95, 100, 95,
+ 117, 97, 108, 100, 124, 80, 88, 93, 91, 24, 65, 83, 124, 72, 103, 90,
+ 125, 8, 7, 8, 2, 11, 68, 73, 87, 102, 90, 88, 91, 75, 86, 108,
+ 103, 77, 110, 97, 122, 122, 123, 124, 65, 77, 70, 71, 4, 9, 69, 74,
+ 88, 116, 74, 41, 40, 124, 9, 3, 5, 4, 3, 66, 82, 73, 64, 11,
+ 6, 2, 68, 69, 7, 70, 5, 2, 22, 37, 31, 20, 16, 19, 12, 17,
+ 24, 65, 25, 21, 29, 89, 18, 35, 32, 62, 62, 47, 62, 62, 62, 61,
+ 62, 62, 62, 62, 62, 62, 52, 62, 62, 62, 62, 62, 62, 62, 54, 62,
+ 60, 62, 26, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 52, 44,
+ 37, 21, 75, 72, 77, 28, 31, 27, 32, 17, 20, 17, 36, 8, 66, 6,
+ 73, 67, 115, 110, 70, 3, 10, 65, 76, 79, 83, 86, 124, 99, 25, 11,
+ 3, 74, 76, 89, 105, 109, 120, 75, 20, 12, 7, 6, 71, 68, 68, 73,
+ 85, 66, 30, 31, 32, 11, 9, 66, 73, 88, 11, 59, 55, 54, 43, 26,
+ 3, 72, 69, 77, 62, 124, 122, 108, 124, 122, 103, 119, 115, 100, 115, 114,
+ 119, 94, 99, 94, 109, 112, 88, 79, 81, 84, 80, 71, 64, 67, 7, 69,
+ 69, 69, 68, 66, 76, 0, 2, 66, 0, 6, 64, 65, 1, 12, 65, 70,
+ 74, 69, 71, 3, 25, 16, 27, 26, 22, 22, 15, 22, 22, 4, 13, 22,
+ 66, 12, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 52, 62, 62, 62, 62, 62, 62, 62, 61, 62, 48, 36, 25, 8, 65, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 42, 32, 18, 15, 14,
+ 17, 40, 40, 41, 41, 34, 38, 28, 20, 23, 12, 70, 8, 71, 83, 30,
+ 13, 8, 84, 80, 76, 80, 78, 71, 73, 82, 70, 66, 3, 65, 65, 4,
+ 4, 62, 62, 62, 62, 60, 56, 49, 32, 4, 70, 39, 28, 22, 12, 7,
+ 1, 64, 66, 81, 80, 75, 71, 77, 71, 67, 69, 75, 65, 2, 6, 3,
+ 4, 9, 5, 62, 62, 62, 62, 60, 56, 49, 32, 4, 75, 65, 4, 66,
+ 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 36, 59, 61, 55, 22,
+ 114, 65, 70, 77, 11, 12, 69, 8, 26, 39, 58, 54, 22, 72, 121, 99,
+ 75, 70, 77, 11, 69, 88, 11, 19, 68, 81, 94, 4, 75, 86, 99, 7,
+ 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 47, 12, 80, 122, 88, 93, 77, 93, 99, 94,
+ 115, 96, 107, 99, 122, 80, 88, 93, 91, 24, 65, 82, 122, 72, 102, 89,
+ 123, 8, 7, 8, 1, 11, 68, 73, 86, 101, 89, 87, 90, 75, 85, 107,
+ 102, 76, 109, 96, 117, 118, 120, 121, 65, 77, 70, 71, 4, 9, 69, 74,
+ 88, 114, 74, 39, 38, 121, 9, 3, 5, 4, 3, 66, 80, 72, 64, 11,
+ 6, 2, 67, 68, 6, 70, 5, 2, 21, 36, 30, 20, 15, 19, 12, 17,
+ 23, 65, 24, 20, 28, 89, 18, 34, 31, 62, 62, 46, 60, 62, 62, 59,
+ 62, 62, 62, 62, 62, 62, 50, 62, 62, 62, 62, 62, 62, 62, 52, 62,
+ 58, 62, 24, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 50, 42,
+ 35, 19, 75, 72, 78, 27, 30, 26, 31, 16, 19, 16, 34, 7, 66, 5,
+ 74, 68, 114, 109, 69, 3, 10, 65, 75, 78, 82, 85, 122, 98, 25, 11,
+ 3, 73, 75, 88, 103, 107, 118, 74, 21, 13, 8, 7, 70, 68, 68, 73,
+ 84, 66, 31, 31, 31, 11, 9, 66, 73, 88, 11, 59, 54, 53, 42, 26,
+ 3, 72, 69, 77, 62, 123, 121, 107, 122, 120, 102, 117, 113, 99, 113, 112,
+ 117, 93, 98, 94, 108, 110, 88, 79, 81, 83, 80, 71, 64, 67, 6, 69,
+ 69, 69, 68, 66, 75, 0, 2, 66, 0, 6, 64, 65, 1, 11, 65, 70,
+ 74, 69, 70, 2, 24, 16, 26, 25, 21, 21, 15, 21, 21, 4, 13, 21,
+ 66, 11, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 50, 62, 62, 62, 62, 62, 62, 62, 59, 59, 46, 34, 24, 7, 66, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 40, 30, 16, 14, 13,
+ 15, 39, 39, 39, 39, 32, 36, 26, 19, 21, 11, 71, 7, 72, 84, 28,
+ 12, 7, 84, 80, 75, 80, 77, 70, 73, 81, 69, 65, 3, 65, 64, 4,
+ 4, 62, 62, 62, 62, 57, 52, 45, 28, 1, 70, 39, 28, 22, 12, 8,
+ 1, 64, 66, 81, 80, 75, 71, 77, 70, 66, 69, 75, 65, 2, 6, 3,
+ 5, 9, 5, 62, 62, 62, 62, 57, 52, 45, 28, 1, 75, 65, 4, 66,
+ 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 34, 57, 60, 55, 22,
+ 112, 65, 69, 76, 11, 12, 69, 8, 25, 38, 56, 51, 20, 73, 118, 98,
+ 75, 69, 76, 11, 70, 87, 11, 19, 68, 81, 94, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 84, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 46, 11, 80, 119, 87, 92, 76, 91, 97, 92,
+ 113, 94, 106, 98, 120, 80, 88, 92, 91, 24, 65, 81, 120, 72, 101, 89,
+ 121, 8, 6, 7, 1, 11, 68, 72, 86, 100, 88, 87, 89, 74, 84, 105,
+ 100, 76, 108, 95, 112, 113, 117, 118, 65, 77, 70, 70, 4, 9, 68, 73,
+ 87, 112, 74, 37, 36, 118, 9, 3, 5, 4, 3, 65, 79, 71, 64, 11,
+ 6, 2, 67, 67, 5, 70, 5, 1, 21, 35, 30, 20, 15, 19, 12, 17,
+ 22, 65, 23, 19, 28, 89, 18, 34, 31, 62, 62, 45, 58, 62, 62, 57,
+ 62, 62, 62, 62, 62, 61, 48, 62, 62, 62, 62, 62, 62, 60, 50, 62,
+ 56, 62, 22, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 48, 40,
+ 34, 17, 75, 72, 78, 26, 29, 25, 30, 15, 18, 15, 32, 6, 67, 4,
+ 75, 68, 114, 107, 68, 4, 10, 65, 74, 78, 82, 85, 120, 97, 25, 11,
+ 4, 72, 74, 87, 102, 106, 116, 73, 21, 13, 8, 7, 69, 67, 68, 73,
+ 84, 66, 31, 31, 30, 11, 9, 66, 73, 87, 11, 58, 54, 52, 41, 26,
+ 3, 72, 69, 77, 62, 122, 119, 106, 121, 119, 101, 115, 111, 98, 112, 110,
+ 115, 93, 97, 93, 107, 108, 87, 79, 81, 83, 79, 71, 64, 67, 6, 69,
+ 69, 70, 67, 65, 74, 0, 2, 65, 0, 6, 64, 65, 1, 11, 65, 70,
+ 74, 69, 70, 1, 23, 16, 25, 24, 20, 21, 15, 20, 20, 4, 13, 20,
+ 66, 10, 62, 62, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 48, 62, 62, 62, 62, 62, 62, 62, 57, 57, 44, 32, 22, 6, 67, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 60, 38, 28, 15, 13, 12,
+ 14, 37, 37, 37, 37, 31, 34, 24, 18, 20, 10, 72, 6, 73, 85, 27,
+ 11, 6, 84, 79, 75, 79, 76, 69, 73, 81, 69, 65, 3, 64, 0, 4,
+ 4, 62, 62, 62, 59, 54, 48, 41, 24, 65, 70, 39, 28, 22, 12, 8,
+ 2, 64, 66, 80, 80, 75, 70, 76, 69, 65, 69, 74, 65, 2, 6, 3,
+ 5, 9, 5, 62, 62, 62, 59, 54, 48, 41, 24, 65, 75, 65, 4, 65,
+ 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 33, 55, 59, 55, 21,
+ 110, 65, 69, 75, 10, 11, 69, 7, 23, 37, 53, 47, 17, 75, 115, 97,
+ 75, 69, 75, 10, 70, 86, 11, 18, 68, 80, 93, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 84, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 45, 11, 80, 117, 86, 91, 74, 89, 96, 91,
+ 112, 93, 104, 97, 118, 80, 87, 92, 91, 24, 65, 80, 118, 72, 101, 88,
+ 119, 8, 6, 7, 0, 11, 68, 72, 85, 99, 87, 86, 88, 74, 84, 104,
+ 99, 75, 107, 94, 107, 109, 114, 115, 65, 76, 70, 70, 4, 9, 68, 73,
+ 87, 110, 74, 35, 34, 116, 9, 4, 5, 4, 3, 65, 77, 70, 0, 10,
+ 6, 2, 66, 67, 4, 70, 5, 1, 20, 34, 29, 19, 14, 19, 12, 17,
+ 21, 65, 22, 18, 27, 89, 17, 33, 30, 62, 62, 44, 56, 62, 62, 55,
+ 62, 62, 62, 62, 62, 59, 46, 59, 62, 62, 62, 62, 62, 57, 48, 62,
+ 54, 62, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 55, 46, 38,
+ 32, 15, 75, 72, 79, 25, 28, 24, 28, 14, 16, 14, 31, 5, 67, 3,
+ 75, 69, 113, 106, 67, 4, 10, 64, 74, 77, 81, 84, 118, 95, 25, 12,
+ 4, 72, 73, 86, 100, 104, 115, 73, 22, 14, 9, 8, 68, 67, 68, 72,
+ 83, 66, 32, 31, 30, 10, 9, 66, 73, 87, 11, 58, 53, 51, 40, 26,
+ 3, 71, 69, 77, 62, 120, 118, 105, 119, 117, 100, 114, 110, 97, 110, 109,
+ 113, 92, 96, 93, 106, 107, 87, 79, 81, 82, 79, 71, 65, 67, 5, 69,
+ 69, 70, 67, 65, 73, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70,
+ 74, 69, 69, 0, 22, 16, 24, 24, 19, 20, 15, 19, 19, 4, 13, 19,
+ 66, 9, 62, 62, 60, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 46, 62, 62, 62, 62, 62, 62, 62, 54, 54, 42, 30, 21, 5, 67, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 57, 36, 26, 13, 12, 12,
+ 12, 36, 36, 36, 35, 29, 32, 23, 17, 18, 9, 73, 4, 74, 85, 25,
+ 9, 4, 83, 79, 74, 79, 75, 68, 73, 80, 68, 64, 3, 64, 1, 4,
+ 4, 62, 62, 62, 56, 50, 44, 36, 20, 68, 69, 39, 28, 22, 12, 9,
+ 2, 64, 66, 80, 80, 75, 70, 76, 69, 64, 69, 74, 64, 3, 6, 3,
+ 6, 9, 5, 62, 62, 62, 56, 50, 44, 36, 20, 68, 75, 65, 4, 65,
+ 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 32, 53, 58, 55, 21,
+ 108, 65, 69, 74, 10, 11, 69, 6, 21, 36, 51, 44, 15, 77, 112, 96,
+ 74, 69, 74, 10, 70, 85, 11, 18, 68, 80, 92, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 83, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 44, 10, 80, 114, 85, 90, 72, 87, 94, 89,
+ 110, 91, 103, 96, 115, 80, 87, 91, 90, 24, 65, 79, 116, 72, 100, 88,
+ 117, 8, 5, 6, 0, 11, 68, 71, 85, 98, 86, 86, 87, 73, 83, 102,
+ 97, 74, 105, 93, 102, 105, 111, 112, 64, 76, 69, 69, 4, 9, 67, 73,
+ 86, 108, 74, 33, 32, 113, 9, 4, 5, 4, 3, 64, 76, 69, 0, 10,
+ 6, 2, 66, 66, 3, 69, 5, 0, 20, 33, 29, 19, 14, 19, 12, 17,
+ 20, 64, 21, 18, 27, 89, 17, 32, 29, 62, 62, 43, 55, 62, 62, 53,
+ 62, 62, 62, 62, 61, 57, 44, 57, 62, 60, 62, 62, 62, 55, 46, 62,
+ 52, 62, 19, 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 53, 44, 37,
+ 30, 13, 75, 72, 79, 24, 27, 23, 27, 13, 15, 13, 29, 4, 68, 2,
+ 76, 70, 112, 104, 66, 5, 10, 64, 73, 77, 81, 83, 116, 94, 25, 12,
+ 5, 71, 72, 85, 99, 103, 113, 72, 23, 15, 10, 8, 67, 66, 67, 72,
+ 83, 66, 32, 31, 29, 10, 9, 66, 73, 86, 11, 57, 52, 50, 39, 26,
+ 3, 71, 69, 76, 62, 119, 116, 103, 117, 116, 99, 112, 108, 96, 108, 107,
+ 111, 91, 95, 92, 105, 105, 87, 79, 80, 82, 78, 71, 65, 67, 5, 69,
+ 69, 71, 66, 65, 72, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70,
+ 74, 69, 69, 64, 21, 16, 23, 23, 19, 19, 15, 19, 18, 4, 13, 18,
+ 66, 8, 62, 62, 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 44, 62, 62, 62, 62, 62, 62, 61, 52, 52, 40, 29, 19, 5, 68, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 61, 55, 54, 34, 24, 12, 12, 11,
+ 10, 35, 34, 34, 33, 27, 30, 21, 16, 17, 8, 73, 3, 75, 86, 24,
+ 8, 3, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, 0, 2, 4,
+ 4, 62, 62, 59, 53, 47, 40, 32, 16, 71, 69, 39, 28, 22, 12, 9,
+ 2, 0, 65, 79, 80, 75, 69, 76, 68, 0, 69, 74, 64, 3, 6, 4,
+ 6, 9, 5, 62, 62, 59, 53, 47, 40, 32, 16, 71, 75, 65, 4, 65,
+ 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 30, 51, 57, 55, 21,
+ 107, 65, 68, 74, 10, 10, 68, 6, 20, 34, 48, 40, 12, 78, 110, 95,
+ 74, 68, 74, 10, 71, 85, 11, 17, 68, 80, 92, 4, 75, 85, 98, 7,
+ 72, 82, 4, 79, 83, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 44, 10, 80, 112, 84, 89, 71, 84, 93, 88,
+ 108, 90, 102, 95, 113, 80, 87, 91, 90, 24, 65, 78, 113, 72, 99, 87,
+ 115, 7, 5, 6, 64, 12, 68, 71, 84, 98, 86, 85, 86, 73, 82, 101,
+ 96, 74, 104, 92, 97, 100, 108, 109, 64, 76, 69, 69, 4, 9, 67, 72,
+ 86, 106, 73, 31, 30, 110, 9, 4, 5, 4, 4, 64, 74, 68, 0, 10,
+ 6, 2, 65, 65, 2, 69, 5, 0, 19, 32, 28, 19, 13, 19, 12, 17,
+ 18, 64, 20, 17, 26, 89, 17, 32, 29, 62, 62, 42, 53, 62, 62, 51,
+ 62, 62, 62, 62, 57, 55, 43, 55, 62, 58, 62, 62, 62, 52, 44, 62,
+ 50, 62, 17, 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, 42, 35,
+ 29, 12, 75, 72, 80, 23, 26, 22, 26, 12, 14, 12, 27, 3, 68, 1,
+ 77, 70, 112, 103, 65, 5, 10, 64, 72, 76, 80, 83, 114, 93, 26, 12,
+ 5, 70, 71, 84, 97, 101, 111, 71, 23, 15, 10, 9, 66, 66, 67, 72,
+ 82, 66, 33, 31, 28, 10, 9, 66, 73, 86, 10, 57, 52, 49, 38, 25,
+ 3, 71, 69, 76, 62, 118, 115, 102, 116, 114, 98, 110, 106, 95, 107, 105,
+ 109, 91, 94, 92, 104, 103, 86, 79, 80, 81, 78, 71, 65, 67, 4, 69,
+ 69, 71, 66, 64, 71, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70,
+ 74, 69, 68, 65, 20, 16, 22, 22, 18, 19, 15, 18, 18, 4, 12, 16,
+ 67, 7, 62, 62, 58, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 42, 62, 62, 62, 62, 62, 62, 58, 50, 49, 38, 27, 18, 4, 69, 62,
+ 62, 62, 62, 62, 62, 62, 62, 61, 58, 52, 51, 32, 23, 10, 11, 10,
+ 9, 33, 33, 32, 31, 26, 28, 19, 15, 15, 7, 74, 2, 76, 87, 22,
+ 7, 2, 83, 78, 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, 3, 4,
+ 4, 62, 62, 57, 50, 44, 36, 28, 12, 74, 69, 39, 28, 22, 12, 10,
+ 3, 0, 65, 79, 79, 74, 69, 75, 67, 1, 68, 73, 64, 3, 6, 4,
+ 7, 9, 5, 62, 62, 57, 50, 44, 36, 28, 12, 74, 75, 65, 4, 64,
+ 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 29, 49, 56, 55, 21,
+ 105, 65, 68, 73, 9, 10, 68, 5, 18, 33, 46, 37, 10, 80, 107, 94,
+ 74, 68, 73, 9, 71, 84, 11, 17, 68, 79, 91, 4, 75, 85, 98, 7,
+ 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 43, 9, 80, 109, 83, 88, 69, 82, 91, 86,
+ 107, 88, 100, 94, 111, 80, 86, 90, 90, 24, 65, 77, 111, 72, 98, 87,
+ 113, 7, 4, 5, 64, 12, 68, 70, 84, 97, 85, 85, 85, 72, 81, 99,
+ 94, 73, 103, 91, 92, 96, 105, 106, 64, 75, 69, 68, 4, 9, 66, 72,
+ 85, 104, 73, 29, 28, 107, 9, 5, 5, 4, 4, 0, 73, 67, 1, 9,
+ 6, 2, 65, 65, 1, 69, 5, 64, 19, 31, 28, 18, 13, 19, 12, 17,
+ 17, 64, 19, 16, 26, 89, 17, 31, 28, 60, 62, 41, 51, 62, 62, 49,
+ 62, 61, 62, 62, 54, 53, 41, 52, 62, 55, 62, 62, 62, 49, 42, 62,
+ 48, 62, 16, 62, 62, 62, 62, 62, 62, 62, 62, 57, 53, 48, 40, 33,
+ 27, 10, 75, 72, 80, 22, 25, 21, 24, 11, 13, 11, 26, 2, 69, 0,
+ 77, 71, 111, 101, 64, 6, 10, 0, 72, 76, 80, 82, 112, 91, 26, 13,
+ 6, 70, 70, 83, 96, 100, 109, 71, 24, 16, 11, 9, 65, 65, 67, 71,
+ 82, 66, 33, 31, 28, 9, 9, 66, 73, 85, 10, 56, 51, 48, 37, 25,
+ 3, 70, 69, 76, 62, 116, 113, 101, 114, 113, 97, 109, 105, 94, 105, 104,
+ 107, 90, 93, 91, 103, 101, 86, 79, 80, 81, 77, 71, 66, 67, 4, 69,
+ 69, 72, 65, 64, 70, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70,
+ 74, 69, 68, 66, 19, 16, 21, 22, 17, 18, 15, 17, 17, 4, 12, 15,
+ 67, 6, 61, 62, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 40, 62, 62, 62, 62, 62, 62, 56, 48, 47, 36, 25, 16, 3, 69, 62,
+ 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, 48, 30, 21, 9, 10, 10,
+ 7, 32, 31, 31, 29, 24, 26, 18, 14, 14, 6, 75, 0, 77, 87, 21,
+ 5, 0, 82, 78, 72, 77, 72, 65, 72, 78, 67, 0, 3, 1, 4, 4,
+ 4, 62, 62, 54, 47, 40, 32, 24, 8, 77, 68, 39, 28, 22, 12, 10,
+ 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, 0, 4, 6, 4,
+ 7, 9, 5, 62, 62, 54, 47, 40, 32, 24, 8, 77, 75, 65, 4, 64,
+ 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 27, 46, 55, 55, 20,
+ 103, 66, 68, 72, 9, 9, 68, 4, 16, 32, 43, 33, 7, 82, 104, 93,
+ 74, 68, 72, 9, 72, 83, 11, 16, 68, 79, 91, 3, 76, 85, 98, 7,
+ 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 42, 9, 81, 107, 82, 87, 68, 80, 90, 85,
+ 105, 87, 99, 93, 109, 80, 86, 90, 90, 24, 65, 76, 109, 72, 98, 86,
+ 111, 7, 4, 5, 65, 12, 68, 70, 83, 96, 84, 84, 85, 72, 81, 98,
+ 93, 73, 102, 90, 88, 92, 102, 104, 64, 75, 69, 68, 3, 9, 66, 72,
+ 85, 102, 73, 27, 26, 105, 9, 5, 5, 4, 4, 0, 71, 67, 1, 9,
+ 5, 2, 64, 64, 64, 69, 5, 64, 18, 29, 27, 18, 12, 19, 12, 16,
+ 16, 64, 18, 15, 25, 89, 16, 30, 27, 58, 62, 39, 49, 62, 62, 46,
+ 62, 59, 62, 62, 50, 51, 39, 50, 62, 53, 62, 62, 62, 46, 40, 62,
+ 46, 62, 14, 62, 62, 62, 62, 62, 62, 62, 60, 55, 51, 46, 38, 31,
+ 25, 8, 75, 73, 81, 21, 23, 20, 23, 10, 11, 9, 24, 1, 69, 64,
+ 78, 72, 111, 100, 0, 6, 10, 0, 71, 75, 79, 82, 110, 90, 26, 13,
+ 6, 69, 69, 82, 94, 98, 108, 70, 24, 16, 11, 10, 64, 65, 67, 71,
+ 81, 67, 34, 31, 27, 9, 9, 66, 73, 85, 10, 56, 50, 47, 36, 25,
+ 3, 70, 69, 76, 62, 115, 112, 100, 113, 111, 96, 107, 103, 93, 104, 102,
+ 105, 90, 93, 91, 102, 100, 86, 79, 80, 80, 77, 71, 66, 67, 3, 69,
+ 69, 72, 65, 64, 69, 0, 1, 64, 1, 5, 0, 64, 1, 8, 65, 70,
+ 74, 69, 67, 67, 18, 16, 19, 21, 16, 17, 14, 16, 16, 4, 12, 14,
+ 67, 4, 60, 60, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60,
+ 38, 62, 62, 62, 62, 62, 62, 53, 45, 44, 34, 23, 15, 2, 70, 62,
+ 62, 62, 62, 62, 62, 62, 62, 56, 53, 47, 45, 28, 19, 7, 9, 9,
+ 5, 30, 30, 29, 27, 22, 24, 16, 12, 12, 4, 76, 64, 78, 88, 19,
+ 4, 64, 82, 78, 72, 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4,
+ 3, 62, 60, 51, 44, 37, 28, 19, 3, 80, 68, 39, 28, 22, 12, 11,
+ 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, 0, 4, 6, 4,
+ 8, 9, 4, 62, 60, 51, 44, 37, 28, 19, 3, 80, 75, 66, 3, 64,
+ 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 26, 44, 54, 56, 20, 101,
+ 66, 67, 71, 9, 8, 68, 4, 15, 31, 41, 29, 4, 83, 101, 92, 73, 67,
+ 71, 9, 72, 82, 11, 16, 67, 79, 90, 3, 76, 85, 98, 7, 72, 81, 4,
+ 79, 82, 92, 65, 76, 70, 84, 69, 2, 22, 0, 0, 0, 77, 88, 97, 68,
+ 15, 0, 41, 9, 81, 105, 80, 86, 66, 78, 88, 84, 103, 85, 98, 91, 106,
+ 80, 86, 90, 89, 24, 65, 75, 107, 71, 97, 85, 109, 7, 4, 5, 65, 12,
+ 68, 70, 82, 95, 83, 83, 84, 71, 80, 97, 91, 72, 100, 89, 83, 87, 98,
+ 101, 0, 75, 68, 67, 3, 9, 66, 71, 84, 99, 73, 25, 25, 102, 9, 5,
+ 5, 4, 4, 1, 69, 66, 1, 9, 5, 2, 0, 0, 65, 68, 5, 64, 17,
+ 28, 26, 18, 11, 19, 12, 16, 15, 0, 17, 15, 24, 89, 16, 30, 27, 56,
+ 62, 38, 48, 62, 62, 44, 60, 57, 62, 62, 47, 49, 37, 48, 62, 51, 62,
+ 62, 62, 44, 38, 62, 44, 62, 12, 62, 62, 62, 62, 62, 62, 60, 58, 53,
+ 49, 44, 37, 30, 24, 6, 75, 73, 81, 21, 22, 19, 22, 9, 10, 8, 22,
+ 0, 69, 65, 79, 72, 110, 99, 1, 6, 10, 0, 70, 74, 78, 81, 107, 89,
+ 26, 13, 6, 68, 68, 81, 92, 96, 106, 69, 25, 17, 12, 11, 0, 65, 66,
+ 71, 80, 67, 35, 31, 26, 9, 10, 65, 73, 84, 10, 56, 50, 46, 35, 25,
+ 3, 70, 69, 75, 62, 114, 111, 98, 111, 109, 95, 105, 101, 92, 102, 100, 103,
+ 89, 92, 90, 101, 98, 85, 78, 79, 79, 76, 71, 66, 67, 2, 69, 69, 72,
+ 65, 0, 68, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, 69, 73, 69, 66,
+ 67, 17, 16, 18, 20, 16, 17, 14, 16, 15, 4, 12, 13, 67, 3, 59, 59,
+ 56, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 36, 62, 62, 62, 62,
+ 62, 62, 50, 43, 42, 33, 22, 14, 2, 71, 62, 62, 62, 62, 62, 62, 62,
+ 62, 54, 51, 45, 43, 26, 17, 5, 9, 8, 4, 29, 29, 27, 25, 21, 23,
+ 14, 11, 10, 3, 76, 65, 78, 89, 17, 3, 65, 82, 77, 71, 77, 70, 1,
+ 71, 77, 65, 2, 3, 2, 5, 4, 3, 62, 58, 49, 41, 34, 24, 15, 64,
+ 83, 68, 39, 28, 23, 13, 12, 4, 1, 64, 78, 79, 74, 68, 74, 65, 3,
+ 68, 72, 0, 4, 6, 5, 9, 9, 4, 62, 58, 49, 41, 34, 24, 15, 64,
+ 83, 75, 66, 3, 0, 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 25, 42, 53, 56, 20, 99,
+ 66, 67, 70, 8, 8, 68, 3, 13, 30, 38, 26, 2, 85, 98, 91, 73, 67,
+ 70, 8, 72, 81, 11, 15, 67, 78, 89, 3, 76, 85, 98, 7, 72, 81, 4,
+ 79, 81, 91, 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 77, 88, 97, 67,
+ 14, 0, 40, 8, 81, 102, 79, 85, 64, 76, 87, 82, 102, 84, 96, 90, 104,
+ 80, 85, 89, 89, 24, 65, 74, 105, 71, 96, 85, 107, 7, 3, 4, 66, 12,
+ 68, 69, 82, 94, 82, 83, 83, 71, 79, 95, 90, 71, 99, 88, 78, 83, 95,
+ 98, 0, 74, 68, 67, 3, 9, 65, 71, 84, 97, 73, 23, 23, 99, 9, 6,
+ 5, 4, 4, 1, 68, 65, 2, 8, 5, 2, 0, 0, 66, 68, 5, 65, 17,
+ 27, 26, 17, 11, 19, 12, 16, 14, 0, 16, 14, 24, 89, 16, 29, 26, 54,
+ 62, 37, 46, 62, 62, 42, 57, 55, 62, 62, 43, 47, 35, 45, 61, 48, 62,
+ 62, 62, 41, 36, 58, 42, 62, 11, 62, 62, 62, 62, 62, 60, 58, 56, 51,
+ 46, 42, 35, 28, 22, 4, 75, 73, 82, 20, 21, 18, 20, 8, 9, 7, 21,
+ 64, 70, 66, 79, 73, 109, 97, 2, 7, 10, 1, 70, 74, 78, 80, 105, 87,
+ 26, 14, 7, 68, 67, 80, 91, 95, 104, 69, 26, 18, 13, 11, 1, 64, 66,
+ 70, 80, 67, 35, 31, 26, 8, 10, 65, 73, 84, 10, 55, 49, 45, 34, 25,
+ 3, 69, 69, 75, 62, 112, 109, 97, 109, 108, 94, 104, 100, 91, 100, 99, 101,
+ 88, 91, 90, 100, 96, 85, 78, 79, 79, 76, 71, 67, 67, 2, 69, 69, 73,
+ 64, 0, 67, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, 69, 73, 69, 66,
+ 68, 16, 16, 17, 20, 15, 16, 14, 15, 14, 4, 12, 12, 67, 2, 58, 58,
+ 55, 59, 60, 62, 62, 62, 62, 62, 62, 62, 62, 55, 34, 62, 62, 62, 62,
+ 62, 62, 48, 41, 39, 31, 20, 12, 1, 71, 62, 62, 62, 62, 62, 62, 62,
+ 62, 52, 48, 43, 40, 24, 15, 4, 8, 8, 2, 28, 27, 26, 23, 19, 21,
+ 13, 10, 9, 2, 77, 67, 79, 89, 16, 1, 67, 81, 77, 70, 76, 69, 2,
+ 71, 76, 65, 2, 3, 2, 6, 4, 3, 62, 56, 46, 38, 30, 20, 11, 68,
+ 86, 67, 39, 28, 23, 13, 12, 4, 1, 64, 77, 79, 74, 67, 74, 64, 4,
+ 68, 72, 1, 5, 6, 5, 9, 9, 4, 62, 56, 46, 38, 30, 20, 11, 68,
+ 86, 75, 66, 3, 0, 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 23, 40, 52, 56, 20, 98, 66,
+ 66, 70, 8, 7, 67, 3, 12, 28, 36, 22, 64, 86, 96, 90, 73, 66, 70, 8,
+ 73, 81, 11, 15, 67, 78, 89, 3, 76, 84, 97, 7, 71, 80, 4, 78, 81, 91,
+ 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 40, 8,
+ 81, 100, 78, 84, 0, 73, 85, 81, 100, 82, 95, 89, 102, 80, 85, 89, 89, 24,
+ 65, 73, 102, 71, 95, 84, 105, 6, 3, 4, 66, 13, 68, 69, 81, 94, 82, 82,
+ 82, 70, 78, 94, 88, 71, 98, 87, 73, 78, 92, 95, 0, 74, 68, 66, 3, 9,
+ 65, 70, 83, 95, 72, 21, 21, 96, 9, 6, 5, 4, 5, 2, 66, 64, 2, 8,
+ 5, 2, 1, 1, 67, 68, 5, 65, 16, 26, 25, 17, 10, 19, 12, 16, 12, 0,
+ 15, 13, 23, 89, 16, 29, 26, 52, 62, 36, 44, 61, 62, 40, 55, 53, 62, 62,
+ 40, 45, 34, 43, 57, 46, 62, 62, 62, 38, 34, 55, 40, 62, 9, 62, 62, 62,
+ 62, 62, 58, 55, 54, 49, 44, 39, 33, 26, 21, 3, 75, 73, 82, 19, 20, 17,
+ 19, 7, 8, 6, 19, 65, 70, 67, 80, 73, 109, 96, 3, 7, 10, 1, 69, 73,
+ 77, 80, 103, 86, 27, 14, 7, 67, 66, 79, 89, 93, 102, 68, 26, 18, 13, 12,
+ 2, 64, 66, 70, 79, 67, 36, 31, 25, 8, 10, 65, 73, 83, 9, 55, 49, 44,
+ 33, 24, 3, 69, 69, 75, 62, 111, 108, 96, 108, 106, 93, 102, 98, 90, 99, 97,
+ 99, 88, 90, 89, 99, 94, 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 73,
+ 64, 1, 66, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, 69, 65, 69,
+ 15, 16, 16, 19, 14, 16, 14, 14, 14, 4, 11, 10, 68, 1, 56, 57, 54, 58,
+ 58, 62, 62, 62, 62, 62, 62, 62, 62, 52, 32, 62, 62, 62, 62, 62, 62, 45,
+ 39, 37, 29, 18, 11, 0, 72, 62, 62, 62, 62, 62, 62, 60, 59, 49, 46, 40,
+ 37, 22, 14, 2, 7, 7, 1, 26, 26, 24, 21, 18, 19, 11, 9, 7, 1, 78,
+ 68, 80, 90, 14, 0, 68, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, 3,
+ 7, 4, 3, 62, 54, 44, 35, 27, 16, 7, 72, 89, 67, 39, 28, 23, 13, 13,
+ 5, 1, 64, 77, 78, 73, 67, 73, 0, 5, 67, 71, 1, 5, 6, 5, 10, 9,
+ 4, 62, 54, 44, 35, 27, 16, 7, 72, 89, 75, 66, 3, 1, 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 22, 38, 51, 56, 19, 96, 66,
+ 66, 69, 8, 7, 67, 2, 10, 27, 33, 19, 66, 88, 93, 89, 73, 66, 69, 8,
+ 73, 80, 11, 14, 67, 78, 88, 3, 76, 84, 97, 7, 71, 80, 4, 78, 80, 91,
+ 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 39, 7,
+ 81, 97, 77, 83, 2, 71, 84, 79, 98, 81, 94, 88, 100, 80, 85, 88, 89, 24,
+ 65, 72, 100, 71, 95, 84, 103, 6, 2, 3, 67, 13, 68, 68, 81, 93, 81, 82,
+ 81, 70, 78, 92, 87, 70, 97, 86, 68, 74, 89, 92, 0, 74, 68, 66, 3, 9,
+ 64, 70, 83, 93, 72, 19, 19, 94, 9, 6, 5, 4, 5, 2, 65, 0, 2, 8,
+ 5, 2, 1, 2, 68, 68, 5, 66, 16, 25, 25, 17, 10, 19, 12, 16, 11, 0,
+ 14, 12, 23, 89, 15, 28, 25, 50, 62, 35, 42, 59, 60, 38, 52, 51, 62, 62,
+ 36, 43, 32, 41, 54, 43, 58, 62, 62, 35, 32, 51, 38, 62, 7, 62, 62, 62,
+ 62, 62, 56, 53, 52, 47, 42, 37, 31, 24, 19, 1, 75, 73, 83, 18, 19, 16,
+ 18, 6, 6, 5, 17, 66, 71, 68, 81, 74, 108, 94, 4, 8, 10, 1, 68, 73,
+ 77, 79, 101, 85, 27, 14, 8, 66, 65, 78, 88, 92, 101, 67, 27, 19, 14, 12,
+ 3, 0, 66, 70, 79, 67, 36, 31, 24, 8, 10, 65, 73, 83, 9, 54, 48, 43,
+ 32, 24, 3, 69, 69, 75, 62, 110, 106, 95, 106, 105, 92, 100, 96, 89, 97, 95,
+ 97, 87, 89, 89, 98, 93, 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 74,
+ 0, 1, 65, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, 69, 65, 70,
+ 14, 16, 15, 18, 13, 15, 14, 13, 13, 4, 11, 9, 68, 0, 55, 56, 53, 56,
+ 56, 62, 61, 62, 62, 62, 62, 62, 61, 50, 30, 62, 62, 62, 62, 62, 59, 43,
+ 36, 34, 27, 16, 9, 64, 73, 62, 62, 62, 62, 62, 62, 57, 56, 47, 43, 38,
+ 34, 20, 12, 1, 6, 6, 64, 25, 24, 22, 19, 16, 17, 9, 8, 6, 0, 79,
+ 69, 81, 91, 13, 64, 69, 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3,
+ 8, 4, 3, 61, 52, 41, 32, 24, 12, 2, 76, 92, 67, 39, 28, 23, 13, 13,
+ 5, 1, 64, 76, 78, 73, 66, 73, 0, 6, 67, 71, 1, 5, 6, 5, 10, 9,
+ 4, 61, 52, 41, 32, 24, 12, 2, 76, 92, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 21, 36, 50, 56, 19, 94, 66,
+ 66, 68, 7, 6, 67, 1, 8, 26, 31, 15, 69, 90, 90, 88, 72, 66, 68, 7,
+ 73, 79, 11, 14, 67, 77, 87, 3, 76, 84, 97, 7, 71, 80, 4, 78, 80, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 75, 89, 97, 66, 12, 64, 38, 7,
+ 81, 95, 76, 82, 4, 69, 82, 78, 97, 79, 92, 87, 97, 80, 84, 88, 88, 24,
+ 65, 71, 98, 71, 94, 83, 101, 6, 2, 3, 67, 13, 68, 68, 80, 92, 80, 81,
+ 80, 69, 77, 91, 85, 69, 95, 85, 0, 70, 86, 89, 1, 73, 67, 65, 3, 9,
+ 64, 70, 82, 91, 72, 17, 17, 91, 9, 7, 5, 4, 5, 3, 0, 1, 3, 7,
+ 5, 2, 2, 2, 69, 67, 5, 66, 15, 24, 24, 16, 9, 19, 12, 16, 10, 1,
+ 13, 12, 22, 89, 15, 27, 24, 48, 62, 34, 41, 57, 58, 36, 50, 49, 62, 62,
+ 33, 41, 30, 38, 51, 41, 55, 62, 62, 33, 30, 48, 36, 62, 6, 62, 62, 62,
+ 61, 60, 54, 51, 50, 45, 39, 35, 29, 23, 17, 64, 75, 73, 83, 17, 18, 15,
+ 16, 5, 5, 4, 16, 67, 71, 69, 81, 75, 107, 93, 5, 8, 10, 2, 68, 72,
+ 76, 78, 99, 83, 27, 15, 8, 66, 64, 77, 86, 90, 99, 67, 28, 20, 15, 13,
+ 4, 0, 65, 69, 78, 67, 37, 31, 24, 7, 10, 65, 73, 82, 9, 54, 47, 42,
+ 31, 24, 3, 68, 69, 74, 62, 108, 105, 93, 104, 103, 91, 99, 95, 88, 95, 94,
+ 95, 86, 88, 88, 97, 91, 84, 78, 78, 77, 74, 71, 68, 67, 0, 69, 69, 74,
+ 0, 1, 64, 1, 1, 1, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, 71,
+ 13, 16, 14, 18, 13, 14, 14, 13, 12, 4, 11, 8, 68, 64, 54, 55, 52, 54,
+ 54, 62, 59, 61, 62, 59, 62, 62, 58, 47, 28, 62, 62, 62, 62, 59, 56, 40,
+ 34, 32, 25, 15, 8, 64, 73, 62, 62, 62, 62, 59, 59, 55, 53, 45, 41, 36,
+ 31, 18, 10, 64, 6, 6, 66, 24, 23, 21, 17, 14, 15, 8, 7, 4, 64, 79,
+ 71, 82, 91, 11, 66, 71, 80, 76, 68, 75, 66, 5, 70, 74, 0, 4, 3, 4,
+ 9, 4, 3, 60, 50, 38, 29, 20, 8, 65, 80, 95, 66, 39, 28, 23, 13, 14,
+ 5, 2, 0, 76, 78, 73, 66, 73, 1, 7, 67, 71, 2, 6, 6, 6, 11, 9,
+ 4, 60, 50, 38, 29, 20, 8, 65, 80, 95, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 19, 34, 49, 56, 19, 92, 66,
+ 65, 67, 7, 6, 67, 1, 7, 25, 28, 12, 71, 91, 87, 87, 72, 65, 67, 7,
+ 74, 78, 11, 13, 67, 77, 87, 3, 76, 84, 97, 7, 71, 79, 4, 78, 79, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 37, 6,
+ 81, 92, 75, 81, 5, 67, 81, 76, 95, 78, 91, 86, 95, 80, 84, 87, 88, 24,
+ 65, 70, 96, 71, 93, 83, 99, 6, 1, 2, 68, 13, 68, 67, 80, 91, 79, 81,
+ 79, 69, 76, 89, 84, 69, 94, 84, 5, 65, 83, 86, 1, 73, 67, 65, 3, 9,
+ 0, 69, 82, 89, 72, 15, 15, 88, 9, 7, 5, 4, 5, 3, 1, 2, 3, 7,
+ 5, 2, 2, 3, 70, 67, 5, 67, 15, 23, 24, 16, 9, 19, 12, 16, 9, 1,
+ 12, 11, 22, 89, 15, 27, 24, 46, 61, 33, 39, 55, 55, 34, 47, 47, 62, 62,
+ 29, 39, 28, 36, 48, 38, 52, 61, 62, 30, 28, 44, 34, 62, 4, 60, 62, 60,
+ 58, 57, 52, 49, 48, 43, 37, 33, 27, 21, 16, 66, 75, 73, 84, 16, 17, 14,
+ 15, 4, 4, 3, 14, 68, 72, 70, 82, 75, 107, 91, 6, 9, 10, 2, 67, 72,
+ 76, 78, 97, 82, 27, 15, 9, 65, 0, 76, 85, 89, 97, 66, 28, 20, 15, 13,
+ 5, 1, 65, 69, 78, 67, 37, 31, 23, 7, 10, 65, 73, 82, 9, 53, 47, 41,
+ 30, 24, 3, 68, 69, 74, 62, 107, 103, 92, 103, 102, 90, 97, 93, 87, 94, 92,
+ 93, 86, 87, 88, 96, 89, 83, 78, 78, 77, 74, 71, 68, 67, 0, 69, 69, 75,
+ 1, 2, 0, 1, 1, 2, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, 72,
+ 12, 16, 13, 17, 12, 14, 14, 12, 11, 4, 11, 7, 68, 65, 53, 54, 51, 53,
+ 52, 60, 57, 59, 59, 57, 62, 60, 55, 45, 26, 62, 62, 62, 62, 55, 53, 38,
+ 32, 29, 23, 13, 6, 65, 74, 62, 62, 62, 60, 56, 57, 52, 50, 42, 38, 33,
+ 28, 16, 8, 65, 5, 5, 67, 22, 21, 19, 15, 13, 13, 6, 6, 3, 65, 80,
+ 72, 83, 92, 10, 67, 72, 80, 75, 68, 74, 65, 6, 70, 74, 0, 4, 3, 4,
+ 10, 4, 3, 59, 48, 36, 26, 17, 4, 69, 84, 98, 66, 39, 28, 23, 13, 14,
+ 6, 2, 0, 75, 78, 73, 65, 72, 2, 8, 67, 70, 2, 6, 6, 6, 11, 9,
+ 4, 59, 48, 36, 26, 17, 4, 69, 84, 98, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 18, 32, 48, 56, 19, 90, 66,
+ 65, 66, 7, 5, 67, 0, 5, 24, 26, 8, 74, 93, 84, 86, 72, 65, 66, 7,
+ 74, 77, 11, 13, 67, 77, 86, 3, 76, 84, 97, 7, 71, 79, 4, 78, 79, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 36, 6,
+ 81, 90, 74, 80, 7, 65, 79, 75, 93, 76, 90, 85, 93, 80, 84, 87, 88, 24,
+ 65, 69, 94, 71, 92, 82, 97, 6, 1, 2, 68, 13, 68, 67, 79, 90, 78, 80,
+ 78, 68, 75, 88, 82, 68, 93, 83, 10, 2, 80, 83, 1, 73, 67, 64, 3, 9,
+ 0, 69, 81, 87, 72, 13, 13, 85, 9, 7, 5, 4, 5, 4, 3, 3, 3, 7,
+ 5, 2, 3, 4, 71, 67, 5, 67, 14, 22, 23, 16, 8, 19, 12, 16, 8, 1,
+ 11, 10, 21, 89, 15, 26, 23, 44, 58, 32, 37, 53, 53, 32, 45, 45, 62, 62,
+ 26, 37, 26, 34, 45, 36, 49, 57, 62, 27, 26, 41, 32, 62, 2, 58, 62, 58,
+ 56, 55, 50, 47, 46, 41, 35, 31, 25, 19, 14, 68, 75, 73, 84, 15, 16, 13,
+ 14, 3, 3, 2, 12, 69, 72, 71, 83, 76, 106, 90, 7, 9, 10, 2, 66, 71,
+ 75, 77, 95, 81, 27, 15, 9, 64, 1, 75, 83, 87, 95, 65, 29, 21, 16, 14,
+ 6, 1, 65, 69, 77, 67, 38, 31, 22, 7, 10, 65, 73, 81, 9, 53, 46, 40,
+ 29, 24, 3, 68, 69, 74, 62, 106, 102, 91, 101, 100, 89, 95, 91, 86, 92, 90,
+ 91, 85, 86, 87, 95, 87, 83, 78, 78, 76, 73, 71, 68, 67, 64, 69, 69, 75,
+ 1, 2, 1, 1, 1, 2, 2, 5, 1, 0, 1, 4, 65, 69, 73, 69, 0, 73,
+ 11, 16, 12, 16, 11, 13, 14, 11, 10, 4, 11, 6, 68, 66, 52, 53, 50, 51,
+ 50, 58, 55, 57, 57, 54, 61, 57, 52, 42, 24, 62, 62, 62, 62, 52, 50, 35,
+ 30, 27, 21, 11, 5, 66, 75, 62, 62, 62, 58, 53, 54, 50, 47, 40, 36, 31,
+ 25, 14, 6, 67, 4, 4, 69, 21, 20, 17, 13, 11, 11, 4, 5, 1, 66, 81,
+ 73, 84, 93, 8, 68, 73, 80, 75, 67, 74, 64, 7, 70, 73, 1, 5, 3, 5,
+ 11, 4, 3, 58, 46, 33, 23, 14, 0, 73, 88, 101, 66, 39, 28, 23, 13, 15,
+ 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, 6, 6, 6, 12, 9,
+ 4, 58, 46, 33, 23, 14, 0, 73, 88, 101, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 16, 29, 47, 56, 18, 89, 67,
+ 65, 66, 6, 4, 67, 64, 3, 22, 23, 4, 77, 95, 82, 86, 72, 65, 66, 6,
+ 75, 77, 11, 12, 67, 77, 86, 2, 77, 84, 97, 6, 71, 79, 4, 78, 79, 90,
+ 65, 76, 71, 84, 67, 2, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 35, 5,
+ 82, 88, 73, 79, 8, 0, 78, 74, 92, 75, 89, 84, 91, 80, 84, 87, 88, 24,
+ 65, 69, 92, 71, 92, 82, 96, 5, 0, 1, 69, 13, 68, 67, 79, 90, 78, 80,
+ 78, 68, 75, 87, 81, 68, 92, 82, 14, 6, 77, 81, 1, 73, 67, 64, 2, 9,
+ 0, 69, 81, 85, 72, 11, 11, 83, 9, 7, 5, 4, 5, 4, 4, 3, 3, 6,
+ 4, 2, 3, 4, 73, 67, 5, 68, 13, 20, 22, 15, 7, 19, 12, 15, 6, 1,
+ 10, 9, 20, 89, 14, 25, 22, 41, 54, 30, 35, 50, 50, 29, 42, 43, 55, 62,
+ 22, 34, 24, 31, 41, 33, 45, 52, 59, 24, 24, 37, 30, 62, 0, 55, 59, 55,
+ 53, 52, 47, 44, 43, 39, 32, 28, 23, 17, 12, 70, 75, 74, 85, 14, 14, 11,
+ 12, 1, 1, 0, 10, 70, 73, 72, 84, 77, 106, 89, 7, 9, 10, 2, 66, 71,
+ 75, 77, 93, 80, 27, 15, 9, 64, 1, 74, 82, 86, 94, 65, 29, 21, 16, 14,
+ 7, 1, 65, 69, 77, 68, 38, 30, 21, 6, 10, 65, 73, 81, 8, 52, 45, 38,
+ 28, 23, 3, 68, 69, 74, 62, 105, 101, 90, 100, 99, 88, 94, 90, 85, 91, 89,
+ 89, 85, 86, 87, 94, 86, 83, 78, 78, 76, 73, 71, 69, 68, 65, 69, 70, 76,
+ 1, 2, 2, 1, 0, 2, 2, 4, 1, 0, 1, 3, 65, 69, 73, 69, 0, 74,
+ 10, 16, 10, 15, 10, 12, 13, 10, 9, 4, 10, 4, 69, 68, 50, 51, 49, 49,
+ 48, 55, 52, 54, 54, 51, 58, 54, 48, 39, 22, 62, 62, 61, 60, 48, 46, 32,
+ 27, 24, 19, 9, 3, 67, 76, 59, 60, 60, 55, 50, 51, 47, 43, 37, 33, 28,
+ 22, 12, 4, 69, 3, 3, 71, 19, 18, 15, 10, 9, 9, 2, 3, 64, 68, 82,
+ 75, 85, 94, 6, 70, 75, 80, 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, 5,
+ 11, 4, 2, 56, 44, 30, 19, 10, 67, 78, 93, 104, 66, 39, 28, 23, 13, 15,
+ 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, 6, 6, 6, 12, 8,
+ 3, 56, 44, 30, 19, 10, 67, 78, 93, 104, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 15, 27, 46, 57, 18, 87, 67, 64,
+ 65, 6, 4, 66, 64, 2, 21, 21, 1, 79, 96, 79, 85, 71, 64, 65, 6, 75, 76,
+ 11, 12, 66, 76, 85, 2, 77, 83, 96, 6, 70, 78, 4, 77, 78, 89, 64, 75, 71,
+ 83, 66, 2, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 35, 5, 82, 85, 71, 77,
+ 10, 3, 76, 72, 90, 73, 87, 82, 88, 80, 83, 86, 87, 24, 65, 68, 89, 70, 91,
+ 81, 94, 5, 0, 1, 69, 14, 68, 66, 78, 89, 77, 79, 77, 67, 74, 85, 79, 67,
+ 90, 80, 19, 11, 73, 78, 2, 72, 66, 0, 2, 10, 1, 68, 80, 82, 71, 9, 10,
+ 80, 9, 8, 5, 5, 6, 5, 6, 4, 4, 6, 4, 2, 4, 5, 74, 66, 5, 68,
+ 13, 19, 22, 15, 7, 19, 12, 15, 5, 2, 10, 9, 20, 89, 14, 25, 22, 39, 51,
+ 29, 34, 48, 48, 27, 40, 41, 49, 62, 19, 32, 23, 29, 38, 31, 42, 48, 55, 22,
+ 22, 34, 28, 62, 64, 53, 57, 53, 51, 50, 45, 42, 41, 37, 30, 26, 22, 16, 11,
+ 71, 75, 74, 85, 14, 13, 10, 11, 0, 0, 64, 9, 71, 73, 73, 84, 77, 105, 87,
+ 8, 10, 10, 3, 65, 70, 74, 76, 90, 78, 28, 16, 10, 0, 2, 72, 80, 84, 92,
+ 64, 30, 22, 17, 15, 8, 2, 64, 68, 76, 68, 39, 30, 21, 6, 11, 64, 73, 80,
+ 8, 52, 45, 37, 27, 23, 4, 67, 68, 73, 62, 103, 99, 88, 98, 97, 86, 92, 88,
+ 83, 89, 87, 86, 84, 85, 86, 92, 84, 82, 77, 77, 75, 72, 70, 69, 68, 65, 69,
+ 70, 76, 2, 3, 3, 2, 0, 3, 3, 4, 2, 1, 1, 3, 64, 68, 72, 68, 1,
+ 74, 9, 16, 9, 15, 10, 12, 13, 10, 9, 4, 10, 3, 69, 69, 49, 50, 49, 48,
+ 47, 53, 50, 52, 52, 49, 56, 52, 45, 37, 20, 61, 60, 57, 56, 45, 43, 30, 25,
+ 22, 18, 8, 2, 67, 76, 57, 58, 58, 53, 48, 49, 45, 40, 35, 31, 26, 20, 11,
+ 3, 70, 3, 3, 72, 18, 17, 14, 8, 8, 8, 1, 2, 65, 69, 82, 76, 85, 94,
+ 5, 71, 76, 79, 74, 66, 73, 2, 10, 69, 72, 2, 6, 4, 6, 12, 4, 2, 55,
+ 42, 28, 16, 7, 71, 82, 97, 106, 65, 39, 29, 24, 14, 16, 7, 3, 1, 74, 77,
+ 72, 64, 71, 4, 10, 66, 69, 3, 7, 6, 7, 13, 8, 3, 55, 42, 28, 16, 7,
+ 71, 82, 97, 106, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 14, 25, 45, 57, 18, 85, 67,
+ 64, 64, 6, 3, 66, 65, 0, 20, 18, 66, 82, 98, 76, 84, 71, 64, 64, 6,
+ 75, 75, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, 78, 4, 77, 78, 89,
+ 64, 75, 71, 83, 66, 2, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 34, 5,
+ 82, 83, 70, 76, 12, 5, 75, 71, 88, 72, 86, 81, 86, 80, 83, 86, 87, 24,
+ 65, 67, 87, 70, 90, 80, 92, 5, 0, 1, 70, 14, 68, 66, 77, 88, 76, 78,
+ 76, 67, 73, 84, 78, 66, 89, 79, 24, 15, 70, 75, 2, 72, 66, 0, 2, 10,
+ 1, 68, 80, 80, 71, 7, 8, 77, 9, 8, 5, 5, 6, 5, 8, 5, 4, 6,
+ 4, 2, 5, 6, 75, 66, 5, 68, 12, 18, 21, 15, 6, 19, 12, 15, 4, 2,
+ 9, 8, 19, 89, 14, 24, 21, 37, 48, 28, 32, 46, 46, 25, 38, 39, 43, 62,
+ 15, 30, 21, 27, 35, 29, 39, 44, 51, 19, 20, 31, 26, 62, 66, 51, 55, 51,
+ 49, 48, 43, 40, 39, 35, 28, 24, 20, 14, 9, 73, 75, 74, 86, 13, 12, 9,
+ 10, 64, 64, 65, 7, 72, 73, 74, 85, 78, 104, 86, 9, 10, 10, 3, 64, 69,
+ 73, 75, 88, 77, 28, 16, 10, 1, 3, 71, 78, 82, 90, 0, 31, 23, 18, 16,
+ 9, 2, 64, 68, 75, 68, 40, 30, 20, 6, 11, 64, 73, 80, 8, 52, 44, 36,
+ 26, 23, 4, 67, 68, 73, 62, 102, 98, 87, 96, 95, 85, 90, 86, 82, 87, 85,
+ 84, 83, 84, 86, 91, 82, 82, 77, 77, 74, 72, 70, 69, 68, 66, 69, 70, 76,
+ 2, 3, 4, 2, 0, 3, 3, 4, 2, 1, 1, 2, 64, 68, 72, 68, 2, 75,
+ 8, 16, 8, 14, 9, 11, 13, 9, 8, 4, 10, 2, 69, 70, 48, 49, 48, 46,
+ 45, 51, 48, 50, 50, 46, 53, 49, 42, 34, 18, 57, 56, 53, 51, 42, 40, 27,
+ 23, 19, 16, 6, 1, 68, 77, 55, 56, 55, 51, 45, 46, 42, 37, 33, 28, 24,
+ 17, 9, 1, 72, 2, 2, 74, 17, 16, 12, 6, 6, 6, 64, 1, 67, 70, 83,
+ 77, 86, 95, 3, 72, 77, 79, 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6,
+ 13, 4, 2, 54, 40, 25, 13, 4, 75, 86, 101, 109, 65, 39, 29, 24, 14, 17,
+ 7, 3, 1, 74, 77, 72, 64, 71, 5, 11, 66, 69, 3, 7, 6, 7, 14, 8,
+ 3, 54, 40, 25, 13, 4, 75, 86, 101, 109, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 12, 23, 44, 57, 18, 83, 67,
+ 0, 0, 6, 3, 66, 65, 64, 19, 16, 69, 84, 99, 73, 83, 71, 0, 0, 6,
+ 76, 74, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, 77, 4, 77, 77, 89,
+ 64, 75, 71, 83, 66, 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 33, 4,
+ 82, 80, 69, 75, 13, 7, 73, 69, 86, 70, 85, 80, 84, 80, 83, 85, 87, 24,
+ 65, 66, 85, 70, 89, 80, 90, 5, 64, 0, 70, 14, 68, 65, 77, 87, 75, 78,
+ 75, 66, 72, 82, 76, 66, 88, 78, 29, 20, 67, 72, 2, 72, 66, 1, 2, 10,
+ 2, 67, 79, 78, 71, 5, 6, 74, 9, 8, 5, 5, 6, 6, 9, 6, 4, 6,
+ 4, 2, 5, 7, 76, 66, 5, 69, 12, 17, 21, 15, 6, 19, 12, 15, 3, 2,
+ 8, 7, 19, 89, 14, 24, 21, 35, 45, 27, 30, 44, 43, 23, 35, 37, 36, 62,
+ 12, 28, 19, 25, 32, 26, 36, 40, 47, 16, 18, 27, 24, 62, 68, 49, 53, 49,
+ 46, 45, 41, 38, 37, 33, 26, 22, 18, 12, 8, 75, 75, 74, 86, 12, 11, 8,
+ 9, 65, 65, 66, 5, 73, 74, 75, 86, 78, 104, 84, 10, 11, 10, 3, 0, 69,
+ 73, 75, 86, 76, 28, 16, 11, 2, 4, 70, 77, 81, 88, 1, 31, 23, 18, 16,
+ 10, 3, 64, 68, 75, 68, 40, 30, 19, 6, 11, 64, 73, 79, 8, 51, 44, 35,
+ 25, 23, 4, 67, 68, 73, 62, 101, 96, 86, 95, 94, 84, 88, 84, 81, 86, 83,
+ 82, 83, 83, 85, 90, 80, 81, 77, 77, 74, 71, 70, 69, 68, 66, 69, 70, 77,
+ 3, 4, 5, 2, 0, 4, 3, 4, 2, 1, 1, 2, 64, 68, 72, 68, 2, 76,
+ 7, 16, 7, 13, 8, 11, 13, 8, 7, 4, 10, 1, 69, 71, 47, 48, 47, 45,
+ 43, 49, 46, 48, 47, 44, 50, 46, 39, 32, 16, 53, 52, 49, 46, 38, 37, 25,
+ 21, 17, 14, 4, 64, 69, 78, 53, 53, 53, 48, 42, 44, 40, 34, 30, 26, 21,
+ 14, 7, 64, 73, 1, 1, 75, 15, 14, 10, 4, 5, 4, 66, 0, 68, 71, 84,
+ 78, 87, 96, 2, 73, 78, 79, 73, 65, 72, 4, 12, 69, 71, 3, 7, 4, 7,
+ 14, 4, 2, 53, 38, 23, 10, 1, 79, 90, 105, 112, 65, 39, 29, 24, 14, 17,
+ 8, 3, 1, 73, 77, 72, 0, 70, 6, 12, 66, 68, 3, 7, 6, 7, 14, 8,
+ 3, 53, 38, 23, 10, 1, 79, 90, 105, 112, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 21, 43, 57, 17, 81, 67,
+ 0, 1, 5, 2, 66, 66, 66, 18, 13, 73, 87, 101, 70, 82, 71, 0, 1, 5,
+ 76, 73, 11, 10, 66, 75, 83, 2, 77, 83, 96, 6, 70, 77, 4, 77, 77, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 32, 4,
+ 82, 78, 68, 74, 15, 9, 72, 68, 85, 69, 83, 79, 82, 80, 82, 85, 87, 24,
+ 65, 65, 83, 70, 89, 79, 88, 5, 64, 0, 71, 14, 68, 65, 76, 86, 74, 77,
+ 74, 66, 72, 81, 75, 65, 87, 77, 34, 24, 64, 69, 2, 71, 66, 1, 2, 10,
+ 2, 67, 79, 76, 71, 3, 4, 72, 9, 9, 5, 5, 6, 6, 11, 7, 5, 5,
+ 4, 2, 6, 7, 77, 66, 5, 69, 11, 16, 20, 14, 5, 19, 12, 15, 2, 2,
+ 7, 6, 18, 89, 13, 23, 20, 33, 41, 26, 28, 42, 41, 21, 33, 35, 30, 62,
+ 8, 26, 17, 22, 29, 24, 32, 35, 43, 13, 16, 24, 22, 62, 69, 47, 51, 46,
+ 44, 43, 39, 36, 35, 31, 23, 20, 16, 10, 6, 77, 75, 74, 87, 11, 10, 7,
+ 7, 66, 67, 67, 4, 74, 74, 76, 86, 79, 103, 83, 11, 11, 10, 4, 0, 68,
+ 72, 74, 84, 74, 28, 17, 11, 2, 5, 69, 75, 79, 87, 1, 32, 24, 19, 17,
+ 11, 3, 64, 67, 74, 68, 41, 30, 19, 5, 11, 64, 73, 79, 8, 51, 43, 34,
+ 24, 23, 4, 66, 68, 73, 62, 99, 95, 85, 93, 92, 83, 87, 83, 80, 84, 82,
+ 80, 82, 82, 85, 89, 79, 81, 77, 77, 73, 71, 70, 70, 68, 67, 69, 70, 77,
+ 3, 4, 6, 2, 0, 4, 3, 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 77,
+ 6, 16, 6, 13, 7, 10, 13, 7, 6, 4, 10, 0, 69, 72, 46, 47, 46, 43,
+ 41, 47, 44, 45, 45, 41, 47, 43, 36, 29, 14, 48, 48, 45, 41, 35, 33, 22,
+ 18, 14, 12, 2, 65, 70, 78, 50, 51, 50, 46, 39, 41, 37, 31, 28, 23, 19,
+ 11, 5, 66, 75, 0, 1, 77, 14, 13, 9, 2, 3, 2, 67, 64, 70, 72, 85,
+ 80, 88, 96, 0, 75, 80, 78, 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7,
+ 15, 4, 2, 52, 36, 20, 7, 66, 83, 95, 109, 115, 64, 39, 29, 24, 14, 18,
+ 8, 3, 1, 73, 77, 72, 0, 70, 6, 13, 66, 68, 4, 8, 6, 7, 15, 8,
+ 3, 52, 36, 20, 7, 66, 83, 95, 109, 115, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 10, 19, 42, 57, 17, 79, 67,
+ 0, 2, 5, 2, 66, 67, 68, 17, 11, 76, 89, 103, 67, 81, 70, 0, 2, 5,
+ 76, 72, 11, 10, 66, 75, 82, 2, 77, 83, 96, 6, 70, 77, 4, 77, 76, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 31, 3,
+ 82, 75, 67, 73, 17, 11, 70, 66, 83, 67, 82, 78, 79, 80, 82, 84, 86, 24,
+ 65, 64, 81, 70, 88, 79, 86, 5, 65, 64, 71, 14, 68, 64, 76, 85, 73, 77,
+ 73, 65, 71, 79, 73, 64, 85, 76, 39, 28, 2, 66, 3, 71, 65, 2, 2, 10,
+ 3, 67, 78, 74, 71, 1, 2, 69, 9, 9, 5, 5, 6, 7, 12, 8, 5, 5,
+ 4, 2, 6, 8, 78, 65, 5, 70, 11, 15, 20, 14, 5, 19, 12, 15, 1, 3,
+ 6, 6, 18, 89, 13, 22, 19, 31, 38, 25, 27, 40, 39, 19, 30, 33, 24, 62,
+ 5, 24, 15, 20, 26, 21, 29, 31, 39, 11, 14, 20, 20, 62, 71, 45, 49, 44,
+ 42, 41, 37, 34, 33, 29, 21, 18, 14, 9, 4, 79, 75, 74, 87, 10, 9, 6,
+ 6, 67, 68, 68, 2, 75, 75, 77, 87, 80, 102, 81, 12, 12, 10, 4, 1, 68,
+ 72, 73, 82, 73, 28, 17, 12, 3, 6, 68, 74, 78, 85, 2, 33, 25, 20, 17,
+ 12, 4, 0, 67, 74, 68, 41, 30, 18, 5, 11, 64, 73, 78, 8, 50, 42, 33,
+ 23, 23, 4, 66, 68, 72, 62, 98, 93, 83, 91, 91, 82, 85, 81, 79, 82, 80,
+ 78, 81, 81, 84, 88, 77, 81, 77, 76, 73, 70, 70, 70, 68, 67, 69, 70, 78,
+ 4, 4, 7, 2, 0, 4, 3, 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 78,
+ 5, 16, 5, 12, 7, 9, 13, 7, 5, 4, 10, 64, 69, 73, 45, 46, 45, 41,
+ 39, 45, 42, 43, 42, 38, 44, 40, 33, 27, 12, 44, 44, 41, 36, 32, 30, 20,
+ 16, 12, 10, 1, 67, 70, 79, 48, 48, 48, 44, 36, 38, 35, 28, 26, 21, 17,
+ 8, 3, 68, 76, 0, 0, 79, 13, 11, 7, 0, 1, 0, 69, 65, 71, 73, 85,
+ 81, 89, 97, 64, 76, 81, 78, 73, 0, 71, 6, 14, 68, 69, 4, 8, 4, 8,
+ 16, 4, 2, 51, 34, 17, 4, 69, 87, 99, 113, 118, 64, 39, 29, 24, 14, 18,
+ 8, 4, 2, 72, 77, 72, 1, 70, 7, 14, 66, 68, 4, 8, 6, 8, 15, 8,
+ 3, 51, 34, 17, 4, 69, 87, 99, 113, 118, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 17, 41, 57, 17, 78, 67,
+ 1, 2, 5, 1, 65, 67, 69, 15, 8, 80, 92, 104, 65, 80, 70, 1, 2, 5,
+ 77, 72, 11, 9, 66, 75, 82, 2, 77, 82, 95, 6, 69, 76, 4, 76, 76, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 31, 3,
+ 82, 73, 66, 72, 18, 14, 69, 65, 81, 66, 81, 77, 77, 80, 82, 84, 86, 24,
+ 65, 0, 78, 70, 87, 78, 84, 4, 65, 64, 72, 15, 68, 64, 75, 85, 73, 76,
+ 72, 65, 70, 78, 72, 64, 84, 75, 44, 33, 5, 0, 3, 71, 65, 2, 2, 10,
+ 3, 66, 78, 72, 70, 64, 0, 66, 9, 9, 5, 5, 7, 7, 14, 9, 5, 5,
+ 4, 2, 7, 9, 79, 65, 5, 70, 10, 14, 19, 14, 4, 19, 12, 15, 64, 3,
+ 5, 5, 17, 89, 13, 22, 19, 29, 35, 24, 25, 37, 36, 17, 28, 31, 17, 62,
+ 1, 22, 14, 18, 22, 19, 26, 27, 34, 8, 12, 17, 18, 62, 73, 43, 47, 42,
+ 39, 38, 35, 31, 31, 27, 19, 15, 12, 7, 3, 80, 75, 74, 88, 9, 8, 5,
+ 5, 68, 69, 69, 0, 76, 75, 78, 88, 80, 102, 80, 13, 12, 10, 4, 2, 67,
+ 71, 73, 80, 72, 29, 17, 12, 4, 7, 67, 72, 76, 83, 3, 33, 25, 20, 18,
+ 13, 4, 0, 67, 73, 68, 42, 30, 17, 5, 11, 64, 73, 78, 7, 50, 42, 32,
+ 22, 22, 4, 66, 68, 72, 62, 97, 92, 82, 90, 89, 81, 83, 79, 78, 81, 78,
+ 76, 81, 80, 84, 87, 75, 80, 77, 76, 72, 70, 70, 70, 68, 68, 69, 70, 78,
+ 4, 5, 8, 2, 0, 5, 4, 4, 3, 2, 1, 0, 64, 68, 72, 68, 4, 79,
+ 4, 16, 4, 11, 6, 9, 13, 6, 5, 4, 9, 66, 70, 74, 43, 45, 44, 40,
+ 37, 43, 40, 41, 40, 36, 41, 38, 30, 24, 10, 40, 40, 37, 32, 28, 27, 17,
+ 14, 9, 8, 64, 68, 71, 80, 46, 46, 45, 41, 33, 36, 32, 25, 23, 18, 14,
+ 5, 1, 69, 78, 64, 64, 80, 11, 10, 5, 65, 0, 65, 71, 66, 73, 74, 86,
+ 82, 90, 98, 66, 77, 82, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8,
+ 17, 4, 2, 50, 32, 15, 1, 72, 91, 103, 117, 121, 64, 39, 29, 24, 14, 19,
+ 9, 4, 2, 72, 76, 71, 1, 69, 8, 15, 65, 67, 4, 8, 6, 8, 16, 8,
+ 3, 50, 32, 15, 1, 72, 91, 103, 117, 121, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 7, 15, 40, 57, 17, 76, 67,
+ 1, 3, 4, 1, 65, 68, 71, 14, 6, 83, 94, 106, 1, 79, 70, 1, 3, 4,
+ 77, 71, 11, 9, 66, 74, 81, 2, 77, 82, 95, 6, 69, 76, 4, 76, 75, 87,
+ 64, 75, 71, 83, 64, 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 30, 2,
+ 82, 70, 65, 71, 20, 16, 67, 0, 80, 64, 79, 76, 75, 80, 81, 83, 86, 24,
+ 65, 1, 76, 70, 86, 78, 82, 4, 66, 65, 72, 15, 68, 0, 75, 84, 72, 76,
+ 71, 64, 69, 76, 70, 0, 83, 74, 49, 37, 8, 3, 3, 70, 65, 3, 2, 10,
+ 4, 66, 77, 70, 70, 66, 65, 0, 9, 10, 5, 5, 7, 8, 15, 10, 6, 4,
+ 4, 2, 7, 9, 80, 65, 5, 71, 10, 13, 19, 13, 4, 19, 12, 15, 65, 3,
+ 4, 4, 17, 89, 13, 21, 18, 27, 32, 23, 23, 35, 34, 15, 25, 29, 11, 62,
+ 65, 20, 12, 15, 19, 16, 23, 22, 30, 5, 10, 13, 16, 62, 74, 41, 45, 40,
+ 37, 36, 33, 29, 29, 25, 16, 13, 10, 5, 1, 82, 75, 74, 88, 8, 7, 4,
+ 3, 69, 70, 70, 64, 77, 76, 79, 88, 81, 101, 78, 14, 13, 10, 5, 2, 67,
+ 71, 72, 78, 70, 29, 18, 13, 4, 8, 66, 71, 75, 81, 3, 34, 26, 21, 18,
+ 14, 5, 0, 66, 73, 68, 42, 30, 17, 4, 11, 64, 73, 77, 7, 49, 41, 31,
+ 21, 22, 4, 65, 68, 72, 62, 95, 90, 81, 88, 88, 80, 82, 78, 77, 79, 77,
+ 74, 80, 79, 83, 86, 73, 80, 77, 76, 72, 69, 70, 71, 68, 68, 69, 70, 79,
+ 5, 5, 9, 2, 0, 5, 4, 4, 3, 2, 1, 0, 64, 68, 72, 68, 4, 80,
+ 3, 16, 3, 11, 5, 8, 13, 5, 4, 4, 9, 67, 70, 75, 42, 44, 43, 38,
+ 35, 41, 38, 38, 37, 33, 38, 35, 27, 22, 8, 35, 36, 33, 27, 25, 24, 15,
+ 12, 7, 6, 66, 70, 72, 80, 43, 43, 43, 39, 30, 33, 30, 22, 21, 16, 12,
+ 2, 64, 71, 79, 65, 64, 82, 10, 8, 4, 67, 65, 67, 72, 67, 74, 75, 87,
+ 84, 91, 98, 67, 79, 84, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9,
+ 18, 4, 2, 49, 30, 12, 65, 76, 95, 107, 121, 124, 0, 39, 29, 24, 14, 19,
+ 9, 4, 2, 71, 76, 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 16, 8,
+ 3, 49, 30, 12, 65, 76, 95, 107, 121, 124, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 5, 12, 39, 57, 16, 74, 68,
+ 1, 4, 4, 0, 65, 69, 73, 13, 3, 87, 97, 108, 4, 78, 70, 1, 4, 4,
+ 78, 70, 11, 8, 66, 74, 81, 1, 78, 82, 95, 6, 69, 76, 4, 76, 75, 87,
+ 64, 75, 71, 83, 64, 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 29, 2,
+ 83, 68, 64, 70, 21, 18, 66, 1, 78, 0, 78, 75, 73, 80, 81, 83, 86, 24,
+ 65, 2, 74, 70, 86, 77, 80, 4, 66, 65, 73, 15, 68, 0, 74, 83, 71, 75,
+ 71, 64, 69, 75, 69, 0, 82, 73, 53, 41, 11, 5, 3, 70, 65, 3, 1, 10,
+ 4, 66, 77, 68, 70, 68, 67, 2, 9, 10, 5, 5, 7, 8, 17, 10, 6, 4,
+ 3, 2, 8, 10, 82, 65, 5, 71, 9, 11, 18, 13, 3, 19, 12, 14, 66, 3,
+ 3, 3, 16, 89, 12, 20, 17, 25, 28, 21, 21, 33, 31, 12, 23, 27, 4, 62,
+ 69, 18, 10, 13, 16, 14, 19, 18, 26, 2, 8, 10, 14, 62, 76, 39, 42, 37,
+ 34, 33, 30, 27, 26, 23, 14, 11, 8, 3, 64, 84, 75, 75, 89, 7, 5, 3,
+ 2, 70, 72, 72, 66, 78, 76, 80, 89, 82, 101, 77, 15, 13, 10, 5, 3, 66,
+ 70, 72, 76, 69, 29, 18, 13, 5, 9, 65, 69, 73, 80, 4, 34, 26, 21, 19,
+ 15, 5, 0, 66, 72, 69, 43, 30, 16, 4, 11, 64, 73, 77, 7, 49, 40, 30,
+ 20, 22, 4, 65, 68, 72, 62, 94, 89, 80, 87, 86, 79, 80, 76, 76, 78, 75,
+ 72, 80, 79, 83, 85, 72, 80, 77, 76, 71, 69, 70, 71, 68, 69, 69, 70, 79,
+ 5, 5, 10, 2, 64, 5, 4, 3, 3, 2, 1, 64, 64, 68, 72, 68, 5, 81,
+ 2, 16, 1, 10, 4, 7, 12, 4, 3, 4, 9, 68, 70, 77, 41, 42, 42, 36,
+ 33, 39, 36, 36, 35, 30, 35, 32, 24, 19, 6, 31, 32, 28, 22, 21, 20, 12,
+ 9, 4, 4, 68, 71, 73, 81, 41, 41, 40, 36, 27, 30, 27, 19, 18, 13, 9,
+ 64, 66, 73, 81, 66, 65, 84, 8, 7, 2, 69, 67, 69, 74, 69, 76, 77, 88,
+ 85, 92, 99, 69, 80, 85, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9,
+ 18, 4, 1, 48, 28, 9, 68, 79, 99, 112, 126, 126, 0, 39, 29, 24, 14, 20,
+ 9, 4, 2, 71, 76, 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 17, 8,
+ 2, 48, 28, 9, 68, 79, 99, 112, 126, 126, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 4, 10, 38, 58, 16, 72, 68,
+ 2, 5, 4, 64, 65, 69, 74, 12, 1, 91, 100, 109, 7, 77, 69, 2, 5, 4,
+ 78, 69, 11, 8, 65, 74, 80, 1, 78, 82, 95, 6, 69, 75, 4, 76, 75, 87,
+ 64, 75, 71, 82, 64, 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 28, 2,
+ 83, 66, 1, 69, 23, 20, 64, 2, 76, 2, 77, 73, 70, 80, 81, 83, 85, 24,
+ 65, 3, 72, 69, 85, 76, 78, 4, 66, 65, 73, 15, 68, 0, 73, 82, 70, 74,
+ 70, 0, 68, 74, 67, 1, 80, 72, 58, 46, 15, 8, 4, 70, 64, 4, 1, 10,
+ 4, 65, 76, 65, 70, 70, 68, 5, 9, 10, 5, 5, 7, 9, 19, 11, 6, 4,
+ 3, 2, 9, 11, 83, 64, 5, 71, 8, 10, 17, 13, 2, 19, 12, 14, 67, 4,
+ 2, 3, 15, 89, 12, 20, 17, 23, 25, 20, 20, 31, 29, 10, 21, 25, 65, 62,
+ 72, 16, 8, 11, 13, 12, 16, 14, 22, 0, 6, 7, 12, 62, 78, 37, 40, 35,
+ 32, 31, 28, 25, 24, 21, 12, 9, 7, 2, 65, 86, 75, 75, 89, 7, 4, 2,
+ 1, 71, 73, 73, 68, 79, 76, 81, 90, 82, 100, 76, 16, 13, 10, 5, 4, 65,
+ 69, 71, 73, 68, 29, 18, 13, 6, 10, 64, 67, 71, 78, 5, 35, 27, 22, 20,
+ 16, 5, 1, 66, 71, 69, 44, 30, 15, 4, 12, 0, 73, 76, 7, 49, 40, 29,
+ 19, 22, 4, 65, 68, 71, 62, 93, 88, 78, 85, 84, 78, 78, 74, 75, 76, 73,
+ 70, 79, 78, 82, 84, 70, 79, 76, 75, 70, 68, 70, 71, 68, 70, 69, 70, 79,
+ 5, 6, 11, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, 71, 68, 6, 81,
+ 1, 16, 0, 9, 4, 7, 12, 4, 2, 4, 9, 69, 70, 78, 40, 41, 42, 35,
+ 31, 37, 34, 34, 33, 28, 32, 29, 21, 16, 4, 27, 28, 24, 17, 18, 17, 9,
+ 7, 2, 3, 69, 72, 73, 82, 39, 39, 38, 34, 25, 28, 25, 16, 16, 11, 7,
+ 66, 68, 75, 83, 66, 66, 85, 7, 6, 0, 71, 68, 70, 76, 70, 78, 78, 88,
+ 86, 92, 100, 71, 81, 86, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, 10,
+ 19, 4, 1, 47, 26, 7, 71, 82, 103, 116, 126, 126, 0, 39, 29, 25, 15, 21,
+ 10, 5, 3, 71, 76, 71, 2, 68, 10, 17, 65, 66, 5, 9, 6, 9, 18, 8,
+ 2, 47, 26, 7, 71, 82, 103, 116, 126, 126, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 3, 8, 37, 58, 16, 70, 68,
+ 2, 6, 3, 64, 65, 70, 76, 11, 65, 94, 102, 111, 10, 76, 69, 2, 6, 3,
+ 78, 68, 11, 7, 65, 73, 79, 1, 78, 82, 95, 6, 69, 75, 4, 76, 74, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 27, 1,
+ 83, 0, 2, 68, 25, 22, 0, 4, 75, 3, 75, 72, 68, 80, 80, 82, 85, 24,
+ 65, 4, 70, 69, 84, 76, 76, 4, 67, 66, 74, 15, 68, 1, 73, 81, 69, 74,
+ 69, 0, 67, 72, 66, 2, 79, 71, 62, 50, 18, 11, 4, 69, 64, 4, 1, 10,
+ 5, 65, 76, 0, 70, 72, 70, 8, 9, 11, 5, 5, 7, 9, 20, 12, 7, 3,
+ 3, 2, 9, 11, 84, 64, 5, 72, 8, 9, 17, 12, 2, 19, 12, 14, 68, 4,
+ 1, 2, 15, 89, 12, 19, 16, 21, 22, 19, 18, 29, 27, 8, 18, 23, 71, 62,
+ 76, 14, 6, 8, 10, 9, 13, 9, 18, 66, 4, 3, 10, 62, 79, 35, 38, 33,
+ 30, 29, 26, 23, 22, 19, 9, 7, 5, 0, 67, 88, 75, 75, 90, 6, 3, 1,
+ 64, 72, 74, 74, 69, 80, 77, 82, 90, 83, 99, 74, 17, 14, 10, 6, 4, 65,
+ 69, 70, 71, 66, 29, 19, 14, 6, 11, 0, 66, 70, 76, 5, 36, 28, 23, 20,
+ 17, 6, 1, 65, 71, 69, 44, 30, 15, 3, 12, 0, 73, 76, 7, 48, 39, 28,
+ 18, 22, 4, 64, 68, 71, 62, 91, 86, 77, 83, 83, 77, 77, 73, 74, 74, 72,
+ 68, 78, 77, 82, 83, 68, 79, 76, 75, 70, 68, 70, 72, 68, 70, 69, 70, 80,
+ 6, 6, 12, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, 71, 68, 6, 82,
+ 0, 16, 64, 9, 3, 6, 12, 3, 1, 4, 9, 70, 70, 79, 39, 40, 41, 33,
+ 29, 35, 32, 31, 30, 25, 29, 26, 18, 14, 2, 22, 24, 20, 12, 15, 14, 7,
+ 5, 64, 1, 71, 74, 74, 82, 36, 36, 35, 32, 22, 25, 22, 13, 14, 8, 5,
+ 69, 70, 77, 84, 67, 66, 87, 6, 4, 64, 73, 70, 72, 77, 71, 79, 79, 89,
+ 88, 93, 100, 72, 83, 88, 76, 71, 3, 69, 11, 20, 67, 66, 7, 11, 4, 10,
+ 20, 4, 1, 46, 24, 4, 74, 86, 107, 120, 126, 126, 1, 39, 29, 25, 15, 21,
+ 10, 5, 3, 70, 76, 71, 3, 68, 11, 18, 65, 66, 6, 10, 6, 9, 18, 8,
+ 2, 46, 24, 4, 74, 86, 107, 120, 126, 126, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 1, 6, 36, 58, 16, 69, 68,
+ 3, 6, 3, 65, 64, 70, 77, 9, 67, 98, 105, 112, 12, 75, 69, 3, 6, 3,
+ 79, 68, 11, 7, 65, 73, 79, 1, 78, 81, 94, 6, 68, 74, 4, 75, 74, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 27, 1,
+ 83, 2, 3, 67, 26, 25, 2, 5, 73, 5, 74, 71, 66, 80, 80, 82, 85, 24,
+ 65, 5, 67, 69, 83, 75, 74, 3, 67, 66, 74, 16, 68, 1, 72, 81, 69, 73,
+ 68, 1, 66, 71, 64, 2, 78, 70, 62, 55, 21, 14, 4, 69, 64, 5, 1, 10,
+ 5, 64, 75, 2, 69, 74, 72, 11, 9, 11, 5, 5, 8, 10, 22, 13, 7, 3,
+ 3, 2, 10, 12, 85, 64, 5, 72, 7, 8, 16, 12, 1, 19, 12, 14, 70, 4,
+ 0, 1, 14, 89, 12, 19, 16, 19, 19, 18, 16, 26, 24, 6, 16, 21, 78, 62,
+ 79, 12, 5, 6, 6, 7, 10, 5, 13, 69, 2, 0, 8, 62, 81, 33, 36, 31,
+ 27, 26, 24, 20, 20, 17, 7, 4, 3, 65, 68, 89, 75, 75, 90, 5, 2, 0,
+ 65, 73, 75, 75, 71, 81, 77, 83, 91, 83, 99, 73, 18, 14, 10, 6, 5, 64,
+ 68, 70, 69, 65, 30, 19, 14, 7, 12, 1, 64, 68, 74, 6, 36, 28, 23, 21,
+ 18, 6, 1, 65, 70, 69, 45, 30, 14, 3, 12, 0, 73, 75, 6, 48, 39, 27,
+ 17, 21, 4, 64, 68, 71, 62, 90, 85, 76, 82, 81, 76, 75, 71, 73, 73, 70,
+ 66, 78, 76, 81, 82, 66, 78, 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 80,
+ 6, 7, 13, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, 71, 68, 7, 83,
+ 64, 16, 65, 8, 2, 6, 12, 2, 1, 4, 8, 72, 71, 80, 37, 39, 40, 32,
+ 27, 33, 30, 29, 28, 23, 26, 24, 15, 11, 0, 18, 20, 16, 8, 11, 11, 4,
+ 3, 66, 64, 73, 75, 75, 83, 34, 34, 33, 29, 19, 23, 20, 10, 11, 6, 2,
+ 72, 72, 78, 86, 68, 67, 88, 4, 3, 66, 75, 71, 74, 79, 72, 81, 80, 90,
+ 89, 94, 101, 74, 84, 89, 76, 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11,
+ 21, 4, 1, 45, 22, 2, 77, 89, 111, 124, 126, 126, 1, 39, 29, 25, 15, 22,
+ 11, 5, 3, 70, 75, 70, 3, 67, 12, 19, 64, 65, 6, 10, 6, 9, 19, 8,
+ 2, 45, 22, 2, 77, 89, 111, 124, 126, 126, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 0, 4, 35, 58, 15, 67, 68,
+ 3, 7, 3, 65, 64, 71, 79, 8, 70, 101, 107, 114, 15, 74, 69, 3, 7, 3,
+ 79, 67, 11, 6, 65, 73, 78, 1, 78, 81, 94, 6, 68, 74, 4, 75, 73, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 26, 0,
+ 83, 5, 4, 66, 28, 27, 3, 7, 71, 6, 73, 70, 64, 80, 80, 81, 85, 24,
+ 65, 6, 65, 69, 83, 75, 72, 3, 68, 67, 75, 16, 68, 2, 72, 80, 68, 73,
+ 67, 1, 66, 69, 0, 3, 77, 69, 62, 59, 24, 17, 4, 69, 64, 5, 1, 10,
+ 6, 64, 75, 4, 69, 76, 74, 13, 9, 11, 5, 5, 8, 10, 23, 14, 7, 3,
+ 3, 2, 10, 13, 86, 64, 5, 73, 7, 7, 16, 12, 1, 19, 12, 14, 71, 4,
+ 64, 0, 14, 89, 11, 18, 15, 17, 15, 17, 14, 24, 22, 4, 13, 19, 84, 62,
+ 83, 10, 3, 4, 3, 4, 6, 1, 9, 72, 0, 67, 6, 62, 83, 31, 34, 28,
+ 25, 24, 22, 18, 18, 15, 5, 2, 1, 67, 70, 91, 75, 75, 91, 4, 1, 64,
+ 66, 74, 77, 76, 73, 82, 78, 84, 92, 84, 98, 71, 19, 15, 10, 6, 6, 64,
+ 68, 69, 67, 64, 30, 19, 15, 8, 13, 2, 0, 67, 73, 7, 37, 29, 24, 21,
+ 19, 7, 1, 65, 70, 69, 45, 30, 13, 3, 12, 0, 73, 75, 6, 47, 38, 26,
+ 16, 21, 4, 64, 68, 71, 62, 89, 83, 75, 80, 80, 75, 73, 69, 72, 71, 68,
+ 64, 77, 75, 81, 81, 65, 78, 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 81,
+ 7, 7, 14, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, 71, 68, 7, 84,
+ 65, 16, 66, 7, 1, 5, 12, 1, 0, 4, 8, 73, 71, 81, 36, 38, 39, 30,
+ 25, 31, 28, 27, 25, 20, 23, 21, 12, 9, 65, 14, 16, 12, 3, 8, 7, 2,
+ 0, 69, 66, 75, 77, 76, 84, 32, 31, 30, 27, 16, 20, 17, 7, 9, 3, 0,
+ 75, 74, 80, 87, 69, 68, 90, 3, 1, 68, 77, 73, 76, 81, 73, 82, 81, 91,
+ 90, 95, 102, 75, 85, 90, 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11,
+ 22, 4, 1, 44, 20, 64, 80, 92, 115, 126, 126, 126, 1, 39, 29, 25, 15, 22,
+ 11, 5, 3, 69, 75, 70, 4, 67, 12, 20, 64, 65, 6, 10, 6, 9, 19, 8,
+ 2, 44, 20, 64, 80, 92, 115, 126, 126, 126, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 64, 2, 34, 58, 15, 65, 68,
+ 3, 8, 2, 66, 64, 72, 81, 7, 72, 105, 110, 116, 18, 73, 68, 3, 8, 2,
+ 79, 66, 11, 6, 65, 72, 77, 1, 78, 81, 94, 6, 68, 74, 4, 75, 73, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 25, 0,
+ 83, 7, 5, 65, 30, 29, 5, 8, 70, 8, 71, 69, 2, 80, 79, 81, 84, 24,
+ 65, 7, 0, 69, 82, 74, 70, 3, 68, 67, 75, 16, 68, 2, 71, 79, 67, 72,
+ 66, 2, 65, 68, 2, 4, 75, 68, 62, 62, 27, 20, 5, 68, 0, 6, 1, 10,
+ 6, 64, 74, 6, 69, 78, 76, 16, 9, 12, 5, 5, 8, 11, 25, 15, 8, 2,
+ 3, 2, 11, 13, 87, 0, 5, 73, 6, 6, 15, 11, 0, 19, 12, 14, 72, 5,
+ 65, 0, 13, 89, 11, 17, 14, 15, 12, 16, 13, 22, 20, 2, 11, 17, 90, 62,
+ 86, 8, 1, 1, 0, 2, 3, 67, 5, 74, 65, 70, 4, 62, 84, 29, 32, 26,
+ 23, 22, 20, 16, 16, 13, 2, 0, 64, 68, 72, 93, 75, 75, 91, 3, 0, 65,
+ 68, 75, 78, 77, 74, 83, 78, 85, 92, 85, 97, 70, 20, 15, 10, 7, 6, 0,
+ 67, 68, 65, 1, 30, 20, 15, 8, 14, 3, 2, 65, 71, 7, 38, 30, 25, 22,
+ 20, 7, 2, 64, 69, 69, 46, 30, 13, 2, 12, 0, 73, 74, 6, 47, 37, 25,
+ 15, 21, 4, 0, 68, 70, 62, 87, 82, 73, 78, 78, 74, 72, 68, 71, 69, 67,
+ 1, 76, 74, 80, 80, 0, 78, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, 81,
+ 7, 7, 15, 3, 64, 7, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, 8, 85,
+ 66, 16, 67, 7, 1, 4, 12, 1, 64, 4, 8, 74, 71, 82, 35, 37, 38, 28,
+ 23, 29, 26, 24, 23, 17, 20, 18, 9, 6, 67, 9, 12, 8, 65, 5, 4, 64,
+ 65, 71, 68, 76, 78, 76, 84, 29, 29, 28, 25, 13, 17, 15, 4, 7, 1, 65,
+ 78, 76, 82, 89, 69, 68, 92, 2, 0, 69, 79, 75, 78, 82, 74, 84, 82, 91,
+ 92, 96, 102, 77, 87, 92, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, 12,
+ 23, 4, 1, 43, 18, 67, 83, 96, 119, 126, 126, 126, 2, 39, 29, 25, 15, 23,
+ 11, 6, 4, 69, 75, 70, 4, 67, 13, 21, 64, 65, 7, 11, 6, 10, 20, 8,
+ 2, 43, 18, 67, 83, 96, 119, 126, 126, 126, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 66, 0, 33, 58, 15, 0, 68,
+ 4, 9, 2, 66, 64, 72, 82, 6, 75, 108, 112, 117, 21, 72, 68, 4, 9, 2,
+ 80, 65, 11, 5, 65, 72, 77, 1, 78, 81, 94, 6, 68, 73, 4, 75, 72, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 24, 64,
+ 83, 10, 6, 64, 31, 31, 6, 10, 68, 9, 70, 68, 4, 80, 79, 80, 84, 24,
+ 65, 8, 2, 69, 81, 74, 68, 3, 69, 68, 76, 16, 68, 3, 71, 78, 66, 72,
+ 65, 2, 64, 66, 3, 4, 74, 67, 62, 62, 30, 23, 5, 68, 0, 6, 1, 10,
+ 7, 0, 74, 8, 69, 80, 78, 19, 9, 12, 5, 5, 8, 11, 26, 16, 8, 2,
+ 3, 2, 11, 14, 88, 0, 5, 74, 6, 5, 15, 11, 0, 19, 12, 14, 73, 5,
+ 66, 64, 13, 89, 11, 17, 14, 13, 9, 15, 11, 20, 17, 0, 8, 15, 97, 62,
+ 90, 6, 64, 64, 66, 64, 0, 71, 1, 77, 67, 74, 2, 62, 86, 27, 30, 24,
+ 20, 19, 18, 14, 14, 11, 0, 65, 66, 70, 73, 95, 75, 75, 92, 2, 64, 66,
+ 69, 76, 79, 78, 76, 84, 79, 86, 93, 85, 97, 68, 21, 16, 10, 7, 7, 0,
+ 67, 68, 0, 2, 30, 20, 16, 9, 15, 4, 3, 64, 69, 8, 38, 30, 25, 22,
+ 21, 8, 2, 64, 69, 69, 46, 30, 12, 2, 12, 0, 73, 74, 6, 46, 37, 24,
+ 14, 21, 4, 0, 68, 70, 62, 86, 80, 72, 77, 77, 73, 70, 66, 70, 68, 65,
+ 3, 76, 73, 80, 79, 2, 77, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, 82,
+ 8, 8, 16, 3, 64, 8, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, 8, 86,
+ 67, 16, 68, 6, 0, 4, 12, 0, 65, 4, 8, 75, 71, 83, 34, 36, 37, 27,
+ 21, 27, 24, 22, 20, 15, 17, 15, 6, 4, 69, 5, 8, 4, 70, 1, 1, 66,
+ 67, 74, 70, 78, 80, 77, 85, 27, 26, 25, 22, 10, 15, 12, 1, 4, 65, 68,
+ 81, 78, 84, 90, 70, 69, 93, 0, 65, 71, 81, 76, 80, 84, 75, 85, 83, 92,
+ 93, 97, 103, 78, 88, 93, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, 4, 12,
+ 24, 4, 1, 42, 16, 69, 86, 99, 123, 126, 126, 126, 2, 39, 29, 25, 15, 23,
+ 12, 6, 4, 68, 75, 70, 5, 66, 14, 22, 64, 64, 7, 11, 6, 10, 20, 8,
+ 2, 42, 16, 69, 86, 99, 123, 126, 126, 126, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 67, 65, 32, 58, 15, 2, 68,
+ 4, 10, 2, 67, 64, 73, 84, 5, 77, 112, 115, 119, 24, 71, 68, 4, 10, 2,
+ 80, 64, 11, 5, 65, 72, 76, 1, 78, 81, 94, 6, 68, 73, 4, 75, 72, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 23, 64,
+ 83, 12, 7, 0, 33, 33, 8, 11, 66, 11, 69, 67, 6, 80, 79, 80, 84, 24,
+ 65, 9, 4, 69, 80, 73, 66, 3, 69, 68, 76, 16, 68, 3, 70, 77, 65, 71,
+ 64, 3, 0, 65, 5, 5, 73, 66, 62, 62, 33, 26, 5, 68, 0, 7, 1, 10,
+ 7, 0, 73, 10, 69, 82, 80, 22, 9, 12, 5, 5, 8, 12, 28, 17, 8, 2,
+ 3, 2, 12, 15, 89, 0, 5, 74, 5, 4, 14, 11, 64, 19, 12, 14, 74, 5,
+ 67, 65, 12, 89, 11, 16, 13, 11, 6, 14, 9, 18, 15, 65, 6, 13, 103, 62,
+ 93, 4, 66, 66, 69, 66, 66, 75, 66, 80, 69, 77, 0, 62, 88, 25, 28, 22,
+ 18, 17, 16, 12, 12, 9, 65, 67, 68, 72, 75, 97, 75, 75, 92, 1, 65, 67,
+ 70, 77, 80, 79, 78, 85, 79, 87, 94, 86, 96, 67, 22, 16, 10, 7, 8, 1,
+ 66, 67, 2, 3, 30, 20, 16, 10, 16, 5, 5, 1, 67, 9, 39, 31, 26, 23,
+ 22, 8, 2, 64, 68, 69, 47, 30, 11, 2, 12, 0, 73, 73, 6, 46, 36, 23,
+ 13, 21, 4, 0, 68, 70, 62, 85, 79, 71, 75, 75, 72, 68, 64, 69, 66, 0,
+ 5, 75, 72, 79, 78, 4, 77, 76, 74, 67, 65, 70, 73, 68, 73, 69, 70, 82,
+ 8, 8, 17, 3, 64, 8, 5, 3, 4, 3, 1, 68, 64, 67, 71, 68, 9, 87,
+ 68, 16, 69, 5, 64, 3, 12, 64, 66, 4, 8, 76, 71, 84, 33, 35, 36, 25,
+ 19, 25, 22, 20, 18, 12, 14, 12, 3, 1, 71, 1, 4, 0, 75, 65, 65, 69,
+ 69, 76, 72, 80, 81, 78, 86, 25, 24, 23, 20, 7, 12, 10, 65, 2, 67, 70,
+ 84, 80, 86, 92, 71, 70, 95, 64, 66, 73, 83, 78, 82, 86, 76, 87, 84, 93,
+ 94, 98, 104, 80, 89, 94, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, 4, 13,
+ 25, 4, 1, 41, 14, 72, 89, 102, 126, 126, 126, 126, 2, 39, 29, 25, 15, 24,
+ 12, 6, 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, 6, 10, 21, 8,
+ 2, 41, 14, 72, 89, 102, 126, 126, 126, 126, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 69, 68, 31, 58, 14, 3, 69,
+ 4, 10, 1, 68, 64, 74, 86, 3, 80, 116, 118, 121, 26, 71, 68, 4, 10, 1,
+ 81, 64, 11, 4, 65, 72, 76, 0, 79, 81, 94, 5, 68, 73, 4, 75, 72, 85,
+ 64, 75, 72, 82, 1, 2, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 22, 65,
+ 84, 14, 8, 1, 34, 35, 9, 12, 65, 12, 68, 66, 8, 80, 79, 80, 84, 24,
+ 65, 9, 6, 69, 80, 73, 65, 2, 70, 69, 77, 16, 68, 3, 70, 77, 65, 71,
+ 64, 3, 0, 64, 6, 5, 72, 65, 62, 62, 36, 28, 5, 68, 0, 7, 0, 10,
+ 7, 0, 73, 12, 69, 84, 82, 24, 9, 12, 5, 5, 8, 12, 29, 17, 8, 1,
+ 2, 2, 12, 15, 91, 0, 5, 75, 4, 2, 13, 10, 65, 19, 12, 13, 76, 5,
+ 68, 66, 11, 89, 10, 15, 12, 8, 2, 12, 7, 15, 12, 68, 3, 11, 110, 62,
+ 97, 1, 68, 69, 73, 69, 70, 80, 71, 83, 71, 81, 65, 62, 90, 22, 25, 19,
+ 15, 14, 13, 9, 9, 7, 68, 70, 70, 74, 77, 99, 75, 76, 93, 0, 67, 69,
+ 72, 79, 82, 81, 80, 86, 80, 88, 95, 87, 96, 66, 22, 16, 10, 7, 8, 1,
+ 66, 67, 4, 4, 30, 20, 16, 10, 16, 6, 6, 2, 66, 9, 39, 31, 26, 23,
+ 23, 8, 2, 64, 68, 70, 47, 29, 10, 1, 12, 0, 73, 73, 5, 45, 35, 21,
+ 12, 20, 4, 0, 68, 70, 62, 84, 78, 70, 74, 74, 71, 67, 0, 68, 65, 1,
+ 7, 75, 72, 79, 77, 5, 77, 76, 74, 67, 65, 70, 74, 69, 74, 69, 71, 83,
+ 8, 8, 18, 3, 65, 8, 5, 2, 4, 3, 1, 69, 64, 67, 71, 68, 9, 88,
+ 69, 16, 71, 4, 65, 2, 11, 65, 67, 4, 7, 78, 72, 86, 31, 33, 35, 23,
+ 17, 22, 19, 17, 15, 9, 11, 9, 64, 65, 73, 67, 0, 68, 80, 69, 69, 72,
+ 72, 79, 74, 82, 83, 79, 87, 22, 21, 20, 17, 4, 9, 7, 69, 64, 70, 73,
+ 87, 82, 88, 94, 72, 71, 97, 66, 68, 75, 86, 80, 84, 88, 78, 89, 86, 94,
+ 96, 99, 105, 82, 91, 96, 75, 69, 6, 67, 17, 26, 66, 0, 10, 14, 4, 13,
+ 25, 4, 0, 39, 12, 75, 93, 106, 126, 126, 126, 126, 2, 39, 29, 25, 15, 24,
+ 12, 6, 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, 6, 10, 21, 7,
+ 1, 39, 12, 75, 93, 106, 126, 126, 126, 126, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 70, 70, 30, 59, 14, 5,
+ 69, 5, 11, 1, 68, 0, 74, 87, 2, 82, 119, 120, 122, 29, 70, 67, 5,
+ 11, 1, 81, 0, 11, 4, 64, 71, 75, 0, 79, 80, 93, 5, 67, 72, 4,
+ 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 64, 94, 97, 6,
+ 67, 68, 22, 65, 84, 17, 10, 3, 36, 38, 11, 14, 0, 14, 66, 64, 11,
+ 80, 78, 79, 83, 24, 65, 10, 9, 68, 79, 72, 0, 2, 70, 69, 77, 17,
+ 68, 4, 69, 76, 64, 70, 0, 4, 1, 1, 8, 6, 70, 0, 62, 62, 40,
+ 31, 6, 67, 1, 8, 0, 11, 8, 1, 72, 15, 68, 86, 83, 27, 9, 13,
+ 5, 6, 9, 13, 31, 18, 9, 1, 2, 2, 13, 16, 92, 1, 5, 75, 4,
+ 1, 13, 10, 65, 19, 12, 13, 77, 6, 68, 66, 11, 89, 10, 15, 12, 6,
+ 64, 11, 6, 13, 10, 70, 1, 9, 116, 62, 100, 64, 69, 71, 76, 71, 73,
+ 84, 75, 85, 73, 84, 67, 62, 91, 20, 23, 17, 13, 12, 11, 7, 7, 5,
+ 70, 72, 71, 75, 78, 100, 75, 76, 93, 0, 68, 70, 73, 80, 83, 82, 81,
+ 87, 80, 89, 95, 87, 95, 64, 23, 17, 10, 8, 9, 2, 65, 66, 7, 6,
+ 31, 21, 17, 11, 17, 8, 8, 4, 64, 10, 40, 32, 27, 24, 24, 9, 3,
+ 0, 67, 70, 48, 29, 10, 1, 13, 1, 73, 72, 5, 45, 35, 20, 11, 20,
+ 5, 1, 67, 69, 62, 82, 76, 68, 72, 72, 69, 65, 2, 66, 0, 3, 10,
+ 74, 71, 78, 75, 7, 76, 75, 73, 66, 64, 69, 74, 69, 74, 69, 71, 83,
+ 9, 9, 19, 4, 65, 9, 6, 2, 5, 4, 1, 69, 0, 66, 70, 67, 10,
+ 88, 70, 16, 72, 4, 65, 2, 11, 65, 67, 4, 7, 79, 72, 87, 30, 32,
+ 35, 22, 16, 20, 17, 15, 13, 7, 9, 7, 67, 67, 75, 71, 66, 72, 84,
+ 72, 72, 74, 74, 81, 75, 83, 84, 79, 87, 20, 19, 18, 15, 2, 7, 5,
+ 72, 66, 72, 75, 89, 83, 89, 95, 72, 71, 98, 67, 69, 76, 88, 81, 85,
+ 89, 79, 90, 87, 94, 97, 99, 105, 83, 92, 97, 74, 68, 7, 66, 19, 28,
+ 65, 1, 11, 15, 5, 14, 26, 4, 0, 38, 10, 77, 96, 109, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 25, 13, 7, 5, 67, 74, 69, 6, 65, 16, 24,
+ 0, 0, 8, 12, 6, 11, 22, 7, 1, 38, 10, 77, 96, 109, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 71, 72, 29, 59, 14, 7,
+ 69, 5, 12, 1, 69, 0, 75, 89, 1, 85, 123, 123, 124, 32, 69, 67, 5,
+ 12, 1, 81, 1, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, 72, 4,
+ 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 21, 65, 84, 19, 11, 4, 38, 40, 12, 15, 2, 15, 65, 0, 13,
+ 80, 78, 79, 83, 24, 65, 11, 11, 68, 78, 71, 2, 2, 70, 69, 78, 17,
+ 68, 4, 68, 75, 0, 69, 1, 4, 2, 2, 9, 7, 69, 1, 62, 62, 43,
+ 34, 6, 67, 1, 8, 0, 11, 8, 1, 72, 17, 68, 88, 85, 30, 9, 13,
+ 5, 6, 9, 13, 33, 19, 9, 1, 2, 2, 14, 17, 93, 1, 5, 75, 3,
+ 0, 12, 10, 66, 19, 12, 13, 78, 6, 69, 67, 10, 89, 10, 14, 11, 4,
+ 67, 10, 4, 11, 8, 72, 64, 7, 122, 62, 104, 66, 71, 73, 79, 73, 76,
+ 88, 79, 88, 75, 87, 69, 62, 93, 18, 21, 15, 11, 10, 9, 5, 5, 3,
+ 72, 74, 73, 77, 80, 102, 75, 76, 94, 64, 69, 71, 74, 81, 84, 83, 83,
+ 88, 80, 90, 96, 88, 94, 0, 24, 17, 10, 8, 10, 3, 64, 65, 9, 7,
+ 31, 21, 17, 12, 18, 9, 10, 6, 1, 11, 41, 33, 28, 25, 25, 9, 3,
+ 0, 66, 70, 49, 29, 9, 1, 13, 1, 73, 72, 5, 45, 34, 19, 10, 20,
+ 5, 1, 67, 69, 62, 81, 75, 67, 70, 70, 68, 0, 4, 65, 2, 5, 12,
+ 73, 70, 78, 74, 9, 76, 75, 73, 65, 64, 69, 74, 69, 75, 69, 71, 83,
+ 9, 9, 20, 4, 65, 9, 6, 2, 5, 4, 1, 70, 0, 66, 70, 67, 11,
+ 89, 71, 16, 73, 3, 66, 1, 11, 66, 68, 4, 7, 80, 72, 88, 29, 31,
+ 34, 20, 14, 18, 15, 13, 11, 4, 6, 4, 70, 70, 77, 75, 70, 76, 89,
+ 75, 75, 77, 76, 84, 77, 85, 85, 80, 88, 18, 17, 15, 13, 64, 4, 2,
+ 75, 68, 75, 77, 92, 85, 91, 97, 73, 72, 100, 68, 70, 78, 90, 83, 87,
+ 91, 80, 92, 88, 95, 98, 100, 106, 85, 93, 98, 74, 68, 8, 66, 20, 29,
+ 65, 2, 12, 16, 5, 14, 27, 4, 0, 37, 8, 80, 99, 112, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 26, 13, 7, 5, 67, 74, 69, 6, 65, 17, 25,
+ 0, 0, 8, 12, 6, 11, 23, 7, 1, 37, 8, 80, 99, 112, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 73, 74, 28, 59, 14, 9,
+ 69, 6, 13, 1, 69, 0, 75, 90, 0, 87, 126, 125, 125, 35, 68, 67, 6,
+ 13, 1, 82, 2, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 70, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 20, 66, 84, 22, 12, 5, 39, 42, 14, 17, 4, 17, 64, 1, 15,
+ 80, 78, 78, 83, 24, 65, 12, 13, 68, 77, 71, 4, 2, 71, 70, 78, 17,
+ 68, 5, 68, 74, 1, 69, 2, 5, 3, 4, 11, 7, 68, 2, 62, 62, 46,
+ 37, 6, 67, 1, 9, 0, 11, 9, 2, 71, 19, 68, 90, 87, 33, 9, 13,
+ 5, 6, 9, 14, 34, 20, 9, 1, 2, 2, 14, 18, 94, 1, 5, 76, 3,
+ 64, 12, 10, 66, 19, 12, 13, 79, 6, 70, 68, 10, 89, 10, 14, 11, 2,
+ 70, 9, 2, 9, 5, 74, 67, 5, 126, 62, 107, 68, 73, 75, 82, 76, 79,
+ 92, 83, 91, 77, 91, 71, 62, 95, 16, 19, 13, 8, 7, 7, 3, 3, 1,
+ 74, 76, 75, 79, 81, 104, 75, 76, 94, 65, 70, 72, 75, 82, 85, 84, 85,
+ 89, 81, 91, 97, 88, 94, 2, 25, 18, 10, 8, 11, 3, 64, 65, 11, 8,
+ 31, 21, 18, 13, 19, 10, 11, 7, 3, 12, 41, 33, 28, 25, 26, 10, 3,
+ 0, 66, 70, 49, 29, 8, 1, 13, 1, 73, 71, 5, 44, 34, 18, 9, 20,
+ 5, 1, 67, 69, 62, 80, 73, 66, 69, 69, 67, 2, 6, 64, 3, 7, 14,
+ 73, 69, 77, 73, 11, 75, 75, 73, 65, 0, 69, 74, 69, 75, 69, 71, 84,
+ 10, 10, 21, 4, 65, 10, 6, 2, 5, 4, 1, 70, 0, 66, 70, 67, 11,
+ 90, 72, 16, 74, 2, 67, 1, 11, 67, 69, 4, 7, 81, 72, 89, 28, 30,
+ 33, 19, 12, 16, 13, 11, 8, 2, 3, 1, 73, 72, 79, 79, 74, 80, 94,
+ 79, 78, 79, 78, 86, 79, 87, 87, 81, 89, 16, 14, 13, 10, 67, 2, 0,
+ 78, 71, 77, 80, 95, 87, 93, 98, 74, 73, 101, 70, 72, 80, 92, 84, 89,
+ 93, 81, 93, 89, 96, 99, 101, 107, 86, 94, 99, 74, 67, 8, 65, 21, 30,
+ 65, 2, 12, 16, 5, 15, 28, 4, 0, 36, 6, 82, 102, 115, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 26, 14, 7, 5, 66, 74, 69, 7, 64, 18, 26,
+ 0, 1, 8, 12, 6, 11, 23, 7, 1, 36, 6, 82, 102, 115, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 74, 76, 27, 59, 13, 11,
+ 69, 6, 14, 0, 70, 0, 76, 92, 64, 90, 126, 126, 126, 38, 67, 67, 6,
+ 14, 0, 82, 3, 11, 2, 64, 70, 73, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 70, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 19, 66, 84, 24, 13, 6, 41, 44, 15, 18, 5, 18, 1, 2, 17,
+ 80, 77, 78, 83, 24, 65, 13, 15, 68, 77, 70, 6, 2, 71, 70, 79, 17,
+ 68, 5, 67, 73, 2, 68, 3, 5, 3, 5, 12, 8, 67, 3, 62, 62, 49,
+ 40, 6, 66, 1, 9, 0, 11, 9, 2, 71, 21, 68, 92, 89, 35, 9, 14,
+ 5, 6, 9, 14, 36, 21, 10, 0, 2, 2, 15, 18, 95, 1, 5, 76, 2,
+ 65, 11, 9, 67, 19, 12, 13, 80, 6, 71, 69, 9, 89, 9, 13, 10, 0,
+ 74, 8, 0, 7, 3, 76, 69, 3, 126, 62, 111, 70, 75, 78, 85, 78, 83,
+ 97, 87, 94, 79, 94, 73, 62, 96, 14, 17, 10, 6, 5, 5, 1, 1, 64,
+ 77, 78, 77, 81, 83, 106, 75, 76, 95, 66, 71, 73, 77, 83, 87, 85, 86,
+ 90, 81, 92, 97, 89, 93, 3, 26, 18, 10, 9, 11, 4, 0, 64, 13, 10,
+ 31, 22, 18, 13, 20, 11, 13, 9, 4, 12, 42, 34, 29, 26, 27, 10, 3,
+ 1, 65, 70, 50, 29, 8, 0, 13, 1, 73, 71, 5, 44, 33, 17, 8, 20,
+ 5, 2, 67, 69, 62, 78, 72, 65, 67, 67, 66, 3, 7, 0, 5, 8, 16,
+ 72, 68, 77, 72, 12, 75, 75, 73, 64, 0, 69, 75, 69, 76, 69, 71, 84,
+ 10, 10, 22, 4, 65, 10, 6, 2, 5, 4, 1, 71, 0, 66, 70, 67, 12,
+ 91, 73, 16, 75, 2, 68, 0, 11, 68, 70, 4, 7, 82, 72, 90, 27, 29,
+ 32, 17, 10, 14, 11, 8, 6, 64, 0, 65, 76, 75, 81, 84, 78, 84, 99,
+ 82, 82, 82, 81, 89, 81, 89, 88, 82, 89, 13, 12, 10, 8, 70, 64, 66,
+ 81, 73, 80, 82, 98, 89, 95, 100, 75, 73, 103, 71, 73, 81, 94, 86, 91,
+ 94, 82, 95, 90, 97, 101, 102, 107, 88, 96, 101, 73, 67, 9, 65, 22, 31,
+ 65, 3, 13, 17, 5, 15, 29, 4, 0, 35, 4, 85, 105, 119, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 27, 14, 7, 5, 66, 74, 69, 7, 64, 18, 27,
+ 0, 1, 9, 13, 6, 11, 24, 7, 1, 35, 4, 85, 105, 119, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 75, 78, 26, 59, 13, 13,
+ 69, 6, 15, 0, 70, 0, 77, 94, 65, 92, 126, 126, 126, 41, 66, 66, 6,
+ 15, 0, 82, 4, 11, 2, 64, 70, 72, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 69, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 1, 95, 97, 8,
+ 71, 68, 18, 67, 84, 27, 14, 7, 43, 46, 17, 20, 7, 20, 2, 3, 20,
+ 80, 77, 77, 82, 24, 65, 14, 17, 68, 76, 70, 8, 2, 72, 71, 79, 17,
+ 68, 6, 67, 72, 3, 68, 4, 6, 4, 7, 14, 9, 65, 4, 62, 62, 52,
+ 43, 7, 66, 2, 10, 0, 11, 10, 2, 70, 23, 68, 94, 91, 38, 9, 14,
+ 5, 6, 9, 15, 37, 22, 10, 0, 2, 2, 15, 19, 96, 2, 5, 77, 2,
+ 66, 11, 9, 67, 19, 12, 13, 81, 7, 72, 69, 9, 89, 9, 12, 9, 65,
+ 77, 7, 64, 5, 1, 78, 72, 1, 126, 62, 114, 72, 77, 80, 88, 81, 86,
+ 101, 91, 96, 81, 98, 75, 62, 98, 12, 15, 8, 4, 3, 3, 64, 64, 66,
+ 79, 80, 79, 82, 85, 108, 75, 76, 95, 67, 72, 74, 78, 84, 88, 86, 88,
+ 91, 82, 93, 98, 90, 92, 5, 27, 19, 10, 9, 12, 4, 0, 0, 15, 11,
+ 31, 22, 19, 14, 21, 12, 14, 10, 6, 13, 43, 35, 30, 26, 28, 11, 4,
+ 1, 65, 70, 50, 29, 7, 0, 13, 1, 73, 70, 5, 43, 32, 16, 7, 20,
+ 5, 2, 67, 68, 62, 77, 70, 0, 65, 66, 65, 5, 9, 1, 7, 10, 18,
+ 71, 67, 76, 71, 14, 75, 75, 72, 64, 1, 69, 75, 69, 76, 69, 71, 85,
+ 11, 10, 23, 4, 65, 10, 6, 2, 5, 4, 1, 71, 0, 66, 70, 67, 12,
+ 92, 74, 16, 76, 1, 68, 64, 11, 68, 71, 4, 7, 83, 72, 91, 26, 28,
+ 31, 15, 8, 12, 9, 6, 3, 67, 66, 68, 79, 77, 83, 88, 82, 88, 104,
+ 85, 85, 84, 83, 91, 83, 90, 90, 82, 90, 11, 9, 8, 6, 73, 67, 68,
+ 84, 75, 82, 84, 101, 91, 97, 101, 75, 74, 105, 72, 75, 83, 96, 88, 93,
+ 96, 83, 96, 91, 97, 102, 103, 108, 89, 97, 102, 73, 67, 10, 64, 23, 32,
+ 64, 4, 13, 17, 5, 16, 30, 4, 0, 34, 2, 88, 108, 122, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 27, 14, 8, 6, 65, 74, 69, 8, 64, 19, 28,
+ 0, 1, 9, 13, 6, 12, 24, 7, 1, 34, 2, 88, 108, 122, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 77, 80, 25, 59, 13, 14,
+ 69, 7, 15, 0, 71, 1, 77, 95, 67, 95, 126, 126, 126, 43, 65, 66, 7,
+ 15, 0, 83, 4, 11, 1, 64, 70, 72, 0, 79, 79, 92, 5, 66, 70, 4,
+ 73, 69, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 2, 95, 97, 8,
+ 71, 69, 18, 67, 84, 29, 15, 8, 44, 49, 18, 21, 9, 21, 3, 4, 22,
+ 80, 77, 77, 82, 24, 65, 15, 20, 68, 75, 69, 10, 1, 72, 71, 80, 18,
+ 68, 6, 66, 72, 3, 67, 5, 6, 5, 8, 15, 9, 64, 5, 62, 62, 55,
+ 46, 7, 66, 2, 10, 0, 11, 10, 3, 70, 25, 67, 96, 93, 41, 9, 14,
+ 5, 6, 10, 15, 39, 23, 10, 0, 2, 2, 16, 20, 97, 2, 5, 77, 1,
+ 67, 10, 9, 68, 19, 12, 13, 83, 7, 73, 70, 8, 89, 9, 12, 9, 67,
+ 80, 6, 66, 2, 65, 80, 74, 64, 126, 62, 118, 74, 78, 82, 92, 83, 89,
+ 105, 96, 99, 83, 101, 77, 62, 100, 10, 13, 6, 1, 0, 1, 67, 66, 68,
+ 81, 83, 81, 84, 86, 109, 75, 76, 96, 68, 73, 75, 79, 85, 89, 87, 90,
+ 92, 82, 94, 99, 90, 92, 6, 28, 19, 10, 9, 13, 5, 1, 0, 17, 12,
+ 32, 22, 19, 15, 22, 13, 16, 12, 8, 14, 43, 35, 30, 27, 29, 11, 4,
+ 1, 64, 70, 51, 29, 6, 0, 13, 1, 73, 70, 4, 43, 32, 15, 6, 19,
+ 5, 2, 67, 68, 62, 76, 69, 1, 64, 64, 64, 7, 11, 2, 8, 12, 20,
+ 71, 66, 76, 70, 16, 74, 75, 72, 0, 1, 69, 75, 69, 77, 69, 71, 85,
+ 11, 11, 24, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66, 70, 67, 13,
+ 93, 75, 16, 77, 0, 69, 64, 11, 69, 71, 4, 6, 85, 73, 92, 24, 27,
+ 30, 14, 6, 10, 7, 4, 1, 69, 69, 70, 82, 80, 85, 92, 86, 92, 108,
+ 89, 88, 87, 85, 94, 85, 92, 91, 83, 91, 9, 7, 5, 3, 76, 69, 71,
+ 87, 78, 85, 87, 104, 93, 98, 103, 76, 75, 106, 74, 76, 85, 98, 89, 95,
+ 98, 84, 98, 92, 98, 103, 104, 109, 91, 98, 103, 73, 66, 10, 64, 24, 33,
+ 64, 4, 14, 18, 5, 16, 31, 4, 0, 33, 0, 90, 111, 125, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 28, 15, 8, 6, 65, 73, 68, 8, 0, 20, 29,
+ 1, 2, 9, 13, 6, 12, 25, 7, 1, 33, 0, 90, 111, 125, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 78, 82, 24, 59, 13,
+ 16, 69, 7, 16, 64, 71, 1, 78, 97, 68, 97, 126, 126, 126, 46, 64,
+ 66, 7, 16, 64, 83, 5, 11, 1, 64, 69, 71, 0, 79, 79, 92, 5,
+ 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 17, 68, 84, 32, 16, 9, 46, 51, 20, 23,
+ 10, 23, 5, 5, 24, 80, 76, 76, 82, 24, 65, 16, 22, 68, 74, 69,
+ 12, 1, 73, 72, 80, 18, 68, 7, 66, 71, 4, 67, 6, 7, 6, 10,
+ 17, 10, 0, 6, 62, 62, 58, 49, 7, 65, 2, 11, 0, 11, 11, 3,
+ 69, 27, 67, 98, 95, 44, 9, 15, 5, 6, 10, 16, 40, 24, 11, 64,
+ 2, 2, 16, 20, 98, 2, 5, 78, 1, 68, 10, 8, 68, 19, 12, 13,
+ 84, 7, 74, 71, 8, 89, 9, 11, 8, 69, 83, 5, 68, 0, 67, 82,
+ 77, 66, 126, 62, 121, 76, 80, 85, 95, 86, 92, 110, 100, 102, 85, 105,
+ 79, 62, 101, 8, 11, 4, 64, 65, 64, 69, 68, 70, 84, 85, 83, 86,
+ 88, 111, 75, 76, 96, 69, 74, 76, 81, 86, 90, 88, 91, 93, 83, 95,
+ 99, 91, 91, 8, 29, 20, 10, 10, 13, 5, 1, 1, 19, 14, 32, 23,
+ 20, 15, 23, 14, 17, 13, 10, 14, 44, 36, 31, 27, 30, 12, 4, 2,
+ 64, 70, 51, 29, 6, 64, 13, 1, 73, 69, 4, 42, 31, 14, 5, 19,
+ 5, 3, 67, 68, 62, 74, 67, 2, 1, 0, 0, 8, 12, 3, 10, 13,
+ 22, 70, 65, 75, 69, 18, 74, 75, 72, 0, 2, 69, 76, 69, 77, 69,
+ 71, 86, 12, 11, 25, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66,
+ 70, 67, 13, 94, 76, 16, 78, 0, 70, 65, 11, 70, 72, 4, 6, 86,
+ 73, 93, 23, 26, 29, 12, 4, 8, 5, 1, 65, 72, 72, 73, 85, 82,
+ 87, 97, 90, 96, 113, 92, 91, 89, 87, 96, 87, 94, 93, 84, 91, 6,
+ 4, 3, 1, 79, 72, 73, 90, 80, 87, 89, 107, 95, 100, 104, 77, 75,
+ 108, 75, 78, 86, 100, 91, 97, 99, 85, 99, 93, 99, 105, 105, 109, 92,
+ 100, 105, 72, 66, 11, 0, 25, 34, 64, 5, 14, 18, 5, 17, 32, 4,
+ 0, 32, 65, 93, 114, 126, 126, 126, 126, 126, 5, 39, 30, 26, 16, 28,
+ 15, 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12,
+ 25, 7, 1, 32, 65, 93, 114, 126, 126, 126, 126, 126, 75, 69, 0, 11,
+ 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 80, 85, 23, 59, 12,
+ 18, 70, 7, 17, 64, 72, 1, 79, 99, 69, 100, 126, 126, 126, 49, 0,
+ 66, 7, 17, 64, 84, 6, 11, 0, 64, 69, 71, 64, 80, 79, 92, 5,
+ 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 16, 68, 85, 34, 17, 10, 47, 53, 21, 24,
+ 12, 24, 6, 6, 26, 80, 76, 76, 82, 24, 65, 17, 24, 68, 74, 68,
+ 14, 1, 73, 72, 81, 18, 68, 7, 65, 70, 5, 66, 6, 7, 6, 11,
+ 18, 10, 1, 7, 62, 62, 61, 51, 7, 65, 2, 11, 64, 11, 11, 3,
+ 69, 29, 67, 100, 97, 46, 9, 15, 5, 6, 10, 16, 42, 24, 11, 64,
+ 1, 2, 17, 21, 100, 2, 5, 78, 0, 70, 9, 8, 69, 19, 12, 12,
+ 85, 7, 75, 72, 7, 89, 8, 10, 7, 71, 87, 3, 70, 65, 70, 85,
+ 79, 68, 126, 62, 125, 78, 82, 87, 98, 88, 96, 114, 104, 105, 87, 108,
+ 81, 62, 103, 6, 8, 1, 67, 68, 67, 71, 71, 72, 86, 87, 85, 88,
+ 90, 113, 75, 77, 97, 70, 76, 77, 82, 87, 92, 90, 93, 94, 83, 96,
+ 100, 92, 91, 9, 30, 20, 10, 10, 14, 6, 2, 1, 21, 15, 32, 23,
+ 20, 16, 24, 15, 19, 15, 11, 15, 44, 36, 31, 28, 31, 12, 4, 2,
+ 0, 71, 52, 29, 5, 64, 13, 1, 73, 69, 4, 42, 30, 13, 4, 19,
+ 5, 3, 67, 68, 62, 73, 66, 3, 2, 2, 1, 10, 14, 4, 11, 15,
+ 24, 70, 65, 75, 68, 19, 74, 75, 72, 1, 2, 69, 76, 69, 78, 69,
+ 71, 86, 12, 11, 26, 4, 66, 11, 7, 1, 6, 5, 1, 73, 0, 66,
+ 70, 67, 14, 95, 77, 16, 80, 64, 71, 66, 10, 71, 73, 4, 6, 87,
+ 73, 95, 22, 24, 28, 10, 2, 6, 3, 64, 67, 75, 75, 76, 88, 85,
+ 89, 101, 94, 101, 118, 96, 95, 92, 90, 99, 89, 96, 94, 85, 92, 4,
+ 2, 0, 65, 82, 75, 76, 93, 83, 90, 92, 110, 97, 102, 106, 78, 76,
+ 110, 77, 79, 88, 102, 93, 99, 101, 87, 101, 95, 100, 106, 106, 110, 94,
+ 101, 106, 72, 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, 17, 32, 4,
+ 64, 31, 67, 96, 117, 126, 126, 126, 126, 126, 5, 39, 30, 26, 16, 29,
+ 15, 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12,
+ 26, 7, 0, 31, 67, 96, 117, 126, 126, 126, 126, 126, 75, 70, 64, 11,
+ 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 81, 87, 22, 60, 12,
+ 20, 70, 8, 18, 64, 73, 1, 79, 100, 70, 102, 126, 126, 126, 52, 1,
+ 65, 8, 18, 64, 84, 7, 11, 0, 0, 69, 70, 64, 80, 79, 92, 5,
+ 66, 69, 4, 73, 68, 82, 0, 74, 72, 80, 4, 2, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 15, 68, 85, 36, 19, 11, 49, 55, 23, 25,
+ 14, 26, 7, 8, 29, 80, 76, 76, 81, 24, 65, 18, 26, 67, 73, 67,
+ 16, 1, 73, 72, 81, 18, 68, 7, 64, 69, 6, 65, 7, 8, 7, 12,
+ 20, 11, 3, 8, 62, 62, 62, 54, 8, 65, 3, 12, 64, 11, 11, 4,
+ 68, 32, 67, 102, 98, 49, 9, 15, 5, 6, 10, 17, 44, 25, 11, 64,
+ 1, 2, 18, 22, 101, 3, 5, 78, 64, 71, 8, 8, 70, 19, 12, 12,
+ 86, 8, 76, 72, 6, 89, 8, 10, 7, 73, 90, 2, 71, 67, 72, 87,
+ 81, 70, 126, 62, 126, 80, 84, 89, 101, 90, 99, 118, 108, 107, 89, 111,
+ 83, 62, 105, 4, 6, 64, 69, 70, 69, 73, 73, 74, 88, 89, 86, 89,
+ 91, 115, 75, 77, 97, 70, 77, 78, 83, 88, 93, 91, 95, 95, 83, 97,
+ 101, 92, 90, 10, 31, 20, 10, 10, 15, 7, 3, 2, 24, 16, 32, 23,
+ 20, 17, 25, 16, 21, 17, 13, 16, 45, 37, 32, 29, 32, 12, 5, 2,
+ 1, 71, 53, 29, 4, 64, 14, 2, 73, 68, 4, 42, 30, 12, 3, 19,
+ 5, 3, 67, 67, 62, 72, 65, 5, 4, 4, 2, 12, 16, 5, 13, 17,
+ 26, 69, 64, 74, 67, 21, 73, 74, 71, 2, 3, 69, 76, 69, 79, 69,
+ 71, 86, 12, 12, 27, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65,
+ 69, 67, 15, 95, 78, 16, 81, 65, 71, 66, 10, 71, 74, 4, 6, 88,
+ 73, 96, 21, 23, 28, 9, 0, 4, 1, 66, 69, 77, 78, 79, 91, 88,
+ 91, 105, 98, 105, 123, 99, 98, 95, 92, 101, 90, 97, 95, 85, 93, 2,
+ 0, 65, 67, 84, 77, 78, 96, 85, 92, 94, 112, 99, 104, 108, 78, 77,
+ 111, 78, 80, 90, 104, 94, 100, 103, 88, 103, 96, 100, 107, 106, 111, 96,
+ 102, 107, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, 5, 18, 33, 4,
+ 64, 30, 69, 98, 120, 126, 126, 126, 126, 126, 5, 39, 30, 27, 17, 30,
+ 16, 9, 7, 64, 73, 68, 9, 1, 22, 31, 1, 3, 10, 14, 6, 13,
+ 27, 7, 0, 30, 69, 98, 120, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 82, 89, 21, 60, 12,
+ 22, 70, 8, 19, 65, 73, 1, 80, 102, 71, 105, 126, 126, 126, 55, 2,
+ 65, 8, 19, 65, 84, 8, 11, 64, 0, 68, 69, 64, 80, 79, 92, 5,
+ 66, 69, 4, 73, 67, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 14, 69, 85, 39, 20, 12, 51, 57, 24, 27,
+ 15, 27, 9, 9, 31, 80, 75, 75, 81, 24, 65, 19, 28, 67, 72, 67,
+ 18, 1, 74, 73, 82, 18, 68, 8, 64, 68, 7, 65, 8, 8, 8, 14,
+ 21, 12, 4, 9, 62, 62, 62, 57, 8, 64, 3, 12, 64, 11, 12, 4,
+ 68, 34, 67, 104, 100, 52, 9, 16, 5, 6, 10, 17, 45, 26, 12, 65,
+ 1, 2, 18, 22, 102, 3, 5, 79, 64, 72, 8, 7, 70, 19, 12, 12,
+ 87, 8, 77, 73, 6, 89, 8, 9, 6, 75, 93, 1, 73, 69, 74, 89,
+ 84, 72, 126, 62, 126, 82, 86, 92, 104, 93, 102, 123, 112, 110, 91, 115,
+ 85, 62, 106, 2, 4, 66, 71, 72, 71, 75, 75, 76, 91, 91, 88, 91,
+ 93, 117, 75, 77, 98, 71, 78, 79, 85, 89, 94, 92, 96, 96, 84, 98,
+ 101, 93, 89, 12, 32, 21, 10, 11, 15, 7, 3, 3, 26, 18, 32, 24,
+ 21, 17, 26, 17, 22, 18, 15, 16, 46, 38, 33, 29, 33, 13, 5, 3,
+ 1, 71, 53, 29, 4, 65, 14, 2, 73, 68, 4, 41, 29, 11, 2, 19,
+ 5, 4, 67, 67, 62, 70, 0, 6, 6, 5, 3, 13, 17, 6, 15, 18,
+ 28, 68, 0, 74, 66, 23, 73, 74, 71, 2, 3, 69, 77, 69, 79, 69,
+ 71, 87, 13, 12, 28, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65,
+ 69, 67, 15, 96, 79, 16, 82, 65, 72, 67, 10, 72, 75, 4, 6, 89,
+ 73, 97, 20, 22, 27, 7, 65, 2, 64, 69, 72, 80, 81, 82, 94, 90,
+ 93, 110, 102, 109, 126, 102, 101, 97, 94, 104, 92, 99, 97, 86, 93, 64,
+ 66, 68, 69, 87, 80, 81, 99, 87, 95, 96, 115, 101, 106, 109, 79, 77,
+ 113, 79, 82, 91, 106, 96, 102, 104, 89, 104, 97, 101, 109, 107, 111, 97,
+ 104, 109, 71, 65, 13, 1, 28, 38, 0, 7, 16, 20, 5, 18, 34, 4,
+ 64, 29, 71, 101, 123, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 30,
+ 16, 9, 7, 0, 73, 68, 10, 1, 23, 32, 1, 3, 11, 15, 6, 13,
+ 27, 7, 0, 29, 71, 101, 123, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 84, 91, 20, 60, 12,
+ 23, 70, 9, 19, 65, 74, 2, 80, 103, 73, 107, 126, 126, 126, 57, 3,
+ 65, 9, 19, 65, 85, 8, 11, 64, 0, 68, 69, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 67, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 14, 69, 85, 41, 21, 13, 52, 60, 26, 28,
+ 17, 29, 10, 10, 33, 80, 75, 75, 81, 24, 65, 20, 31, 67, 71, 66,
+ 20, 0, 74, 73, 82, 19, 68, 8, 0, 68, 7, 64, 9, 9, 9, 15,
+ 23, 12, 5, 10, 62, 62, 62, 60, 8, 64, 3, 13, 64, 11, 12, 5,
+ 67, 36, 66, 106, 102, 55, 9, 16, 5, 6, 11, 18, 47, 27, 12, 65,
+ 1, 2, 19, 23, 103, 3, 5, 79, 65, 73, 7, 7, 71, 19, 12, 12,
+ 89, 8, 78, 74, 5, 89, 8, 9, 6, 77, 96, 0, 75, 72, 77, 91,
+ 86, 74, 126, 62, 126, 84, 87, 94, 108, 95, 105, 126, 117, 113, 93, 118,
+ 87, 62, 108, 0, 2, 68, 74, 75, 73, 78, 77, 78, 93, 94, 90, 93,
+ 94, 118, 75, 77, 98, 72, 79, 80, 86, 90, 95, 93, 98, 97, 84, 99,
+ 102, 93, 89, 13, 33, 21, 10, 11, 16, 8, 4, 3, 28, 19, 33, 24,
+ 21, 18, 27, 18, 24, 20, 17, 17, 46, 38, 33, 30, 34, 13, 5, 3,
+ 2, 71, 54, 29, 3, 65, 14, 2, 73, 67, 3, 41, 29, 10, 1, 18,
+ 5, 4, 67, 67, 62, 69, 1, 7, 7, 7, 4, 15, 19, 7, 16, 20,
+ 30, 68, 1, 73, 65, 25, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69,
+ 71, 87, 13, 13, 29, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65,
+ 69, 67, 16, 97, 80, 16, 83, 66, 73, 67, 10, 73, 75, 4, 5, 91,
+ 74, 98, 18, 21, 26, 6, 67, 0, 66, 71, 74, 82, 84, 84, 97, 93,
+ 95, 114, 106, 113, 126, 106, 104, 100, 96, 106, 94, 101, 98, 87, 94, 66,
+ 68, 70, 72, 90, 82, 83, 102, 90, 97, 99, 118, 103, 107, 111, 80, 78,
+ 114, 81, 83, 93, 108, 97, 104, 106, 90, 106, 98, 102, 110, 108, 112, 99,
+ 105, 110, 71, 64, 13, 1, 29, 39, 0, 7, 17, 21, 5, 19, 35, 4,
+ 64, 28, 73, 103, 126, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 31,
+ 17, 9, 7, 0, 72, 67, 10, 2, 24, 33, 2, 4, 11, 15, 6, 13,
+ 28, 7, 0, 28, 73, 103, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 85, 93, 19, 60, 11,
+ 25, 70, 9, 20, 65, 74, 2, 81, 105, 74, 110, 126, 126, 126, 60, 4,
+ 65, 9, 20, 65, 85, 9, 11, 65, 0, 68, 68, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 66, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 13, 70, 85, 44, 22, 14, 54, 62, 27, 30,
+ 19, 30, 11, 11, 35, 80, 75, 74, 81, 24, 65, 21, 33, 67, 71, 66,
+ 22, 0, 75, 74, 83, 19, 68, 9, 0, 67, 8, 64, 10, 9, 9, 17,
+ 24, 13, 6, 11, 62, 62, 62, 62, 8, 64, 3, 13, 64, 11, 13, 5,
+ 67, 38, 66, 108, 104, 57, 9, 16, 5, 6, 11, 18, 48, 28, 12, 65,
+ 1, 2, 19, 24, 104, 3, 5, 80, 65, 74, 7, 7, 71, 19, 12, 12,
+ 90, 8, 79, 75, 5, 89, 7, 8, 5, 79, 100, 64, 77, 74, 79, 93,
+ 89, 76, 126, 62, 126, 86, 89, 96, 111, 98, 109, 126, 121, 116, 95, 122,
+ 89, 62, 110, 65, 0, 71, 76, 77, 75, 80, 79, 80, 95, 96, 92, 95,
+ 96, 120, 75, 77, 99, 73, 80, 81, 87, 91, 97, 94, 100, 98, 85, 100,
+ 103, 94, 88, 15, 34, 22, 10, 11, 17, 8, 4, 4, 30, 20, 33, 24,
+ 22, 19, 28, 19, 25, 21, 18, 18, 47, 39, 34, 30, 35, 14, 5, 3,
+ 2, 71, 54, 29, 2, 65, 14, 2, 73, 67, 3, 40, 28, 9, 0, 18,
+ 5, 4, 67, 67, 62, 68, 3, 8, 9, 8, 5, 17, 21, 8, 18, 22,
+ 32, 67, 2, 73, 64, 26, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69,
+ 71, 88, 14, 13, 30, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65,
+ 69, 67, 16, 98, 81, 16, 84, 67, 74, 68, 10, 74, 76, 4, 5, 92,
+ 74, 99, 17, 20, 25, 4, 69, 65, 68, 73, 77, 85, 87, 87, 100, 95,
+ 97, 118, 110, 117, 126, 109, 108, 102, 99, 109, 96, 103, 100, 88, 95, 68,
+ 71, 73, 74, 93, 85, 86, 105, 92, 100, 101, 121, 105, 109, 112, 81, 79,
+ 116, 82, 85, 95, 110, 99, 106, 108, 91, 107, 99, 103, 111, 109, 113, 100,
+ 106, 111, 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19, 36, 4,
+ 64, 27, 75, 106, 126, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 31,
+ 17, 9, 7, 1, 72, 67, 11, 2, 24, 34, 2, 4, 11, 15, 6, 13,
+ 28, 7, 0, 27, 75, 106, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 86, 95, 18, 60, 11,
+ 27, 70, 9, 21, 66, 75, 2, 82, 107, 75, 112, 126, 126, 126, 62, 5,
+ 64, 9, 21, 66, 85, 10, 11, 65, 0, 67, 67, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 66, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 12, 70, 85, 46, 23, 15, 56, 62, 29, 31,
+ 20, 32, 13, 12, 38, 80, 74, 74, 80, 24, 65, 22, 35, 67, 70, 65,
+ 24, 0, 75, 74, 83, 19, 68, 9, 1, 66, 9, 0, 11, 10, 10, 18,
+ 26, 14, 8, 12, 62, 62, 62, 62, 9, 0, 4, 14, 64, 11, 13, 5,
+ 66, 40, 66, 110, 106, 60, 9, 17, 5, 6, 11, 19, 50, 29, 13, 66,
+ 1, 2, 20, 24, 105, 4, 5, 80, 66, 75, 6, 6, 72, 19, 12, 12,
+ 91, 9, 80, 75, 4, 89, 7, 7, 4, 81, 103, 65, 78, 76, 81, 95,
+ 91, 78, 126, 62, 126, 88, 91, 99, 114, 100, 112, 126, 125, 118, 97, 125,
+ 91, 62, 111, 67, 65, 73, 78, 79, 77, 82, 81, 82, 98, 98, 94, 96,
+ 98, 122, 75, 77, 99, 74, 81, 82, 89, 92, 98, 95, 101, 99, 85, 101,
+ 103, 95, 87, 16, 35, 22, 10, 12, 17, 9, 5, 5, 32, 22, 33, 25,
+ 22, 19, 29, 20, 27, 23, 20, 18, 48, 40, 35, 31, 36, 14, 6, 4,
+ 3, 71, 55, 29, 2, 66, 14, 2, 73, 66, 3, 40, 27, 8, 64, 18,
+ 5, 5, 67, 66, 62, 66, 4, 10, 11, 10, 6, 18, 22, 9, 20, 23,
+ 34, 66, 3, 72, 0, 28, 72, 74, 70, 4, 5, 69, 78, 69, 81, 69,
+ 71, 88, 14, 13, 31, 5, 66, 13, 8, 1, 7, 6, 1, 76, 0, 65,
+ 69, 67, 17, 99, 82, 16, 85, 67, 74, 69, 10, 74, 77, 4, 5, 93,
+ 74, 100, 16, 19, 24, 2, 71, 67, 70, 76, 79, 88, 90, 90, 103, 98,
+ 99, 123, 114, 121, 126, 112, 111, 105, 101, 111, 98, 104, 101, 88, 95, 71,
+ 73, 75, 76, 96, 88, 88, 108, 94, 102, 103, 124, 107, 111, 114, 81, 79,
+ 118, 83, 86, 96, 112, 101, 108, 109, 92, 109, 100, 103, 113, 110, 113, 102,
+ 108, 113, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20, 37, 4,
+ 64, 26, 77, 109, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 32,
+ 17, 10, 8, 1, 72, 67, 11, 2, 25, 35, 2, 4, 12, 16, 6, 14,
+ 29, 7, 0, 26, 77, 109, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 88, 97, 17, 60, 11,
+ 29, 70, 10, 22, 66, 75, 2, 82, 108, 76, 115, 126, 126, 126, 62, 6,
+ 64, 10, 22, 66, 86, 11, 11, 66, 0, 67, 67, 64, 80, 78, 91, 5,
+ 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 11, 71, 85, 49, 24, 16, 57, 62, 30, 33,
+ 22, 33, 14, 13, 40, 80, 74, 73, 80, 24, 65, 23, 37, 67, 69, 65,
+ 26, 0, 76, 75, 84, 19, 68, 10, 1, 65, 10, 0, 12, 10, 11, 20,
+ 27, 14, 9, 13, 62, 62, 62, 62, 9, 0, 4, 14, 64, 11, 14, 6,
+ 66, 42, 66, 112, 108, 62, 9, 17, 5, 6, 11, 19, 51, 30, 13, 66,
+ 1, 2, 20, 25, 106, 4, 5, 81, 66, 76, 6, 6, 72, 19, 12, 12,
+ 92, 9, 81, 76, 4, 89, 7, 7, 4, 83, 106, 66, 80, 78, 84, 97,
+ 94, 80, 126, 62, 126, 90, 93, 101, 117, 103, 115, 126, 126, 121, 99, 126,
+ 93, 62, 113, 69, 67, 75, 81, 82, 79, 84, 83, 84, 100, 100, 96, 98,
+ 99, 124, 75, 77, 100, 75, 82, 83, 90, 93, 99, 96, 103, 100, 86, 102,
+ 104, 95, 87, 18, 36, 23, 10, 12, 18, 9, 5, 5, 34, 23, 33, 25,
+ 23, 20, 30, 21, 28, 24, 22, 19, 48, 40, 35, 31, 37, 15, 6, 4,
+ 3, 71, 55, 29, 1, 66, 14, 2, 73, 66, 3, 39, 27, 7, 65, 18,
+ 5, 5, 67, 66, 62, 65, 6, 11, 12, 11, 7, 20, 24, 10, 21, 25,
+ 36, 66, 4, 72, 1, 30, 71, 74, 70, 4, 5, 69, 78, 69, 81, 69,
+ 71, 89, 15, 14, 32, 5, 66, 14, 8, 1, 7, 6, 1, 76, 0, 65,
+ 69, 67, 17, 100, 83, 16, 86, 68, 75, 69, 10, 75, 78, 4, 5, 94,
+ 74, 101, 15, 18, 23, 1, 73, 69, 72, 78, 82, 90, 93, 93, 106, 100,
+ 101, 126, 118, 125, 126, 116, 114, 107, 103, 114, 100, 106, 103, 89, 96, 73,
+ 76, 78, 79, 99, 90, 91, 111, 97, 105, 106, 126, 109, 113, 115, 82, 80,
+ 119, 85, 88, 98, 114, 102, 110, 111, 93, 110, 101, 104, 114, 111, 114, 103,
+ 109, 114, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20, 38, 4,
+ 64, 25, 79, 111, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 32,
+ 18, 10, 8, 2, 72, 67, 12, 3, 26, 36, 2, 5, 12, 16, 6, 14,
+ 29, 7, 0, 25, 79, 111, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 89, 99, 16, 60, 11,
+ 31, 70, 10, 23, 66, 76, 2, 83, 110, 77, 117, 126, 126, 126, 62, 7,
+ 64, 10, 23, 66, 86, 12, 11, 66, 0, 67, 66, 64, 80, 78, 91, 5,
+ 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 10, 71, 85, 51, 25, 17, 59, 62, 32, 34,
+ 24, 35, 15, 14, 42, 80, 74, 73, 80, 24, 65, 24, 39, 67, 68, 64,
+ 28, 0, 76, 75, 84, 19, 68, 10, 2, 64, 11, 1, 13, 11, 12, 21,
+ 29, 15, 10, 14, 62, 62, 62, 62, 9, 0, 4, 15, 64, 11, 14, 6,
+ 65, 44, 66, 114, 110, 62, 9, 17, 5, 6, 11, 20, 53, 31, 13, 66,
+ 1, 2, 21, 26, 107, 4, 5, 81, 67, 77, 5, 6, 73, 19, 12, 12,
+ 93, 9, 82, 77, 3, 89, 7, 6, 3, 85, 109, 67, 82, 80, 86, 99,
+ 96, 82, 126, 62, 126, 92, 95, 103, 120, 105, 118, 126, 126, 124, 101, 126,
+ 95, 62, 115, 71, 69, 77, 83, 84, 81, 86, 85, 86, 102, 102, 98, 100,
+ 101, 126, 75, 77, 100, 76, 83, 84, 91, 94, 100, 97, 105, 101, 86, 103,
+ 105, 96, 86, 19, 37, 23, 10, 12, 19, 10, 6, 6, 36, 24, 33, 25,
+ 23, 21, 31, 22, 30, 26, 24, 20, 49, 41, 36, 32, 38, 15, 6, 4,
+ 4, 71, 56, 29, 0, 66, 14, 2, 73, 65, 3, 39, 26, 6, 66, 18,
+ 5, 5, 67, 66, 62, 64, 7, 12, 14, 13, 8, 22, 26, 11, 23, 27,
+ 38, 65, 5, 71, 2, 32, 71, 74, 70, 5, 6, 69, 78, 69, 82, 69,
+ 71, 89, 15, 14, 33, 5, 66, 14, 8, 1, 7, 6, 1, 77, 0, 65,
+ 69, 67, 18, 101, 84, 16, 87, 69, 76, 70, 10, 76, 79, 4, 5, 95,
+ 74, 102, 14, 17, 22, 64, 75, 71, 74, 80, 84, 93, 96, 96, 109, 103,
+ 103, 126, 122, 126, 126, 119, 117, 110, 105, 116, 102, 108, 104, 90, 97, 75,
+ 78, 80, 81, 102, 93, 93, 114, 99, 107, 108, 126, 111, 115, 117, 83, 81,
+ 121, 86, 89, 100, 116, 104, 112, 113, 94, 112, 102, 105, 115, 112, 115, 105,
+ 110, 115, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21, 39, 4,
+ 64, 24, 81, 114, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 33,
+ 18, 10, 8, 2, 72, 67, 12, 3, 27, 37, 2, 5, 12, 16, 6, 14,
+ 30, 7, 0, 24, 81, 114, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 91, 102, 15, 60, 10,
+ 32, 71, 10, 23, 67, 77, 2, 84, 112, 79, 120, 126, 126, 126, 62, 7,
+ 64, 10, 23, 67, 87, 12, 11, 67, 0, 67, 66, 65, 81, 78, 91, 4,
+ 65, 67, 4, 72, 65, 80, 0, 74, 73, 80, 6, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 9, 72, 86, 53, 26, 18, 60, 62, 33, 35,
+ 25, 36, 16, 15, 44, 80, 74, 73, 80, 24, 65, 24, 41, 67, 68, 64,
+ 29, 64, 77, 76, 85, 19, 68, 10, 2, 64, 11, 1, 13, 11, 12, 22,
+ 30, 15, 11, 15, 62, 62, 62, 62, 9, 0, 4, 15, 65, 11, 14, 6,
+ 65, 46, 66, 116, 112, 62, 9, 17, 5, 6, 11, 20, 54, 31, 13, 67,
+ 0, 2, 21, 26, 109, 4, 5, 82, 68, 79, 4, 5, 74, 19, 12, 11,
+ 95, 9, 83, 78, 2, 89, 6, 5, 2, 88, 113, 69, 84, 83, 89, 102,
+ 99, 84, 126, 62, 126, 95, 97, 106, 124, 108, 122, 126, 126, 126, 103, 126,
+ 97, 62, 117, 74, 72, 80, 86, 87, 84, 89, 88, 88, 105, 105, 100, 102,
+ 103, 126, 75, 78, 101, 77, 85, 86, 93, 96, 102, 99, 107, 102, 87, 104,
+ 106, 97, 86, 20, 37, 23, 10, 12, 19, 10, 6, 6, 38, 25, 33, 25,
+ 23, 21, 31, 23, 31, 27, 25, 20, 49, 41, 36, 32, 39, 15, 6, 4,
+ 4, 72, 56, 28, 64, 67, 14, 2, 73, 65, 2, 38, 25, 4, 67, 17,
+ 5, 5, 67, 66, 62, 0, 8, 13, 15, 14, 9, 23, 27, 12, 24, 28,
+ 40, 65, 5, 71, 3, 33, 71, 74, 70, 5, 6, 69, 79, 70, 83, 69,
+ 72, 90, 15, 14, 34, 5, 67, 14, 8, 0, 7, 6, 1, 78, 0, 65,
+ 69, 67, 18, 102, 85, 16, 89, 70, 77, 71, 9, 77, 80, 4, 4, 97,
+ 75, 104, 12, 15, 21, 66, 77, 74, 77, 83, 87, 96, 99, 99, 113, 106,
+ 105, 126, 126, 126, 126, 123, 121, 113, 108, 119, 104, 110, 106, 91, 98, 78,
+ 81, 83, 84, 105, 96, 96, 118, 102, 110, 111, 126, 113, 117, 119, 84, 82,
+ 123, 88, 91, 102, 119, 106, 114, 115, 96, 114, 104, 106, 117, 113, 116, 107,
+ 112, 117, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, 21, 39, 4,
+ 65, 22, 83, 117, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 33,
+ 18, 10, 8, 2, 72, 67, 12, 3, 27, 37, 2, 5, 12, 16, 6, 14,
+ 30, 6, 64, 22, 83, 117, 126, 126, 126, 126, 126, 126, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 92, 104, 14, 61, 10,
+ 34, 71, 11, 24, 67, 77, 3, 84, 113, 80, 122, 126, 126, 126, 62, 8,
+ 0, 11, 24, 67, 87, 13, 11, 67, 1, 66, 65, 65, 81, 77, 90, 4,
+ 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 9, 72, 86, 56, 28, 20, 62, 62, 35, 37,
+ 27, 38, 18, 17, 47, 80, 73, 72, 79, 24, 65, 25, 44, 66, 67, 0,
+ 31, 64, 77, 76, 85, 20, 68, 11, 3, 0, 12, 2, 14, 12, 13, 24,
+ 32, 16, 13, 17, 62, 62, 62, 62, 10, 1, 5, 16, 65, 12, 15, 7,
+ 64, 49, 65, 118, 113, 62, 9, 18, 5, 7, 12, 21, 56, 32, 14, 67,
+ 0, 2, 22, 27, 110, 5, 5, 82, 68, 80, 4, 5, 74, 19, 12, 11,
+ 96, 10, 83, 78, 2, 89, 6, 5, 2, 90, 116, 70, 85, 85, 91, 104,
+ 101, 86, 126, 62, 126, 97, 98, 108, 126, 110, 125, 126, 126, 126, 105, 126,
+ 99, 62, 118, 76, 74, 82, 88, 89, 86, 91, 90, 90, 107, 107, 101, 103,
+ 104, 126, 75, 78, 101, 77, 86, 87, 94, 97, 103, 100, 108, 103, 87, 105,
+ 106, 97, 85, 22, 38, 24, 10, 13, 20, 11, 7, 7, 41, 27, 34, 26,
+ 24, 22, 32, 25, 33, 29, 27, 21, 50, 42, 37, 33, 40, 16, 7, 5,
+ 5, 72, 57, 28, 64, 67, 15, 3, 73, 64, 2, 38, 25, 3, 68, 17,
+ 6, 6, 66, 65, 62, 2, 10, 15, 17, 16, 11, 25, 29, 14, 26, 30,
+ 43, 64, 6, 70, 5, 35, 70, 73, 69, 6, 7, 68, 79, 70, 83, 69,
+ 72, 90, 16, 15, 35, 6, 67, 15, 9, 0, 8, 7, 1, 78, 1, 64,
+ 68, 66, 19, 102, 86, 16, 90, 70, 77, 71, 9, 77, 80, 4, 4, 98,
+ 75, 105, 11, 14, 21, 67, 78, 76, 79, 85, 89, 98, 101, 101, 116, 108,
+ 107, 126, 126, 126, 126, 126, 124, 115, 110, 121, 105, 111, 107, 91, 98, 80,
+ 83, 85, 86, 107, 98, 98, 121, 104, 112, 113, 126, 114, 118, 120, 84, 82,
+ 124, 89, 92, 103, 121, 107, 115, 116, 97, 115, 105, 106, 118, 113, 116, 108,
+ 113, 118, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, 22, 40, 4,
+ 65, 21, 85, 119, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 34,
+ 19, 11, 9, 3, 71, 66, 13, 4, 28, 38, 3, 6, 13, 17, 6, 15,
+ 31, 6, 64, 21, 85, 119, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 93, 106, 13, 61, 10,
+ 36, 71, 11, 25, 67, 78, 3, 85, 115, 81, 125, 126, 126, 126, 62, 9,
+ 0, 11, 25, 67, 87, 14, 11, 68, 1, 66, 64, 65, 81, 77, 90, 4,
+ 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 8, 72, 86, 58, 29, 21, 62, 62, 36, 38,
+ 29, 39, 19, 18, 49, 80, 73, 72, 79, 24, 65, 26, 46, 66, 66, 1,
+ 33, 64, 77, 76, 86, 20, 68, 11, 4, 1, 13, 3, 15, 12, 14, 25,
+ 33, 17, 14, 18, 62, 62, 62, 62, 10, 1, 5, 16, 65, 12, 15, 7,
+ 64, 51, 65, 120, 115, 62, 9, 18, 5, 7, 12, 21, 58, 33, 14, 67,
+ 0, 2, 23, 28, 111, 5, 5, 82, 69, 81, 3, 5, 75, 19, 12, 11,
+ 97, 10, 84, 79, 1, 89, 6, 4, 1, 92, 119, 71, 87, 87, 93, 106,
+ 103, 88, 126, 62, 126, 99, 100, 110, 126, 112, 126, 126, 126, 126, 107, 126,
+ 101, 62, 120, 78, 76, 84, 90, 91, 88, 93, 92, 92, 109, 109, 103, 105,
+ 106, 126, 75, 78, 102, 78, 87, 88, 95, 98, 104, 101, 110, 104, 87, 106,
+ 107, 98, 84, 23, 39, 24, 10, 13, 21, 12, 8, 8, 43, 28, 34, 26,
+ 24, 23, 33, 26, 35, 31, 29, 22, 51, 43, 38, 34, 41, 16, 7, 5,
+ 6, 72, 58, 28, 65, 67, 15, 3, 73, 64, 2, 38, 24, 2, 69, 17,
+ 6, 6, 66, 65, 62, 3, 11, 16, 19, 18, 12, 27, 31, 15, 28, 32,
+ 45, 0, 7, 70, 6, 37, 70, 73, 69, 7, 7, 68, 79, 70, 84, 69,
+ 72, 90, 16, 15, 36, 6, 67, 15, 9, 0, 8, 7, 1, 79, 1, 64,
+ 68, 66, 20, 103, 87, 16, 91, 71, 78, 72, 9, 78, 81, 4, 4, 99,
+ 75, 106, 10, 13, 20, 69, 80, 78, 81, 87, 91, 101, 104, 104, 119, 111,
+ 109, 126, 126, 126, 126, 126, 126, 118, 112, 124, 107, 113, 108, 92, 99, 82,
+ 85, 88, 88, 110, 101, 101, 124, 106, 115, 115, 126, 116, 120, 122, 85, 83,
+ 126, 90, 93, 105, 123, 109, 117, 118, 98, 117, 106, 107, 119, 114, 117, 110,
+ 114, 119, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, 22, 41, 4,
+ 65, 20, 87, 122, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 35,
+ 19, 11, 9, 3, 71, 66, 13, 4, 29, 39, 3, 6, 13, 17, 6, 15,
+ 32, 6, 64, 20, 87, 122, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 95, 108, 12, 61, 10,
+ 38, 71, 12, 26, 67, 78, 3, 85, 116, 82, 126, 126, 126, 126, 62, 10,
+ 0, 12, 26, 67, 88, 15, 11, 68, 1, 66, 64, 65, 81, 77, 90, 4,
+ 64, 65, 4, 71, 0, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 7, 73, 86, 61, 30, 22, 62, 62, 38, 40,
+ 31, 41, 20, 19, 51, 80, 73, 71, 79, 24, 65, 27, 48, 66, 65, 1,
+ 35, 64, 78, 77, 86, 20, 68, 12, 4, 2, 14, 3, 16, 13, 15, 27,
+ 35, 17, 15, 19, 62, 62, 62, 62, 10, 1, 5, 17, 65, 12, 16, 8,
+ 0, 53, 65, 122, 117, 62, 9, 18, 5, 7, 12, 22, 59, 34, 14, 67,
+ 0, 2, 23, 29, 112, 5, 5, 83, 69, 82, 3, 5, 75, 19, 12, 11,
+ 98, 10, 85, 80, 1, 89, 6, 4, 1, 94, 122, 72, 89, 89, 96, 108,
+ 106, 90, 126, 62, 126, 101, 102, 112, 126, 115, 126, 126, 126, 126, 109, 126,
+ 103, 62, 122, 80, 78, 86, 93, 94, 90, 95, 94, 94, 111, 111, 105, 107,
+ 107, 126, 75, 78, 102, 79, 88, 89, 96, 99, 105, 102, 112, 105, 88, 107,
+ 108, 98, 84, 25, 40, 25, 10, 13, 22, 12, 8, 8, 45, 29, 34, 26,
+ 25, 24, 34, 27, 36, 32, 31, 23, 51, 43, 38, 34, 42, 17, 7, 5,
+ 6, 72, 58, 28, 66, 67, 15, 3, 73, 0, 2, 37, 24, 1, 70, 17,
+ 6, 6, 66, 65, 62, 4, 13, 17, 20, 19, 13, 29, 33, 16, 29, 34,
+ 47, 0, 8, 69, 7, 39, 69, 73, 69, 7, 8, 68, 79, 70, 84, 69,
+ 72, 91, 17, 16, 37, 6, 67, 16, 9, 0, 8, 7, 1, 79, 1, 64,
+ 68, 66, 20, 104, 88, 16, 92, 72, 79, 72, 9, 79, 82, 4, 4, 100,
+ 75, 107, 9, 12, 19, 70, 82, 80, 83, 89, 94, 103, 107, 107, 122, 113,
+ 111, 126, 126, 126, 126, 126, 126, 120, 114, 126, 109, 115, 110, 93, 100, 84,
+ 88, 90, 91, 113, 103, 103, 126, 109, 117, 118, 126, 118, 122, 123, 86, 84,
+ 126, 92, 95, 107, 125, 110, 119, 120, 99, 118, 107, 108, 120, 115, 118, 111,
+ 115, 120, 69, 2, 18, 5, 38, 48, 2, 12, 21, 25, 6, 23, 42, 4,
+ 65, 19, 89, 124, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 35,
+ 20, 11, 9, 4, 71, 66, 14, 5, 30, 40, 3, 7, 13, 17, 6, 15,
+ 32, 6, 64, 19, 89, 124, 126, 126, 126, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 47, 62, 62, 12, 1,
+ 99, 47, 85, 102, 6, 6, 73, 6, 23, 53, 62, 62, 21, 97, 126, 117,
+ 74, 85, 102, 6, 93, 88, 19, 8, 89, 103, 116, 6, 5, 84, 96, 0,
+ 85, 106, 0, 75, 90, 101, 8, 79, 75, 97, 13, 3, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 29, 88, 126, 126, 91, 95, 84, 86, 89, 91,
+ 126, 76, 103, 90, 126, 80, 76, 84, 78, 8, 2, 83, 126, 79, 104, 91,
+ 126, 65, 79, 72, 92, 7, 68, 71, 98, 86, 88, 82, 72, 67, 72, 89,
+ 69, 4, 66, 6, 71, 71, 5, 74, 19, 69, 1, 12, 16, 21, 22, 10,
+ 76, 78, 83, 11, 67, 90, 67, 72, 75, 80, 83, 64, 32, 64, 94, 75,
+ 0, 74, 28, 36, 91, 65, 69, 77, 66, 1, 68, 81, 33, 56, 40, 74,
+ 66, 124, 26, 62, 62, 126, 24, 21, 29, 34, 32, 26, 21, 23, 30, 20,
+ 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, 11, 26, 14, 5, 15, 18,
+ 69, 30, 0, 62, 62, 62, 53, 62, 62, 62, 62, 46, 38, 34, 30, 48,
+ 43, 73, 29, 32, 19, 47, 27, 27, 35, 42, 43, 51, 47, 21, 93, 7,
+ 6, 25, 126, 115, 82, 1, 10, 4, 85, 89, 94, 92, 126, 100, 6, 67,
+ 71, 77, 85, 88, 104, 98, 126, 82, 15, 2, 66, 70, 75, 79, 83, 92,
+ 108, 79, 69, 75, 5, 5, 78, 83, 81, 99, 81, 25, 1, 5, 4, 73,
+ 76, 86, 83, 87, 62, 126, 126, 120, 126, 114, 117, 118, 117, 113, 118, 120,
+ 124, 94, 102, 99, 106, 126, 92, 6, 86, 94, 91, 77, 71, 73, 64, 81,
+ 64, 6, 67, 68, 67, 68, 77, 64, 68, 78, 8, 4, 65, 9, 19, 3,
+ 70, 76, 86, 70, 64, 70, 8, 7, 69, 65, 74, 9, 9, 76, 82, 77,
+ 77, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 52, 62, 62, 62, 62, 62, 62, 48, 62, 62, 46, 25, 18, 9, 79, 62,
+ 62, 62, 62, 48, 48, 38, 41, 47, 45, 35, 22, 35, 16, 1, 32, 37,
+ 39, 40, 47, 33, 34, 22, 21, 3, 11, 3, 78, 123, 10, 7, 2, 30,
+ 13, 2, 78, 74, 72, 72, 75, 71, 0, 70, 75, 72, 67, 10, 4, 11,
+ 68, 62, 62, 62, 62, 56, 51, 40, 25, 64, 71, 26, 19, 14, 7, 4,
+ 0, 67, 68, 79, 78, 74, 72, 72, 75, 71, 0, 70, 75, 72, 67, 10,
+ 4, 11, 68, 62, 62, 62, 62, 56, 51, 40, 25, 64, 75, 65, 4, 67,
+ 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 46, 62, 62, 13, 2,
+ 97, 46, 84, 100, 6, 6, 71, 6, 22, 52, 62, 60, 19, 97, 125, 115,
+ 73, 84, 100, 6, 92, 87, 20, 8, 88, 102, 114, 5, 4, 84, 96, 0,
+ 84, 105, 0, 75, 89, 100, 8, 78, 74, 96, 14, 3, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 29, 87, 125, 124, 89, 94, 82, 84, 88, 89,
+ 125, 75, 101, 89, 124, 80, 76, 84, 78, 9, 2, 82, 124, 78, 103, 90,
+ 125, 65, 78, 72, 91, 8, 68, 70, 97, 85, 87, 81, 71, 66, 71, 88,
+ 68, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11,
+ 76, 77, 82, 11, 67, 89, 67, 71, 74, 79, 81, 1, 33, 1, 92, 75,
+ 64, 73, 29, 37, 91, 65, 68, 77, 65, 1, 67, 79, 33, 56, 41, 72,
+ 67, 122, 25, 62, 62, 125, 24, 21, 29, 34, 32, 26, 21, 23, 30, 20,
+ 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, 11, 26, 14, 4, 15, 18,
+ 69, 29, 0, 62, 62, 62, 52, 62, 62, 62, 62, 45, 37, 32, 29, 46,
+ 42, 74, 28, 31, 18, 46, 27, 27, 34, 41, 42, 50, 46, 20, 93, 7,
+ 6, 24, 125, 113, 80, 2, 10, 4, 84, 88, 93, 91, 125, 98, 7, 66,
+ 70, 76, 83, 87, 102, 97, 124, 81, 16, 3, 65, 69, 74, 78, 82, 91,
+ 106, 78, 67, 74, 6, 5, 77, 82, 80, 98, 80, 26, 2, 6, 5, 72,
+ 75, 85, 82, 86, 62, 125, 125, 118, 125, 112, 115, 116, 115, 111, 116, 118,
+ 121, 93, 101, 98, 105, 123, 91, 5, 85, 93, 90, 76, 71, 72, 64, 80,
+ 64, 6, 67, 68, 66, 68, 77, 64, 68, 77, 8, 4, 65, 9, 19, 3,
+ 70, 75, 84, 70, 64, 69, 8, 7, 69, 65, 73, 9, 9, 75, 81, 76,
+ 76, 20, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 50, 62, 62, 62, 62, 62, 62, 47, 60, 60, 45, 24, 17, 9, 79, 62,
+ 62, 62, 60, 46, 47, 37, 39, 46, 43, 34, 20, 33, 15, 0, 31, 36,
+ 37, 39, 46, 32, 33, 21, 20, 2, 11, 3, 78, 122, 9, 6, 1, 29,
+ 12, 1, 77, 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, 12,
+ 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, 70, 27, 20, 15, 8, 5,
+ 1, 66, 67, 78, 77, 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11,
+ 5, 12, 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, 75, 65, 4, 66,
+ 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 44, 60, 62, 14, 2,
+ 95, 44, 84, 99, 6, 6, 70, 5, 21, 51, 60, 57, 17, 98, 123, 114,
+ 73, 84, 99, 6, 92, 86, 20, 8, 87, 101, 113, 4, 3, 84, 96, 0,
+ 84, 104, 0, 75, 89, 100, 8, 78, 74, 95, 14, 3, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 29, 86, 124, 122, 88, 93, 80, 82, 87, 88,
+ 123, 74, 100, 88, 122, 81, 76, 84, 78, 9, 2, 81, 122, 78, 102, 89,
+ 123, 65, 78, 72, 91, 8, 68, 70, 96, 85, 86, 81, 71, 66, 71, 87,
+ 67, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11,
+ 77, 76, 81, 10, 67, 89, 67, 70, 74, 79, 80, 2, 34, 3, 90, 76,
+ 65, 73, 29, 37, 92, 65, 68, 78, 64, 1, 67, 78, 33, 56, 41, 71,
+ 68, 121, 24, 62, 62, 124, 24, 21, 29, 33, 31, 26, 21, 23, 29, 19,
+ 26, 16, 8, 5, 3, 18, 18, 20, 15, 7, 11, 25, 13, 3, 14, 17,
+ 69, 28, 64, 62, 62, 62, 50, 60, 62, 62, 62, 44, 35, 30, 27, 44,
+ 40, 75, 27, 30, 16, 45, 26, 26, 33, 39, 40, 48, 44, 18, 93, 6,
+ 5, 22, 124, 112, 79, 3, 10, 4, 83, 87, 92, 90, 123, 97, 8, 65,
+ 69, 75, 82, 86, 101, 96, 122, 80, 16, 3, 65, 69, 73, 77, 81, 90,
+ 105, 78, 66, 73, 6, 5, 76, 81, 80, 97, 79, 26, 3, 6, 5, 71,
+ 74, 84, 81, 85, 62, 124, 123, 116, 123, 111, 114, 114, 113, 110, 114, 116,
+ 119, 92, 100, 97, 104, 120, 91, 4, 85, 92, 89, 76, 71, 72, 64, 80,
+ 64, 5, 67, 68, 65, 68, 77, 64, 68, 77, 8, 4, 65, 8, 18, 3,
+ 70, 75, 83, 71, 64, 68, 7, 7, 69, 65, 73, 9, 9, 75, 80, 76,
+ 76, 18, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 48, 62, 62, 62, 62, 62, 61, 45, 58, 58, 43, 23, 16, 8, 79, 62,
+ 62, 62, 58, 44, 45, 35, 37, 44, 41, 32, 18, 31, 13, 64, 30, 35,
+ 35, 37, 44, 30, 31, 20, 19, 1, 10, 2, 78, 121, 8, 5, 64, 28,
+ 11, 0, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11, 6, 13,
+ 66, 62, 62, 62, 60, 52, 48, 36, 22, 66, 69, 27, 20, 16, 9, 6,
+ 1, 65, 67, 77, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11,
+ 6, 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, 66, 75, 65, 4, 66,
+ 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 42, 59, 61, 14, 2,
+ 93, 43, 84, 97, 6, 5, 69, 4, 20, 50, 58, 53, 15, 99, 121, 112,
+ 73, 84, 97, 6, 91, 85, 21, 8, 86, 100, 112, 3, 2, 84, 97, 0,
+ 84, 103, 0, 76, 89, 100, 8, 78, 74, 94, 15, 3, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 28, 86, 123, 120, 87, 92, 79, 81, 86, 87,
+ 121, 73, 99, 87, 120, 82, 76, 84, 78, 10, 2, 80, 120, 78, 101, 88,
+ 121, 65, 78, 72, 91, 9, 68, 69, 95, 85, 85, 81, 71, 66, 70, 86,
+ 67, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12,
+ 77, 76, 80, 10, 67, 89, 67, 69, 74, 78, 79, 3, 35, 4, 88, 76,
+ 66, 72, 29, 37, 93, 65, 67, 78, 64, 1, 67, 77, 33, 56, 41, 70,
+ 69, 119, 23, 62, 62, 122, 24, 21, 28, 32, 31, 25, 20, 23, 29, 18,
+ 25, 16, 8, 5, 2, 18, 17, 19, 14, 7, 11, 24, 13, 2, 14, 16,
+ 69, 27, 64, 62, 62, 61, 49, 58, 62, 62, 62, 43, 33, 28, 26, 42,
+ 38, 77, 26, 29, 14, 44, 25, 25, 32, 38, 38, 46, 42, 17, 93, 5,
+ 4, 21, 122, 110, 77, 3, 10, 4, 82, 86, 91, 89, 121, 96, 9, 64,
+ 68, 75, 81, 85, 99, 95, 120, 80, 17, 4, 64, 68, 72, 77, 81, 89,
+ 104, 78, 64, 72, 6, 5, 75, 81, 80, 96, 78, 27, 4, 7, 5, 70,
+ 74, 83, 81, 85, 62, 122, 122, 115, 121, 110, 112, 113, 112, 108, 112, 114,
+ 117, 92, 99, 97, 103, 117, 91, 3, 85, 91, 88, 76, 71, 72, 64, 79,
+ 64, 4, 67, 68, 65, 68, 77, 64, 68, 77, 7, 4, 65, 7, 17, 3,
+ 70, 75, 82, 72, 64, 67, 6, 7, 69, 65, 72, 9, 8, 74, 79, 76,
+ 76, 17, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 46, 62, 62, 62, 62, 62, 59, 43, 56, 55, 41, 22, 15, 7, 79, 62,
+ 62, 62, 56, 42, 43, 34, 35, 42, 39, 30, 16, 29, 11, 65, 29, 34,
+ 33, 36, 42, 29, 29, 18, 17, 0, 9, 1, 78, 120, 7, 3, 65, 27,
+ 10, 64, 77, 72, 70, 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13,
+ 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 69, 28, 21, 17, 9, 7,
+ 2, 65, 66, 77, 77, 72, 70, 70, 71, 68, 3, 69, 71, 69, 64, 12,
+ 7, 13, 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 75, 65, 4, 65,
+ 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 40, 57, 60, 15, 2,
+ 92, 41, 84, 96, 5, 5, 68, 3, 18, 48, 56, 50, 12, 100, 119, 111,
+ 73, 84, 96, 5, 91, 84, 21, 7, 86, 99, 110, 2, 0, 85, 97, 0,
+ 83, 102, 64, 76, 89, 100, 8, 78, 74, 94, 15, 3, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 28, 85, 122, 118, 86, 91, 77, 79, 86, 86,
+ 119, 72, 98, 86, 117, 82, 77, 84, 79, 10, 1, 79, 117, 77, 101, 88,
+ 119, 65, 78, 72, 91, 9, 68, 69, 94, 85, 85, 80, 71, 66, 70, 85,
+ 66, 5, 67, 5, 70, 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12,
+ 78, 75, 80, 9, 67, 88, 67, 68, 73, 78, 77, 5, 36, 6, 86, 77,
+ 67, 72, 30, 37, 94, 65, 67, 79, 0, 1, 67, 76, 33, 56, 41, 68,
+ 70, 118, 22, 62, 62, 121, 23, 21, 28, 32, 30, 25, 20, 23, 28, 17,
+ 24, 15, 8, 5, 2, 17, 17, 18, 14, 6, 10, 23, 12, 1, 13, 15,
+ 69, 25, 65, 62, 62, 59, 47, 57, 62, 62, 62, 42, 31, 25, 24, 40,
+ 36, 78, 24, 28, 13, 43, 24, 24, 30, 36, 36, 44, 41, 15, 93, 4,
+ 3, 19, 121, 109, 76, 4, 10, 4, 81, 85, 90, 89, 119, 94, 10, 64,
+ 68, 74, 79, 84, 98, 94, 117, 79, 17, 4, 64, 68, 71, 76, 80, 89,
+ 103, 78, 0, 71, 6, 5, 74, 80, 80, 95, 77, 27, 5, 7, 5, 69,
+ 73, 82, 80, 84, 62, 121, 120, 113, 120, 109, 111, 111, 110, 107, 111, 112,
+ 114, 91, 98, 96, 102, 114, 90, 2, 84, 90, 88, 76, 71, 72, 65, 79,
+ 65, 3, 67, 68, 64, 68, 77, 64, 68, 76, 7, 3, 65, 6, 16, 2,
+ 70, 75, 81, 73, 65, 67, 6, 6, 69, 65, 72, 8, 8, 74, 79, 76,
+ 76, 15, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 44, 62, 62, 62, 62, 62, 57, 41, 54, 53, 39, 20, 14, 6, 79, 62,
+ 62, 62, 54, 40, 41, 32, 33, 40, 37, 28, 14, 26, 10, 67, 28, 33,
+ 30, 34, 41, 27, 27, 17, 16, 64, 8, 0, 78, 119, 5, 2, 67, 25,
+ 9, 65, 77, 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, 14,
+ 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, 68, 28, 21, 17, 10, 7,
+ 2, 64, 66, 76, 77, 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12,
+ 8, 14, 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, 75, 65, 4, 65,
+ 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 38, 56, 59, 16, 2,
+ 90, 39, 83, 94, 5, 5, 67, 2, 17, 47, 54, 47, 10, 100, 117, 110,
+ 73, 83, 94, 5, 91, 83, 21, 7, 85, 98, 109, 1, 64, 85, 97, 0,
+ 83, 101, 64, 76, 89, 100, 8, 77, 74, 93, 16, 3, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 27, 85, 120, 115, 85, 90, 76, 78, 85, 85,
+ 117, 71, 97, 85, 115, 83, 77, 84, 79, 10, 1, 78, 115, 77, 100, 87,
+ 117, 65, 78, 72, 90, 9, 68, 68, 93, 84, 84, 80, 71, 65, 69, 84,
+ 66, 5, 67, 5, 69, 70, 5, 73, 21, 68, 1, 15, 18, 23, 23, 12,
+ 78, 75, 79, 9, 67, 88, 67, 67, 73, 77, 76, 6, 37, 7, 84, 77,
+ 68, 71, 30, 37, 95, 65, 66, 79, 1, 1, 67, 74, 33, 56, 41, 67,
+ 71, 116, 21, 62, 62, 120, 23, 21, 27, 31, 30, 25, 19, 23, 28, 16,
+ 23, 15, 8, 5, 2, 17, 16, 17, 13, 6, 10, 22, 12, 0, 12, 15,
+ 69, 24, 65, 62, 62, 58, 46, 55, 62, 62, 62, 41, 29, 23, 23, 38,
+ 34, 79, 23, 27, 11, 42, 23, 23, 29, 35, 34, 42, 39, 14, 93, 3,
+ 2, 17, 119, 107, 75, 4, 10, 4, 80, 84, 89, 88, 117, 93, 11, 0,
+ 67, 73, 78, 83, 96, 93, 115, 78, 18, 5, 0, 67, 70, 75, 80, 88,
+ 102, 77, 1, 70, 6, 5, 73, 80, 79, 94, 76, 27, 6, 7, 5, 68,
+ 72, 81, 80, 83, 62, 120, 119, 112, 118, 108, 109, 110, 108, 105, 109, 110,
+ 112, 90, 97, 95, 101, 111, 90, 1, 84, 89, 87, 76, 71, 72, 65, 78,
+ 65, 2, 67, 68, 0, 68, 77, 64, 68, 76, 6, 3, 65, 5, 15, 2,
+ 70, 75, 80, 73, 65, 66, 5, 6, 69, 65, 72, 8, 7, 74, 78, 76,
+ 76, 14, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 42, 62, 62, 62, 62, 62, 55, 40, 52, 50, 37, 19, 13, 5, 79, 62,
+ 62, 62, 52, 38, 39, 31, 31, 38, 35, 26, 12, 24, 8, 68, 27, 32,
+ 28, 33, 39, 26, 25, 16, 15, 65, 7, 64, 78, 118, 4, 1, 68, 24,
+ 8, 66, 77, 71, 69, 68, 69, 67, 4, 68, 69, 67, 1, 13, 9, 14,
+ 64, 62, 62, 58, 54, 46, 42, 29, 16, 70, 68, 29, 22, 18, 11, 8,
+ 3, 64, 66, 75, 77, 71, 69, 68, 69, 67, 4, 68, 69, 67, 1, 13,
+ 9, 14, 64, 62, 62, 58, 54, 46, 42, 29, 16, 70, 75, 65, 4, 65,
+ 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 37, 54, 58, 16, 3,
+ 88, 38, 83, 93, 5, 4, 66, 1, 16, 46, 53, 43, 8, 101, 115, 108,
+ 73, 83, 93, 5, 90, 82, 22, 7, 84, 97, 108, 64, 65, 85, 98, 0,
+ 83, 101, 64, 77, 88, 100, 7, 77, 74, 92, 16, 3, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 27, 84, 119, 113, 84, 89, 74, 76, 84, 84,
+ 115, 70, 96, 85, 113, 84, 77, 84, 79, 11, 1, 77, 113, 77, 99, 86,
+ 115, 65, 78, 72, 90, 10, 69, 68, 93, 84, 83, 80, 70, 65, 69, 83,
+ 65, 5, 67, 5, 69, 70, 5, 73, 21, 68, 1, 15, 18, 24, 24, 13,
+ 79, 74, 78, 8, 67, 88, 67, 66, 73, 77, 75, 7, 37, 9, 83, 78,
+ 69, 71, 30, 37, 95, 66, 66, 80, 1, 0, 66, 73, 33, 56, 42, 66,
+ 72, 115, 20, 62, 62, 118, 23, 21, 27, 30, 29, 24, 19, 22, 27, 16,
+ 23, 15, 7, 5, 1, 16, 15, 16, 13, 6, 10, 22, 11, 65, 12, 14,
+ 69, 23, 66, 62, 62, 56, 44, 53, 62, 62, 62, 39, 27, 21, 21, 36,
+ 32, 81, 22, 25, 9, 40, 22, 22, 28, 33, 32, 40, 37, 12, 93, 2,
+ 1, 16, 118, 106, 73, 5, 10, 4, 79, 84, 89, 87, 116, 92, 12, 1,
+ 66, 73, 77, 82, 95, 92, 113, 78, 18, 5, 0, 67, 69, 75, 79, 87,
+ 101, 77, 3, 69, 6, 5, 73, 79, 79, 94, 76, 28, 6, 8, 5, 67,
+ 72, 81, 79, 83, 62, 118, 117, 110, 116, 106, 108, 108, 107, 104, 107, 108,
+ 110, 90, 96, 95, 101, 108, 90, 0, 84, 89, 86, 76, 71, 72, 65, 78,
+ 65, 1, 67, 68, 0, 68, 77, 64, 68, 76, 6, 3, 65, 4, 14, 2,
+ 70, 75, 79, 74, 65, 65, 4, 6, 69, 65, 71, 8, 7, 73, 77, 76,
+ 76, 12, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 40, 62, 62, 62, 62, 62, 52, 38, 50, 48, 35, 18, 12, 4, 79, 62,
+ 62, 62, 50, 36, 38, 29, 29, 36, 32, 24, 10, 22, 6, 69, 26, 30,
+ 26, 31, 37, 24, 23, 14, 13, 66, 6, 65, 79, 117, 3, 64, 70, 23,
+ 6, 67, 76, 71, 68, 68, 68, 66, 5, 68, 68, 66, 2, 13, 10, 15,
+ 0, 62, 62, 56, 52, 44, 40, 27, 14, 71, 67, 29, 22, 19, 11, 9,
+ 3, 0, 65, 75, 76, 71, 68, 68, 68, 66, 5, 68, 68, 66, 2, 13,
+ 10, 15, 0, 62, 62, 56, 52, 44, 40, 27, 14, 71, 75, 65, 4, 64,
+ 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 35, 53, 57, 17, 3,
+ 87, 36, 83, 91, 4, 4, 65, 0, 15, 45, 51, 40, 5, 102, 113, 107,
+ 73, 83, 91, 4, 90, 81, 22, 7, 84, 96, 106, 65, 66, 85, 98, 0,
+ 82, 100, 65, 77, 88, 100, 7, 77, 74, 91, 17, 3, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 26, 84, 118, 111, 83, 88, 73, 75, 83, 83,
+ 113, 69, 95, 84, 110, 84, 78, 84, 80, 11, 1, 76, 110, 76, 99, 86,
+ 113, 65, 78, 72, 90, 10, 69, 67, 92, 84, 82, 79, 70, 65, 68, 82,
+ 65, 5, 68, 5, 69, 70, 5, 73, 21, 68, 1, 16, 18, 24, 24, 13,
+ 79, 74, 78, 8, 67, 87, 67, 65, 72, 76, 73, 9, 38, 10, 81, 78,
+ 70, 70, 31, 37, 96, 66, 65, 80, 2, 0, 66, 72, 33, 56, 42, 64,
+ 73, 113, 19, 62, 62, 117, 23, 21, 26, 30, 29, 24, 18, 22, 27, 15,
+ 22, 15, 7, 5, 1, 16, 15, 15, 12, 6, 10, 21, 11, 66, 11, 13,
+ 69, 22, 66, 62, 62, 54, 43, 52, 62, 62, 62, 38, 25, 19, 20, 34,
+ 30, 82, 21, 24, 8, 39, 21, 21, 26, 32, 30, 38, 36, 11, 93, 1,
+ 0, 14, 116, 104, 72, 5, 10, 4, 78, 83, 88, 87, 114, 90, 13, 2,
+ 66, 72, 75, 81, 93, 91, 110, 77, 19, 6, 1, 66, 68, 74, 79, 86,
+ 100, 77, 4, 68, 6, 5, 72, 79, 79, 93, 75, 28, 7, 8, 5, 66,
+ 71, 80, 79, 82, 62, 117, 116, 109, 115, 105, 106, 107, 105, 102, 105, 106,
+ 107, 89, 95, 94, 100, 105, 89, 64, 83, 88, 85, 76, 71, 72, 65, 77,
+ 66, 0, 67, 68, 1, 68, 77, 64, 68, 75, 5, 2, 65, 3, 13, 1,
+ 70, 75, 78, 75, 66, 64, 4, 5, 69, 65, 71, 7, 6, 73, 77, 76,
+ 76, 11, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 38, 62, 62, 62, 62, 62, 50, 36, 48, 45, 33, 17, 11, 3, 79, 62,
+ 61, 62, 48, 34, 36, 28, 27, 34, 30, 22, 8, 20, 5, 71, 25, 29,
+ 24, 30, 36, 23, 21, 13, 12, 67, 5, 66, 79, 116, 1, 65, 71, 21,
+ 5, 68, 76, 70, 68, 67, 67, 65, 5, 67, 67, 65, 3, 14, 11, 15,
+ 0, 62, 60, 54, 50, 42, 38, 24, 12, 72, 67, 30, 23, 19, 12, 10,
+ 4, 0, 65, 74, 76, 70, 68, 67, 67, 65, 5, 67, 67, 65, 3, 14,
+ 11, 15, 0, 62, 60, 54, 50, 42, 38, 24, 12, 72, 75, 65, 4, 64,
+ 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 33, 51, 56, 17, 3,
+ 85, 34, 83, 90, 4, 3, 64, 64, 13, 43, 49, 36, 3, 103, 111, 106,
+ 73, 83, 90, 4, 90, 81, 22, 6, 83, 95, 105, 66, 68, 86, 99, 0,
+ 82, 99, 65, 78, 88, 100, 7, 77, 74, 91, 17, 3, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 26, 83, 117, 109, 82, 88, 71, 73, 83, 82,
+ 111, 69, 94, 83, 108, 85, 78, 85, 80, 11, 0, 76, 108, 76, 98, 85,
+ 112, 65, 78, 72, 90, 10, 69, 67, 91, 84, 82, 79, 70, 65, 68, 81,
+ 64, 5, 68, 4, 69, 70, 4, 73, 21, 68, 1, 16, 18, 24, 24, 13,
+ 80, 73, 77, 7, 67, 87, 67, 64, 72, 76, 72, 10, 39, 12, 79, 79,
+ 71, 70, 31, 37, 97, 66, 65, 81, 2, 0, 66, 71, 33, 56, 42, 0,
+ 74, 112, 18, 59, 62, 116, 22, 21, 26, 29, 28, 23, 18, 22, 26, 14,
+ 21, 14, 7, 4, 0, 15, 14, 14, 12, 5, 9, 20, 10, 67, 10, 12,
+ 69, 20, 67, 62, 62, 52, 41, 50, 60, 62, 62, 37, 23, 16, 18, 31,
+ 28, 84, 19, 23, 6, 38, 20, 20, 25, 30, 28, 36, 34, 9, 93, 0,
+ 64, 12, 115, 103, 71, 6, 10, 4, 78, 82, 87, 86, 112, 89, 13, 2,
+ 65, 72, 74, 80, 92, 90, 108, 77, 19, 6, 1, 66, 68, 74, 78, 86,
+ 99, 77, 5, 67, 6, 5, 71, 78, 79, 92, 74, 28, 8, 8, 5, 65,
+ 71, 79, 78, 82, 62, 116, 114, 107, 113, 104, 105, 105, 104, 101, 104, 104,
+ 105, 89, 94, 94, 99, 102, 89, 65, 83, 87, 85, 76, 71, 72, 66, 77,
+ 66, 64, 67, 68, 1, 68, 77, 65, 68, 75, 5, 2, 66, 2, 12, 1,
+ 71, 75, 77, 76, 66, 64, 3, 5, 69, 66, 71, 7, 6, 73, 76, 76,
+ 76, 9, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61,
+ 36, 62, 62, 62, 62, 61, 48, 34, 45, 43, 31, 15, 9, 2, 79, 61,
+ 59, 62, 46, 31, 34, 26, 24, 32, 28, 20, 6, 17, 3, 72, 23, 28,
+ 21, 28, 34, 21, 19, 11, 10, 68, 4, 67, 79, 115, 0, 67, 73, 20,
+ 4, 69, 76, 70, 67, 67, 66, 65, 6, 67, 66, 65, 4, 14, 11, 16,
+ 1, 61, 58, 52, 48, 40, 36, 22, 10, 74, 66, 30, 23, 20, 12, 10,
+ 4, 1, 65, 74, 76, 70, 67, 67, 66, 65, 6, 67, 66, 65, 4, 14,
+ 11, 16, 1, 61, 58, 52, 48, 40, 36, 22, 10, 74, 75, 66, 3, 64,
+ 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 31, 49, 56, 18, 3,
+ 83, 33, 82, 88, 4, 3, 0, 64, 12, 42, 47, 33, 1, 103, 109, 104,
+ 72, 82, 88, 4, 89, 80, 23, 6, 82, 94, 104, 67, 69, 86, 99, 0,
+ 82, 98, 65, 78, 88, 100, 7, 76, 73, 90, 17, 3, 22, 0, 0, 0,
+ 77, 88, 97, 68, 15, 0, 26, 82, 115, 106, 81, 87, 69, 71, 82, 81,
+ 109, 68, 92, 82, 106, 86, 78, 85, 80, 12, 0, 75, 106, 76, 97, 84,
+ 110, 65, 77, 72, 89, 11, 69, 66, 90, 83, 81, 79, 70, 64, 67, 80,
+ 0, 5, 68, 4, 68, 69, 4, 73, 22, 68, 1, 16, 19, 25, 24, 14,
+ 80, 72, 76, 6, 67, 87, 67, 0, 72, 75, 71, 11, 40, 14, 77, 80,
+ 72, 69, 31, 38, 98, 66, 65, 81, 3, 0, 66, 69, 33, 56, 42, 1,
+ 75, 111, 17, 57, 62, 114, 22, 21, 26, 28, 28, 23, 18, 22, 26, 13,
+ 20, 14, 7, 4, 0, 15, 13, 14, 12, 5, 9, 19, 9, 68, 10, 12,
+ 69, 19, 67, 62, 62, 51, 40, 48, 58, 62, 62, 36, 21, 14, 17, 29,
+ 27, 85, 18, 22, 4, 37, 19, 19, 24, 28, 27, 34, 32, 8, 93, 0,
+ 65, 11, 113, 101, 69, 7, 10, 4, 77, 81, 86, 85, 110, 88, 14, 3,
+ 64, 71, 73, 79, 91, 89, 106, 76, 20, 7, 2, 66, 67, 73, 77, 85,
+ 97, 76, 7, 66, 7, 5, 70, 77, 78, 91, 73, 29, 9, 9, 6, 64,
+ 70, 78, 77, 81, 62, 114, 112, 105, 111, 103, 104, 103, 102, 99, 102, 102,
+ 103, 88, 93, 93, 98, 98, 89, 66, 83, 86, 84, 75, 71, 72, 66, 77,
+ 66, 65, 67, 68, 2, 68, 77, 65, 68, 75, 5, 2, 66, 2, 11, 1,
+ 71, 74, 75, 76, 66, 0, 2, 5, 69, 66, 70, 7, 6, 72, 75, 75,
+ 75, 7, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 58,
+ 34, 62, 62, 62, 62, 58, 46, 33, 43, 41, 30, 14, 8, 1, 79, 59,
+ 57, 60, 44, 29, 32, 25, 22, 30, 26, 18, 4, 15, 1, 73, 22, 27,
+ 19, 27, 32, 20, 17, 10, 9, 69, 3, 67, 79, 114, 64, 68, 75, 19,
+ 3, 70, 76, 69, 66, 66, 64, 64, 7, 67, 65, 64, 5, 15, 12, 17,
+ 2, 60, 57, 50, 46, 38, 34, 20, 8, 75, 65, 30, 24, 21, 13, 11,
+ 5, 2, 64, 73, 76, 69, 66, 66, 64, 64, 7, 67, 65, 64, 5, 15,
+ 12, 17, 2, 60, 57, 50, 46, 38, 34, 20, 8, 75, 75, 66, 3, 0,
+ 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 29, 48, 55, 19, 3,
+ 82, 31, 82, 87, 3, 3, 1, 65, 11, 41, 45, 30, 65, 104, 107, 103,
+ 72, 82, 87, 3, 89, 79, 23, 6, 82, 93, 102, 68, 70, 86, 99, 0,
+ 81, 97, 66, 78, 88, 100, 7, 76, 73, 89, 18, 3, 22, 0, 0, 0,
+ 77, 88, 97, 67, 14, 0, 25, 82, 114, 104, 80, 86, 68, 70, 81, 80,
+ 107, 67, 91, 81, 103, 86, 79, 85, 81, 12, 0, 74, 103, 75, 97, 84,
+ 108, 65, 77, 72, 89, 11, 69, 66, 89, 83, 80, 78, 70, 64, 67, 79,
+ 0, 5, 69, 4, 68, 69, 4, 73, 22, 68, 1, 17, 19, 25, 24, 14,
+ 81, 72, 76, 6, 67, 86, 67, 1, 71, 75, 69, 13, 41, 15, 75, 80,
+ 73, 69, 32, 38, 99, 66, 64, 82, 4, 0, 66, 68, 33, 56, 42, 3,
+ 76, 109, 16, 54, 62, 113, 22, 21, 25, 28, 27, 23, 17, 22, 25, 12,
+ 19, 14, 7, 4, 0, 14, 13, 13, 11, 5, 9, 18, 9, 69, 9, 11,
+ 69, 18, 68, 60, 62, 49, 38, 47, 56, 62, 62, 35, 19, 12, 15, 27,
+ 25, 86, 17, 21, 3, 36, 18, 18, 22, 27, 25, 32, 31, 6, 93, 64,
+ 66, 9, 112, 100, 68, 7, 10, 4, 76, 80, 85, 85, 108, 86, 15, 4,
+ 64, 70, 71, 78, 89, 88, 103, 75, 20, 7, 2, 65, 66, 72, 77, 84,
+ 96, 76, 8, 65, 7, 5, 69, 77, 78, 90, 72, 29, 10, 9, 6, 0,
+ 69, 77, 77, 80, 62, 113, 111, 104, 110, 102, 102, 102, 100, 98, 100, 100,
+ 100, 87, 92, 92, 97, 95, 88, 67, 82, 85, 83, 75, 71, 72, 66, 76,
+ 67, 66, 67, 68, 3, 68, 77, 65, 68, 74, 4, 1, 66, 1, 10, 0,
+ 71, 74, 74, 77, 67, 1, 2, 4, 69, 66, 70, 6, 5, 72, 75, 75,
+ 75, 6, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 56,
+ 32, 62, 62, 62, 62, 55, 44, 31, 41, 38, 28, 13, 7, 0, 79, 57,
+ 54, 57, 42, 27, 30, 23, 20, 28, 24, 16, 2, 13, 0, 75, 21, 26,
+ 17, 25, 31, 18, 15, 9, 8, 70, 2, 68, 79, 113, 66, 69, 76, 17,
+ 2, 71, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, 15, 13, 17,
+ 2, 60, 55, 48, 44, 36, 32, 17, 6, 76, 65, 31, 24, 21, 14, 12,
+ 5, 2, 64, 72, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, 15,
+ 13, 17, 2, 60, 55, 48, 44, 36, 32, 17, 6, 76, 75, 66, 3, 0,
+ 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 28, 46, 54, 19, 4,
+ 80, 30, 82, 85, 3, 2, 2, 66, 10, 40, 44, 26, 67, 105, 105, 101,
+ 72, 82, 85, 3, 88, 78, 24, 6, 81, 92, 101, 70, 71, 86, 100, 0,
+ 81, 97, 66, 79, 87, 100, 6, 76, 73, 88, 18, 3, 22, 0, 0, 0,
+ 76, 88, 97, 67, 14, 64, 25, 81, 113, 102, 79, 85, 66, 68, 80, 79,
+ 105, 66, 90, 81, 101, 87, 79, 85, 81, 13, 0, 73, 101, 75, 96, 83,
+ 106, 65, 77, 72, 89, 12, 70, 65, 89, 83, 79, 78, 69, 64, 66, 78,
+ 1, 5, 69, 4, 68, 69, 4, 73, 22, 68, 1, 17, 19, 26, 25, 15,
+ 81, 71, 75, 5, 67, 86, 67, 2, 71, 74, 68, 14, 41, 17, 74, 81,
+ 74, 68, 32, 38, 99, 67, 64, 82, 4, 64, 65, 67, 33, 56, 43, 4,
+ 77, 108, 15, 51, 62, 111, 22, 21, 25, 27, 27, 22, 17, 21, 25, 12,
+ 19, 14, 6, 4, 64, 14, 12, 12, 11, 5, 9, 18, 8, 71, 9, 10,
+ 69, 17, 68, 57, 62, 47, 37, 45, 54, 62, 61, 33, 17, 10, 14, 25,
+ 23, 88, 16, 19, 1, 34, 17, 17, 21, 25, 23, 30, 29, 5, 93, 65,
+ 67, 8, 110, 98, 66, 8, 10, 4, 75, 80, 85, 84, 107, 85, 16, 5,
+ 0, 70, 70, 77, 88, 87, 101, 75, 21, 8, 3, 65, 65, 72, 76, 83,
+ 95, 76, 10, 64, 7, 5, 69, 76, 78, 90, 72, 30, 10, 10, 6, 1,
+ 69, 77, 76, 80, 62, 111, 109, 102, 108, 100, 101, 100, 99, 96, 98, 98,
+ 98, 87, 91, 92, 97, 92, 88, 68, 82, 85, 82, 75, 71, 72, 66, 76,
+ 67, 67, 67, 68, 3, 68, 77, 65, 68, 74, 4, 1, 66, 0, 9, 0,
+ 71, 74, 73, 78, 67, 2, 1, 4, 69, 66, 69, 6, 5, 71, 74, 75,
+ 75, 4, 62, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 53,
+ 30, 62, 62, 62, 62, 53, 41, 29, 39, 36, 26, 12, 6, 64, 79, 55,
+ 52, 55, 40, 25, 29, 22, 18, 26, 21, 14, 0, 11, 65, 76, 20, 24,
+ 15, 24, 29, 17, 13, 7, 6, 71, 1, 69, 80, 112, 67, 71, 78, 16,
+ 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, 7, 16, 14, 18,
+ 3, 59, 53, 46, 42, 34, 30, 15, 4, 77, 64, 31, 25, 22, 14, 13,
+ 6, 3, 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, 7, 16,
+ 14, 18, 3, 59, 53, 46, 42, 34, 30, 15, 4, 77, 75, 66, 3, 1,
+ 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 26, 45, 53, 20, 4, 78,
+ 28, 82, 84, 3, 2, 3, 67, 8, 38, 42, 23, 69, 106, 103, 100, 72, 82,
+ 84, 3, 88, 77, 24, 5, 80, 91, 100, 71, 73, 87, 100, 0, 81, 96, 66,
+ 79, 87, 100, 6, 76, 73, 88, 19, 3, 22, 0, 0, 0, 76, 89, 97, 66,
+ 13, 64, 24, 81, 112, 100, 78, 84, 65, 67, 80, 78, 103, 65, 89, 80, 99,
+ 88, 79, 85, 81, 13, 64, 72, 99, 75, 95, 82, 104, 65, 77, 72, 89, 12,
+ 70, 65, 88, 83, 79, 78, 69, 64, 66, 77, 1, 5, 69, 3, 68, 69, 4,
+ 73, 22, 68, 1, 18, 19, 26, 25, 15, 82, 71, 74, 5, 67, 86, 67, 3,
+ 71, 74, 67, 15, 42, 18, 72, 81, 75, 68, 32, 38, 100, 67, 0, 83, 5,
+ 64, 65, 66, 33, 56, 43, 5, 78, 106, 14, 48, 60, 110, 21, 21, 24, 26,
+ 26, 22, 16, 21, 24, 11, 18, 13, 6, 4, 64, 13, 11, 11, 10, 4, 8,
+ 17, 8, 72, 8, 9, 69, 15, 69, 55, 62, 45, 35, 43, 52, 62, 58, 32,
+ 15, 7, 12, 23, 21, 89, 14, 18, 64, 33, 16, 16, 20, 24, 21, 28, 27,
+ 3, 93, 66, 68, 6, 109, 97, 65, 8, 10, 4, 74, 79, 84, 83, 105, 84,
+ 17, 5, 1, 69, 69, 76, 86, 86, 99, 74, 21, 8, 3, 64, 64, 71, 76,
+ 83, 94, 76, 11, 0, 7, 5, 68, 76, 78, 89, 71, 30, 11, 10, 6, 2,
+ 68, 76, 76, 79, 62, 110, 108, 101, 106, 99, 99, 99, 97, 95, 97, 96, 96,
+ 86, 90, 91, 96, 89, 88, 69, 82, 84, 82, 75, 71, 72, 67, 75, 67, 68,
+ 67, 68, 4, 68, 77, 65, 68, 74, 3, 1, 66, 64, 8, 0, 71, 74, 72,
+ 79, 67, 2, 0, 4, 69, 66, 69, 6, 4, 71, 73, 75, 75, 3, 62, 60,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, 28, 62, 62, 62, 62,
+ 50, 39, 27, 37, 33, 24, 10, 5, 65, 79, 52, 50, 53, 38, 23, 27, 20,
+ 16, 24, 19, 12, 65, 8, 67, 77, 19, 23, 12, 22, 27, 15, 11, 6, 5,
+ 72, 0, 70, 80, 111, 68, 72, 79, 15, 64, 73, 75, 68, 65, 64, 2, 1,
+ 9, 66, 1, 2, 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, 2,
+ 79, 64, 32, 25, 23, 15, 13, 6, 3, 0, 71, 75, 68, 65, 64, 2, 1,
+ 9, 66, 1, 2, 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, 2,
+ 79, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 24, 43, 52, 21, 4, 77,
+ 26, 81, 82, 2, 2, 4, 68, 7, 37, 40, 20, 72, 106, 101, 99, 72, 81,
+ 82, 2, 88, 76, 24, 5, 80, 90, 98, 72, 74, 87, 100, 0, 80, 95, 67,
+ 79, 87, 100, 6, 75, 73, 87, 19, 3, 22, 0, 0, 0, 75, 89, 97, 66,
+ 12, 64, 24, 80, 110, 97, 77, 83, 0, 65, 79, 77, 101, 64, 88, 79, 96,
+ 88, 80, 85, 82, 13, 64, 71, 96, 74, 95, 82, 102, 65, 77, 72, 88, 12,
+ 70, 64, 87, 82, 78, 77, 69, 0, 65, 76, 2, 5, 70, 3, 67, 69, 4,
+ 73, 23, 68, 1, 18, 20, 26, 25, 15, 82, 70, 74, 4, 67, 85, 67, 4,
+ 70, 73, 65, 17, 43, 20, 70, 82, 76, 67, 33, 38, 101, 67, 0, 83, 6,
+ 64, 65, 64, 33, 56, 43, 7, 79, 105, 13, 46, 57, 109, 21, 21, 24, 26,
+ 26, 22, 16, 21, 24, 10, 17, 13, 6, 4, 64, 13, 11, 10, 10, 4, 8,
+ 16, 7, 73, 7, 9, 69, 14, 69, 53, 62, 44, 34, 42, 50, 62, 56, 31,
+ 13, 5, 11, 21, 19, 90, 13, 17, 65, 32, 15, 15, 18, 22, 19, 26, 26,
+ 2, 93, 67, 69, 4, 107, 95, 64, 9, 10, 4, 73, 78, 83, 83, 103, 82,
+ 18, 6, 1, 68, 67, 75, 85, 85, 96, 73, 22, 9, 4, 64, 0, 70, 75,
+ 82, 93, 75, 12, 1, 7, 5, 67, 75, 77, 88, 70, 30, 12, 10, 6, 3,
+ 67, 75, 75, 78, 62, 109, 106, 99, 105, 98, 98, 97, 95, 93, 95, 94, 93,
+ 85, 89, 90, 95, 86, 87, 70, 81, 83, 81, 75, 71, 72, 67, 75, 68, 69,
+ 67, 68, 5, 68, 77, 65, 68, 73, 3, 0, 66, 65, 7, 64, 71, 74, 71,
+ 79, 68, 3, 0, 3, 69, 66, 69, 5, 4, 71, 73, 75, 75, 1, 62, 59,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 48, 26, 62, 62, 62, 62,
+ 47, 37, 26, 35, 31, 22, 9, 4, 66, 79, 50, 47, 50, 36, 21, 25, 19,
+ 14, 22, 17, 10, 67, 6, 68, 79, 18, 22, 10, 21, 26, 14, 9, 5, 4,
+ 73, 64, 71, 80, 110, 70, 73, 81, 13, 65, 74, 75, 67, 64, 0, 3, 2,
+ 9, 65, 2, 3, 9, 17, 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0,
+ 80, 0, 32, 26, 23, 16, 14, 7, 4, 0, 70, 75, 67, 64, 0, 3, 2,
+ 9, 65, 2, 3, 9, 17, 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0,
+ 80, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 22, 42, 51, 21, 4, 75,
+ 25, 81, 81, 2, 1, 5, 69, 6, 36, 38, 16, 74, 107, 99, 97, 72, 81,
+ 81, 2, 87, 75, 25, 5, 79, 89, 97, 73, 75, 87, 101, 0, 80, 94, 67,
+ 80, 87, 100, 6, 75, 73, 86, 20, 3, 22, 0, 0, 0, 75, 89, 97, 65,
+ 11, 64, 23, 80, 109, 95, 76, 82, 1, 64, 78, 76, 99, 0, 87, 78, 94,
+ 89, 80, 85, 82, 14, 64, 70, 94, 74, 94, 81, 100, 65, 77, 72, 88, 13,
+ 70, 64, 86, 82, 77, 77, 69, 0, 65, 75, 2, 5, 70, 3, 67, 69, 4,
+ 73, 23, 68, 1, 19, 20, 27, 25, 16, 83, 70, 73, 4, 67, 85, 67, 5,
+ 70, 73, 64, 18, 44, 21, 68, 82, 77, 67, 33, 38, 102, 67, 1, 84, 6,
+ 64, 65, 0, 33, 56, 43, 8, 80, 103, 12, 43, 54, 107, 21, 21, 23, 25,
+ 25, 21, 15, 21, 23, 9, 16, 13, 6, 4, 65, 12, 10, 9, 9, 4, 8,
+ 15, 7, 74, 7, 8, 69, 13, 70, 51, 60, 42, 32, 40, 48, 62, 53, 30,
+ 11, 3, 9, 19, 17, 92, 12, 16, 67, 31, 14, 14, 17, 21, 17, 24, 24,
+ 0, 93, 68, 70, 3, 106, 94, 1, 9, 10, 4, 72, 77, 82, 82, 101, 81,
+ 19, 7, 2, 68, 66, 74, 83, 84, 94, 73, 22, 9, 4, 0, 1, 70, 75,
+ 81, 92, 75, 14, 2, 7, 5, 66, 75, 77, 87, 69, 31, 13, 11, 6, 4,
+ 67, 74, 75, 78, 62, 107, 105, 98, 103, 97, 96, 96, 94, 92, 93, 92, 91,
+ 85, 88, 90, 94, 83, 87, 71, 81, 82, 80, 75, 71, 72, 67, 74, 68, 70,
+ 67, 68, 5, 68, 77, 65, 68, 73, 2, 0, 66, 66, 6, 64, 71, 74, 70,
+ 80, 68, 4, 64, 3, 69, 66, 68, 5, 3, 70, 72, 75, 75, 0, 62, 58,
+ 61, 61, 61, 62, 62, 62, 61, 62, 62, 62, 57, 45, 24, 62, 60, 59, 60,
+ 44, 35, 24, 33, 28, 20, 8, 3, 67, 79, 48, 45, 48, 34, 19, 23, 17,
+ 12, 20, 15, 8, 69, 4, 70, 80, 17, 21, 8, 19, 24, 12, 7, 3, 2,
+ 74, 65, 72, 80, 109, 71, 75, 82, 12, 66, 75, 75, 67, 64, 0, 4, 3,
+ 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, 36, 28, 24, 8, 65,
+ 81, 0, 33, 26, 24, 16, 15, 7, 4, 1, 70, 75, 67, 64, 0, 4, 3,
+ 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, 36, 28, 24, 8, 65,
+ 81, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 20, 40, 50, 22, 4, 73, 23,
+ 81, 79, 2, 1, 6, 70, 5, 35, 36, 13, 76, 108, 97, 96, 72, 81, 79, 2,
+ 87, 74, 25, 5, 78, 88, 96, 74, 76, 87, 101, 0, 80, 93, 67, 80, 87, 100,
+ 6, 75, 73, 85, 20, 3, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 23, 79,
+ 108, 93, 75, 81, 3, 1, 77, 75, 97, 1, 86, 77, 92, 90, 80, 85, 82, 14,
+ 64, 69, 92, 74, 93, 80, 98, 65, 77, 72, 88, 13, 70, 0, 85, 82, 76, 77,
+ 69, 0, 64, 74, 3, 5, 70, 3, 67, 69, 4, 73, 23, 68, 1, 19, 20, 27,
+ 25, 16, 83, 69, 72, 3, 67, 85, 67, 6, 70, 72, 0, 19, 45, 23, 66, 83,
+ 78, 66, 33, 38, 103, 67, 1, 84, 7, 64, 65, 1, 33, 56, 43, 9, 81, 102,
+ 11, 40, 51, 106, 21, 21, 23, 24, 25, 21, 15, 21, 23, 8, 15, 13, 6, 4,
+ 65, 12, 9, 8, 9, 4, 8, 14, 6, 75, 6, 7, 69, 12, 70, 49, 58, 40,
+ 31, 38, 46, 59, 51, 29, 9, 1, 8, 17, 15, 93, 11, 15, 69, 30, 13, 13,
+ 16, 19, 15, 22, 22, 64, 93, 69, 71, 1, 104, 92, 2, 10, 10, 4, 71, 76,
+ 81, 81, 99, 80, 20, 8, 3, 67, 65, 73, 82, 83, 92, 72, 23, 10, 5, 0,
+ 2, 69, 74, 80, 91, 75, 15, 3, 7, 5, 65, 74, 77, 86, 68, 31, 14, 11,
+ 6, 5, 66, 73, 74, 77, 62, 106, 103, 96, 101, 96, 95, 94, 92, 90, 91, 90,
+ 89, 84, 87, 89, 93, 80, 87, 72, 81, 81, 79, 75, 71, 72, 67, 74, 68, 71,
+ 67, 68, 6, 68, 77, 65, 68, 73, 2, 0, 66, 67, 5, 64, 71, 74, 69, 81,
+ 68, 5, 65, 3, 69, 66, 68, 5, 3, 70, 71, 75, 75, 65, 61, 57, 60, 59,
+ 59, 62, 62, 62, 59, 60, 62, 61, 54, 42, 22, 61, 57, 55, 55, 41, 33, 22,
+ 31, 26, 18, 7, 2, 68, 79, 46, 43, 46, 32, 17, 21, 16, 10, 18, 13, 6,
+ 71, 2, 72, 81, 16, 20, 6, 18, 22, 11, 5, 2, 1, 75, 66, 73, 80, 108,
+ 72, 76, 84, 11, 67, 76, 75, 66, 0, 1, 5, 4, 11, 65, 4, 5, 11, 18,
+ 18, 20, 6, 57, 45, 38, 34, 26, 22, 6, 67, 82, 1, 33, 27, 25, 17, 16,
+ 8, 5, 1, 69, 75, 66, 0, 1, 5, 4, 11, 65, 4, 5, 11, 18, 18, 20,
+ 6, 57, 45, 38, 34, 26, 22, 6, 67, 82, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 18, 38, 49, 22, 4, 72, 21,
+ 81, 78, 1, 0, 7, 71, 3, 33, 34, 9, 79, 109, 95, 95, 72, 81, 78, 1,
+ 87, 74, 25, 4, 78, 88, 95, 76, 78, 88, 102, 64, 80, 93, 68, 81, 87, 100,
+ 5, 75, 73, 85, 20, 2, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 22, 79,
+ 107, 91, 74, 81, 4, 2, 77, 74, 96, 1, 85, 77, 90, 91, 81, 86, 83, 14,
+ 65, 69, 90, 74, 93, 80, 97, 65, 77, 72, 88, 13, 71, 0, 85, 82, 76, 77,
+ 69, 0, 64, 73, 3, 5, 71, 2, 67, 69, 3, 73, 23, 68, 1, 19, 20, 27,
+ 25, 16, 84, 69, 72, 2, 67, 85, 68, 6, 70, 72, 1, 20, 45, 24, 65, 84,
+ 80, 66, 33, 38, 104, 68, 1, 85, 7, 65, 65, 2, 33, 55, 43, 10, 82, 101,
+ 9, 37, 47, 105, 20, 21, 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3,
+ 66, 11, 8, 7, 8, 3, 7, 13, 5, 77, 5, 6, 69, 10, 71, 46, 55, 38,
+ 29, 36, 43, 55, 48, 27, 7, 65, 6, 14, 13, 95, 9, 13, 71, 28, 12, 12,
+ 14, 17, 13, 20, 20, 66, 93, 70, 72, 64, 103, 91, 3, 10, 10, 4, 71, 76,
+ 81, 81, 98, 79, 20, 8, 3, 67, 64, 72, 81, 83, 90, 72, 23, 10, 5, 0,
+ 2, 69, 74, 80, 90, 75, 16, 4, 7, 4, 65, 74, 77, 86, 68, 31, 14, 11,
+ 6, 6, 66, 73, 74, 77, 62, 105, 102, 95, 100, 95, 94, 93, 91, 89, 90, 89,
+ 87, 84, 87, 89, 93, 77, 87, 74, 81, 81, 79, 75, 71, 72, 68, 74, 69, 72,
+ 68, 68, 6, 69, 77, 66, 68, 73, 1, 64, 67, 68, 4, 65, 72, 74, 68, 82,
+ 69, 5, 66, 2, 69, 67, 68, 4, 2, 70, 71, 75, 75, 67, 59, 56, 58, 57,
+ 56, 62, 62, 62, 56, 57, 62, 58, 50, 39, 20, 57, 53, 51, 49, 38, 30, 20,
+ 28, 23, 16, 5, 0, 69, 79, 43, 40, 43, 30, 14, 19, 14, 7, 16, 10, 4,
+ 74, 64, 74, 83, 14, 18, 3, 16, 20, 9, 3, 0, 64, 76, 67, 74, 81, 107,
+ 74, 78, 86, 9, 69, 78, 75, 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18,
+ 18, 20, 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 1, 33, 27, 25, 17, 16,
+ 8, 5, 1, 69, 75, 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18, 18, 20,
+ 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 17, 37, 49, 23, 5, 70, 20,
+ 80, 76, 1, 0, 9, 71, 2, 32, 33, 6, 81, 109, 93, 93, 71, 80, 76, 1,
+ 86, 73, 26, 4, 77, 87, 93, 77, 79, 88, 102, 64, 79, 92, 68, 81, 86, 99,
+ 5, 74, 72, 84, 21, 2, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 22, 78,
+ 105, 88, 72, 80, 6, 4, 76, 72, 94, 2, 83, 76, 87, 91, 81, 86, 83, 15,
+ 65, 68, 87, 73, 92, 79, 95, 65, 76, 72, 87, 14, 71, 1, 84, 81, 75, 76,
+ 68, 1, 0, 72, 4, 6, 71, 2, 66, 68, 3, 72, 24, 67, 1, 20, 21, 28,
+ 26, 17, 84, 68, 71, 2, 67, 84, 68, 7, 69, 71, 3, 22, 46, 26, 0, 84,
+ 81, 65, 34, 39, 104, 68, 2, 85, 8, 65, 64, 4, 33, 55, 44, 12, 83, 99,
+ 8, 35, 44, 103, 20, 21, 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3,
+ 66, 11, 8, 7, 8, 3, 7, 13, 5, 78, 5, 6, 69, 9, 71, 44, 53, 37,
+ 28, 35, 41, 52, 46, 26, 6, 67, 5, 12, 12, 96, 8, 12, 72, 27, 12, 12,
+ 13, 16, 12, 19, 19, 67, 93, 70, 72, 65, 101, 89, 5, 11, 10, 4, 70, 75,
+ 80, 80, 96, 77, 21, 9, 4, 66, 1, 71, 79, 82, 87, 71, 24, 11, 6, 1,
+ 3, 68, 73, 79, 88, 74, 18, 5, 8, 4, 64, 73, 76, 85, 67, 32, 15, 12,
+ 7, 7, 65, 72, 73, 76, 62, 103, 100, 93, 98, 93, 92, 91, 89, 87, 88, 87,
+ 84, 83, 86, 88, 92, 73, 86, 75, 80, 80, 78, 74, 71, 71, 68, 73, 69, 72,
+ 68, 68, 7, 69, 77, 66, 68, 72, 1, 64, 67, 68, 4, 65, 72, 73, 66, 82,
+ 69, 6, 66, 2, 69, 67, 67, 4, 2, 69, 70, 74, 74, 68, 58, 55, 57, 56,
+ 54, 60, 60, 59, 54, 55, 59, 56, 47, 37, 18, 54, 50, 48, 44, 36, 28, 19,
+ 26, 21, 15, 4, 64, 69, 79, 41, 38, 41, 28, 12, 18, 13, 5, 15, 8, 3,
+ 76, 66, 75, 84, 13, 17, 1, 15, 19, 8, 2, 64, 65, 77, 67, 74, 81, 106,
+ 75, 79, 87, 8, 70, 79, 74, 65, 1, 2, 8, 5, 12, 64, 7, 6, 13, 19,
+ 19, 21, 7, 56, 42, 35, 29, 21, 19, 1, 70, 85, 2, 34, 28, 26, 18, 17,
+ 9, 6, 2, 68, 74, 65, 1, 2, 8, 5, 12, 64, 7, 6, 13, 19, 19, 21,
+ 7, 56, 42, 35, 29, 21, 19, 1, 70, 85, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 15, 35, 48, 24, 5, 68, 18,
+ 80, 75, 1, 0, 10, 72, 1, 31, 31, 3, 83, 110, 91, 92, 71, 80, 75, 1,
+ 86, 72, 26, 4, 76, 86, 92, 78, 80, 88, 102, 64, 79, 91, 68, 81, 86, 99,
+ 5, 74, 72, 83, 21, 2, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 22, 77,
+ 104, 86, 71, 79, 8, 6, 75, 71, 92, 3, 82, 75, 85, 92, 81, 86, 83, 15,
+ 65, 67, 85, 73, 91, 78, 93, 65, 76, 72, 87, 14, 71, 1, 83, 81, 74, 76,
+ 68, 1, 0, 71, 5, 6, 71, 2, 66, 68, 3, 72, 24, 67, 1, 20, 21, 28,
+ 26, 17, 85, 67, 70, 1, 67, 84, 68, 8, 69, 71, 4, 23, 47, 28, 2, 85,
+ 82, 65, 34, 39, 105, 68, 2, 86, 9, 65, 64, 5, 33, 55, 44, 13, 84, 98,
+ 7, 32, 41, 102, 20, 21, 22, 22, 23, 20, 14, 20, 21, 6, 13, 12, 5, 3,
+ 66, 10, 7, 6, 8, 3, 7, 12, 4, 79, 4, 5, 69, 8, 72, 42, 51, 35,
+ 26, 33, 39, 49, 44, 25, 4, 69, 3, 10, 10, 97, 7, 11, 74, 26, 11, 11,
+ 12, 14, 10, 17, 17, 69, 93, 71, 73, 67, 100, 88, 6, 12, 10, 4, 69, 74,
+ 79, 79, 94, 76, 22, 10, 5, 65, 2, 70, 78, 81, 85, 70, 24, 11, 6, 1,
+ 4, 67, 72, 78, 87, 74, 19, 6, 8, 4, 0, 72, 76, 84, 66, 32, 16, 12,
+ 7, 8, 64, 71, 72, 75, 62, 102, 98, 91, 96, 92, 91, 89, 87, 86, 86, 85,
+ 82, 82, 85, 87, 91, 70, 86, 76, 80, 79, 77, 74, 71, 71, 68, 73, 69, 73,
+ 68, 68, 8, 69, 77, 66, 68, 72, 1, 64, 67, 69, 3, 65, 72, 73, 65, 83,
+ 69, 7, 67, 2, 69, 67, 67, 4, 2, 69, 69, 74, 74, 70, 57, 54, 56, 54,
+ 52, 57, 57, 56, 52, 52, 56, 53, 44, 34, 16, 50, 46, 44, 39, 33, 26, 17,
+ 24, 19, 13, 3, 65, 70, 79, 39, 36, 39, 26, 10, 16, 11, 3, 13, 6, 1,
+ 78, 68, 77, 85, 12, 16, 64, 13, 17, 6, 0, 65, 66, 78, 68, 75, 81, 105,
+ 76, 80, 89, 7, 71, 80, 74, 65, 2, 3, 9, 6, 13, 64, 8, 7, 14, 19,
+ 20, 22, 8, 55, 40, 33, 27, 19, 17, 64, 72, 86, 3, 34, 28, 27, 19, 18,
+ 9, 7, 2, 67, 74, 65, 2, 3, 9, 6, 13, 64, 8, 7, 14, 19, 20, 22,
+ 8, 55, 40, 33, 27, 19, 17, 64, 72, 86, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 13, 34, 47, 24, 5, 66, 17, 80,
+ 73, 1, 64, 11, 73, 0, 30, 29, 64, 85, 111, 89, 90, 71, 80, 73, 1, 85, 71,
+ 27, 4, 75, 85, 91, 79, 81, 88, 103, 64, 79, 90, 68, 82, 86, 99, 5, 74, 72,
+ 82, 22, 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 21, 77, 103, 84, 70, 78,
+ 9, 7, 74, 70, 90, 4, 81, 74, 83, 93, 81, 86, 83, 16, 65, 66, 83, 73, 90,
+ 77, 91, 65, 76, 72, 87, 15, 71, 2, 82, 81, 73, 76, 68, 1, 1, 70, 5, 6,
+ 71, 2, 66, 68, 3, 72, 24, 67, 1, 21, 21, 29, 26, 18, 85, 67, 69, 1, 67,
+ 84, 68, 9, 69, 70, 5, 24, 48, 29, 4, 85, 83, 64, 34, 39, 106, 68, 3, 86,
+ 9, 65, 64, 6, 33, 55, 44, 14, 85, 96, 6, 29, 38, 100, 20, 21, 21, 21, 23,
+ 19, 13, 20, 21, 5, 12, 12, 5, 3, 67, 10, 6, 5, 7, 3, 7, 11, 4, 80,
+ 4, 4, 69, 7, 72, 40, 49, 33, 25, 31, 37, 46, 41, 24, 2, 71, 2, 8, 8,
+ 99, 6, 10, 76, 25, 10, 10, 11, 13, 8, 15, 15, 70, 93, 72, 74, 68, 98, 86,
+ 8, 12, 10, 4, 68, 73, 78, 78, 92, 75, 23, 11, 6, 65, 3, 69, 76, 80, 83,
+ 70, 25, 12, 7, 2, 5, 67, 72, 77, 86, 74, 21, 7, 8, 4, 1, 72, 76, 83,
+ 65, 33, 17, 13, 7, 9, 64, 70, 72, 75, 62, 100, 97, 90, 94, 91, 89, 88, 86,
+ 84, 84, 83, 80, 82, 84, 87, 90, 67, 86, 77, 80, 78, 76, 74, 71, 71, 68, 72,
+ 69, 74, 68, 68, 8, 69, 77, 66, 68, 72, 0, 64, 67, 70, 2, 65, 72, 73, 64,
+ 84, 69, 8, 68, 2, 69, 67, 66, 4, 1, 68, 68, 74, 74, 71, 56, 53, 55, 52,
+ 50, 55, 55, 53, 49, 49, 53, 50, 41, 31, 14, 46, 43, 40, 34, 30, 24, 15, 22,
+ 16, 11, 2, 66, 71, 79, 37, 34, 37, 24, 8, 14, 10, 1, 11, 4, 64, 80, 70,
+ 79, 86, 11, 15, 66, 12, 15, 5, 65, 67, 68, 79, 69, 76, 81, 104, 77, 82, 90,
+ 6, 72, 81, 74, 64, 2, 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55,
+ 38, 31, 25, 17, 15, 66, 74, 87, 3, 35, 29, 28, 19, 19, 10, 7, 3, 67, 74,
+ 64, 2, 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55, 38, 31, 25, 17,
+ 15, 66, 74, 87, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 32, 46, 25, 5, 65, 15, 80,
+ 72, 0, 64, 12, 74, 65, 28, 27, 67, 88, 112, 87, 89, 71, 80, 72, 0, 85, 70,
+ 27, 3, 75, 84, 89, 80, 83, 89, 103, 64, 78, 89, 69, 82, 86, 99, 5, 74, 72,
+ 82, 22, 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 21, 76, 102, 82, 69, 77,
+ 11, 9, 74, 69, 88, 5, 80, 73, 80, 93, 82, 86, 84, 16, 66, 65, 80, 72, 90,
+ 77, 89, 65, 76, 72, 87, 15, 71, 2, 81, 81, 73, 75, 68, 1, 1, 69, 6, 6,
+ 72, 1, 66, 68, 3, 72, 24, 67, 1, 21, 21, 29, 26, 18, 86, 66, 69, 0, 67,
+ 83, 68, 10, 68, 70, 7, 26, 49, 31, 6, 86, 84, 64, 35, 39, 107, 68, 3, 87,
+ 10, 65, 64, 7, 33, 55, 44, 16, 86, 95, 5, 26, 35, 99, 19, 21, 21, 21, 22,
+ 19, 13, 20, 20, 4, 11, 11, 5, 3, 67, 9, 6, 4, 7, 2, 6, 10, 3, 81,
+ 3, 3, 69, 5, 73, 38, 47, 31, 23, 30, 35, 42, 39, 23, 0, 74, 0, 6, 6,
+ 100, 4, 9, 77, 24, 9, 9, 9, 11, 6, 13, 14, 72, 93, 73, 75, 70, 97, 85,
+ 9, 13, 10, 4, 67, 72, 77, 78, 90, 73, 24, 11, 6, 64, 5, 68, 75, 79, 80,
+ 69, 25, 12, 7, 2, 6, 66, 71, 77, 85, 74, 22, 8, 8, 4, 2, 71, 76, 82,
+ 64, 33, 18, 13, 7, 10, 0, 69, 71, 74, 62, 99, 95, 88, 93, 90, 88, 86, 84,
+ 83, 83, 81, 77, 81, 83, 86, 89, 64, 85, 78, 79, 77, 76, 74, 71, 71, 69, 72,
+ 70, 75, 68, 68, 9, 69, 77, 66, 68, 71, 0, 65, 67, 71, 1, 66, 72, 73, 0,
+ 85, 70, 8, 68, 1, 69, 67, 66, 3, 1, 68, 68, 74, 74, 73, 55, 52, 54, 51,
+ 47, 52, 52, 50, 47, 46, 49, 47, 37, 29, 12, 42, 39, 36, 29, 27, 22, 13, 20,
+ 14, 9, 0, 67, 72, 79, 34, 31, 34, 22, 6, 12, 8, 64, 9, 2, 66, 82, 73,
+ 80, 88, 10, 14, 69, 10, 14, 3, 67, 68, 69, 80, 70, 77, 81, 103, 79, 83, 92,
+ 4, 73, 82, 74, 64, 3, 4, 11, 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54,
+ 36, 29, 23, 15, 13, 69, 76, 89, 4, 35, 29, 28, 20, 19, 10, 8, 3, 66, 74,
+ 64, 3, 4, 11, 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54, 36, 29, 23, 15,
+ 13, 69, 76, 89, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 9, 31, 45, 26, 5, 0, 13, 79,
+ 70, 0, 64, 13, 75, 66, 27, 25, 70, 90, 112, 85, 88, 71, 79, 70, 0, 85, 69,
+ 27, 3, 74, 83, 88, 81, 84, 89, 103, 64, 78, 88, 69, 82, 86, 99, 5, 73, 72,
+ 81, 23, 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 20, 76, 100, 79, 68, 76,
+ 12, 10, 73, 68, 86, 6, 79, 72, 78, 94, 82, 86, 84, 16, 66, 64, 78, 72, 89,
+ 76, 87, 65, 76, 72, 86, 15, 71, 3, 80, 80, 72, 75, 68, 2, 2, 68, 6, 6,
+ 72, 1, 65, 68, 3, 72, 25, 67, 1, 22, 22, 29, 26, 18, 86, 66, 68, 0, 67,
+ 83, 68, 11, 68, 69, 8, 27, 50, 32, 8, 86, 85, 0, 35, 39, 108, 68, 4, 87,
+ 11, 65, 64, 9, 33, 55, 44, 17, 87, 93, 4, 24, 32, 98, 19, 21, 20, 20, 22,
+ 19, 12, 20, 20, 3, 10, 11, 5, 3, 67, 9, 5, 3, 6, 2, 6, 9, 3, 82,
+ 2, 3, 69, 4, 73, 36, 45, 30, 22, 28, 33, 39, 36, 22, 65, 76, 64, 4, 4,
+ 101, 3, 8, 79, 23, 8, 8, 8, 10, 4, 11, 12, 73, 93, 74, 76, 72, 95, 83,
+ 10, 13, 10, 4, 66, 71, 76, 77, 88, 72, 25, 12, 7, 0, 6, 67, 73, 78, 78,
+ 68, 26, 13, 8, 3, 7, 65, 71, 76, 84, 73, 23, 9, 8, 4, 3, 71, 75, 81,
+ 0, 33, 19, 13, 7, 11, 1, 68, 71, 73, 62, 98, 94, 87, 91, 89, 86, 85, 82,
+ 81, 81, 79, 75, 80, 82, 85, 88, 2, 85, 79, 79, 76, 75, 74, 71, 71, 69, 71,
+ 70, 76, 68, 68, 10, 69, 77, 66, 68, 71, 64, 65, 67, 72, 0, 66, 72, 73, 1,
+ 85, 70, 9, 69, 1, 69, 67, 66, 3, 0, 68, 67, 74, 74, 74, 54, 51, 53, 49,
+ 45, 50, 49, 47, 44, 43, 46, 44, 34, 26, 10, 38, 36, 32, 24, 24, 20, 12, 18,
+ 11, 7, 64, 68, 73, 79, 32, 29, 32, 20, 4, 10, 7, 66, 7, 0, 68, 84, 75,
+ 82, 89, 9, 13, 71, 9, 12, 2, 69, 69, 70, 81, 71, 78, 81, 102, 80, 84, 93,
+ 3, 74, 83, 74, 0, 3, 5, 12, 8, 15, 0, 11, 10, 17, 21, 23, 23, 10, 54,
+ 34, 27, 21, 13, 11, 71, 78, 90, 4, 36, 30, 29, 21, 20, 11, 8, 3, 65, 74,
+ 0, 3, 5, 12, 8, 15, 0, 11, 10, 17, 21, 23, 23, 10, 54, 34, 27, 21, 13,
+ 11, 71, 78, 90, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 29, 44, 26, 6, 2, 12, 79,
+ 69, 0, 65, 14, 76, 67, 26, 24, 74, 92, 113, 83, 86, 71, 79, 69, 0, 84, 68,
+ 28, 3, 73, 82, 87, 83, 85, 89, 104, 64, 78, 88, 69, 83, 85, 99, 4, 73, 72,
+ 80, 23, 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 20, 75, 99, 77, 67, 75,
+ 14, 12, 72, 67, 84, 7, 78, 72, 76, 95, 82, 86, 84, 17, 66, 0, 76, 72, 88,
+ 75, 85, 65, 76, 72, 86, 16, 72, 3, 80, 80, 71, 75, 67, 2, 2, 67, 7, 6,
+ 72, 1, 65, 68, 3, 72, 25, 67, 1, 22, 22, 30, 27, 19, 87, 65, 67, 64, 67,
+ 83, 68, 12, 68, 69, 9, 28, 50, 34, 9, 87, 86, 0, 35, 39, 108, 69, 4, 88,
+ 11, 66, 0, 10, 33, 55, 45, 18, 88, 92, 3, 21, 29, 96, 19, 21, 20, 19, 21,
+ 18, 12, 19, 19, 3, 10, 11, 4, 3, 68, 8, 4, 2, 6, 2, 6, 9, 2, 84,
+ 2, 2, 69, 3, 74, 33, 43, 28, 20, 26, 31, 36, 34, 20, 67, 78, 66, 2, 2,
+ 103, 2, 6, 81, 21, 7, 7, 7, 8, 2, 9, 10, 75, 93, 75, 77, 73, 94, 82,
+ 12, 14, 10, 4, 65, 71, 76, 76, 87, 71, 26, 13, 8, 0, 7, 66, 72, 77, 76,
+ 68, 26, 13, 8, 3, 8, 65, 70, 75, 83, 73, 25, 10, 8, 4, 3, 70, 75, 81,
+ 0, 34, 19, 14, 7, 12, 1, 68, 70, 73, 62, 96, 92, 85, 89, 87, 85, 83, 81,
+ 80, 79, 77, 73, 80, 81, 85, 88, 5, 85, 80, 79, 76, 74, 74, 71, 71, 69, 71,
+ 70, 77, 68, 68, 10, 69, 77, 66, 68, 71, 64, 65, 67, 73, 64, 66, 72, 73, 2,
+ 86, 70, 10, 70, 1, 69, 67, 65, 3, 0, 67, 66, 74, 74, 76, 53, 50, 52, 47,
+ 43, 47, 47, 44, 42, 40, 43, 41, 31, 23, 8, 35, 32, 28, 19, 22, 17, 10, 16,
+ 9, 5, 65, 69, 74, 79, 30, 27, 30, 18, 2, 9, 5, 68, 5, 66, 70, 86, 77,
+ 84, 90, 8, 11, 73, 7, 10, 0, 71, 71, 72, 82, 72, 79, 82, 101, 81, 86, 95,
+ 2, 76, 84, 73, 0, 4, 5, 13, 9, 16, 0, 12, 11, 18, 21, 24, 24, 11, 53,
+ 32, 25, 19, 11, 9, 73, 80, 91, 5, 36, 30, 30, 21, 21, 11, 9, 4, 65, 73,
+ 0, 4, 5, 13, 9, 16, 0, 12, 11, 18, 21, 24, 24, 11, 53, 32, 25, 19, 11,
+ 9, 73, 80, 91, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 6, 28, 43, 27, 6, 3, 10, 79,
+ 67, 64, 65, 15, 77, 68, 25, 22, 77, 95, 114, 81, 85, 71, 79, 67, 64, 84, 67,
+ 28, 3, 73, 81, 85, 84, 86, 89, 104, 64, 77, 87, 70, 83, 85, 99, 4, 73, 72,
+ 79, 24, 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 19, 75, 98, 75, 66, 74,
+ 15, 13, 71, 66, 82, 8, 77, 71, 73, 95, 83, 86, 85, 17, 66, 1, 73, 71, 88,
+ 75, 83, 65, 76, 72, 86, 16, 72, 4, 79, 80, 70, 74, 67, 2, 3, 66, 7, 6,
+ 73, 1, 65, 68, 3, 72, 25, 67, 1, 23, 22, 30, 27, 19, 87, 65, 67, 64, 67,
+ 82, 68, 13, 67, 68, 11, 30, 51, 35, 11, 87, 87, 1, 36, 39, 109, 69, 5, 88,
+ 12, 66, 0, 11, 33, 55, 45, 20, 89, 90, 2, 18, 26, 95, 19, 21, 19, 19, 21,
+ 18, 11, 19, 19, 2, 9, 11, 4, 3, 68, 8, 4, 1, 5, 2, 6, 8, 2, 85,
+ 1, 1, 69, 2, 74, 31, 41, 26, 19, 25, 29, 33, 31, 19, 69, 80, 67, 0, 0,
+ 104, 1, 5, 82, 20, 6, 6, 5, 7, 0, 7, 9, 76, 93, 76, 78, 75, 92, 80,
+ 13, 14, 10, 4, 64, 70, 75, 76, 85, 69, 27, 14, 8, 1, 9, 65, 70, 76, 73,
+ 67, 27, 14, 9, 4, 9, 64, 70, 74, 82, 73, 26, 11, 8, 4, 4, 70, 75, 80,
+ 1, 34, 20, 14, 7, 13, 2, 67, 70, 72, 62, 95, 91, 84, 88, 86, 83, 82, 79,
+ 78, 77, 75, 70, 79, 80, 84, 87, 8, 84, 81, 78, 75, 73, 74, 71, 71, 69, 70,
+ 71, 78, 68, 68, 11, 69, 77, 66, 68, 70, 65, 66, 67, 74, 65, 67, 72, 73, 3,
+ 87, 71, 11, 70, 0, 69, 67, 65, 2, 64, 67, 66, 74, 74, 77, 52, 49, 51, 46,
+ 40, 45, 44, 41, 39, 37, 40, 38, 28, 21, 6, 31, 29, 24, 14, 19, 15, 8, 14,
+ 6, 3, 66, 70, 75, 79, 28, 24, 27, 16, 0, 7, 4, 70, 3, 68, 72, 88, 79,
+ 85, 92, 7, 10, 75, 6, 9, 64, 73, 72, 73, 83, 73, 80, 82, 100, 83, 87, 96,
+ 0, 77, 85, 73, 1, 4, 6, 14, 10, 16, 1, 13, 12, 19, 22, 25, 24, 11, 53,
+ 30, 23, 17, 9, 7, 76, 82, 92, 5, 37, 31, 30, 22, 22, 12, 9, 4, 64, 73,
+ 1, 4, 6, 14, 10, 16, 1, 13, 12, 19, 22, 25, 24, 11, 53, 30, 23, 17, 9,
+ 7, 76, 82, 92, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 4, 26, 42, 27, 6, 5, 8, 79,
+ 66, 64, 66, 16, 78, 70, 23, 20, 81, 97, 115, 79, 84, 71, 79, 66, 64, 84, 67,
+ 28, 2, 72, 80, 84, 85, 88, 90, 105, 64, 77, 86, 70, 84, 85, 99, 4, 73, 72,
+ 79, 24, 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 19, 74, 97, 73, 65, 74,
+ 17, 15, 71, 65, 80, 8, 76, 70, 71, 96, 83, 87, 85, 17, 67, 1, 71, 71, 87,
+ 74, 82, 65, 76, 72, 86, 16, 72, 4, 78, 80, 70, 74, 67, 2, 3, 65, 8, 6,
+ 73, 0, 65, 68, 2, 72, 25, 67, 1, 23, 22, 30, 27, 19, 88, 64, 66, 65, 67,
+ 82, 68, 14, 67, 68, 12, 31, 52, 37, 13, 88, 88, 1, 36, 39, 110, 69, 5, 89,
+ 12, 66, 0, 12, 33, 55, 45, 21, 90, 89, 1, 15, 22, 94, 18, 21, 19, 18, 20,
+ 17, 11, 19, 18, 1, 8, 10, 4, 2, 69, 7, 3, 0, 5, 1, 5, 7, 1, 86,
+ 0, 0, 69, 0, 75, 29, 39, 24, 17, 23, 26, 29, 29, 18, 71, 83, 69, 66, 65,
+ 106, 64, 4, 84, 19, 5, 5, 4, 5, 65, 5, 7, 78, 93, 77, 79, 77, 91, 79,
+ 14, 15, 10, 4, 64, 69, 74, 75, 83, 68, 27, 14, 9, 1, 10, 64, 69, 75, 71,
+ 67, 27, 14, 9, 4, 9, 64, 69, 74, 81, 73, 27, 12, 8, 4, 5, 69, 75, 79,
+ 2, 34, 21, 14, 7, 14, 2, 66, 69, 72, 62, 94, 89, 82, 86, 85, 82, 80, 78,
+ 77, 76, 73, 68, 79, 79, 84, 86, 11, 84, 82, 78, 74, 73, 74, 71, 71, 70, 70,
+ 71, 79, 68, 68, 11, 69, 77, 67, 68, 70, 65, 66, 68, 75, 66, 67, 73, 73, 4,
+ 88, 71, 11, 71, 0, 69, 68, 65, 2, 64, 67, 65, 74, 74, 79, 51, 48, 50, 44,
+ 38, 42, 41, 38, 37, 34, 36, 35, 24, 18, 4, 27, 25, 20, 9, 16, 13, 6, 11,
+ 4, 1, 68, 72, 76, 79, 25, 22, 25, 14, 66, 5, 2, 73, 1, 70, 74, 90, 82,
+ 87, 93, 5, 9, 78, 4, 7, 66, 75, 74, 75, 84, 74, 81, 82, 99, 84, 89, 98,
+ 64, 78, 86, 73, 1, 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52,
+ 28, 21, 15, 7, 5, 78, 84, 94, 6, 37, 31, 31, 22, 22, 12, 10, 4, 64, 73,
+ 1, 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52, 28, 21, 15, 7,
+ 5, 78, 84, 94, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 2, 24, 42, 28, 6, 7, 7, 78,
+ 64, 64, 66, 17, 78, 71, 22, 18, 84, 99, 115, 77, 82, 70, 78, 64, 64, 83, 66,
+ 29, 2, 71, 79, 83, 86, 89, 90, 105, 64, 77, 85, 70, 84, 85, 99, 4, 72, 71,
+ 78, 24, 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 19, 73, 95, 70, 64, 73,
+ 19, 17, 70, 64, 78, 9, 74, 69, 69, 97, 83, 87, 85, 18, 67, 2, 69, 71, 86,
+ 73, 80, 65, 75, 72, 85, 17, 72, 5, 77, 79, 69, 74, 67, 3, 4, 64, 9, 6,
+ 73, 0, 64, 67, 2, 72, 26, 67, 1, 23, 23, 31, 27, 20, 88, 0, 65, 66, 67,
+ 82, 68, 15, 67, 67, 13, 32, 53, 39, 15, 89, 89, 2, 36, 40, 111, 69, 5, 89,
+ 13, 66, 0, 14, 33, 55, 45, 22, 91, 88, 0, 13, 19, 92, 18, 21, 19, 17, 20,
+ 17, 11, 19, 18, 0, 7, 10, 4, 2, 69, 7, 2, 0, 5, 1, 5, 6, 0, 87,
+ 0, 0, 69, 64, 75, 27, 37, 23, 16, 21, 24, 26, 27, 17, 73, 85, 70, 68, 66,
+ 107, 65, 3, 86, 18, 4, 4, 3, 3, 66, 3, 5, 79, 93, 77, 80, 78, 89, 77,
+ 16, 16, 10, 4, 0, 68, 73, 74, 81, 67, 28, 15, 10, 2, 11, 0, 68, 74, 69,
+ 66, 28, 15, 10, 4, 10, 0, 68, 73, 79, 72, 29, 13, 9, 4, 6, 68, 74, 78,
+ 3, 35, 22, 15, 8, 15, 3, 65, 68, 71, 62, 92, 87, 80, 84, 84, 81, 78, 76,
+ 75, 74, 71, 66, 78, 78, 83, 85, 15, 84, 83, 78, 73, 72, 73, 71, 71, 70, 70,
+ 71, 80, 68, 68, 12, 69, 77, 67, 68, 70, 65, 66, 68, 75, 67, 67, 73, 72, 6,
+ 88, 71, 12, 72, 0, 69, 68, 64, 2, 64, 66, 64, 73, 73, 81, 50, 47, 49, 42,
+ 36, 39, 39, 35, 35, 32, 33, 33, 21, 15, 2, 23, 22, 17, 4, 13, 11, 5, 9,
+ 2, 0, 69, 73, 77, 79, 23, 20, 23, 12, 68, 3, 1, 75, 64, 72, 76, 92, 84,
+ 89, 94, 4, 8, 80, 3, 5, 67, 77, 75, 76, 85, 75, 81, 82, 98, 85, 90, 100,
+ 65, 79, 87, 73, 2, 6, 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, 51,
+ 27, 19, 13, 5, 3, 80, 86, 95, 7, 37, 32, 32, 23, 23, 13, 11, 5, 0, 73,
+ 2, 6, 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, 51, 27, 19, 13, 5,
+ 3, 80, 86, 95, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 0, 23, 41, 29, 6, 8, 5,
+ 78, 0, 65, 66, 18, 79, 72, 21, 16, 87, 102, 116, 75, 81, 70, 78, 0, 65,
+ 83, 65, 29, 2, 71, 78, 81, 87, 90, 90, 105, 64, 76, 84, 71, 84, 85, 99,
+ 4, 72, 71, 77, 25, 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 73,
+ 94, 68, 0, 72, 20, 18, 69, 0, 76, 10, 73, 68, 66, 97, 84, 87, 86, 18,
+ 67, 3, 66, 70, 86, 73, 78, 65, 75, 72, 85, 17, 72, 5, 76, 79, 68, 73,
+ 67, 3, 4, 0, 9, 6, 74, 0, 64, 67, 2, 72, 26, 67, 1, 24, 23, 31,
+ 27, 20, 89, 0, 65, 66, 67, 81, 68, 16, 66, 67, 15, 34, 54, 40, 17, 89,
+ 90, 2, 37, 40, 112, 69, 6, 90, 14, 66, 0, 15, 33, 55, 45, 24, 92, 86,
+ 64, 10, 16, 91, 18, 21, 18, 17, 19, 17, 10, 19, 17, 64, 6, 10, 4, 2,
+ 69, 6, 2, 64, 4, 1, 5, 5, 0, 88, 64, 64, 69, 65, 76, 25, 35, 21,
+ 14, 20, 22, 23, 24, 16, 75, 87, 72, 70, 68, 108, 66, 2, 87, 17, 3, 3,
+ 1, 2, 68, 1, 4, 81, 93, 78, 81, 80, 88, 76, 17, 16, 10, 4, 1, 67,
+ 72, 74, 79, 65, 29, 16, 10, 3, 13, 1, 66, 73, 66, 65, 28, 15, 10, 5,
+ 11, 1, 68, 72, 78, 72, 30, 14, 9, 4, 7, 68, 74, 77, 4, 35, 23, 15,
+ 8, 16, 4, 64, 68, 70, 62, 91, 86, 79, 83, 83, 79, 77, 74, 74, 72, 69,
+ 0, 77, 77, 82, 84, 18, 83, 84, 77, 72, 71, 73, 71, 71, 70, 69, 72, 81,
+ 68, 68, 13, 69, 77, 67, 68, 69, 66, 67, 68, 76, 68, 68, 73, 72, 7, 89,
+ 72, 13, 72, 64, 69, 68, 64, 1, 65, 66, 64, 73, 73, 82, 49, 46, 48, 41,
+ 33, 37, 36, 32, 32, 29, 30, 30, 18, 13, 0, 19, 18, 13, 64, 10, 9, 3,
+ 7, 64, 65, 70, 74, 78, 79, 21, 17, 20, 10, 70, 1, 64, 77, 66, 74, 78,
+ 94, 86, 90, 96, 3, 7, 82, 1, 4, 69, 79, 76, 77, 86, 76, 82, 82, 97,
+ 87, 91, 101, 67, 80, 88, 73, 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23,
+ 27, 26, 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 7, 38, 32, 32, 24, 24,
+ 13, 11, 5, 1, 73, 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23, 27, 26,
+ 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 64, 21, 40, 29, 7, 10, 4,
+ 78, 2, 65, 67, 19, 80, 73, 20, 15, 91, 104, 117, 73, 79, 70, 78, 2, 65,
+ 82, 64, 30, 2, 70, 77, 80, 89, 91, 90, 106, 64, 76, 84, 71, 85, 84, 99,
+ 3, 72, 71, 76, 25, 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 72,
+ 93, 66, 1, 71, 22, 20, 68, 1, 74, 11, 72, 68, 64, 98, 84, 87, 86, 19,
+ 67, 4, 64, 70, 85, 72, 76, 65, 75, 72, 85, 18, 73, 6, 76, 79, 67, 73,
+ 66, 3, 5, 1, 10, 6, 74, 0, 64, 67, 2, 72, 26, 67, 1, 24, 23, 32,
+ 28, 21, 89, 1, 64, 67, 67, 81, 68, 17, 66, 66, 16, 35, 54, 42, 18, 90,
+ 91, 3, 37, 40, 112, 70, 6, 90, 14, 67, 1, 16, 33, 55, 46, 25, 93, 85,
+ 65, 7, 13, 89, 18, 21, 18, 16, 19, 16, 10, 18, 17, 64, 6, 10, 3, 2,
+ 70, 6, 1, 65, 4, 1, 5, 5, 64, 90, 64, 65, 69, 66, 76, 22, 33, 19,
+ 13, 18, 20, 20, 22, 14, 77, 89, 73, 72, 70, 110, 67, 0, 89, 15, 2, 2,
+ 0, 0, 70, 64, 2, 82, 93, 79, 82, 81, 86, 74, 19, 17, 10, 4, 2, 67,
+ 72, 73, 78, 64, 30, 17, 11, 3, 14, 2, 65, 72, 64, 65, 29, 16, 11, 5,
+ 12, 1, 67, 71, 77, 72, 32, 15, 9, 4, 7, 67, 74, 77, 4, 36, 23, 16,
+ 8, 17, 4, 64, 67, 70, 62, 89, 84, 77, 81, 81, 78, 75, 73, 72, 70, 67,
+ 2, 77, 76, 82, 84, 21, 83, 85, 77, 72, 70, 73, 71, 71, 70, 69, 72, 82,
+ 68, 68, 13, 69, 77, 67, 68, 69, 66, 67, 68, 77, 69, 68, 73, 72, 8, 90,
+ 72, 14, 73, 64, 69, 68, 0, 1, 65, 65, 0, 73, 73, 84, 48, 45, 47, 39,
+ 31, 34, 34, 29, 30, 26, 27, 27, 15, 10, 65, 16, 15, 9, 69, 8, 6, 1,
+ 5, 66, 67, 71, 75, 79, 79, 19, 15, 18, 8, 72, 0, 65, 79, 68, 77, 80,
+ 96, 88, 92, 97, 2, 5, 84, 0, 2, 70, 81, 78, 79, 87, 77, 83, 83, 96,
+ 88, 93, 103, 68, 82, 89, 72, 3, 7, 8, 19, 13, 19, 2, 17, 15, 23, 24,
+ 28, 27, 14, 50, 23, 15, 9, 1, 64, 85, 90, 97, 8, 38, 33, 33, 24, 25,
+ 14, 12, 6, 1, 72, 3, 7, 8, 19, 13, 19, 2, 17, 15, 23, 24, 28, 27,
+ 14, 50, 23, 15, 9, 1, 64, 85, 90, 97, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 66, 20, 39, 30, 7, 12, 2,
+ 78, 3, 65, 67, 20, 81, 75, 18, 13, 94, 106, 118, 71, 78, 70, 78, 3, 65,
+ 82, 0, 30, 1, 69, 76, 79, 90, 93, 91, 106, 64, 76, 83, 71, 85, 84, 99,
+ 3, 72, 71, 76, 26, 2, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 17, 72,
+ 92, 64, 2, 70, 23, 21, 68, 2, 72, 12, 71, 67, 1, 99, 84, 87, 86, 19,
+ 68, 5, 1, 70, 84, 71, 74, 65, 75, 72, 85, 18, 73, 6, 75, 79, 67, 73,
+ 66, 3, 5, 2, 10, 6, 74, 64, 64, 67, 2, 72, 26, 67, 1, 25, 23, 32,
+ 28, 21, 90, 1, 0, 67, 67, 81, 68, 18, 66, 66, 17, 36, 55, 43, 20, 90,
+ 92, 3, 37, 40, 113, 70, 7, 91, 15, 67, 1, 17, 33, 55, 46, 26, 94, 83,
+ 66, 4, 10, 88, 17, 21, 17, 15, 18, 16, 9, 18, 16, 65, 5, 9, 3, 2,
+ 70, 5, 0, 66, 3, 0, 4, 4, 64, 91, 65, 66, 69, 68, 77, 20, 31, 17,
+ 11, 16, 18, 16, 19, 13, 79, 92, 75, 74, 72, 111, 69, 64, 91, 14, 1, 1,
+ 64, 64, 72, 66, 0, 84, 93, 80, 83, 83, 85, 73, 20, 17, 10, 4, 3, 66,
+ 71, 72, 76, 0, 31, 17, 12, 4, 15, 3, 0, 71, 1, 64, 29, 16, 11, 6,
+ 13, 2, 67, 71, 76, 72, 33, 16, 9, 4, 8, 67, 74, 76, 5, 36, 24, 16,
+ 8, 18, 5, 0, 67, 69, 62, 88, 83, 76, 79, 80, 76, 74, 71, 71, 69, 65,
+ 4, 76, 75, 81, 83, 24, 83, 86, 77, 71, 70, 73, 71, 71, 71, 68, 72, 83,
+ 68, 68, 14, 69, 77, 67, 68, 69, 67, 67, 68, 78, 70, 68, 73, 72, 9, 91,
+ 72, 14, 74, 64, 69, 68, 0, 1, 66, 65, 1, 73, 73, 85, 47, 44, 46, 37,
+ 29, 32, 31, 26, 27, 23, 23, 24, 11, 7, 67, 12, 11, 5, 74, 5, 4, 64,
+ 3, 69, 69, 73, 76, 80, 79, 16, 13, 16, 6, 74, 65, 67, 81, 70, 79, 82,
+ 98, 91, 94, 98, 1, 4, 87, 65, 0, 72, 83, 79, 80, 88, 78, 84, 83, 95,
+ 89, 94, 104, 69, 83, 90, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, 24, 24,
+ 29, 27, 15, 50, 21, 13, 7, 64, 66, 87, 92, 99, 8, 39, 33, 34, 25, 25,
+ 14, 12, 6, 2, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, 24, 24, 29, 27,
+ 15, 50, 21, 13, 7, 64, 66, 87, 92, 99, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 68, 18, 38, 31, 7, 13, 0,
+ 77, 5, 66, 67, 21, 82, 76, 17, 11, 97, 109, 118, 69, 77, 70, 77, 5, 66,
+ 82, 1, 30, 1, 69, 75, 77, 91, 94, 91, 106, 64, 75, 82, 72, 85, 84, 99,
+ 3, 71, 71, 75, 26, 2, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 17, 71,
+ 90, 2, 3, 69, 25, 23, 67, 3, 70, 13, 70, 66, 4, 99, 85, 87, 87, 19,
+ 68, 6, 4, 69, 84, 71, 72, 65, 75, 72, 84, 18, 73, 7, 74, 78, 66, 72,
+ 66, 4, 6, 3, 11, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 25, 24, 32,
+ 28, 21, 90, 2, 0, 68, 67, 80, 68, 19, 65, 65, 19, 38, 56, 45, 22, 91,
+ 93, 4, 38, 40, 114, 70, 7, 91, 16, 67, 1, 19, 33, 55, 46, 28, 95, 82,
+ 67, 2, 7, 87, 17, 21, 17, 15, 18, 16, 9, 18, 16, 66, 4, 9, 3, 2,
+ 70, 5, 0, 67, 3, 0, 4, 3, 65, 92, 66, 66, 69, 69, 77, 18, 29, 16,
+ 10, 15, 16, 13, 17, 12, 81, 94, 76, 76, 74, 112, 70, 65, 92, 13, 0, 0,
+ 66, 66, 74, 68, 64, 85, 93, 81, 84, 85, 83, 71, 21, 18, 10, 4, 4, 65,
+ 70, 72, 74, 2, 32, 18, 12, 5, 17, 4, 1, 70, 4, 0, 30, 17, 12, 6,
+ 14, 3, 66, 70, 75, 71, 34, 17, 9, 4, 9, 66, 73, 75, 6, 36, 25, 16,
+ 8, 19, 6, 1, 66, 68, 62, 87, 81, 74, 78, 79, 75, 72, 69, 69, 67, 0,
+ 7, 75, 74, 80, 82, 27, 82, 87, 76, 70, 69, 73, 71, 71, 71, 68, 73, 84,
+ 68, 68, 15, 69, 77, 67, 68, 68, 67, 68, 68, 79, 71, 69, 73, 72, 10, 91,
+ 73, 15, 74, 65, 69, 68, 0, 0, 66, 65, 1, 73, 73, 87, 46, 43, 45, 36,
+ 26, 29, 28, 23, 25, 20, 20, 21, 8, 5, 69, 8, 8, 1, 79, 2, 2, 65,
+ 1, 71, 71, 74, 77, 81, 79, 14, 10, 13, 4, 76, 67, 68, 83, 72, 81, 84,
+ 100, 93, 95, 100, 0, 3, 89, 66, 64, 73, 85, 80, 81, 89, 79, 85, 83, 94,
+ 91, 95, 106, 71, 84, 91, 72, 4, 8, 10, 21, 14, 20, 3, 19, 17, 25, 25,
+ 30, 28, 15, 49, 19, 11, 5, 66, 68, 90, 94, 100, 9, 39, 34, 34, 26, 26,
+ 15, 13, 6, 3, 72, 4, 8, 10, 21, 14, 20, 3, 19, 17, 25, 25, 30, 28,
+ 15, 49, 19, 11, 5, 66, 68, 90, 94, 100, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 70, 17, 37, 31, 7, 15, 64,
+ 77, 6, 66, 68, 22, 83, 77, 16, 9, 101, 111, 119, 67, 75, 70, 77, 6, 66,
+ 81, 2, 31, 1, 68, 74, 76, 92, 95, 91, 107, 64, 75, 81, 72, 86, 84, 99,
+ 3, 71, 71, 74, 27, 2, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 16, 71,
+ 89, 4, 4, 68, 26, 24, 66, 4, 68, 14, 69, 65, 6, 100, 85, 87, 87, 20,
+ 68, 7, 6, 69, 83, 70, 70, 65, 75, 72, 84, 19, 73, 7, 73, 78, 65, 72,
+ 66, 4, 6, 4, 11, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 26, 24, 33,
+ 28, 22, 91, 2, 1, 68, 67, 80, 68, 20, 65, 65, 20, 39, 57, 46, 24, 91,
+ 94, 4, 38, 40, 115, 70, 8, 92, 16, 67, 1, 20, 33, 55, 46, 29, 96, 80,
+ 68, 64, 4, 85, 17, 21, 16, 14, 17, 15, 8, 18, 15, 67, 3, 9, 3, 2,
+ 71, 4, 64, 68, 2, 0, 4, 2, 65, 93, 66, 67, 69, 70, 78, 16, 27, 14,
+ 8, 13, 14, 10, 14, 11, 83, 96, 78, 78, 76, 114, 71, 66, 94, 12, 64, 64,
+ 67, 67, 76, 70, 66, 87, 93, 82, 85, 86, 82, 70, 23, 18, 10, 4, 5, 64,
+ 69, 71, 72, 3, 33, 19, 13, 5, 18, 5, 3, 69, 6, 0, 30, 17, 12, 7,
+ 15, 3, 66, 69, 74, 71, 36, 18, 9, 4, 10, 66, 73, 74, 7, 37, 26, 17,
+ 8, 20, 6, 2, 66, 68, 62, 85, 80, 73, 76, 78, 73, 71, 68, 68, 65, 2,
+ 9, 75, 73, 80, 81, 30, 82, 88, 76, 69, 68, 73, 71, 71, 71, 67, 73, 85,
+ 68, 68, 15, 69, 77, 67, 68, 68, 68, 68, 68, 80, 72, 69, 73, 72, 11, 92,
+ 73, 16, 75, 65, 69, 68, 1, 0, 67, 64, 2, 73, 73, 88, 45, 42, 44, 34,
+ 24, 27, 26, 20, 22, 17, 17, 18, 5, 2, 71, 4, 4, 66, 84, 64, 0, 67,
+ 64, 74, 73, 75, 78, 82, 79, 12, 8, 11, 2, 78, 69, 70, 85, 74, 83, 86,
+ 102, 95, 97, 101, 64, 2, 91, 68, 66, 75, 87, 82, 83, 90, 80, 86, 83, 93,
+ 92, 97, 107, 72, 85, 92, 72, 4, 8, 10, 22, 15, 21, 3, 20, 18, 26, 25,
+ 31, 28, 16, 49, 17, 9, 3, 68, 70, 92, 96, 101, 9, 40, 34, 35, 26, 27,
+ 15, 13, 7, 3, 72, 4, 8, 10, 22, 15, 21, 3, 20, 18, 26, 25, 31, 28,
+ 16, 49, 17, 9, 3, 68, 70, 92, 96, 101, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 72, 15, 36, 32, 7, 17, 66,
+ 77, 8, 66, 68, 23, 84, 78, 15, 7, 104, 113, 120, 65, 74, 70, 77, 8, 66,
+ 81, 3, 31, 1, 67, 73, 75, 93, 96, 91, 107, 64, 75, 80, 72, 86, 84, 99,
+ 3, 71, 71, 73, 27, 2, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 16, 70,
+ 88, 6, 5, 67, 28, 26, 65, 5, 66, 15, 68, 64, 8, 101, 85, 87, 87, 20,
+ 68, 8, 8, 69, 82, 69, 68, 65, 75, 72, 84, 19, 73, 8, 72, 78, 64, 72,
+ 66, 4, 7, 5, 12, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 26, 24, 33,
+ 28, 22, 91, 3, 2, 69, 67, 80, 68, 21, 65, 64, 21, 40, 58, 48, 26, 92,
+ 95, 5, 38, 40, 116, 70, 8, 92, 17, 67, 1, 21, 33, 55, 46, 30, 97, 79,
+ 69, 67, 1, 84, 17, 21, 16, 13, 17, 15, 8, 18, 15, 68, 2, 9, 3, 2,
+ 71, 4, 65, 69, 2, 0, 4, 1, 66, 94, 67, 68, 69, 71, 78, 14, 25, 12,
+ 7, 11, 12, 7, 12, 10, 85, 98, 79, 80, 78, 115, 72, 67, 96, 11, 65, 65,
+ 68, 69, 78, 72, 68, 88, 93, 83, 86, 88, 80, 68, 24, 19, 10, 4, 6, 0,
+ 68, 70, 70, 4, 34, 20, 14, 6, 19, 6, 4, 68, 8, 1, 31, 18, 13, 7,
+ 16, 4, 65, 68, 73, 71, 37, 19, 9, 4, 11, 65, 73, 73, 8, 37, 27, 17,
+ 8, 21, 7, 3, 65, 67, 62, 84, 78, 71, 74, 77, 72, 69, 66, 66, 0, 4,
+ 11, 74, 72, 79, 80, 33, 82, 89, 76, 68, 67, 73, 71, 71, 71, 67, 73, 86,
+ 68, 68, 16, 69, 77, 67, 68, 68, 68, 68, 68, 81, 73, 69, 73, 72, 12, 93,
+ 73, 17, 76, 65, 69, 68, 1, 0, 67, 64, 3, 73, 73, 90, 44, 41, 43, 32,
+ 22, 24, 23, 17, 20, 14, 14, 15, 2, 64, 73, 0, 1, 70, 89, 67, 65, 69,
+ 66, 76, 75, 76, 79, 83, 79, 10, 6, 9, 0, 80, 71, 71, 87, 76, 85, 88,
+ 104, 97, 99, 102, 65, 1, 93, 69, 68, 76, 89, 83, 84, 91, 81, 87, 83, 92,
+ 93, 98, 109, 73, 86, 93, 72, 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26,
+ 32, 29, 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 10, 40, 35, 36, 27, 28,
+ 16, 14, 7, 4, 72, 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, 29,
+ 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 74, 13, 35, 32, 7, 18,
+ 68, 77, 9, 67, 69, 24, 85, 80, 13, 5, 108, 116, 121, 0, 73, 70, 77,
+ 9, 67, 81, 3, 31, 0, 67, 73, 74, 95, 98, 92, 108, 65, 75, 80, 73,
+ 87, 84, 99, 2, 71, 71, 73, 27, 1, 22, 0, 0, 0, 65, 94, 97, 5,
+ 67, 68, 15, 70, 87, 8, 6, 67, 29, 27, 65, 6, 65, 15, 67, 64, 10,
+ 102, 86, 88, 88, 20, 69, 8, 10, 69, 82, 69, 67, 65, 75, 72, 84, 19,
+ 74, 8, 72, 78, 64, 72, 66, 4, 7, 6, 12, 6, 76, 65, 0, 67, 1,
+ 72, 27, 67, 1, 26, 24, 33, 28, 22, 92, 3, 2, 70, 67, 80, 69, 21,
+ 65, 64, 22, 41, 58, 49, 27, 93, 97, 5, 38, 40, 117, 71, 8, 93, 17,
+ 68, 1, 22, 33, 54, 46, 31, 98, 78, 71, 70, 66, 83, 16, 21, 15, 12,
+ 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, 72, 3, 66, 70, 1, 64, 3,
+ 0, 67, 96, 68, 69, 69, 73, 79, 11, 22, 10, 5, 9, 9, 3, 9, 8,
+ 87, 101, 81, 83, 80, 117, 74, 69, 98, 9, 66, 66, 70, 71, 80, 74, 70,
+ 90, 93, 84, 87, 90, 79, 67, 25, 19, 10, 4, 6, 0, 68, 70, 69, 5,
+ 34, 20, 14, 6, 20, 7, 5, 68, 10, 1, 31, 18, 13, 7, 16, 4, 65,
+ 68, 72, 71, 38, 20, 9, 3, 11, 65, 73, 73, 8, 37, 27, 17, 8, 22,
+ 7, 3, 65, 67, 62, 83, 77, 70, 73, 76, 71, 68, 65, 65, 1, 5, 13,
+ 74, 72, 79, 80, 36, 82, 91, 76, 68, 67, 73, 71, 71, 72, 67, 74, 87,
+ 69, 68, 16, 70, 77, 68, 68, 68, 69, 69, 69, 82, 74, 70, 74, 72, 13,
+ 94, 74, 17, 77, 66, 69, 69, 1, 64, 68, 64, 3, 73, 73, 92, 42, 40,
+ 41, 30, 19, 21, 20, 14, 17, 11, 10, 12, 65, 67, 75, 67, 66, 74, 95,
+ 70, 68, 71, 69, 79, 77, 78, 81, 84, 79, 7, 3, 6, 65, 83, 73, 73,
+ 90, 78, 88, 90, 107, 100, 101, 104, 67, 64, 96, 71, 70, 78, 91, 85, 86,
+ 92, 82, 88, 84, 91, 95, 100, 111, 75, 88, 95, 72, 5, 9, 11, 24, 16,
+ 22, 3, 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, 100,
+ 104, 10, 40, 35, 36, 27, 28, 16, 14, 7, 4, 72, 5, 9, 11, 24, 16,
+ 22, 3, 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, 100,
+ 104, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 75, 12, 35, 33, 8, 20,
+ 69, 76, 11, 67, 69, 26, 85, 81, 12, 4, 111, 118, 121, 2, 71, 69, 76,
+ 11, 67, 80, 4, 32, 0, 66, 72, 72, 96, 99, 92, 108, 65, 74, 79, 73,
+ 87, 83, 98, 2, 70, 70, 72, 28, 1, 22, 0, 0, 0, 64, 94, 97, 6,
+ 67, 68, 15, 69, 85, 11, 8, 66, 31, 29, 64, 8, 0, 16, 65, 0, 13,
+ 102, 86, 88, 88, 21, 69, 9, 13, 68, 81, 68, 65, 65, 74, 72, 83, 20,
+ 74, 9, 71, 77, 0, 71, 65, 5, 8, 7, 13, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 27, 25, 34, 29, 23, 92, 4, 3, 70, 67, 79, 69, 22,
+ 64, 0, 24, 43, 59, 51, 29, 93, 98, 6, 39, 41, 117, 71, 9, 93, 18,
+ 68, 2, 24, 33, 54, 47, 33, 99, 76, 72, 72, 69, 81, 16, 21, 15, 12,
+ 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, 72, 3, 66, 70, 1, 64, 3,
+ 0, 67, 97, 68, 69, 69, 74, 79, 9, 20, 9, 4, 8, 7, 0, 7, 7,
+ 88, 103, 82, 85, 81, 118, 75, 70, 99, 8, 66, 66, 71, 72, 81, 75, 71,
+ 91, 93, 84, 87, 91, 77, 65, 27, 20, 10, 4, 7, 1, 67, 69, 67, 7,
+ 35, 21, 15, 7, 22, 8, 7, 67, 13, 2, 32, 19, 14, 8, 17, 5, 64,
+ 67, 70, 70, 40, 21, 10, 3, 12, 64, 72, 72, 9, 38, 28, 18, 9, 23,
+ 8, 4, 64, 66, 62, 81, 75, 68, 71, 74, 69, 66, 0, 0, 3, 7, 16,
+ 73, 71, 78, 79, 40, 81, 92, 75, 67, 66, 72, 71, 70, 72, 66, 74, 87,
+ 69, 68, 17, 70, 77, 68, 68, 67, 69, 69, 69, 82, 74, 70, 74, 71, 15,
+ 94, 74, 18, 77, 66, 69, 69, 2, 64, 68, 0, 4, 72, 72, 93, 41, 39,
+ 40, 29, 17, 19, 18, 11, 15, 9, 7, 10, 68, 69, 77, 70, 69, 77, 100,
+ 72, 70, 72, 71, 81, 78, 79, 82, 84, 79, 5, 1, 4, 67, 85, 74, 74,
+ 92, 79, 90, 91, 109, 102, 102, 105, 68, 65, 98, 72, 71, 79, 92, 86, 87,
+ 93, 82, 88, 84, 90, 96, 101, 112, 76, 89, 96, 71, 6, 10, 12, 26, 17,
+ 23, 4, 24, 20, 29, 27, 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101,
+ 105, 11, 41, 36, 37, 28, 29, 17, 15, 8, 5, 71, 6, 10, 12, 26, 17,
+ 23, 4, 24, 20, 29, 27, 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101,
+ 105, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 77, 10, 34, 34, 8, 22,
+ 71, 76, 12, 67, 69, 27, 86, 82, 11, 2, 114, 120, 122, 4, 70, 69, 76,
+ 12, 67, 80, 5, 32, 0, 65, 71, 71, 97, 100, 92, 108, 65, 74, 78, 73,
+ 87, 83, 98, 2, 70, 70, 71, 28, 1, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 15, 68, 84, 13, 9, 65, 33, 31, 0, 9, 2, 17, 64, 1, 15,
+ 103, 86, 88, 88, 21, 69, 10, 15, 68, 80, 67, 0, 65, 74, 72, 83, 20,
+ 74, 9, 70, 77, 1, 71, 65, 5, 8, 8, 14, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 27, 25, 34, 29, 23, 93, 5, 4, 71, 67, 79, 69, 23,
+ 64, 0, 25, 44, 60, 53, 31, 94, 99, 6, 39, 41, 118, 71, 9, 94, 19,
+ 68, 2, 25, 33, 54, 47, 34, 100, 75, 73, 75, 72, 80, 16, 21, 15, 11,
+ 15, 14, 7, 17, 13, 70, 0, 8, 2, 1, 72, 2, 67, 71, 1, 64, 3,
+ 64, 68, 98, 69, 70, 69, 75, 80, 7, 18, 7, 2, 6, 5, 66, 5, 6,
+ 90, 105, 84, 87, 83, 119, 76, 71, 101, 7, 67, 67, 72, 74, 83, 77, 73,
+ 93, 93, 85, 88, 93, 76, 64, 28, 21, 10, 4, 8, 2, 66, 68, 65, 8,
+ 36, 22, 16, 8, 23, 9, 8, 66, 15, 3, 32, 19, 14, 8, 18, 6, 0,
+ 66, 69, 70, 41, 22, 10, 3, 13, 0, 72, 71, 10, 38, 29, 18, 9, 24,
+ 9, 5, 0, 65, 62, 80, 73, 66, 69, 73, 68, 64, 2, 1, 5, 9, 18,
+ 72, 70, 77, 78, 43, 81, 93, 75, 66, 65, 72, 71, 70, 72, 66, 74, 88,
+ 69, 68, 18, 70, 77, 68, 68, 67, 69, 69, 69, 83, 75, 70, 74, 71, 16,
+ 95, 74, 19, 78, 66, 69, 69, 2, 64, 68, 0, 5, 72, 72, 95, 40, 38,
+ 39, 27, 15, 16, 15, 8, 13, 6, 4, 7, 71, 72, 79, 74, 73, 81, 105,
+ 75, 72, 74, 73, 83, 80, 80, 83, 85, 79, 3, 64, 2, 69, 87, 76, 76,
+ 94, 81, 92, 93, 111, 104, 104, 106, 69, 66, 100, 74, 73, 81, 94, 87, 88,
+ 94, 83, 89, 84, 89, 97, 102, 114, 77, 90, 97, 71, 6, 11, 13, 27, 18,
+ 24, 4, 25, 21, 30, 27, 34, 31, 19, 46, 10, 2, 69, 77, 77, 101, 103,
+ 106, 12, 41, 36, 38, 29, 30, 17, 16, 8, 6, 71, 6, 11, 13, 27, 18,
+ 24, 4, 25, 21, 30, 27, 34, 31, 19, 46, 10, 2, 69, 77, 77, 101, 103,
+ 106, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 79, 9, 33, 34, 8, 24,
+ 72, 76, 14, 67, 70, 28, 87, 83, 10, 0, 118, 122, 123, 6, 68, 69, 76,
+ 14, 67, 79, 6, 33, 0, 64, 70, 70, 98, 101, 92, 109, 65, 74, 77, 73,
+ 88, 83, 98, 2, 70, 70, 70, 29, 1, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 14, 68, 83, 15, 10, 64, 34, 32, 1, 10, 4, 18, 0, 2, 17,
+ 104, 86, 88, 88, 22, 69, 11, 17, 68, 79, 66, 2, 65, 74, 72, 83, 21,
+ 74, 10, 69, 77, 2, 71, 65, 5, 9, 9, 14, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 28, 25, 35, 29, 24, 93, 5, 5, 71, 67, 79, 69, 24,
+ 64, 1, 26, 45, 61, 54, 33, 94, 100, 7, 39, 41, 119, 71, 10, 94, 19,
+ 68, 2, 26, 33, 54, 47, 35, 101, 73, 74, 78, 75, 78, 16, 21, 14, 10,
+ 15, 13, 6, 17, 13, 71, 64, 8, 2, 1, 73, 2, 68, 72, 0, 64, 3,
+ 65, 68, 99, 69, 71, 69, 76, 80, 5, 16, 5, 1, 4, 3, 69, 2, 5,
+ 92, 107, 85, 89, 85, 121, 77, 72, 103, 6, 68, 68, 73, 75, 85, 79, 75,
+ 94, 93, 86, 89, 94, 74, 1, 30, 21, 10, 4, 9, 3, 65, 67, 0, 9,
+ 37, 23, 17, 8, 24, 10, 10, 65, 17, 3, 33, 20, 15, 9, 19, 6, 0,
+ 65, 68, 70, 43, 23, 10, 3, 14, 0, 72, 70, 11, 39, 30, 19, 9, 25,
+ 9, 6, 0, 65, 62, 78, 72, 65, 67, 72, 66, 0, 3, 3, 7, 11, 20,
+ 72, 69, 77, 77, 46, 81, 94, 75, 65, 64, 72, 71, 70, 72, 65, 74, 89,
+ 69, 68, 18, 70, 77, 68, 68, 67, 70, 69, 69, 84, 76, 70, 74, 71, 17,
+ 96, 74, 20, 79, 66, 69, 69, 3, 64, 69, 1, 6, 72, 72, 96, 39, 37,
+ 38, 25, 13, 14, 13, 5, 10, 3, 1, 4, 74, 75, 81, 78, 76, 85, 110,
+ 78, 74, 76, 75, 86, 82, 81, 84, 86, 79, 1, 66, 0, 71, 89, 78, 77,
+ 96, 83, 94, 95, 113, 106, 106, 107, 70, 67, 102, 75, 75, 82, 96, 89, 90,
+ 95, 84, 90, 84, 88, 98, 104, 115, 78, 91, 98, 71, 7, 11, 13, 28, 19,
+ 25, 4, 26, 22, 31, 28, 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105,
+ 107, 12, 42, 37, 39, 29, 31, 18, 16, 9, 6, 71, 7, 11, 13, 28, 19,
+ 25, 4, 26, 22, 31, 28, 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105,
+ 107, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 81, 7, 32, 35, 8, 25,
+ 74, 76, 15, 68, 70, 29, 88, 85, 8, 65, 121, 125, 124, 8, 67, 69, 76,
+ 15, 68, 79, 7, 33, 64, 64, 69, 68, 99, 103, 93, 109, 65, 73, 76, 74,
+ 88, 83, 98, 2, 70, 70, 70, 29, 1, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 14, 67, 82, 17, 11, 0, 36, 34, 1, 11, 6, 19, 1, 3, 20,
+ 104, 87, 88, 89, 22, 70, 12, 20, 67, 79, 66, 4, 65, 74, 72, 83, 21,
+ 74, 10, 68, 77, 2, 70, 65, 5, 9, 10, 15, 7, 77, 66, 1, 66, 1,
+ 71, 28, 66, 1, 28, 25, 35, 29, 24, 94, 6, 5, 72, 67, 78, 69, 25,
+ 0, 1, 28, 47, 62, 56, 35, 95, 101, 7, 40, 41, 120, 71, 10, 95, 20,
+ 68, 2, 27, 33, 54, 47, 37, 102, 72, 75, 81, 78, 77, 15, 21, 14, 10,
+ 14, 13, 6, 17, 12, 72, 65, 7, 2, 1, 73, 1, 68, 73, 0, 65, 2,
+ 66, 69, 100, 70, 72, 69, 78, 81, 3, 14, 3, 64, 3, 1, 73, 0, 4,
+ 94, 110, 87, 91, 87, 122, 79, 73, 104, 5, 69, 69, 75, 77, 87, 81, 76,
+ 96, 93, 87, 90, 96, 73, 2, 31, 22, 10, 4, 10, 4, 64, 67, 2, 11,
+ 38, 23, 17, 9, 26, 11, 11, 64, 20, 4, 33, 20, 15, 9, 20, 7, 1,
+ 65, 67, 70, 44, 24, 10, 3, 15, 1, 72, 69, 12, 39, 31, 19, 9, 26,
+ 10, 7, 1, 64, 62, 77, 70, 0, 66, 71, 65, 2, 5, 4, 8, 13, 23,
+ 71, 68, 76, 76, 49, 80, 95, 74, 64, 64, 72, 71, 70, 73, 65, 75, 90,
+ 69, 68, 19, 70, 77, 68, 68, 66, 70, 70, 69, 85, 77, 71, 74, 71, 18,
+ 97, 75, 20, 79, 67, 69, 69, 3, 65, 69, 1, 6, 72, 72, 98, 38, 36,
+ 37, 24, 10, 11, 10, 2, 8, 0, 66, 1, 78, 77, 83, 82, 80, 89, 115,
+ 81, 76, 78, 77, 88, 84, 83, 85, 87, 79, 65, 69, 66, 73, 91, 80, 79,
+ 98, 85, 96, 97, 115, 109, 107, 109, 71, 68, 105, 77, 76, 84, 98, 90, 91,
+ 96, 85, 91, 84, 87, 100, 105, 117, 80, 92, 99, 71, 7, 12, 14, 29, 19,
+ 25, 5, 27, 23, 32, 28, 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107,
+ 109, 13, 42, 37, 39, 30, 31, 18, 17, 9, 7, 71, 7, 12, 14, 29, 19,
+ 25, 5, 27, 23, 32, 28, 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107,
+ 109, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 83, 6, 31, 36, 8,
+ 27, 76, 75, 17, 68, 70, 30, 89, 86, 7, 67, 124, 126, 124, 10, 66,
+ 69, 75, 17, 68, 79, 8, 33, 64, 0, 68, 67, 100, 104, 93, 109, 65,
+ 73, 75, 74, 88, 83, 98, 2, 69, 70, 69, 30, 1, 22, 0, 0, 0,
+ 1, 95, 97, 8, 71, 68, 13, 67, 80, 20, 12, 1, 37, 35, 2, 12,
+ 8, 20, 2, 4, 22, 105, 87, 88, 89, 22, 70, 13, 22, 67, 78, 65,
+ 6, 65, 74, 72, 82, 21, 74, 11, 67, 76, 3, 70, 65, 6, 10, 11,
+ 15, 7, 77, 66, 2, 66, 1, 71, 29, 66, 1, 29, 26, 35, 29, 24,
+ 94, 6, 6, 72, 67, 78, 69, 26, 0, 2, 29, 48, 62, 57, 37, 95,
+ 102, 8, 40, 41, 121, 71, 11, 95, 21, 68, 2, 29, 33, 54, 47, 38,
+ 103, 70, 76, 83, 81, 76, 15, 21, 13, 9, 14, 13, 5, 17, 12, 73,
+ 66, 7, 2, 1, 73, 1, 69, 74, 64, 65, 2, 67, 69, 101, 71, 72,
+ 69, 79, 81, 1, 12, 2, 65, 1, 64, 76, 66, 3, 96, 112, 88, 93,
+ 89, 123, 80, 74, 106, 4, 70, 70, 76, 78, 89, 83, 78, 97, 93, 88,
+ 91, 98, 71, 4, 32, 22, 10, 4, 11, 5, 0, 66, 4, 12, 39, 24,
+ 18, 10, 27, 12, 13, 0, 22, 5, 34, 21, 16, 10, 21, 8, 1, 64,
+ 66, 69, 45, 25, 10, 3, 16, 1, 71, 68, 13, 39, 32, 19, 9, 27,
+ 11, 8, 1, 0, 62, 76, 69, 1, 64, 70, 0, 3, 7, 6, 10, 15,
+ 25, 70, 67, 75, 75, 52, 80, 96, 74, 0, 0, 72, 71, 70, 73, 64,
+ 75, 91, 69, 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 86, 78, 71,
+ 74, 71, 19, 97, 75, 21, 80, 67, 69, 69, 3, 65, 70, 1, 7, 72,
+ 72, 99, 37, 35, 36, 22, 8, 9, 7, 64, 5, 66, 69, 65, 81, 80,
+ 85, 86, 83, 93, 120, 84, 78, 79, 79, 91, 86, 84, 86, 88, 79, 67,
+ 71, 68, 75, 93, 82, 80, 100, 87, 98, 99, 117, 111, 109, 110, 72, 69,
+ 107, 78, 78, 85, 100, 91, 92, 97, 86, 92, 84, 86, 101, 106, 118, 81,
+ 93, 100, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, 33, 29, 37, 32,
+ 21, 45, 4, 67, 75, 83, 83, 108, 109, 110, 13, 43, 38, 40, 31, 32,
+ 19, 17, 9, 8, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, 33, 29,
+ 37, 32, 21, 45, 4, 67, 75, 83, 83, 108, 109, 110, 75, 69, 0, 10,
+ 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 84, 4, 30, 36, 9,
+ 29, 77, 75, 18, 68, 71, 31, 90, 87, 6, 68, 126, 126, 125, 12, 64,
+ 69, 75, 18, 68, 78, 9, 34, 64, 1, 67, 66, 102, 105, 93, 110, 65,
+ 73, 75, 74, 89, 82, 98, 1, 69, 70, 68, 30, 1, 22, 0, 0, 0,
+ 2, 95, 97, 8, 71, 69, 13, 66, 79, 22, 13, 2, 39, 37, 3, 13,
+ 10, 21, 3, 4, 24, 106, 87, 88, 89, 23, 70, 14, 24, 67, 77, 64,
+ 8, 65, 74, 72, 82, 22, 75, 11, 67, 76, 4, 70, 64, 6, 10, 12,
+ 16, 7, 77, 66, 2, 66, 1, 71, 29, 66, 1, 29, 26, 36, 30, 25,
+ 95, 7, 7, 73, 67, 78, 69, 27, 0, 2, 30, 49, 62, 59, 38, 96,
+ 103, 8, 40, 41, 121, 72, 11, 96, 21, 69, 3, 30, 33, 54, 48, 39,
+ 104, 69, 77, 86, 84, 74, 15, 21, 13, 8, 13, 12, 5, 16, 11, 73,
+ 66, 7, 1, 1, 74, 0, 70, 75, 64, 65, 2, 67, 70, 103, 71, 73,
+ 69, 80, 82, 65, 10, 0, 67, 64, 66, 79, 68, 1, 98, 114, 90, 95,
+ 91, 125, 81, 76, 108, 2, 71, 71, 77, 80, 91, 85, 80, 99, 93, 89,
+ 92, 99, 70, 5, 34, 23, 10, 4, 12, 5, 0, 65, 5, 13, 40, 25,
+ 19, 10, 28, 13, 14, 1, 24, 5, 34, 21, 16, 10, 22, 8, 2, 0,
+ 65, 69, 47, 26, 10, 3, 16, 2, 71, 68, 13, 40, 32, 20, 9, 28,
+ 11, 8, 2, 0, 62, 74, 67, 3, 1, 68, 1, 5, 8, 7, 12, 17,
+ 27, 70, 66, 75, 75, 55, 80, 97, 74, 0, 1, 72, 71, 70, 73, 64,
+ 75, 92, 69, 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 87, 79, 71,
+ 74, 71, 20, 98, 75, 22, 81, 67, 69, 69, 4, 65, 70, 2, 8, 72,
+ 72, 101, 36, 34, 35, 20, 6, 6, 5, 67, 3, 69, 72, 68, 84, 83,
+ 87, 89, 87, 97, 125, 86, 81, 81, 81, 93, 88, 85, 87, 89, 79, 69,
+ 73, 70, 77, 95, 83, 82, 102, 89, 101, 101, 119, 113, 111, 111, 73, 71,
+ 109, 80, 80, 87, 102, 93, 94, 98, 87, 93, 85, 85, 102, 108, 120, 82,
+ 95, 101, 70, 8, 13, 15, 31, 21, 27, 5, 29, 25, 34, 29, 38, 33,
+ 22, 44, 2, 69, 77, 85, 85, 110, 111, 111, 14, 43, 38, 41, 31, 33,
+ 19, 18, 10, 8, 70, 8, 13, 15, 31, 21, 27, 5, 29, 25, 34, 29,
+ 38, 33, 22, 44, 2, 69, 77, 85, 85, 110, 111, 111, 75, 69, 0, 11,
+ 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 86, 3, 29, 37, 9,
+ 30, 79, 75, 20, 69, 71, 32, 91, 88, 5, 70, 126, 126, 126, 14, 0,
+ 69, 75, 20, 69, 78, 10, 34, 64, 1, 66, 64, 103, 106, 93, 110, 65,
+ 72, 74, 75, 89, 82, 98, 1, 69, 70, 67, 31, 1, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 12, 66, 78, 24, 14, 3, 40, 38, 4, 14,
+ 12, 22, 4, 5, 27, 106, 88, 88, 90, 23, 70, 15, 27, 66, 77, 64,
+ 10, 65, 74, 72, 82, 22, 75, 12, 66, 76, 5, 69, 64, 6, 11, 13,
+ 16, 7, 78, 66, 2, 66, 1, 71, 29, 66, 1, 30, 26, 36, 30, 25,
+ 95, 7, 7, 73, 67, 77, 69, 28, 1, 3, 32, 51, 62, 60, 40, 96,
+ 104, 9, 41, 41, 122, 72, 12, 96, 22, 69, 3, 31, 33, 54, 48, 41,
+ 105, 67, 78, 89, 87, 73, 15, 21, 12, 8, 13, 12, 4, 16, 11, 74,
+ 67, 7, 1, 1, 74, 0, 70, 76, 65, 65, 2, 68, 70, 104, 72, 74,
+ 69, 81, 82, 67, 8, 65, 68, 65, 68, 82, 71, 0, 100, 116, 91, 97,
+ 93, 126, 82, 77, 109, 1, 72, 72, 79, 81, 93, 87, 81, 100, 93, 90,
+ 93, 101, 68, 7, 35, 23, 10, 4, 13, 6, 1, 65, 7, 15, 41, 26,
+ 19, 11, 30, 14, 16, 2, 27, 6, 35, 22, 17, 11, 23, 9, 2, 1,
+ 64, 69, 48, 27, 10, 3, 17, 2, 71, 67, 14, 40, 33, 20, 9, 29,
+ 12, 9, 2, 1, 62, 73, 66, 4, 2, 67, 3, 6, 10, 9, 14, 19,
+ 30, 69, 65, 74, 74, 58, 79, 98, 73, 1, 2, 72, 71, 70, 73, 0,
+ 76, 93, 69, 68, 21, 70, 77, 68, 68, 65, 72, 71, 69, 88, 80, 72,
+ 74, 71, 21, 99, 76, 23, 81, 68, 69, 69, 4, 66, 71, 2, 8, 72,
+ 72, 102, 35, 33, 34, 19, 3, 4, 2, 70, 0, 72, 75, 71, 87, 85,
+ 89, 93, 90, 101, 126, 89, 83, 83, 83, 96, 90, 86, 88, 90, 79, 71,
+ 76, 73, 79, 97, 85, 83, 104, 91, 103, 103, 121, 115, 112, 113, 74, 72,
+ 111, 81, 81, 88, 104, 94, 95, 99, 88, 94, 85, 84, 104, 109, 121, 84,
+ 96, 102, 70, 9, 13, 16, 32, 22, 27, 6, 30, 26, 35, 30, 39, 33,
+ 22, 44, 0, 71, 79, 87, 87, 113, 113, 112, 14, 44, 39, 41, 32, 34,
+ 20, 18, 10, 9, 70, 9, 13, 16, 32, 22, 27, 6, 30, 26, 35, 30,
+ 39, 33, 22, 44, 0, 71, 79, 87, 87, 113, 113, 112, 75, 69, 0, 11,
+ 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 88, 1, 28, 37, 9,
+ 32, 81, 75, 21, 69, 72, 33, 92, 90, 3, 72, 126, 126, 126, 16, 1,
+ 69, 75, 21, 69, 78, 10, 34, 65, 2, 65, 0, 104, 108, 94, 111, 65,
+ 72, 73, 75, 90, 82, 98, 1, 69, 70, 67, 31, 1, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 12, 65, 77, 26, 15, 3, 42, 40, 4, 15,
+ 14, 22, 5, 6, 29, 107, 88, 89, 90, 23, 71, 15, 29, 66, 76, 0,
+ 11, 65, 74, 72, 82, 22, 75, 12, 65, 76, 5, 69, 64, 6, 11, 14,
+ 17, 7, 78, 67, 2, 66, 0, 71, 29, 66, 1, 30, 26, 36, 30, 25,
+ 96, 8, 8, 74, 67, 77, 69, 29, 1, 3, 33, 52, 62, 62, 42, 97,
+ 105, 9, 41, 41, 123, 72, 12, 97, 22, 69, 3, 32, 33, 54, 48, 42,
+ 106, 66, 79, 92, 91, 72, 14, 21, 12, 7, 12, 11, 4, 16, 10, 75,
+ 68, 6, 1, 0, 75, 64, 71, 77, 65, 66, 1, 69, 71, 105, 73, 75,
+ 69, 83, 83, 69, 6, 67, 70, 67, 71, 86, 73, 64, 102, 119, 93, 100,
+ 95, 126, 84, 78, 111, 0, 73, 73, 80, 83, 95, 89, 83, 102, 93, 91,
+ 94, 103, 67, 8, 36, 24, 10, 4, 13, 7, 2, 64, 9, 16, 41, 26,
+ 20, 11, 31, 15, 17, 3, 29, 6, 35, 22, 17, 11, 23, 9, 3, 1,
+ 0, 69, 49, 28, 10, 3, 18, 3, 71, 66, 15, 40, 34, 20, 9, 30,
+ 12, 10, 3, 1, 62, 72, 64, 6, 4, 66, 4, 8, 11, 10, 15, 21,
+ 32, 69, 64, 74, 73, 61, 79, 99, 73, 2, 2, 72, 71, 70, 74, 0,
+ 76, 94, 69, 68, 21, 70, 77, 69, 68, 65, 72, 71, 70, 89, 81, 72,
+ 75, 71, 22, 100, 76, 23, 82, 68, 69, 70, 4, 66, 71, 2, 9, 72,
+ 72, 104, 34, 32, 33, 17, 1, 1, 64, 73, 65, 75, 79, 74, 91, 88,
+ 91, 97, 94, 105, 126, 92, 85, 85, 86, 98, 92, 88, 90, 91, 79, 74,
+ 78, 75, 81, 100, 87, 85, 107, 93, 105, 105, 123, 118, 114, 114, 76, 73,
+ 114, 83, 83, 90, 106, 96, 97, 100, 89, 95, 85, 83, 105, 111, 123, 85,
+ 97, 103, 70, 9, 14, 16, 33, 22, 28, 6, 31, 26, 36, 30, 39, 34,
+ 23, 43, 65, 73, 81, 89, 89, 115, 115, 114, 15, 44, 39, 42, 32, 34,
+ 20, 19, 10, 9, 70, 9, 14, 16, 33, 22, 28, 6, 31, 26, 36, 30,
+ 39, 34, 23, 43, 65, 73, 81, 89, 89, 115, 115, 114, 75, 70, 64, 11,
+ 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 90, 64, 28, 38, 9,
+ 34, 82, 74, 23, 69, 72, 34, 92, 91, 2, 74, 126, 126, 126, 18, 3,
+ 68, 74, 23, 69, 77, 11, 35, 65, 3, 64, 1, 105, 109, 94, 111, 65,
+ 72, 72, 75, 90, 82, 98, 1, 68, 69, 66, 31, 1, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 12, 64, 75, 29, 16, 4, 44, 42, 5, 16,
+ 16, 23, 7, 7, 31, 108, 88, 89, 90, 24, 71, 16, 31, 66, 75, 1,
+ 13, 65, 73, 72, 81, 23, 75, 13, 64, 75, 6, 69, 64, 7, 12, 15,
+ 18, 7, 78, 67, 3, 65, 0, 71, 30, 66, 1, 30, 27, 37, 30, 26,
+ 96, 9, 9, 75, 67, 77, 69, 30, 1, 4, 34, 53, 62, 62, 44, 98,
+ 106, 10, 41, 42, 124, 72, 12, 97, 23, 69, 3, 34, 33, 54, 48, 43,
+ 107, 65, 80, 94, 94, 70, 14, 21, 12, 6, 12, 11, 4, 16, 10, 76,
+ 69, 6, 1, 0, 75, 64, 72, 77, 65, 66, 1, 70, 72, 106, 73, 75,
+ 69, 84, 83, 71, 4, 68, 71, 69, 73, 89, 75, 65, 104, 121, 94, 102,
+ 96, 126, 85, 79, 113, 64, 74, 74, 81, 85, 96, 91, 85, 103, 93, 91,
+ 95, 104, 65, 10, 38, 25, 10, 4, 14, 8, 3, 0, 11, 17, 42, 27,
+ 21, 12, 32, 16, 18, 4, 31, 7, 36, 23, 18, 11, 24, 10, 4, 2,
+ 2, 68, 51, 29, 11, 3, 19, 4, 70, 65, 16, 41, 35, 21, 10, 31,
+ 13, 11, 4, 2, 62, 70, 1, 8, 6, 65, 5, 10, 13, 12, 17, 23,
+ 34, 68, 0, 73, 72, 62, 79, 100, 73, 3, 3, 71, 71, 70, 74, 0,
+ 76, 95, 69, 68, 22, 70, 77, 69, 68, 65, 72, 71, 70, 89, 82, 72,
+ 75, 70, 24, 100, 76, 24, 83, 68, 69, 70, 5, 66, 71, 3, 10, 71,
+ 71, 106, 33, 31, 32, 15, 64, 65, 66, 76, 67, 77, 82, 76, 94, 91,
+ 93, 101, 97, 108, 126, 95, 87, 86, 88, 100, 93, 89, 91, 92, 79, 76,
+ 80, 77, 83, 102, 89, 86, 109, 95, 107, 107, 125, 120, 116, 115, 77, 74,
+ 116, 84, 85, 91, 108, 97, 98, 101, 90, 95, 85, 82, 106, 112, 125, 86,
+ 98, 104, 70, 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, 35,
+ 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, 16, 44, 40, 43, 33, 35,
+ 21, 20, 11, 10, 70, 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31,
+ 40, 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 92, 65, 27, 39, 9,
+ 35, 84, 74, 24, 70, 72, 35, 93, 92, 1, 76, 126, 126, 126, 20, 4,
+ 68, 74, 24, 70, 77, 12, 35, 65, 3, 0, 3, 106, 110, 94, 111, 65,
+ 71, 71, 76, 90, 82, 98, 1, 68, 69, 65, 32, 1, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 11, 64, 74, 31, 17, 5, 45, 43, 6, 17,
+ 18, 24, 8, 8, 34, 108, 89, 89, 91, 24, 71, 17, 34, 65, 75, 1,
+ 15, 65, 73, 72, 81, 23, 75, 13, 0, 75, 7, 68, 64, 7, 12, 16,
+ 18, 7, 79, 67, 3, 65, 0, 71, 30, 66, 1, 31, 27, 37, 30, 26,
+ 97, 9, 9, 75, 67, 76, 69, 31, 2, 4, 36, 55, 62, 62, 46, 98,
+ 107, 10, 42, 42, 125, 72, 13, 98, 24, 69, 3, 35, 33, 54, 48, 45,
+ 108, 0, 81, 97, 97, 69, 14, 21, 11, 6, 11, 11, 3, 16, 9, 77,
+ 70, 6, 1, 0, 75, 65, 72, 78, 66, 66, 1, 71, 72, 107, 74, 76,
+ 69, 85, 84, 73, 2, 70, 73, 70, 75, 92, 78, 66, 106, 123, 96, 104,
+ 98, 126, 86, 80, 114, 65, 75, 75, 83, 86, 98, 93, 86, 105, 93, 92,
+ 96, 106, 64, 11, 39, 25, 10, 4, 15, 9, 4, 0, 13, 19, 43, 28,
+ 21, 13, 34, 17, 20, 5, 34, 8, 36, 23, 18, 12, 25, 11, 4, 3,
+ 3, 68, 52, 30, 11, 3, 20, 4, 70, 64, 17, 41, 36, 21, 10, 32,
+ 14, 12, 4, 3, 62, 69, 2, 9, 7, 64, 7, 11, 15, 13, 19, 25,
+ 37, 67, 1, 72, 71, 62, 78, 101, 72, 4, 4, 71, 71, 70, 74, 1,
+ 77, 96, 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, 90, 83, 73,
+ 75, 70, 25, 101, 77, 25, 83, 69, 69, 70, 5, 67, 72, 3, 10, 71,
+ 71, 107, 32, 30, 31, 14, 67, 67, 69, 79, 70, 80, 85, 79, 97, 93,
+ 95, 105, 101, 112, 126, 98, 89, 88, 90, 103, 95, 90, 92, 93, 79, 78,
+ 83, 80, 85, 104, 91, 88, 111, 97, 109, 109, 126, 122, 117, 117, 78, 75,
+ 118, 86, 86, 93, 110, 98, 99, 102, 91, 96, 85, 81, 108, 113, 126, 88,
+ 99, 105, 70, 10, 15, 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35,
+ 24, 42, 68, 77, 85, 93, 93, 120, 119, 116, 16, 45, 40, 43, 34, 36,
+ 21, 20, 11, 11, 70, 10, 15, 18, 36, 24, 29, 7, 33, 28, 38, 31,
+ 41, 35, 24, 42, 68, 77, 85, 93, 93, 120, 119, 116, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 93, 67, 26, 39, 10,
+ 37, 85, 74, 26, 70, 73, 36, 94, 93, 0, 77, 126, 126, 126, 22, 6,
+ 68, 74, 26, 70, 76, 13, 36, 65, 4, 1, 4, 108, 111, 94, 112, 65,
+ 71, 71, 76, 91, 81, 98, 0, 68, 69, 64, 32, 1, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 11, 0, 73, 33, 18, 6, 47, 45, 7, 18,
+ 20, 25, 9, 8, 36, 109, 89, 89, 91, 25, 71, 18, 36, 65, 74, 2,
+ 17, 65, 73, 72, 81, 24, 76, 14, 0, 75, 8, 68, 0, 7, 13, 17,
+ 19, 7, 79, 67, 3, 65, 0, 71, 30, 66, 1, 31, 27, 38, 31, 27,
+ 97, 10, 10, 76, 67, 76, 69, 32, 2, 5, 37, 56, 62, 62, 47, 99,
+ 108, 11, 42, 42, 125, 73, 13, 98, 24, 70, 4, 36, 33, 54, 49, 46,
+ 109, 1, 82, 100, 100, 67, 14, 21, 11, 5, 11, 10, 3, 15, 9, 77,
+ 70, 6, 0, 0, 76, 65, 73, 79, 66, 66, 1, 71, 73, 109, 74, 77,
+ 69, 86, 84, 76, 0, 72, 74, 72, 77, 95, 80, 68, 108, 125, 97, 106,
+ 100, 126, 87, 82, 116, 67, 76, 76, 84, 88, 100, 95, 88, 106, 93, 93,
+ 97, 107, 1, 13, 41, 26, 10, 4, 16, 9, 4, 1, 14, 20, 44, 29,
+ 22, 13, 35, 18, 21, 6, 36, 8, 37, 24, 19, 12, 26, 11, 5, 4,
+ 4, 68, 54, 31, 11, 3, 20, 5, 70, 64, 17, 42, 36, 22, 10, 33,
+ 14, 12, 5, 3, 62, 67, 4, 11, 9, 1, 8, 13, 16, 15, 21, 27,
+ 39, 67, 2, 72, 71, 62, 78, 102, 72, 4, 5, 71, 71, 70, 74, 1,
+ 77, 97, 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, 91, 84, 73,
+ 75, 70, 26, 102, 77, 26, 84, 69, 69, 70, 6, 67, 72, 4, 11, 71,
+ 71, 109, 31, 29, 30, 12, 69, 70, 71, 82, 72, 83, 88, 82, 100, 96,
+ 97, 108, 104, 116, 126, 100, 92, 90, 92, 105, 97, 91, 93, 94, 79, 80,
+ 85, 82, 87, 106, 92, 89, 113, 99, 112, 111, 126, 124, 119, 118, 79, 77,
+ 120, 87, 88, 94, 112, 100, 101, 103, 92, 97, 86, 80, 109, 115, 126, 89,
+ 101, 106, 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, 42, 36,
+ 25, 41, 70, 79, 87, 95, 95, 122, 121, 117, 17, 45, 41, 44, 34, 37,
+ 22, 21, 12, 11, 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32,
+ 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, 117, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 95, 68, 25, 40, 10,
+ 39, 87, 74, 27, 70, 73, 37, 95, 95, 65, 79, 126, 126, 126, 24, 7,
+ 68, 74, 27, 70, 76, 14, 36, 66, 5, 2, 5, 109, 113, 95, 112, 65,
+ 71, 70, 76, 91, 81, 98, 0, 68, 69, 64, 33, 1, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 10, 0, 72, 35, 19, 7, 48, 46, 7, 19,
+ 22, 26, 10, 9, 38, 110, 89, 89, 91, 25, 72, 19, 38, 65, 73, 3,
+ 19, 65, 73, 72, 81, 24, 76, 14, 1, 75, 8, 68, 0, 7, 13, 18,
+ 19, 7, 79, 68, 3, 65, 0, 71, 30, 66, 1, 32, 27, 38, 31, 27,
+ 98, 10, 11, 76, 67, 76, 69, 33, 2, 5, 38, 57, 62, 62, 49, 99,
+ 109, 11, 42, 42, 126, 73, 14, 99, 25, 70, 4, 37, 33, 54, 49, 47,
+ 110, 3, 83, 103, 103, 66, 13, 21, 10, 4, 10, 10, 2, 15, 8, 78,
+ 71, 5, 0, 0, 76, 66, 74, 80, 67, 67, 0, 72, 73, 110, 75, 78,
+ 69, 88, 85, 78, 65, 74, 76, 74, 79, 99, 83, 69, 110, 126, 99, 108,
+ 102, 126, 89, 83, 118, 68, 77, 77, 85, 89, 102, 97, 90, 108, 93, 94,
+ 98, 109, 2, 14, 42, 26, 10, 4, 17, 10, 5, 2, 16, 21, 45, 29,
+ 23, 14, 36, 19, 23, 7, 38, 9, 37, 24, 19, 13, 27, 12, 5, 4,
+ 5, 68, 55, 32, 11, 3, 21, 5, 70, 0, 18, 42, 37, 22, 10, 34,
+ 15, 13, 5, 4, 62, 66, 5, 12, 11, 2, 10, 14, 18, 16, 22, 29,
+ 41, 66, 3, 71, 70, 62, 78, 103, 72, 5, 5, 71, 71, 70, 75, 2,
+ 77, 98, 69, 68, 24, 70, 77, 69, 68, 64, 74, 72, 70, 92, 85, 73,
+ 75, 70, 27, 103, 77, 26, 85, 69, 69, 70, 6, 67, 73, 4, 12, 71,
+ 71, 110, 30, 28, 29, 10, 71, 72, 74, 85, 75, 86, 92, 85, 104, 99,
+ 99, 112, 108, 120, 126, 103, 94, 92, 94, 108, 99, 93, 94, 95, 79, 83,
+ 87, 84, 89, 108, 94, 91, 115, 101, 114, 113, 126, 126, 121, 119, 80, 78,
+ 123, 89, 90, 96, 114, 101, 102, 104, 93, 98, 86, 79, 110, 116, 126, 90,
+ 102, 107, 69, 11, 16, 19, 38, 25, 31, 7, 35, 30, 40, 32, 43, 36,
+ 26, 41, 72, 81, 89, 97, 97, 124, 123, 119, 17, 46, 41, 45, 35, 37,
+ 22, 21, 12, 12, 69, 11, 16, 19, 38, 25, 31, 7, 35, 30, 40, 32,
+ 43, 36, 26, 41, 72, 81, 89, 97, 97, 124, 123, 119, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 70, 24, 41, 10,
+ 40, 89, 73, 29, 71, 73, 38, 96, 96, 66, 81, 126, 126, 126, 26, 8,
+ 68, 73, 29, 71, 76, 15, 36, 66, 5, 3, 7, 110, 114, 95, 112, 65,
+ 70, 69, 77, 91, 81, 98, 0, 67, 69, 0, 33, 1, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 10, 1, 70, 38, 20, 8, 50, 48, 8, 20,
+ 24, 27, 11, 10, 41, 110, 90, 89, 92, 25, 72, 20, 41, 64, 73, 3,
+ 21, 65, 73, 72, 80, 24, 76, 15, 2, 74, 9, 67, 0, 8, 14, 19,
+ 20, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 32, 28, 38, 31, 27,
+ 98, 11, 11, 77, 67, 75, 69, 34, 3, 6, 40, 59, 62, 62, 51, 100,
+ 110, 12, 43, 42, 126, 73, 14, 99, 26, 70, 4, 39, 33, 54, 49, 49,
+ 111, 4, 84, 105, 106, 65, 13, 21, 10, 4, 10, 10, 2, 15, 8, 79,
+ 72, 5, 0, 0, 76, 66, 74, 81, 67, 67, 0, 73, 74, 111, 76, 78,
+ 69, 89, 85, 80, 67, 75, 77, 75, 81, 102, 85, 70, 112, 126, 100, 110,
+ 104, 126, 90, 84, 119, 69, 78, 78, 87, 91, 104, 99, 91, 109, 93, 95,
+ 99, 111, 4, 16, 43, 27, 10, 4, 18, 11, 6, 2, 18, 23, 46, 30,
+ 23, 15, 38, 20, 24, 8, 41, 10, 38, 25, 20, 13, 28, 13, 6, 5,
+ 6, 67, 56, 33, 11, 3, 22, 6, 69, 1, 19, 42, 38, 22, 10, 35,
+ 16, 14, 6, 5, 62, 65, 7, 14, 12, 3, 11, 16, 20, 18, 24, 31,
+ 44, 65, 4, 70, 69, 62, 77, 104, 71, 6, 6, 71, 71, 70, 75, 2,
+ 78, 99, 69, 68, 25, 70, 77, 69, 68, 0, 74, 73, 70, 93, 86, 74,
+ 75, 70, 28, 103, 78, 27, 85, 70, 69, 70, 6, 68, 73, 4, 12, 71,
+ 71, 112, 29, 27, 28, 9, 74, 75, 77, 88, 77, 89, 95, 88, 107, 101,
+ 101, 116, 111, 124, 126, 106, 96, 93, 96, 110, 101, 94, 95, 96, 79, 85,
+ 90, 87, 91, 110, 96, 92, 117, 103, 116, 115, 126, 126, 122, 121, 81, 79,
+ 125, 90, 91, 97, 116, 102, 103, 105, 94, 99, 86, 78, 112, 117, 126, 92,
+ 103, 108, 69, 12, 17, 20, 39, 26, 31, 8, 36, 31, 41, 33, 44, 37,
+ 26, 40, 74, 83, 91, 99, 99, 126, 125, 120, 18, 46, 42, 45, 36, 38,
+ 23, 22, 12, 13, 69, 12, 17, 20, 39, 26, 31, 8, 36, 31, 41, 33,
+ 44, 37, 26, 40, 74, 83, 91, 99, 99, 126, 125, 120, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 71, 23, 41, 10,
+ 42, 90, 73, 30, 71, 74, 39, 97, 97, 67, 83, 126, 126, 126, 28, 10,
+ 68, 73, 30, 71, 75, 16, 37, 66, 6, 4, 8, 111, 115, 95, 113, 65,
+ 70, 68, 77, 92, 81, 98, 0, 67, 69, 1, 34, 1, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 9, 1, 69, 40, 21, 9, 51, 49, 9, 21,
+ 26, 28, 12, 11, 43, 111, 90, 89, 92, 26, 72, 21, 43, 64, 72, 4,
+ 23, 65, 73, 72, 80, 25, 76, 15, 3, 74, 10, 67, 0, 8, 14, 20,
+ 20, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 99, 11, 12, 77, 67, 75, 69, 35, 3, 6, 41, 60, 62, 62, 53, 100,
+ 111, 12, 43, 42, 126, 73, 15, 100, 26, 70, 4, 40, 33, 54, 49, 50,
+ 112, 6, 85, 108, 109, 0, 13, 21, 9, 3, 9, 9, 1, 15, 7, 80,
+ 73, 5, 0, 0, 77, 67, 75, 82, 68, 67, 0, 74, 74, 112, 76, 79,
+ 69, 90, 86, 82, 69, 77, 79, 77, 83, 105, 88, 71, 114, 126, 102, 112,
+ 106, 126, 91, 85, 121, 70, 79, 79, 88, 92, 106, 101, 93, 111, 93, 96,
+ 100, 112, 5, 17, 45, 27, 10, 4, 19, 12, 7, 3, 20, 24, 47, 31,
+ 24, 15, 39, 21, 26, 9, 43, 10, 38, 25, 20, 14, 29, 13, 6, 6,
+ 7, 67, 58, 34, 11, 3, 23, 6, 69, 2, 20, 43, 39, 23, 10, 36,
+ 16, 15, 6, 5, 62, 0, 8, 15, 14, 4, 13, 17, 21, 19, 26, 33,
+ 46, 65, 5, 70, 68, 62, 77, 105, 71, 7, 7, 71, 71, 70, 75, 3,
+ 78, 100, 69, 68, 25, 70, 77, 69, 68, 0, 75, 73, 70, 94, 87, 74,
+ 75, 70, 29, 104, 78, 28, 86, 70, 69, 70, 7, 68, 74, 5, 13, 71,
+ 71, 113, 28, 26, 27, 7, 76, 77, 79, 91, 80, 92, 98, 91, 110, 104,
+ 103, 120, 115, 126, 126, 109, 98, 95, 98, 113, 103, 95, 96, 97, 79, 87,
+ 92, 89, 93, 112, 98, 94, 119, 105, 118, 117, 126, 126, 124, 122, 82, 80,
+ 126, 92, 93, 99, 118, 104, 105, 106, 95, 100, 86, 77, 113, 119, 126, 93,
+ 104, 109, 69, 12, 17, 20, 40, 27, 32, 8, 37, 32, 42, 33, 45, 37,
+ 27, 40, 76, 85, 93, 101, 101, 126, 126, 121, 18, 47, 42, 46, 36, 39,
+ 23, 22, 13, 13, 69, 12, 17, 20, 40, 27, 32, 8, 37, 32, 42, 33,
+ 45, 37, 27, 40, 76, 85, 93, 101, 101, 126, 126, 121, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 101, 73, 22, 42, 10,
+ 44, 92, 73, 32, 71, 74, 40, 98, 98, 68, 85, 126, 126, 126, 30, 11,
+ 68, 73, 32, 71, 75, 17, 37, 66, 7, 5, 9, 112, 116, 95, 113, 65,
+ 70, 67, 77, 92, 81, 98, 0, 67, 69, 2, 34, 1, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 9, 2, 68, 42, 22, 10, 53, 51, 10, 22,
+ 28, 29, 13, 12, 45, 112, 90, 89, 92, 26, 72, 22, 45, 64, 71, 5,
+ 25, 65, 73, 72, 80, 25, 76, 16, 4, 74, 11, 67, 0, 8, 15, 21,
+ 21, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 99, 12, 13, 78, 67, 75, 69, 36, 3, 7, 42, 61, 62, 62, 55, 101,
+ 112, 13, 43, 42, 126, 73, 15, 100, 27, 70, 4, 41, 33, 54, 49, 51,
+ 113, 7, 86, 111, 112, 1, 13, 21, 9, 2, 9, 9, 1, 15, 7, 81,
+ 74, 5, 0, 0, 77, 67, 76, 83, 68, 67, 0, 75, 75, 113, 77, 80,
+ 69, 91, 86, 84, 71, 79, 80, 79, 85, 108, 90, 72, 116, 126, 103, 114,
+ 108, 126, 92, 86, 123, 71, 80, 80, 89, 94, 108, 103, 95, 112, 93, 97,
+ 101, 114, 7, 19, 46, 28, 10, 4, 20, 13, 8, 4, 22, 25, 48, 32,
+ 25, 16, 40, 22, 27, 10, 45, 11, 39, 26, 21, 14, 30, 14, 7, 7,
+ 8, 67, 59, 35, 11, 3, 24, 7, 69, 3, 21, 43, 40, 23, 10, 37,
+ 17, 16, 7, 6, 62, 1, 10, 17, 16, 5, 14, 19, 23, 21, 28, 35,
+ 48, 64, 6, 69, 67, 62, 77, 106, 71, 8, 8, 71, 71, 70, 75, 3,
+ 78, 101, 69, 68, 26, 70, 77, 69, 68, 0, 75, 73, 70, 95, 88, 74,
+ 75, 70, 30, 105, 78, 29, 87, 70, 69, 70, 7, 68, 74, 5, 14, 71,
+ 71, 115, 27, 25, 26, 5, 78, 80, 82, 94, 82, 95, 101, 94, 113, 107,
+ 105, 124, 118, 126, 126, 112, 100, 97, 100, 115, 105, 96, 97, 98, 79, 89,
+ 94, 91, 95, 114, 100, 95, 121, 107, 120, 119, 126, 126, 126, 123, 83, 81,
+ 126, 93, 95, 100, 120, 105, 106, 107, 96, 101, 86, 76, 114, 120, 126, 94,
+ 105, 110, 69, 13, 18, 21, 41, 28, 33, 8, 38, 33, 43, 34, 46, 38,
+ 28, 39, 78, 87, 95, 103, 103, 126, 126, 122, 19, 47, 43, 47, 37, 40,
+ 24, 23, 13, 14, 69, 13, 18, 21, 41, 28, 33, 8, 38, 33, 43, 34,
+ 46, 38, 28, 39, 78, 87, 95, 103, 103, 126, 126, 122, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 103, 75, 21, 42, 10,
+ 45, 94, 73, 33, 72, 75, 41, 99, 100, 70, 87, 126, 126, 126, 32, 12,
+ 68, 73, 33, 72, 75, 17, 37, 67, 7, 5, 10, 114, 118, 96, 114, 66,
+ 70, 67, 78, 93, 81, 98, 64, 67, 69, 2, 34, 0, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 8, 2, 67, 44, 23, 10, 54, 52, 10, 23,
+ 29, 29, 14, 12, 47, 113, 91, 90, 93, 26, 73, 22, 47, 64, 71, 5,
+ 26, 65, 73, 72, 80, 25, 77, 16, 4, 74, 11, 67, 0, 8, 15, 22,
+ 21, 7, 81, 69, 4, 65, 64, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 100, 12, 13, 79, 67, 75, 70, 36, 3, 7, 43, 62, 62, 62, 56, 102,
+ 114, 13, 43, 42, 126, 74, 15, 101, 27, 71, 4, 42, 33, 53, 49, 52,
+ 114, 8, 88, 114, 116, 2, 12, 21, 8, 1, 8, 8, 0, 14, 6, 82,
+ 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, 76, 76, 115, 78, 81,
+ 69, 93, 87, 87, 74, 81, 82, 81, 88, 112, 93, 74, 118, 126, 105, 117,
+ 110, 126, 94, 88, 125, 73, 81, 81, 91, 96, 110, 105, 97, 114, 93, 98,
+ 102, 116, 8, 20, 47, 28, 10, 4, 20, 13, 8, 4, 23, 26, 48, 32,
+ 25, 16, 41, 23, 28, 10, 47, 11, 39, 26, 21, 14, 30, 14, 7, 7,
+ 9, 67, 60, 36, 11, 2, 24, 7, 69, 3, 21, 43, 40, 23, 10, 38,
+ 17, 16, 7, 6, 62, 2, 11, 18, 17, 6, 15, 20, 24, 22, 29, 36,
+ 50, 64, 6, 69, 67, 62, 77, 108, 71, 8, 8, 71, 71, 70, 76, 3,
+ 79, 102, 70, 68, 26, 71, 77, 70, 68, 0, 76, 74, 71, 96, 89, 75,
+ 76, 70, 31, 106, 79, 29, 88, 71, 69, 71, 7, 69, 75, 5, 14, 71,
+ 71, 117, 25, 24, 24, 3, 81, 83, 85, 97, 85, 98, 105, 97, 117, 110,
+ 107, 126, 122, 126, 126, 115, 103, 99, 103, 118, 107, 98, 99, 99, 79, 92,
+ 97, 94, 97, 117, 102, 97, 124, 109, 123, 121, 126, 126, 126, 125, 85, 83,
+ 126, 95, 97, 102, 122, 107, 108, 108, 97, 102, 87, 75, 116, 122, 126, 96,
+ 107, 112, 69, 13, 18, 21, 42, 28, 33, 8, 39, 33, 44, 34, 46, 38,
+ 28, 38, 80, 89, 98, 106, 105, 126, 126, 124, 19, 47, 43, 47, 37, 40,
+ 24, 23, 13, 14, 69, 13, 18, 21, 42, 28, 33, 8, 39, 33, 44, 34,
+ 46, 38, 28, 38, 80, 89, 98, 106, 105, 126, 126, 124, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 104, 76, 21, 43, 11,
+ 47, 95, 72, 35, 72, 75, 43, 99, 101, 71, 88, 126, 126, 126, 34, 14,
+ 67, 72, 35, 72, 74, 18, 38, 67, 8, 6, 12, 115, 119, 96, 114, 66,
+ 69, 66, 78, 93, 80, 97, 64, 66, 68, 3, 35, 0, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 8, 3, 65, 47, 25, 11, 56, 54, 11, 25,
+ 31, 30, 16, 13, 50, 113, 91, 90, 93, 27, 73, 23, 50, 0, 70, 6,
+ 28, 65, 72, 72, 79, 26, 77, 17, 5, 73, 12, 66, 1, 9, 16, 23,
+ 22, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29,
+ 100, 13, 14, 79, 67, 74, 70, 37, 4, 8, 45, 62, 62, 62, 58, 102,
+ 115, 14, 44, 43, 126, 74, 16, 101, 28, 71, 5, 44, 33, 53, 50, 54,
+ 115, 10, 89, 116, 119, 4, 12, 21, 8, 1, 8, 8, 0, 14, 6, 82,
+ 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, 76, 76, 116, 78, 81,
+ 69, 94, 87, 89, 76, 82, 83, 82, 90, 115, 95, 75, 119, 126, 106, 119,
+ 111, 126, 95, 89, 126, 74, 81, 81, 92, 97, 111, 106, 98, 115, 93, 98,
+ 102, 117, 10, 22, 49, 29, 10, 4, 21, 14, 9, 5, 25, 28, 49, 33,
+ 26, 17, 43, 24, 30, 11, 50, 12, 40, 27, 22, 15, 31, 15, 8, 8,
+ 11, 66, 62, 37, 12, 2, 25, 8, 68, 4, 22, 44, 41, 24, 11, 39,
+ 18, 17, 8, 7, 62, 4, 13, 20, 19, 8, 17, 22, 26, 24, 31, 38,
+ 53, 0, 7, 68, 66, 62, 76, 109, 70, 9, 9, 70, 71, 69, 76, 4,
+ 79, 102, 70, 68, 27, 71, 77, 70, 68, 1, 76, 74, 71, 96, 89, 75,
+ 76, 69, 33, 106, 79, 30, 88, 71, 69, 71, 8, 69, 75, 6, 15, 70,
+ 70, 118, 24, 23, 23, 2, 83, 85, 87, 100, 87, 100, 108, 99, 120, 112,
+ 109, 126, 125, 126, 126, 117, 105, 100, 105, 120, 108, 99, 100, 99, 79, 94,
+ 99, 96, 99, 119, 103, 98, 126, 110, 125, 122, 126, 126, 126, 126, 86, 84,
+ 126, 96, 98, 103, 123, 108, 109, 109, 97, 102, 87, 74, 117, 123, 126, 97,
+ 108, 113, 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, 47, 39,
+ 29, 38, 81, 90, 100, 108, 106, 126, 126, 125, 20, 48, 44, 48, 38, 41,
+ 25, 24, 14, 15, 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35,
+ 47, 39, 29, 38, 81, 90, 100, 108, 106, 126, 126, 125, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 106, 78, 20, 44, 11,
+ 49, 97, 72, 36, 72, 75, 44, 100, 102, 72, 90, 126, 126, 126, 36, 15,
+ 67, 72, 36, 72, 74, 19, 38, 67, 9, 7, 13, 116, 120, 96, 114, 66,
+ 69, 65, 78, 93, 80, 97, 64, 66, 68, 4, 35, 0, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 8, 4, 64, 49, 26, 12, 58, 56, 12, 26,
+ 33, 31, 17, 14, 52, 114, 91, 90, 93, 27, 73, 24, 52, 0, 69, 7,
+ 30, 65, 72, 72, 79, 26, 77, 17, 6, 73, 13, 66, 1, 9, 16, 24,
+ 23, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29,
+ 101, 14, 15, 80, 67, 74, 70, 38, 4, 8, 46, 62, 62, 62, 60, 103,
+ 116, 14, 44, 43, 126, 74, 16, 102, 29, 71, 5, 45, 33, 53, 50, 55,
+ 116, 11, 90, 119, 122, 5, 12, 21, 8, 0, 7, 8, 0, 14, 5, 83,
+ 76, 4, 64, 64, 78, 69, 78, 85, 69, 68, 64, 77, 77, 117, 79, 82,
+ 69, 95, 88, 91, 78, 84, 85, 84, 92, 118, 97, 76, 121, 126, 108, 121,
+ 113, 126, 96, 90, 126, 75, 82, 82, 93, 99, 113, 108, 100, 117, 93, 99,
+ 103, 119, 11, 23, 50, 30, 10, 4, 22, 15, 10, 6, 27, 29, 50, 34,
+ 27, 18, 44, 25, 31, 12, 52, 13, 40, 27, 22, 15, 32, 16, 9, 9,
+ 12, 66, 62, 38, 12, 2, 26, 9, 68, 5, 23, 44, 42, 24, 11, 40,
+ 19, 18, 9, 8, 62, 5, 15, 22, 21, 9, 18, 24, 28, 25, 33, 40,
+ 55, 1, 8, 67, 65, 62, 76, 110, 70, 10, 10, 70, 71, 69, 76, 4,
+ 79, 103, 70, 68, 28, 71, 77, 70, 68, 1, 76, 74, 71, 97, 90, 75,
+ 76, 69, 34, 107, 79, 31, 89, 71, 69, 71, 8, 69, 75, 6, 16, 70,
+ 70, 120, 23, 22, 22, 0, 85, 88, 90, 103, 89, 103, 111, 102, 123, 115,
+ 111, 126, 126, 126, 126, 120, 107, 102, 107, 122, 110, 100, 101, 100, 79, 96,
+ 101, 98, 101, 121, 105, 100, 126, 112, 126, 124, 126, 126, 126, 126, 87, 85,
+ 126, 98, 100, 105, 125, 109, 110, 110, 98, 103, 87, 73, 118, 124, 126, 98,
+ 109, 114, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35, 48, 40,
+ 30, 37, 83, 92, 102, 110, 108, 126, 126, 126, 21, 48, 44, 49, 39, 42,
+ 25, 25, 14, 16, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35,
+ 48, 40, 30, 37, 83, 92, 102, 110, 108, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 108, 79, 19, 44, 11,
+ 51, 98, 72, 38, 72, 76, 45, 101, 103, 73, 92, 126, 126, 126, 38, 17,
+ 67, 72, 38, 72, 73, 20, 39, 67, 10, 8, 14, 117, 121, 96, 115, 66,
+ 69, 64, 78, 94, 80, 97, 64, 66, 68, 5, 36, 0, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 7, 4, 0, 51, 27, 13, 59, 57, 13, 27,
+ 35, 32, 18, 15, 54, 115, 91, 90, 93, 28, 73, 25, 54, 0, 68, 8,
+ 32, 65, 72, 72, 79, 27, 77, 18, 7, 73, 14, 66, 1, 9, 17, 25,
+ 23, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 35, 29, 41, 32, 30,
+ 101, 14, 16, 80, 67, 74, 70, 39, 4, 9, 47, 62, 62, 62, 62, 103,
+ 117, 15, 44, 43, 126, 74, 17, 102, 29, 71, 5, 46, 33, 53, 50, 56,
+ 117, 13, 91, 122, 125, 7, 12, 21, 7, 64, 7, 7, 64, 14, 5, 84,
+ 77, 4, 64, 64, 79, 69, 79, 86, 70, 68, 64, 78, 77, 118, 79, 83,
+ 69, 96, 88, 93, 80, 86, 86, 86, 94, 121, 100, 77, 123, 126, 109, 123,
+ 115, 126, 97, 91, 126, 76, 83, 83, 94, 100, 115, 110, 102, 118, 93, 100,
+ 104, 120, 13, 25, 52, 30, 10, 4, 23, 16, 11, 7, 29, 30, 51, 35,
+ 28, 18, 45, 26, 33, 13, 54, 13, 41, 28, 23, 16, 33, 16, 9, 10,
+ 13, 66, 62, 39, 12, 2, 27, 9, 68, 6, 24, 45, 43, 25, 11, 41,
+ 19, 19, 9, 8, 62, 7, 16, 23, 23, 10, 20, 25, 29, 27, 35, 42,
+ 57, 1, 9, 67, 64, 62, 76, 111, 70, 11, 11, 70, 71, 69, 76, 5,
+ 79, 104, 70, 68, 28, 71, 77, 70, 68, 1, 77, 74, 71, 98, 91, 75,
+ 76, 69, 35, 108, 79, 32, 90, 71, 69, 71, 9, 69, 76, 7, 17, 70,
+ 70, 121, 22, 21, 21, 65, 87, 90, 92, 106, 92, 106, 114, 105, 126, 118,
+ 113, 126, 126, 126, 126, 123, 109, 104, 109, 125, 112, 101, 102, 101, 79, 98,
+ 103, 100, 103, 123, 107, 101, 126, 114, 126, 126, 126, 126, 126, 126, 88, 86,
+ 126, 99, 102, 106, 126, 111, 112, 111, 99, 104, 87, 72, 119, 126, 126, 99,
+ 110, 115, 68, 15, 20, 23, 46, 31, 36, 9, 43, 36, 47, 36, 49, 40,
+ 31, 37, 85, 94, 104, 112, 110, 126, 126, 126, 21, 49, 45, 50, 39, 43,
+ 26, 25, 15, 16, 68, 15, 20, 23, 46, 31, 36, 9, 43, 36, 47, 36,
+ 49, 40, 31, 37, 85, 94, 104, 112, 110, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, 54, 14,
+ 118, 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, 67, 90, 104, 126, 104,
+ 67, 78, 65, 1, 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5,
+ 76, 94, 9, 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 52, 8, 69, 126, 102, 82, 74, 107, 126, 126,
+ 126, 95, 126, 114, 126, 123, 115, 122, 115, 0, 68, 84, 104, 70, 93, 90,
+ 126, 74, 97, 91, 126, 7, 82, 76, 125, 93, 87, 77, 71, 0, 68, 84,
+ 1, 65, 2, 7, 66, 64, 2, 78, 13, 11, 28, 19, 25, 18, 17, 19,
+ 46, 12, 13, 44, 30, 1, 108, 100, 101, 91, 94, 88, 84, 86, 83, 87,
+ 94, 70, 72, 74, 4, 102, 100, 95, 75, 72, 75, 71, 17, 69, 1, 65,
+ 26, 72, 6, 9, 1, 72, 62, 54, 38, 45, 54, 44, 26, 45, 34, 30,
+ 33, 18, 5, 1, 2, 25, 18, 24, 21, 19, 18, 22, 14, 29, 21, 8,
+ 12, 17, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 46, 62, 60, 41, 62, 62, 62, 62, 60, 58, 62, 47, 41, 15, 26,
+ 3, 68, 97, 71, 21, 13, 9, 1, 5, 0, 72, 74, 91, 67, 36, 24,
+ 19, 17, 64, 68, 78, 77, 86, 92, 8, 3, 1, 65, 73, 76, 80, 88,
+ 110, 97, 84, 79, 73, 74, 86, 96, 97, 117, 78, 30, 15, 10, 1, 71,
+ 79, 86, 90, 97, 62, 93, 84, 79, 66, 71, 1, 3, 4, 75, 1, 5,
+ 66, 79, 71, 68, 19, 1, 27, 23, 36, 34, 19, 27, 31, 21, 15, 1,
+ 17, 64, 104, 97, 96, 88, 85, 85, 85, 88, 66, 77, 76, 76, 5, 76,
+ 83, 99, 95, 95, 76, 74, 70, 75, 68, 65, 73, 1, 1, 68, 75, 8,
+ 64, 70, 57, 44, 47, 49, 50, 52, 48, 47, 40, 40, 43, 37, 19, 23,
+ 16, 46, 42, 41, 36, 34, 28, 13, 6, 0, 77, 82, 94, 69, 109, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 50, 28, 5, 62, 62,
+ 33, 62, 62, 62, 60, 62, 58, 52, 58, 51, 52, 34, 37, 24, 66, 42,
+ 32, 13, 120, 112, 114, 85, 92, 89, 71, 81, 80, 68, 70, 7, 68, 13,
+ 74, 62, 62, 62, 62, 60, 57, 29, 9, 82, 75, 40, 29, 20, 9, 8,
+ 2, 64, 68, 92, 106, 97, 90, 90, 88, 73, 79, 86, 73, 70, 69, 66,
+ 64, 5, 4, 62, 62, 62, 62, 60, 54, 43, 27, 67, 126, 126, 99, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, 62, 54, 14,
+ 115, 6, 77, 64, 1, 14, 72, 12, 65, 20, 62, 68, 91, 104, 124, 102,
+ 67, 77, 64, 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5,
+ 75, 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 52, 8, 69, 125, 101, 82, 73, 105, 125, 125,
+ 125, 93, 125, 112, 125, 121, 114, 121, 114, 1, 67, 83, 103, 69, 92, 89,
+ 125, 73, 96, 90, 125, 8, 81, 75, 123, 92, 86, 76, 70, 1, 67, 83,
+ 2, 64, 2, 7, 65, 64, 2, 77, 13, 11, 28, 19, 25, 18, 17, 19,
+ 45, 12, 13, 43, 29, 1, 107, 99, 100, 90, 93, 87, 83, 85, 82, 86,
+ 92, 70, 72, 73, 3, 101, 99, 95, 74, 72, 74, 70, 17, 68, 1, 65,
+ 25, 71, 6, 8, 1, 72, 62, 54, 38, 45, 54, 44, 26, 45, 34, 29,
+ 33, 18, 5, 1, 2, 25, 18, 24, 21, 19, 17, 22, 14, 28, 20, 8,
+ 11, 16, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 60, 44, 62, 59, 40, 62, 62, 62, 62, 58, 56, 61, 45, 39, 15, 25,
+ 2, 68, 97, 70, 22, 14, 10, 2, 5, 0, 71, 73, 90, 66, 37, 25,
+ 20, 17, 0, 67, 77, 76, 85, 91, 9, 4, 2, 64, 72, 75, 79, 87,
+ 108, 96, 82, 78, 72, 73, 85, 95, 96, 115, 77, 31, 16, 11, 2, 70,
+ 78, 85, 89, 96, 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6,
+ 65, 78, 71, 68, 19, 2, 27, 23, 35, 34, 19, 26, 30, 21, 15, 1,
+ 16, 64, 103, 96, 95, 87, 84, 84, 84, 87, 66, 76, 75, 75, 5, 75,
+ 82, 98, 94, 95, 76, 73, 70, 74, 68, 65, 72, 1, 1, 67, 74, 8,
+ 64, 70, 57, 44, 47, 49, 49, 52, 48, 47, 40, 40, 43, 37, 19, 22,
+ 15, 45, 41, 40, 35, 33, 27, 13, 6, 0, 76, 81, 93, 69, 108, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 59, 48, 27, 5, 62, 62,
+ 32, 62, 62, 62, 58, 62, 56, 50, 56, 49, 50, 33, 35, 23, 67, 41,
+ 31, 12, 118, 110, 112, 84, 91, 88, 69, 80, 79, 68, 69, 9, 66, 15,
+ 73, 62, 62, 62, 62, 58, 55, 27, 7, 83, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 91, 105, 96, 89, 89, 86, 72, 78, 85, 72, 69, 68, 65,
+ 0, 6, 4, 62, 62, 62, 62, 59, 53, 41, 26, 67, 126, 126, 98, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, 61, 54, 14,
+ 113, 6, 76, 0, 1, 13, 72, 11, 66, 19, 60, 70, 92, 105, 121, 101,
+ 67, 76, 0, 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5,
+ 75, 92, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 52, 8, 69, 124, 100, 82, 73, 104, 123, 123,
+ 124, 92, 123, 111, 123, 120, 113, 120, 113, 2, 67, 82, 102, 69, 92, 88,
+ 123, 73, 96, 90, 124, 8, 81, 75, 122, 92, 85, 76, 70, 1, 67, 82,
+ 2, 64, 1, 7, 65, 64, 2, 77, 13, 11, 27, 19, 24, 18, 17, 19,
+ 43, 12, 13, 41, 28, 0, 106, 98, 99, 89, 92, 86, 82, 84, 82, 85,
+ 91, 70, 72, 73, 2, 101, 98, 95, 74, 72, 73, 70, 16, 67, 1, 65,
+ 24, 70, 5, 7, 1, 73, 60, 53, 37, 44, 53, 43, 25, 44, 34, 28,
+ 32, 18, 5, 1, 2, 24, 17, 23, 20, 18, 16, 21, 13, 26, 19, 7,
+ 10, 15, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 58, 41, 62, 57, 38, 62, 62, 62, 62, 56, 54, 58, 43, 37, 14, 23,
+ 1, 69, 97, 70, 22, 14, 10, 2, 5, 0, 71, 73, 89, 66, 37, 25,
+ 20, 17, 1, 67, 76, 76, 84, 90, 10, 5, 2, 64, 71, 75, 79, 86,
+ 107, 95, 81, 77, 72, 73, 84, 94, 95, 114, 77, 31, 16, 11, 2, 69,
+ 77, 84, 88, 95, 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6,
+ 64, 78, 71, 68, 18, 2, 26, 22, 34, 33, 19, 25, 29, 21, 15, 0,
+ 15, 65, 102, 95, 94, 87, 84, 84, 83, 86, 66, 76, 75, 75, 4, 75,
+ 82, 98, 93, 95, 76, 73, 70, 73, 68, 65, 71, 1, 1, 67, 73, 7,
+ 64, 71, 56, 44, 47, 48, 48, 51, 47, 46, 39, 39, 42, 36, 18, 21,
+ 14, 43, 40, 38, 33, 32, 26, 12, 5, 0, 76, 81, 93, 70, 107, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 57, 46, 26, 4, 62, 60,
+ 31, 62, 62, 62, 56, 60, 54, 48, 54, 47, 48, 31, 33, 21, 68, 39,
+ 29, 10, 117, 109, 111, 83, 90, 87, 67, 79, 78, 68, 68, 10, 65, 16,
+ 72, 62, 62, 62, 62, 55, 52, 24, 5, 84, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 90, 104, 95, 88, 88, 85, 71, 77, 84, 71, 68, 67, 65,
+ 1, 6, 4, 62, 62, 62, 61, 57, 51, 39, 24, 68, 126, 126, 97, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, 60, 54, 14,
+ 111, 6, 75, 1, 1, 12, 72, 10, 67, 19, 58, 71, 93, 105, 118, 100,
+ 67, 75, 1, 1, 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5,
+ 75, 92, 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 52, 8, 69, 123, 99, 82, 72, 103, 121, 121,
+ 122, 91, 121, 110, 121, 119, 112, 119, 112, 3, 67, 81, 101, 69, 91, 88,
+ 121, 73, 95, 89, 123, 8, 81, 74, 120, 91, 84, 76, 70, 1, 67, 81,
+ 3, 0, 1, 7, 65, 64, 2, 77, 13, 10, 27, 19, 23, 18, 17, 19,
+ 41, 12, 12, 39, 27, 64, 105, 97, 98, 88, 91, 86, 81, 84, 81, 84,
+ 90, 70, 72, 73, 1, 100, 97, 95, 74, 72, 72, 70, 15, 66, 1, 65,
+ 23, 69, 5, 6, 1, 74, 59, 52, 37, 43, 52, 42, 25, 43, 33, 27,
+ 31, 18, 5, 1, 1, 23, 16, 22, 19, 17, 15, 20, 13, 24, 18, 7,
+ 9, 14, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 55, 39, 62, 55, 37, 62, 61, 62, 59, 54, 51, 56, 41, 34, 13, 21,
+ 0, 70, 97, 70, 23, 14, 10, 2, 5, 0, 71, 73, 89, 66, 37, 25,
+ 20, 17, 2, 66, 76, 75, 84, 89, 11, 5, 3, 64, 70, 74, 78, 86,
+ 106, 94, 80, 76, 71, 73, 83, 93, 94, 113, 76, 31, 16, 11, 2, 68,
+ 77, 83, 87, 94, 62, 91, 82, 77, 66, 70, 1, 4, 5, 74, 2, 6,
+ 64, 78, 71, 68, 18, 3, 25, 21, 33, 32, 19, 24, 28, 21, 15, 0,
+ 14, 65, 101, 94, 93, 86, 83, 83, 83, 85, 66, 76, 75, 74, 4, 75,
+ 82, 97, 92, 95, 76, 73, 70, 72, 68, 65, 70, 1, 1, 67, 72, 6,
+ 64, 72, 55, 43, 46, 47, 47, 50, 46, 45, 38, 38, 41, 35, 17, 20,
+ 13, 42, 39, 37, 31, 30, 25, 11, 5, 64, 76, 81, 93, 70, 106, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 54, 44, 24, 3, 61, 59,
+ 29, 62, 62, 60, 54, 58, 52, 46, 52, 45, 45, 29, 31, 19, 69, 37,
+ 27, 9, 116, 108, 110, 82, 89, 86, 66, 78, 77, 68, 67, 12, 0, 18,
+ 71, 62, 62, 62, 62, 52, 49, 21, 3, 85, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 90, 103, 94, 87, 87, 84, 71, 77, 83, 71, 68, 67, 65,
+ 1, 6, 4, 62, 62, 62, 59, 55, 49, 37, 22, 69, 126, 126, 96, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, 58, 54, 14,
+ 108, 5, 74, 1, 1, 11, 72, 9, 68, 18, 56, 73, 94, 106, 115, 99,
+ 67, 74, 1, 1, 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5,
+ 75, 91, 8, 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 52, 8, 69, 122, 98, 82, 72, 101, 120, 119,
+ 121, 90, 120, 108, 119, 118, 112, 118, 112, 3, 67, 80, 100, 69, 91, 87,
+ 119, 73, 95, 89, 122, 8, 80, 74, 119, 91, 84, 76, 69, 1, 67, 81,
+ 3, 0, 0, 6, 65, 64, 2, 77, 13, 10, 26, 19, 23, 18, 17, 18,
+ 39, 12, 12, 37, 26, 65, 104, 96, 97, 87, 91, 85, 80, 83, 81, 83,
+ 89, 70, 72, 72, 0, 100, 96, 95, 74, 72, 72, 70, 14, 65, 1, 65,
+ 21, 68, 4, 5, 1, 75, 57, 51, 36, 42, 51, 41, 24, 42, 33, 25,
+ 30, 17, 5, 1, 1, 22, 16, 21, 19, 16, 14, 19, 12, 22, 17, 6,
+ 8, 13, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59,
+ 53, 36, 62, 54, 35, 62, 59, 62, 57, 51, 49, 53, 39, 32, 12, 20,
+ 65, 71, 97, 70, 23, 15, 10, 2, 5, 0, 71, 73, 88, 65, 38, 25,
+ 20, 17, 3, 66, 75, 75, 83, 89, 12, 6, 3, 64, 70, 74, 78, 85,
+ 105, 94, 79, 76, 71, 73, 82, 92, 94, 112, 76, 32, 16, 11, 2, 67,
+ 76, 83, 86, 93, 62, 91, 82, 77, 66, 70, 1, 4, 5, 73, 2, 6,
+ 0, 78, 71, 68, 17, 3, 24, 20, 32, 31, 19, 22, 27, 20, 15, 64,
+ 13, 66, 101, 94, 92, 86, 83, 83, 82, 84, 67, 76, 75, 74, 3, 75,
+ 82, 97, 91, 95, 76, 72, 70, 72, 68, 65, 69, 1, 0, 67, 71, 6,
+ 65, 73, 54, 43, 46, 46, 46, 49, 45, 44, 37, 37, 40, 34, 16, 19,
+ 12, 40, 37, 35, 29, 29, 24, 10, 4, 64, 76, 81, 93, 71, 106, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 60, 55, 52, 42, 23, 2, 59, 57,
+ 28, 62, 62, 58, 52, 55, 50, 44, 50, 43, 43, 27, 29, 17, 70, 35,
+ 25, 7, 115, 107, 109, 82, 88, 85, 64, 77, 76, 68, 66, 13, 1, 19,
+ 71, 62, 62, 62, 62, 49, 46, 18, 1, 86, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 89, 102, 93, 86, 87, 83, 70, 76, 82, 70, 67, 66, 64,
+ 2, 7, 4, 62, 62, 62, 57, 53, 47, 35, 20, 70, 126, 126, 96, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, 57, 54, 14,
+ 106, 5, 73, 2, 1, 11, 71, 8, 69, 18, 54, 75, 95, 106, 112, 97,
+ 67, 73, 2, 1, 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5,
+ 75, 90, 8, 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 52, 8, 69, 121, 97, 82, 71, 100, 118, 117,
+ 119, 89, 118, 107, 117, 117, 111, 117, 111, 4, 67, 79, 99, 69, 90, 86,
+ 117, 73, 95, 88, 120, 9, 80, 73, 118, 90, 83, 76, 69, 2, 66, 80,
+ 4, 1, 0, 6, 65, 64, 2, 77, 13, 9, 25, 19, 22, 18, 17, 18,
+ 37, 12, 11, 36, 25, 66, 103, 95, 96, 86, 90, 84, 79, 82, 80, 82,
+ 88, 70, 72, 72, 64, 99, 95, 95, 73, 72, 71, 70, 13, 64, 1, 65,
+ 20, 67, 4, 4, 1, 75, 56, 50, 36, 41, 50, 40, 23, 42, 33, 24,
+ 29, 17, 5, 1, 0, 22, 15, 20, 18, 15, 13, 19, 11, 20, 16, 5,
+ 7, 12, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57,
+ 51, 34, 60, 52, 33, 62, 57, 60, 55, 49, 47, 50, 37, 29, 11, 18,
+ 66, 71, 97, 70, 23, 15, 10, 2, 5, 0, 71, 73, 88, 65, 38, 25,
+ 20, 17, 4, 65, 74, 75, 82, 88, 13, 7, 3, 0, 69, 73, 77, 85,
+ 104, 93, 77, 75, 71, 72, 81, 91, 93, 111, 75, 32, 17, 11, 2, 66,
+ 75, 82, 85, 92, 62, 91, 82, 76, 66, 70, 1, 4, 5, 73, 2, 7,
+ 0, 78, 71, 68, 16, 4, 23, 19, 31, 31, 19, 21, 26, 20, 15, 65,
+ 12, 66, 100, 93, 91, 85, 82, 82, 82, 83, 67, 76, 75, 74, 2, 75,
+ 82, 96, 90, 95, 76, 72, 70, 71, 68, 65, 68, 1, 0, 67, 70, 5,
+ 65, 73, 53, 43, 45, 46, 45, 48, 44, 43, 37, 36, 39, 33, 15, 18,
+ 11, 39, 36, 34, 27, 28, 23, 9, 3, 65, 76, 80, 93, 71, 105, 62,
+ 62, 62, 62, 62, 62, 62, 62, 60, 58, 53, 50, 40, 21, 1, 57, 55,
+ 27, 61, 62, 56, 50, 53, 48, 42, 48, 41, 40, 25, 27, 15, 71, 33,
+ 23, 6, 114, 105, 108, 81, 87, 84, 1, 76, 75, 68, 65, 15, 3, 21,
+ 70, 62, 62, 62, 62, 47, 43, 16, 64, 87, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 89, 101, 92, 85, 86, 82, 69, 76, 81, 69, 66, 65, 64,
+ 2, 7, 4, 62, 62, 62, 56, 51, 45, 33, 18, 71, 126, 126, 95, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, 56, 54, 14,
+ 104, 5, 73, 3, 1, 10, 71, 7, 70, 17, 53, 76, 96, 107, 109, 96,
+ 67, 73, 3, 1, 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5,
+ 74, 90, 8, 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 52, 8, 69, 120, 97, 82, 71, 99, 116, 115,
+ 118, 88, 116, 106, 115, 116, 110, 116, 110, 5, 67, 78, 99, 68, 90, 86,
+ 115, 73, 94, 88, 119, 9, 80, 73, 116, 90, 82, 75, 69, 2, 66, 79,
+ 4, 1, 64, 6, 65, 64, 2, 77, 13, 9, 25, 19, 21, 18, 17, 18,
+ 35, 12, 11, 34, 24, 67, 103, 94, 96, 86, 89, 84, 78, 82, 80, 82,
+ 86, 70, 72, 72, 65, 99, 94, 95, 73, 72, 70, 69, 12, 64, 1, 65,
+ 19, 66, 3, 3, 1, 76, 54, 49, 35, 41, 49, 40, 23, 41, 32, 23,
+ 28, 17, 5, 1, 0, 21, 14, 19, 17, 15, 12, 18, 11, 18, 15, 5,
+ 6, 11, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 54,
+ 48, 31, 58, 50, 32, 62, 54, 57, 52, 47, 44, 48, 34, 27, 10, 16,
+ 67, 72, 97, 69, 24, 15, 11, 2, 5, 0, 71, 73, 87, 65, 38, 26,
+ 20, 17, 5, 65, 74, 74, 82, 87, 14, 7, 4, 0, 68, 73, 77, 84,
+ 103, 92, 76, 74, 70, 72, 81, 91, 92, 109, 75, 32, 17, 11, 3, 66,
+ 75, 81, 85, 91, 62, 90, 81, 76, 66, 70, 1, 4, 5, 73, 3, 7,
+ 1, 78, 71, 69, 16, 4, 22, 18, 30, 30, 19, 20, 25, 20, 15, 65,
+ 11, 67, 99, 92, 90, 85, 82, 82, 81, 83, 67, 75, 74, 73, 2, 75,
+ 82, 96, 89, 95, 76, 72, 70, 70, 68, 65, 67, 0, 0, 67, 70, 4,
+ 65, 74, 52, 42, 45, 45, 44, 48, 44, 42, 36, 36, 38, 32, 14, 17,
+ 10, 37, 35, 32, 25, 26, 21, 8, 3, 65, 76, 80, 92, 72, 104, 62,
+ 62, 62, 62, 62, 62, 62, 62, 58, 55, 51, 47, 38, 20, 1, 56, 54,
+ 25, 59, 62, 54, 48, 51, 46, 40, 45, 39, 38, 23, 25, 14, 73, 31,
+ 21, 4, 113, 104, 107, 80, 86, 83, 2, 75, 74, 68, 64, 16, 4, 22,
+ 69, 62, 62, 62, 59, 44, 41, 13, 66, 89, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 88, 100, 92, 84, 85, 81, 69, 75, 80, 69, 66, 65, 64,
+ 3, 7, 4, 62, 62, 61, 54, 50, 44, 30, 17, 72, 126, 126, 94, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, 54, 54, 14,
+ 101, 4, 72, 3, 1, 9, 71, 6, 71, 17, 51, 78, 97, 107, 106, 95,
+ 67, 72, 3, 1, 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5,
+ 74, 89, 7, 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 52, 8, 69, 119, 96, 82, 70, 97, 115, 113,
+ 116, 87, 115, 104, 113, 115, 109, 115, 110, 6, 67, 77, 98, 68, 89, 85,
+ 113, 73, 94, 87, 118, 9, 79, 72, 115, 89, 82, 75, 68, 2, 66, 78,
+ 5, 2, 64, 5, 65, 64, 2, 77, 13, 8, 24, 19, 21, 18, 17, 17,
+ 33, 12, 10, 32, 23, 68, 102, 93, 95, 85, 88, 83, 77, 81, 79, 81,
+ 85, 70, 72, 71, 66, 98, 93, 95, 73, 72, 70, 69, 11, 0, 1, 65,
+ 17, 65, 3, 2, 1, 77, 53, 48, 35, 40, 48, 39, 22, 40, 32, 22,
+ 27, 17, 5, 1, 64, 20, 14, 18, 17, 14, 11, 17, 10, 16, 14, 4,
+ 5, 10, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 61, 52,
+ 46, 29, 56, 49, 30, 62, 52, 55, 50, 44, 42, 45, 32, 24, 9, 15,
+ 69, 73, 97, 69, 24, 16, 11, 2, 5, 0, 71, 73, 87, 64, 39, 26,
+ 20, 17, 6, 64, 73, 74, 81, 86, 15, 8, 4, 0, 67, 72, 76, 84,
+ 102, 92, 75, 74, 70, 72, 80, 90, 92, 108, 74, 33, 17, 11, 3, 65,
+ 74, 80, 84, 90, 62, 90, 81, 75, 66, 70, 1, 4, 5, 72, 3, 7,
+ 1, 78, 71, 69, 15, 5, 21, 17, 29, 29, 19, 19, 24, 19, 15, 66,
+ 10, 67, 98, 92, 89, 84, 81, 81, 81, 82, 67, 75, 74, 73, 1, 75,
+ 82, 95, 88, 95, 76, 71, 70, 70, 68, 65, 66, 0, 0, 67, 69, 4,
+ 66, 75, 51, 42, 44, 44, 43, 47, 43, 41, 35, 35, 37, 31, 13, 16,
+ 9, 36, 33, 31, 23, 25, 20, 7, 2, 66, 76, 80, 92, 72, 103, 62,
+ 62, 62, 62, 62, 62, 62, 61, 56, 53, 49, 45, 36, 18, 0, 54, 52,
+ 24, 57, 62, 52, 46, 49, 44, 38, 43, 37, 35, 21, 23, 12, 74, 29,
+ 19, 3, 112, 103, 106, 80, 85, 82, 4, 74, 73, 68, 0, 18, 6, 24,
+ 69, 62, 62, 61, 56, 41, 38, 10, 68, 90, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 88, 99, 91, 83, 84, 80, 68, 75, 79, 68, 65, 64, 0,
+ 3, 8, 4, 62, 62, 59, 52, 48, 42, 28, 15, 73, 126, 126, 94, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, 53, 54, 14,
+ 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, 49, 80, 98, 108, 104, 94,
+ 67, 71, 4, 1, 83, 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5,
+ 74, 89, 7, 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 52, 8, 69, 118, 95, 82, 70, 96, 113, 111,
+ 115, 86, 113, 103, 112, 114, 109, 114, 109, 6, 67, 76, 97, 68, 89, 85,
+ 112, 73, 94, 87, 117, 9, 79, 72, 114, 89, 81, 75, 68, 2, 66, 78,
+ 5, 2, 65, 5, 65, 64, 2, 77, 13, 8, 23, 19, 20, 18, 17, 17,
+ 31, 12, 10, 30, 22, 69, 101, 92, 94, 84, 88, 83, 76, 81, 79, 80,
+ 84, 70, 72, 71, 68, 98, 92, 95, 73, 73, 69, 69, 10, 1, 1, 65,
+ 16, 64, 2, 1, 1, 78, 51, 47, 34, 39, 47, 38, 21, 39, 31, 20,
+ 26, 16, 5, 1, 64, 19, 13, 17, 16, 13, 10, 16, 9, 14, 12, 3,
+ 4, 9, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 58, 49,
+ 43, 26, 54, 47, 28, 61, 50, 52, 47, 42, 39, 42, 30, 22, 8, 13,
+ 70, 74, 98, 69, 24, 16, 11, 2, 5, 0, 71, 73, 86, 64, 39, 26,
+ 20, 17, 7, 64, 73, 74, 81, 86, 16, 8, 4, 0, 67, 72, 76, 83,
+ 101, 91, 74, 73, 70, 72, 79, 89, 91, 107, 74, 33, 17, 11, 3, 64,
+ 74, 80, 83, 90, 62, 90, 81, 75, 66, 70, 1, 4, 5, 72, 3, 7,
+ 2, 78, 71, 69, 14, 5, 20, 16, 28, 28, 19, 17, 22, 19, 15, 67,
+ 9, 68, 98, 91, 88, 84, 81, 81, 80, 81, 68, 75, 74, 73, 0, 75,
+ 82, 95, 88, 96, 76, 71, 70, 69, 68, 65, 66, 0, 64, 67, 68, 3,
+ 66, 76, 50, 41, 44, 43, 41, 46, 42, 40, 34, 34, 36, 30, 12, 15,
+ 8, 34, 32, 29, 21, 23, 19, 6, 1, 66, 76, 80, 92, 73, 103, 62,
+ 62, 62, 62, 62, 62, 61, 58, 54, 51, 47, 42, 34, 17, 64, 52, 50,
+ 22, 55, 61, 49, 43, 46, 41, 36, 41, 34, 33, 19, 20, 10, 75, 27,
+ 17, 1, 111, 102, 105, 79, 84, 82, 5, 73, 73, 68, 0, 19, 7, 25,
+ 68, 62, 62, 58, 53, 38, 35, 7, 70, 91, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 87, 99, 90, 82, 84, 79, 68, 74, 79, 68, 65, 64, 0,
+ 4, 8, 3, 62, 62, 57, 50, 46, 40, 26, 13, 74, 126, 126, 93, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, 52, 54, 14,
+ 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, 47, 81, 99, 109, 101, 92,
+ 67, 70, 5, 1, 82, 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5,
+ 74, 88, 7, 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, 0, 0, 0,
+ 77, 88, 97, 68, 15, 0, 52, 8, 69, 117, 94, 82, 70, 95, 111, 109,
+ 113, 84, 111, 102, 110, 113, 108, 113, 108, 7, 66, 75, 96, 68, 88, 84,
+ 110, 73, 93, 87, 115, 10, 79, 72, 112, 89, 80, 75, 68, 3, 65, 77,
+ 5, 2, 65, 5, 64, 64, 2, 76, 13, 8, 23, 19, 19, 18, 17, 17,
+ 29, 12, 10, 29, 21, 69, 100, 91, 93, 83, 87, 82, 75, 80, 79, 79,
+ 83, 70, 72, 71, 69, 97, 91, 95, 72, 73, 68, 69, 9, 2, 1, 65,
+ 15, 0, 1, 0, 1, 78, 50, 46, 34, 38, 46, 37, 21, 39, 31, 19,
+ 25, 16, 5, 1, 64, 19, 12, 16, 15, 12, 9, 16, 9, 13, 11, 3,
+ 3, 8, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 56, 46,
+ 41, 23, 53, 45, 27, 59, 48, 50, 45, 40, 37, 40, 28, 20, 8, 11,
+ 71, 74, 98, 69, 25, 16, 11, 3, 5, 0, 70, 73, 85, 64, 39, 26,
+ 21, 17, 8, 0, 72, 73, 80, 85, 17, 9, 5, 1, 66, 71, 76, 82,
+ 100, 90, 72, 72, 69, 71, 78, 88, 90, 106, 73, 33, 18, 12, 3, 0,
+ 73, 79, 82, 89, 62, 89, 80, 74, 66, 70, 1, 5, 6, 72, 3, 8,
+ 3, 78, 71, 69, 14, 5, 19, 16, 27, 28, 19, 16, 21, 19, 15, 67,
+ 8, 69, 97, 90, 87, 84, 80, 81, 79, 80, 68, 75, 74, 72, 0, 75,
+ 82, 95, 87, 96, 76, 71, 70, 68, 68, 65, 65, 0, 64, 67, 67, 2,
+ 66, 76, 49, 41, 44, 43, 40, 45, 41, 39, 34, 33, 35, 30, 12, 14,
+ 7, 33, 31, 27, 19, 22, 18, 6, 1, 66, 75, 79, 92, 74, 102, 62,
+ 62, 62, 62, 62, 62, 59, 56, 52, 49, 45, 40, 32, 16, 65, 50, 49,
+ 21, 53, 59, 47, 41, 44, 39, 34, 39, 32, 31, 18, 18, 8, 76, 25,
+ 15, 64, 110, 100, 103, 78, 83, 81, 7, 72, 72, 68, 1, 21, 8, 27,
+ 67, 62, 62, 56, 50, 36, 32, 5, 72, 92, 73, 41, 29, 20, 9, 10,
+ 2, 64, 68, 86, 98, 89, 81, 83, 77, 67, 73, 78, 67, 64, 0, 0,
+ 5, 8, 3, 62, 61, 56, 49, 44, 38, 24, 11, 74, 126, 126, 92, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, 50, 54, 14,
+ 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, 45, 83, 100, 109, 98, 91,
+ 67, 69, 5, 1, 82, 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5,
+ 74, 87, 6, 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0,
+ 77, 88, 97, 67, 14, 0, 52, 8, 69, 116, 93, 82, 69, 93, 110, 107,
+ 112, 83, 110, 100, 108, 112, 107, 112, 108, 8, 66, 74, 95, 68, 88, 83,
+ 108, 73, 93, 86, 114, 10, 78, 71, 111, 88, 80, 75, 67, 3, 65, 76,
+ 6, 3, 66, 4, 64, 64, 2, 76, 13, 7, 22, 19, 19, 18, 17, 16,
+ 27, 12, 9, 27, 20, 70, 99, 90, 92, 82, 86, 81, 74, 79, 78, 78,
+ 82, 70, 72, 70, 70, 97, 90, 95, 72, 73, 68, 69, 8, 3, 1, 65,
+ 13, 1, 1, 64, 1, 79, 48, 45, 33, 37, 45, 36, 20, 38, 31, 18,
+ 24, 16, 5, 1, 65, 18, 12, 15, 15, 11, 8, 15, 8, 11, 10, 2,
+ 2, 7, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 54, 53, 44,
+ 39, 21, 51, 44, 25, 56, 46, 48, 43, 37, 35, 37, 26, 17, 7, 10,
+ 73, 75, 98, 69, 25, 17, 11, 3, 5, 0, 70, 73, 85, 0, 40, 26,
+ 21, 17, 9, 0, 71, 73, 79, 84, 18, 10, 5, 1, 65, 71, 75, 82,
+ 99, 90, 71, 72, 69, 71, 77, 87, 90, 105, 73, 34, 18, 12, 3, 1,
+ 72, 78, 81, 88, 62, 89, 80, 74, 66, 70, 1, 5, 6, 71, 3, 8,
+ 3, 78, 71, 69, 13, 6, 18, 15, 26, 27, 19, 15, 20, 18, 15, 68,
+ 7, 69, 96, 90, 86, 83, 80, 80, 79, 79, 68, 75, 74, 72, 64, 75,
+ 82, 94, 86, 96, 76, 70, 70, 68, 68, 65, 64, 0, 64, 67, 66, 2,
+ 67, 77, 48, 41, 43, 42, 39, 44, 40, 38, 33, 32, 34, 29, 11, 13,
+ 6, 31, 29, 26, 17, 21, 17, 5, 0, 67, 75, 79, 92, 74, 101, 62,
+ 62, 62, 62, 62, 60, 57, 53, 50, 47, 43, 38, 30, 14, 66, 48, 47,
+ 20, 51, 57, 45, 39, 42, 37, 32, 37, 30, 28, 16, 16, 6, 77, 23,
+ 13, 65, 109, 99, 102, 78, 82, 80, 9, 71, 71, 68, 2, 22, 10, 28,
+ 67, 62, 60, 53, 47, 33, 29, 2, 74, 93, 73, 41, 29, 20, 9, 10,
+ 2, 64, 68, 86, 97, 88, 80, 82, 76, 66, 73, 77, 66, 0, 1, 1,
+ 5, 9, 3, 60, 59, 54, 47, 42, 36, 22, 9, 75, 126, 126, 92, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, 49, 54, 14,
+ 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, 44, 84, 101, 110, 95, 90,
+ 67, 69, 6, 1, 81, 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5,
+ 73, 87, 6, 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0,
+ 76, 88, 97, 67, 14, 64, 52, 8, 69, 115, 93, 82, 69, 92, 108, 105,
+ 110, 82, 108, 99, 106, 111, 106, 111, 107, 9, 66, 73, 95, 67, 87, 83,
+ 106, 73, 92, 86, 113, 10, 78, 71, 109, 88, 79, 74, 67, 3, 65, 75,
+ 6, 3, 66, 4, 64, 64, 2, 76, 13, 7, 22, 19, 18, 18, 17, 16,
+ 25, 12, 9, 25, 19, 71, 99, 89, 92, 82, 85, 81, 73, 79, 78, 78,
+ 80, 70, 72, 70, 71, 96, 89, 95, 72, 73, 67, 68, 7, 3, 1, 65,
+ 12, 2, 0, 65, 1, 80, 47, 44, 33, 37, 44, 36, 20, 37, 30, 17,
+ 23, 16, 5, 1, 65, 17, 11, 14, 14, 11, 7, 14, 8, 9, 9, 2,
+ 1, 6, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 54, 52, 51, 41,
+ 36, 18, 49, 42, 24, 54, 43, 45, 40, 35, 32, 35, 23, 15, 6, 8,
+ 74, 76, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, 84, 0, 40, 27,
+ 21, 17, 10, 1, 71, 72, 79, 83, 19, 10, 6, 1, 64, 70, 75, 81,
+ 98, 89, 70, 71, 68, 71, 77, 87, 89, 103, 72, 34, 18, 12, 4, 1,
+ 72, 77, 81, 87, 62, 88, 79, 73, 66, 70, 1, 5, 6, 71, 4, 8,
+ 4, 78, 71, 70, 13, 6, 17, 14, 25, 26, 19, 14, 19, 18, 15, 68,
+ 6, 70, 95, 89, 85, 83, 79, 80, 78, 79, 68, 74, 73, 71, 64, 75,
+ 82, 94, 85, 96, 76, 70, 70, 67, 68, 65, 0, 64, 64, 67, 66, 1,
+ 67, 78, 47, 40, 43, 41, 38, 44, 40, 37, 32, 32, 33, 28, 10, 12,
+ 5, 30, 28, 24, 15, 19, 15, 4, 0, 67, 75, 79, 91, 75, 100, 62,
+ 62, 62, 62, 62, 58, 55, 51, 48, 44, 41, 35, 28, 13, 66, 47, 46,
+ 18, 49, 54, 43, 37, 40, 35, 30, 34, 28, 26, 14, 14, 5, 79, 21,
+ 11, 67, 108, 98, 101, 77, 81, 79, 10, 70, 70, 68, 3, 24, 11, 30,
+ 66, 61, 59, 51, 44, 30, 27, 64, 76, 95, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 85, 96, 88, 79, 81, 75, 66, 72, 76, 66, 0, 1, 1,
+ 6, 9, 3, 59, 58, 52, 45, 41, 35, 19, 8, 76, 126, 124, 91, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, 48, 54, 14,
+ 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, 42, 86, 102, 110, 92, 89,
+ 67, 68, 7, 1, 81, 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5,
+ 73, 86, 6, 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, 0, 0, 0,
+ 76, 89, 97, 66, 13, 64, 52, 8, 69, 114, 92, 82, 68, 91, 106, 103,
+ 109, 81, 106, 98, 104, 110, 106, 110, 106, 9, 66, 72, 94, 67, 87, 82,
+ 104, 73, 92, 85, 112, 10, 78, 70, 108, 87, 78, 74, 67, 3, 65, 75,
+ 7, 4, 67, 4, 64, 64, 2, 76, 13, 6, 21, 19, 17, 18, 17, 16,
+ 23, 12, 8, 23, 18, 72, 98, 88, 91, 81, 85, 80, 72, 78, 77, 77,
+ 79, 70, 72, 70, 72, 96, 88, 95, 72, 73, 66, 68, 6, 4, 1, 65,
+ 11, 3, 0, 66, 1, 81, 45, 43, 32, 36, 43, 35, 19, 36, 30, 15,
+ 22, 15, 5, 1, 66, 16, 10, 13, 13, 10, 6, 13, 7, 7, 8, 1,
+ 0, 5, 89, 62, 62, 61, 62, 62, 62, 62, 62, 61, 52, 50, 48, 39,
+ 34, 16, 47, 40, 22, 52, 41, 43, 38, 33, 30, 32, 21, 12, 5, 6,
+ 75, 77, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, 84, 0, 40, 27,
+ 21, 17, 11, 1, 70, 72, 78, 83, 20, 11, 6, 1, 64, 70, 74, 81,
+ 97, 88, 69, 70, 68, 71, 76, 86, 88, 102, 72, 34, 18, 12, 4, 2,
+ 71, 77, 80, 86, 62, 88, 79, 73, 66, 70, 1, 5, 6, 71, 4, 8,
+ 4, 78, 71, 70, 12, 7, 16, 13, 24, 25, 19, 12, 18, 18, 15, 69,
+ 5, 70, 95, 88, 84, 82, 79, 79, 78, 78, 69, 74, 73, 71, 65, 75,
+ 82, 93, 84, 96, 76, 70, 70, 66, 68, 65, 1, 64, 65, 67, 65, 0,
+ 67, 79, 46, 40, 42, 40, 37, 43, 39, 36, 31, 31, 32, 27, 9, 11,
+ 4, 28, 27, 23, 13, 18, 14, 3, 64, 68, 75, 79, 91, 75, 100, 62,
+ 62, 62, 62, 62, 56, 53, 48, 46, 42, 39, 33, 26, 11, 67, 45, 44,
+ 17, 47, 52, 41, 35, 37, 33, 28, 32, 26, 23, 12, 12, 3, 80, 19,
+ 9, 68, 107, 97, 100, 76, 80, 78, 12, 69, 69, 68, 4, 25, 13, 31,
+ 65, 59, 57, 48, 41, 27, 24, 67, 78, 96, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 85, 95, 87, 78, 81, 74, 65, 72, 75, 65, 1, 2, 1,
+ 6, 9, 3, 58, 56, 50, 43, 39, 33, 17, 6, 77, 126, 123, 90, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, 46, 54, 14, 87,
+ 2, 67, 7, 1, 5, 69, 0, 78, 13, 40, 88, 103, 111, 89, 87, 67, 67,
+ 7, 1, 81, 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5,
+ 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, 75, 89, 97, 66,
+ 12, 64, 52, 8, 69, 113, 91, 82, 68, 89, 105, 101, 107, 80, 105, 96, 102,
+ 109, 105, 109, 106, 10, 66, 71, 93, 67, 86, 81, 102, 73, 92, 85, 110, 11,
+ 77, 70, 107, 87, 78, 74, 66, 4, 64, 74, 7, 4, 67, 3, 64, 64, 2,
+ 76, 13, 6, 20, 19, 17, 18, 17, 15, 21, 12, 8, 22, 17, 73, 97, 87,
+ 90, 80, 84, 79, 71, 77, 77, 76, 78, 70, 72, 69, 73, 95, 87, 95, 71,
+ 73, 66, 68, 5, 5, 1, 65, 9, 4, 64, 67, 1, 81, 44, 42, 32, 35,
+ 42, 34, 18, 36, 30, 14, 21, 15, 5, 1, 66, 16, 10, 12, 13, 9, 5,
+ 13, 6, 5, 7, 0, 64, 4, 89, 61, 62, 59, 62, 61, 60, 60, 60, 59,
+ 50, 48, 46, 36, 32, 13, 45, 39, 20, 49, 39, 41, 36, 30, 28, 29, 19,
+ 10, 4, 5, 77, 77, 98, 68, 26, 18, 12, 3, 5, 0, 70, 73, 83, 1,
+ 41, 27, 21, 17, 12, 2, 69, 72, 77, 82, 21, 12, 6, 2, 0, 69, 74,
+ 80, 96, 88, 67, 70, 68, 70, 75, 85, 88, 101, 71, 35, 19, 12, 4, 3,
+ 70, 76, 79, 85, 62, 88, 79, 72, 66, 70, 1, 5, 6, 70, 4, 9, 5,
+ 78, 71, 70, 11, 7, 15, 12, 23, 25, 19, 11, 17, 17, 15, 70, 4, 71,
+ 94, 88, 83, 82, 78, 79, 77, 77, 69, 74, 73, 71, 66, 75, 82, 93, 83,
+ 96, 76, 69, 70, 66, 68, 65, 2, 64, 65, 67, 64, 0, 68, 79, 45, 40,
+ 42, 40, 36, 42, 38, 35, 31, 30, 31, 26, 8, 10, 3, 27, 25, 21, 11,
+ 17, 13, 2, 65, 68, 75, 78, 91, 76, 99, 62, 62, 62, 62, 60, 54, 51,
+ 46, 44, 40, 37, 31, 24, 10, 68, 43, 42, 16, 45, 50, 39, 33, 35, 31,
+ 26, 30, 24, 21, 10, 10, 1, 81, 17, 7, 70, 106, 95, 99, 76, 79, 77,
+ 14, 68, 68, 68, 5, 27, 14, 33, 65, 58, 55, 46, 38, 25, 21, 69, 80,
+ 97, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 94, 86, 77, 80, 73, 64,
+ 71, 74, 64, 2, 3, 2, 7, 10, 3, 56, 55, 49, 42, 37, 31, 15, 4,
+ 78, 126, 122, 90, 62, 62, 62, 62},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, 45, 54, 14, 85,
+ 2, 66, 8, 1, 4, 69, 64, 79, 13, 38, 89, 104, 111, 86, 86, 67, 66,
+ 8, 1, 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5,
+ 72, 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 75, 89, 97, 65,
+ 11, 64, 52, 8, 69, 112, 90, 82, 67, 88, 103, 99, 106, 79, 103, 95, 100,
+ 108, 104, 108, 105, 11, 66, 70, 92, 67, 86, 81, 100, 73, 91, 84, 109, 11,
+ 77, 69, 105, 86, 77, 74, 66, 4, 64, 73, 8, 5, 68, 3, 64, 64, 2,
+ 76, 13, 5, 20, 19, 16, 18, 17, 15, 19, 12, 7, 20, 16, 74, 96, 86,
+ 89, 79, 83, 79, 70, 77, 76, 75, 77, 70, 72, 69, 74, 95, 86, 95, 71,
+ 73, 65, 68, 4, 6, 1, 65, 8, 5, 64, 68, 1, 82, 42, 41, 31, 34,
+ 41, 33, 18, 35, 29, 13, 20, 15, 5, 1, 67, 15, 9, 11, 12, 8, 4,
+ 12, 6, 3, 6, 0, 65, 3, 89, 60, 61, 58, 62, 59, 58, 58, 58, 56,
+ 47, 46, 43, 34, 29, 11, 43, 37, 19, 47, 37, 38, 33, 28, 25, 27, 17,
+ 7, 3, 3, 78, 78, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, 83, 1,
+ 41, 27, 21, 17, 13, 2, 69, 71, 77, 81, 22, 12, 7, 2, 1, 69, 73,
+ 80, 95, 87, 66, 69, 67, 70, 74, 84, 87, 100, 71, 35, 19, 12, 4, 4,
+ 70, 75, 78, 84, 62, 87, 78, 72, 66, 70, 1, 5, 6, 70, 4, 9, 5,
+ 78, 71, 70, 11, 8, 14, 11, 22, 24, 19, 10, 16, 17, 15, 70, 3, 71,
+ 93, 87, 82, 81, 78, 78, 77, 76, 69, 74, 73, 70, 66, 75, 82, 92, 82,
+ 96, 76, 69, 70, 65, 68, 65, 3, 64, 65, 67, 0, 64, 68, 80, 44, 39,
+ 41, 39, 35, 41, 37, 34, 30, 29, 30, 25, 7, 9, 2, 25, 24, 20, 9,
+ 15, 12, 1, 65, 69, 75, 78, 91, 76, 98, 62, 62, 61, 61, 57, 52, 49,
+ 43, 42, 38, 35, 28, 22, 8, 69, 41, 41, 14, 43, 48, 37, 31, 33, 29,
+ 24, 28, 22, 18, 8, 8, 64, 82, 15, 5, 71, 105, 94, 98, 75, 78, 76,
+ 15, 67, 67, 68, 6, 28, 16, 34, 64, 56, 54, 43, 35, 22, 18, 72, 82,
+ 98, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 93, 85, 76, 79, 72, 64,
+ 71, 73, 64, 2, 3, 2, 7, 10, 3, 55, 53, 47, 40, 35, 29, 13, 2,
+ 79, 125, 120, 89, 62, 62, 62, 62},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, 54, 14, 83, 2,
+ 65, 9, 1, 3, 69, 65, 80, 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1,
+ 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 52, 8,
+ 69, 111, 89, 82, 67, 87, 101, 97, 104, 78, 101, 94, 98, 107, 103, 107, 104, 12,
+ 66, 69, 91, 67, 85, 80, 98, 73, 91, 84, 108, 11, 77, 69, 104, 86, 76, 74,
+ 66, 4, 64, 72, 8, 5, 68, 3, 64, 64, 2, 76, 13, 5, 19, 19, 15, 18,
+ 17, 15, 17, 12, 7, 18, 15, 75, 95, 85, 88, 78, 82, 78, 69, 76, 76, 74,
+ 76, 70, 72, 69, 75, 94, 85, 95, 71, 73, 64, 68, 3, 7, 1, 65, 7, 6,
+ 65, 69, 1, 83, 41, 40, 31, 33, 40, 32, 17, 34, 29, 12, 19, 15, 5, 1,
+ 67, 14, 8, 10, 11, 7, 3, 11, 5, 1, 5, 64, 66, 2, 89, 58, 60, 56,
+ 60, 57, 56, 56, 56, 54, 45, 44, 41, 31, 27, 8, 41, 35, 17, 45, 35, 36,
+ 31, 26, 23, 24, 15, 5, 2, 1, 79, 79, 98, 68, 27, 18, 12, 3, 5, 0,
+ 70, 73, 82, 1, 41, 27, 21, 17, 14, 3, 68, 71, 76, 80, 23, 13, 7, 2,
+ 2, 68, 73, 79, 94, 86, 65, 68, 67, 70, 73, 83, 86, 99, 70, 35, 19, 12,
+ 4, 5, 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, 70, 4, 9,
+ 6, 78, 71, 70, 10, 8, 13, 10, 21, 23, 19, 9, 15, 17, 15, 71, 2, 72,
+ 92, 86, 81, 81, 77, 78, 76, 75, 69, 74, 73, 70, 67, 75, 82, 92, 81, 96,
+ 76, 69, 70, 64, 68, 65, 4, 64, 65, 67, 1, 65, 68, 81, 43, 39, 41, 38,
+ 34, 40, 36, 33, 29, 28, 29, 24, 6, 8, 1, 24, 23, 18, 7, 14, 11, 0,
+ 66, 69, 75, 78, 91, 77, 97, 62, 62, 59, 59, 54, 50, 47, 41, 40, 36, 33,
+ 26, 20, 7, 70, 39, 39, 13, 41, 46, 35, 29, 31, 27, 22, 26, 20, 16, 6,
+ 6, 66, 83, 13, 3, 73, 104, 93, 97, 74, 77, 75, 17, 66, 66, 68, 7, 30,
+ 17, 36, 0, 55, 52, 41, 32, 19, 15, 75, 84, 99, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 83, 92, 84, 75, 78, 71, 0, 70, 72, 0, 3, 4, 2, 8, 10,
+ 3, 54, 52, 45, 38, 33, 27, 11, 0, 80, 124, 119, 88, 62, 62, 62, 62},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, 53, 14, 81, 1,
+ 65, 9, 0, 2, 69, 67, 82, 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0,
+ 80, 78, 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, 78, 88,
+ 3, 69, 70, 75, 65, 4, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 52, 7,
+ 69, 110, 89, 82, 67, 86, 100, 96, 103, 77, 100, 93, 97, 106, 103, 106, 104, 12,
+ 66, 69, 91, 67, 85, 80, 97, 73, 91, 84, 107, 11, 77, 69, 103, 86, 76, 74,
+ 66, 4, 64, 72, 8, 5, 69, 2, 64, 65, 2, 76, 12, 4, 18, 19, 14, 17,
+ 17, 14, 15, 11, 6, 16, 14, 76, 95, 85, 88, 78, 82, 78, 68, 76, 76, 74,
+ 75, 71, 72, 69, 77, 94, 85, 95, 71, 74, 64, 68, 2, 7, 1, 65, 5, 6,
+ 66, 70, 1, 84, 39, 39, 30, 32, 39, 31, 16, 33, 28, 10, 18, 14, 4, 1,
+ 68, 13, 7, 9, 10, 6, 2, 10, 4, 64, 3, 65, 68, 0, 89, 56, 58, 54,
+ 58, 55, 53, 53, 53, 51, 42, 41, 38, 28, 24, 5, 39, 33, 15, 42, 32, 33,
+ 28, 23, 20, 21, 12, 2, 1, 64, 81, 80, 99, 68, 27, 18, 12, 3, 5, 64,
+ 70, 73, 82, 1, 41, 27, 21, 17, 15, 3, 68, 71, 76, 80, 23, 13, 7, 2,
+ 2, 68, 73, 79, 93, 86, 64, 68, 67, 70, 73, 83, 86, 98, 70, 35, 19, 12,
+ 4, 5, 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, 70, 4, 9,
+ 6, 78, 71, 71, 9, 8, 12, 9, 20, 22, 18, 7, 13, 16, 14, 72, 0, 73,
+ 92, 86, 80, 81, 77, 78, 76, 75, 70, 74, 73, 70, 68, 75, 82, 92, 81, 97,
+ 76, 69, 70, 64, 69, 65, 4, 65, 66, 67, 1, 66, 69, 82, 42, 38, 40, 37,
+ 32, 39, 35, 32, 28, 27, 28, 23, 5, 6, 64, 22, 21, 16, 5, 12, 9, 64,
+ 67, 70, 75, 78, 91, 78, 97, 62, 61, 57, 56, 51, 47, 44, 38, 37, 33, 30,
+ 23, 17, 5, 71, 37, 37, 11, 39, 43, 32, 26, 28, 24, 20, 23, 17, 13, 4,
+ 3, 68, 85, 11, 1, 75, 103, 92, 96, 74, 77, 75, 18, 66, 66, 68, 7, 31,
+ 18, 37, 0, 53, 50, 38, 28, 16, 12, 78, 87, 101, 72, 41, 28, 19, 9, 10,
+ 2, 65, 68, 83, 92, 84, 75, 78, 70, 0, 70, 72, 0, 3, 4, 2, 8, 10,
+ 2, 52, 50, 43, 36, 31, 25, 8, 65, 81, 124, 118, 88, 62, 62, 62, 62},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, 53, 14, 78, 1,
+ 64, 10, 0, 2, 68, 68, 83, 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0,
+ 79, 76, 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, 77, 88,
+ 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 52, 7,
+ 69, 108, 88, 82, 66, 84, 98, 94, 101, 75, 98, 91, 95, 104, 102, 105, 103, 13,
+ 65, 68, 90, 66, 84, 79, 95, 72, 90, 83, 105, 12, 76, 68, 101, 85, 75, 73,
+ 65, 5, 0, 71, 9, 6, 69, 2, 0, 65, 2, 75, 12, 4, 18, 19, 14, 17,
+ 17, 14, 14, 11, 6, 15, 13, 76, 94, 84, 87, 77, 81, 77, 67, 75, 75, 73,
+ 73, 71, 72, 68, 78, 93, 84, 95, 70, 74, 0, 67, 2, 8, 1, 65, 4, 7,
+ 66, 71, 1, 84, 38, 39, 30, 32, 39, 31, 16, 33, 28, 9, 18, 14, 4, 1,
+ 68, 13, 7, 9, 10, 6, 1, 10, 4, 65, 2, 65, 69, 64, 89, 55, 57, 53,
+ 57, 54, 51, 51, 51, 49, 40, 39, 36, 26, 22, 3, 38, 32, 14, 40, 30, 31,
+ 26, 21, 18, 19, 10, 0, 1, 65, 82, 80, 99, 67, 28, 19, 13, 4, 5, 64,
+ 69, 72, 81, 2, 42, 28, 22, 17, 16, 4, 67, 70, 75, 79, 24, 14, 8, 3,
+ 3, 67, 72, 78, 91, 85, 1, 67, 66, 69, 72, 82, 85, 96, 69, 36, 20, 13,
+ 5, 6, 68, 73, 76, 82, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, 10,
+ 7, 77, 71, 71, 9, 9, 12, 9, 19, 22, 18, 6, 12, 16, 14, 72, 64, 73,
+ 91, 85, 79, 80, 76, 77, 75, 74, 70, 73, 72, 69, 68, 74, 81, 91, 80, 97,
+ 76, 68, 70, 0, 69, 65, 5, 65, 66, 66, 2, 66, 69, 82, 42, 38, 40, 37,
+ 31, 39, 35, 32, 28, 27, 28, 23, 5, 5, 65, 21, 20, 15, 4, 11, 8, 64,
+ 67, 70, 74, 77, 90, 78, 96, 60, 59, 55, 54, 49, 45, 42, 36, 35, 31, 28,
+ 21, 15, 4, 71, 36, 36, 10, 38, 41, 30, 24, 26, 22, 18, 21, 15, 11, 3,
+ 1, 69, 86, 10, 0, 76, 101, 90, 94, 73, 76, 74, 20, 65, 65, 68, 8, 33,
+ 20, 39, 1, 52, 49, 36, 25, 14, 10, 80, 89, 102, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 82, 91, 83, 74, 77, 68, 1, 69, 71, 1, 4, 5, 3, 9, 11,
+ 2, 51, 49, 42, 35, 30, 24, 6, 66, 81, 123, 116, 87, 62, 62, 62, 62},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, 53, 14, 76, 1,
+ 0, 11, 0, 1, 68, 69, 84, 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0,
+ 79, 75, 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, 77, 88,
+ 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 52, 7,
+ 69, 107, 87, 82, 66, 83, 96, 92, 100, 74, 96, 90, 93, 103, 101, 104, 102, 14,
+ 65, 67, 89, 66, 84, 78, 93, 72, 90, 83, 104, 12, 76, 68, 100, 85, 74, 73,
+ 65, 5, 0, 70, 9, 6, 70, 2, 0, 65, 2, 75, 12, 4, 17, 19, 13, 17,
+ 17, 14, 12, 11, 6, 13, 12, 77, 93, 83, 86, 76, 80, 76, 66, 74, 75, 72,
+ 72, 71, 72, 68, 79, 93, 83, 95, 70, 74, 1, 67, 1, 9, 1, 65, 3, 8,
+ 67, 72, 1, 85, 36, 38, 29, 31, 38, 30, 15, 32, 28, 8, 17, 14, 4, 1,
+ 68, 12, 6, 8, 9, 5, 0, 9, 3, 67, 1, 66, 70, 65, 89, 53, 56, 51,
+ 55, 52, 49, 49, 49, 46, 38, 37, 33, 23, 20, 0, 36, 30, 12, 38, 28, 29,
+ 24, 19, 16, 16, 8, 65, 0, 67, 83, 81, 99, 67, 28, 19, 13, 4, 5, 64,
+ 69, 72, 80, 2, 42, 28, 22, 17, 17, 4, 66, 70, 74, 78, 25, 15, 8, 3,
+ 4, 67, 72, 77, 90, 84, 2, 66, 66, 69, 71, 81, 84, 95, 69, 36, 20, 13,
+ 5, 7, 67, 72, 75, 81, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, 10,
+ 8, 77, 71, 71, 8, 9, 11, 8, 18, 21, 18, 5, 11, 16, 14, 73, 65, 74,
+ 90, 84, 78, 80, 76, 77, 74, 73, 70, 73, 72, 69, 69, 74, 81, 91, 79, 97,
+ 76, 68, 70, 1, 69, 65, 6, 65, 66, 66, 3, 67, 69, 83, 41, 38, 40, 36,
+ 30, 38, 34, 31, 27, 26, 27, 22, 4, 4, 66, 19, 19, 13, 2, 10, 7, 65,
+ 68, 70, 74, 77, 90, 79, 95, 58, 57, 53, 52, 46, 43, 40, 33, 33, 29, 26,
+ 19, 13, 3, 72, 34, 34, 9, 36, 39, 28, 22, 24, 20, 16, 19, 13, 9, 1,
+ 64, 71, 87, 8, 65, 78, 100, 89, 93, 72, 75, 73, 22, 64, 64, 68, 9, 34,
+ 21, 40, 2, 51, 47, 33, 22, 11, 7, 83, 91, 103, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 81, 90, 82, 73, 76, 67, 2, 68, 70, 2, 5, 6, 3, 10, 11,
+ 2, 50, 47, 40, 33, 28, 22, 4, 68, 82, 122, 115, 86, 62, 62, 62, 62},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, 53, 14, 74, 1,
+ 1, 12, 0, 0, 68, 70, 85, 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0,
+ 78, 74, 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, 77, 88,
+ 5, 68, 69, 74, 0, 4, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 52, 7,
+ 69, 106, 86, 82, 65, 82, 94, 90, 98, 73, 94, 89, 91, 102, 100, 103, 101, 15,
+ 65, 66, 88, 66, 83, 78, 91, 72, 89, 82, 103, 12, 76, 67, 98, 84, 73, 73,
+ 65, 5, 0, 69, 10, 7, 70, 2, 0, 65, 2, 75, 12, 3, 17, 19, 12, 17,
+ 17, 14, 10, 11, 5, 11, 11, 78, 92, 82, 85, 75, 79, 76, 65, 74, 74, 71,
+ 71, 71, 72, 68, 80, 92, 82, 95, 70, 74, 2, 67, 0, 10, 1, 65, 2, 9,
+ 67, 73, 1, 86, 35, 37, 29, 30, 37, 29, 15, 31, 27, 7, 16, 14, 4, 1,
+ 69, 11, 5, 7, 8, 4, 64, 8, 3, 69, 0, 66, 71, 66, 89, 52, 54, 50,
+ 53, 50, 47, 47, 47, 44, 35, 35, 31, 21, 17, 65, 34, 28, 11, 36, 26, 26,
+ 21, 17, 13, 14, 6, 68, 64, 69, 84, 82, 99, 67, 29, 19, 13, 4, 5, 64,
+ 69, 72, 80, 2, 42, 28, 22, 17, 18, 5, 66, 69, 74, 77, 26, 15, 9, 3,
+ 5, 66, 71, 77, 89, 83, 3, 65, 65, 69, 70, 80, 83, 94, 68, 36, 20, 13,
+ 5, 8, 67, 71, 74, 80, 62, 85, 76, 69, 66, 69, 1, 6, 7, 69, 5, 10,
+ 8, 77, 71, 71, 8, 10, 10, 7, 17, 20, 18, 4, 10, 16, 14, 73, 66, 74,
+ 89, 83, 77, 79, 75, 76, 74, 72, 70, 73, 72, 68, 69, 74, 81, 90, 78, 97,
+ 76, 68, 70, 2, 69, 65, 7, 65, 66, 66, 4, 68, 69, 84, 40, 37, 39, 35,
+ 29, 37, 33, 30, 26, 25, 26, 21, 3, 3, 67, 18, 18, 12, 0, 8, 6, 66,
+ 68, 71, 74, 77, 90, 79, 94, 56, 55, 51, 50, 43, 41, 38, 31, 31, 27, 24,
+ 16, 11, 1, 73, 32, 33, 7, 34, 37, 26, 20, 22, 18, 14, 17, 11, 6, 64,
+ 66, 73, 88, 6, 67, 79, 99, 88, 92, 71, 74, 72, 23, 0, 0, 68, 10, 36,
+ 23, 42, 3, 49, 46, 31, 19, 8, 4, 86, 93, 104, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 81, 89, 81, 72, 75, 66, 2, 68, 69, 2, 5, 6, 3, 10, 11,
+ 2, 49, 46, 38, 31, 26, 20, 2, 70, 83, 121, 113, 85, 62, 62, 62, 62},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, 53, 14, 71, 0,
+ 2, 12, 0, 64, 68, 71, 86, 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0,
+ 78, 73, 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, 77, 88,
+ 5, 67, 69, 73, 0, 4, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 52, 7,
+ 69, 105, 85, 82, 65, 80, 93, 88, 97, 72, 93, 87, 89, 101, 100, 102, 101, 15,
+ 65, 65, 87, 66, 83, 77, 89, 72, 89, 82, 102, 12, 75, 67, 97, 84, 73, 73,
+ 64, 5, 0, 69, 10, 7, 71, 1, 0, 65, 2, 75, 12, 3, 16, 19, 12, 17,
+ 17, 13, 8, 11, 5, 9, 10, 79, 91, 81, 84, 74, 79, 75, 64, 73, 74, 70,
+ 70, 71, 72, 67, 81, 92, 81, 95, 70, 74, 2, 67, 64, 11, 1, 65, 0, 10,
+ 68, 74, 1, 87, 33, 36, 28, 29, 36, 28, 14, 30, 27, 5, 15, 13, 4, 1,
+ 69, 10, 5, 6, 8, 3, 65, 7, 2, 71, 64, 67, 72, 67, 89, 50, 53, 48,
+ 51, 48, 45, 44, 45, 41, 33, 33, 28, 18, 15, 68, 32, 27, 9, 33, 24, 24,
+ 19, 14, 11, 11, 4, 70, 65, 70, 86, 83, 99, 67, 29, 20, 13, 4, 5, 64,
+ 69, 72, 79, 3, 43, 28, 22, 17, 19, 5, 65, 69, 73, 77, 27, 16, 9, 3,
+ 5, 66, 71, 76, 88, 83, 4, 65, 65, 69, 69, 79, 83, 93, 68, 37, 20, 13,
+ 5, 9, 66, 71, 73, 79, 62, 85, 76, 69, 66, 69, 1, 6, 7, 68, 5, 10,
+ 9, 77, 71, 71, 7, 10, 9, 6, 16, 19, 18, 2, 9, 15, 14, 74, 67, 75,
+ 89, 83, 76, 79, 75, 76, 73, 71, 71, 73, 72, 68, 70, 74, 81, 90, 77, 97,
+ 76, 67, 70, 2, 69, 65, 8, 65, 67, 66, 5, 68, 70, 85, 39, 37, 39, 34,
+ 28, 36, 32, 29, 25, 24, 25, 20, 2, 2, 68, 16, 16, 10, 65, 7, 5, 67,
+ 69, 71, 74, 77, 90, 80, 94, 53, 52, 49, 47, 40, 39, 36, 28, 29, 25, 22,
+ 14, 9, 0, 74, 30, 31, 6, 32, 35, 24, 18, 19, 16, 12, 15, 9, 4, 66,
+ 68, 75, 89, 4, 69, 81, 98, 87, 91, 71, 73, 71, 25, 1, 1, 68, 11, 37,
+ 24, 43, 3, 48, 44, 28, 16, 5, 1, 89, 95, 105, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 80, 88, 80, 71, 75, 65, 3, 67, 68, 3, 6, 7, 4, 11, 12,
+ 2, 47, 44, 36, 29, 24, 18, 0, 72, 84, 120, 112, 85, 62, 62, 62, 62},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, 53, 14, 69, 0,
+ 3, 13, 0, 64, 67, 72, 87, 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0,
+ 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, 77, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 52, 7,
+ 69, 104, 84, 82, 64, 79, 91, 86, 95, 71, 91, 86, 87, 100, 99, 101, 100, 16,
+ 65, 64, 86, 66, 82, 76, 87, 72, 89, 81, 100, 13, 75, 66, 96, 83, 72, 73,
+ 64, 6, 1, 68, 11, 8, 71, 1, 0, 65, 2, 75, 12, 2, 15, 19, 11, 17,
+ 17, 13, 6, 11, 4, 8, 9, 80, 90, 80, 83, 73, 78, 74, 0, 72, 73, 69,
+ 69, 71, 72, 67, 82, 91, 80, 95, 69, 74, 3, 67, 65, 12, 1, 65, 64, 11,
+ 68, 75, 1, 87, 32, 35, 28, 28, 35, 27, 13, 30, 27, 4, 14, 13, 4, 1,
+ 70, 10, 4, 5, 7, 2, 66, 7, 1, 73, 65, 68, 73, 68, 89, 48, 52, 46,
+ 49, 47, 43, 42, 43, 39, 31, 31, 26, 16, 13, 70, 30, 25, 7, 31, 22, 22,
+ 17, 12, 9, 8, 2, 73, 66, 72, 87, 83, 99, 67, 29, 20, 13, 4, 5, 64,
+ 69, 72, 79, 3, 43, 28, 22, 17, 20, 6, 64, 69, 72, 76, 28, 17, 9, 4,
+ 6, 65, 70, 76, 87, 82, 6, 64, 65, 68, 68, 78, 82, 92, 67, 37, 21, 13,
+ 5, 10, 65, 70, 72, 78, 62, 85, 76, 68, 66, 69, 1, 6, 7, 68, 5, 11,
+ 9, 77, 71, 71, 6, 11, 8, 5, 15, 19, 18, 1, 8, 15, 14, 75, 68, 75,
+ 88, 82, 75, 78, 74, 75, 73, 70, 71, 73, 72, 68, 71, 74, 81, 89, 76, 97,
+ 76, 67, 70, 3, 69, 65, 9, 65, 67, 66, 6, 69, 70, 85, 38, 37, 38, 34,
+ 27, 35, 31, 28, 25, 23, 24, 19, 1, 1, 69, 15, 15, 9, 67, 6, 4, 68,
+ 70, 72, 74, 76, 90, 80, 93, 51, 50, 47, 45, 38, 37, 34, 26, 27, 23, 20,
+ 12, 7, 65, 75, 28, 29, 5, 30, 33, 22, 16, 17, 14, 10, 13, 7, 1, 68,
+ 70, 77, 90, 2, 71, 82, 97, 85, 90, 70, 72, 70, 27, 2, 2, 68, 12, 39,
+ 26, 45, 4, 46, 42, 26, 13, 3, 65, 91, 97, 106, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 80, 87, 79, 70, 74, 64, 4, 67, 67, 4, 7, 8, 4, 11, 12,
+ 2, 46, 43, 35, 28, 22, 16, 65, 74, 85, 119, 111, 84, 62, 62, 62, 62},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, 53, 14, 67, 0,
+ 3, 14, 0, 65, 67, 73, 88, 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0,
+ 77, 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, 76, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 52, 7,
+ 69, 103, 84, 82, 64, 78, 89, 84, 94, 70, 89, 85, 85, 99, 98, 100, 99, 17,
+ 65, 0, 86, 65, 82, 76, 85, 72, 88, 81, 99, 13, 75, 66, 94, 83, 71, 72,
+ 64, 6, 1, 67, 11, 8, 72, 1, 0, 65, 2, 75, 12, 2, 15, 19, 10, 17,
+ 17, 13, 4, 11, 4, 6, 8, 81, 90, 79, 83, 73, 77, 74, 1, 72, 73, 69,
+ 67, 71, 72, 67, 83, 91, 79, 95, 69, 74, 4, 66, 66, 12, 1, 65, 65, 12,
+ 69, 76, 1, 88, 30, 34, 27, 28, 34, 27, 13, 29, 26, 3, 13, 13, 4, 1,
+ 70, 9, 3, 4, 6, 2, 67, 6, 1, 75, 66, 68, 74, 69, 89, 47, 50, 45,
+ 47, 45, 41, 40, 41, 36, 28, 29, 23, 13, 10, 73, 28, 23, 6, 29, 19, 19,
+ 14, 10, 6, 6, 64, 75, 67, 74, 88, 84, 99, 66, 30, 20, 14, 4, 5, 64,
+ 69, 72, 78, 3, 43, 29, 22, 17, 21, 6, 64, 68, 72, 75, 29, 17, 10, 4,
+ 7, 65, 70, 75, 86, 81, 7, 0, 64, 68, 68, 78, 81, 90, 67, 37, 21, 13,
+ 6, 10, 65, 69, 72, 77, 62, 84, 75, 68, 66, 69, 1, 6, 7, 68, 6, 11,
+ 10, 77, 71, 72, 6, 11, 7, 4, 14, 18, 18, 0, 7, 15, 14, 75, 69, 76,
+ 87, 81, 74, 78, 74, 75, 72, 70, 71, 72, 71, 67, 71, 74, 81, 89, 75, 97,
+ 76, 67, 70, 4, 69, 65, 10, 66, 67, 66, 6, 70, 70, 86, 37, 36, 38, 33,
+ 26, 35, 31, 27, 24, 23, 23, 18, 0, 0, 70, 13, 14, 7, 69, 4, 2, 69,
+ 70, 72, 74, 76, 89, 81, 92, 49, 48, 45, 43, 35, 35, 32, 23, 25, 20, 18,
+ 9, 5, 66, 75, 27, 28, 3, 28, 30, 20, 14, 15, 12, 8, 10, 5, 64, 70,
+ 72, 78, 92, 0, 73, 84, 96, 84, 89, 69, 71, 69, 28, 3, 3, 68, 13, 40,
+ 27, 46, 5, 45, 41, 23, 10, 0, 67, 94, 99, 108, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 79, 86, 79, 69, 73, 0, 4, 66, 66, 4, 7, 8, 4, 12, 12,
+ 2, 45, 41, 33, 26, 21, 15, 68, 75, 86, 118, 109, 83, 62, 62, 62, 62},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, 53, 14, 64, 64,
+ 4, 14, 0, 66, 67, 74, 89, 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0,
+ 77, 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 52, 7,
+ 69, 102, 83, 82, 0, 76, 88, 82, 92, 69, 88, 83, 83, 98, 97, 99, 99, 18,
+ 65, 1, 85, 65, 81, 75, 83, 72, 88, 80, 98, 13, 74, 65, 93, 82, 71, 72,
+ 0, 6, 1, 66, 12, 9, 72, 0, 0, 65, 2, 75, 12, 1, 14, 19, 10, 17,
+ 17, 12, 2, 11, 3, 4, 7, 82, 89, 78, 82, 72, 76, 73, 2, 71, 72, 68,
+ 66, 71, 72, 66, 84, 90, 78, 95, 69, 74, 4, 66, 67, 13, 1, 65, 67, 13,
+ 69, 77, 1, 89, 29, 33, 27, 27, 33, 26, 12, 28, 26, 2, 12, 13, 4, 1,
+ 71, 8, 3, 3, 6, 1, 68, 5, 0, 77, 67, 69, 75, 70, 89, 45, 49, 43,
+ 45, 43, 39, 37, 39, 34, 26, 27, 21, 11, 8, 75, 26, 22, 4, 26, 17, 17,
+ 12, 7, 4, 3, 66, 78, 68, 75, 90, 85, 99, 66, 30, 21, 14, 4, 5, 64,
+ 69, 72, 78, 4, 44, 29, 22, 17, 22, 7, 0, 68, 71, 74, 30, 18, 10, 4,
+ 8, 64, 69, 75, 85, 81, 8, 0, 64, 68, 67, 77, 81, 89, 66, 38, 21, 13,
+ 6, 11, 64, 68, 71, 76, 62, 84, 75, 67, 66, 69, 1, 6, 7, 67, 6, 11,
+ 10, 77, 71, 72, 5, 12, 6, 3, 13, 17, 18, 64, 6, 14, 14, 76, 70, 76,
+ 86, 81, 73, 77, 73, 74, 72, 69, 71, 72, 71, 67, 72, 74, 81, 88, 74, 97,
+ 76, 66, 70, 4, 69, 65, 11, 66, 67, 66, 7, 70, 71, 87, 36, 36, 37, 32,
+ 25, 34, 30, 26, 23, 22, 22, 17, 64, 64, 71, 12, 12, 6, 71, 3, 1, 70,
+ 71, 73, 74, 76, 89, 81, 91, 47, 46, 43, 40, 32, 33, 30, 21, 23, 18, 16,
+ 7, 3, 68, 76, 25, 26, 2, 26, 28, 18, 12, 13, 10, 6, 8, 3, 67, 72,
+ 74, 80, 93, 65, 75, 85, 95, 83, 88, 69, 70, 68, 30, 4, 4, 68, 14, 42,
+ 29, 48, 5, 43, 39, 21, 7, 66, 70, 97, 101, 109, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 79, 85, 78, 68, 72, 1, 5, 66, 65, 5, 8, 9, 5, 12, 13,
+ 2, 43, 40, 31, 24, 19, 13, 70, 77, 87, 117, 108, 83, 62, 62, 62, 62},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, 53, 14, 1, 64,
+ 5, 15, 0, 67, 67, 75, 91, 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0,
+ 77, 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 52, 7,
+ 69, 101, 82, 82, 0, 75, 86, 80, 91, 68, 86, 82, 82, 97, 97, 98, 98, 18,
+ 65, 2, 84, 65, 81, 75, 82, 72, 88, 80, 97, 13, 74, 65, 92, 82, 70, 72,
+ 0, 6, 1, 66, 12, 9, 73, 0, 0, 65, 2, 75, 12, 1, 13, 19, 9, 17,
+ 17, 12, 0, 11, 3, 2, 6, 83, 88, 77, 81, 71, 76, 73, 3, 71, 72, 67,
+ 65, 71, 72, 66, 86, 90, 77, 95, 69, 75, 5, 66, 68, 14, 1, 65, 68, 14,
+ 70, 78, 1, 90, 27, 32, 26, 26, 32, 25, 11, 27, 25, 0, 11, 12, 4, 1,
+ 71, 7, 2, 2, 5, 0, 69, 4, 64, 79, 69, 70, 76, 71, 89, 43, 47, 41,
+ 43, 41, 37, 35, 37, 31, 23, 25, 18, 8, 5, 78, 24, 20, 2, 24, 15, 14,
+ 9, 5, 1, 0, 68, 80, 69, 77, 91, 86, 100, 66, 30, 21, 14, 4, 5, 64,
+ 69, 72, 77, 4, 44, 29, 22, 17, 23, 7, 0, 68, 71, 74, 31, 18, 10, 4,
+ 8, 64, 69, 74, 84, 80, 9, 1, 64, 68, 66, 76, 80, 88, 66, 38, 21, 13,
+ 6, 12, 64, 68, 70, 76, 62, 84, 75, 67, 66, 69, 1, 6, 7, 67, 6, 11,
+ 11, 77, 71, 72, 4, 12, 5, 2, 12, 16, 18, 66, 4, 14, 14, 77, 71, 77,
+ 86, 80, 72, 77, 73, 74, 71, 68, 72, 72, 71, 67, 73, 74, 81, 88, 74, 98,
+ 76, 66, 70, 5, 69, 65, 11, 66, 68, 66, 8, 71, 71, 88, 35, 35, 37, 31,
+ 23, 33, 29, 25, 22, 21, 21, 16, 65, 65, 72, 10, 11, 4, 73, 1, 0, 71,
+ 72, 73, 74, 76, 89, 82, 91, 44, 43, 41, 38, 29, 30, 27, 18, 21, 16, 14,
+ 4, 1, 69, 77, 23, 24, 0, 24, 26, 15, 9, 10, 7, 4, 6, 0, 69, 74,
+ 77, 82, 94, 67, 77, 87, 94, 82, 87, 68, 69, 68, 31, 5, 4, 68, 14, 43,
+ 30, 49, 6, 42, 37, 18, 4, 69, 73, 100, 103, 110, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 78, 85, 77, 67, 72, 2, 5, 65, 65, 5, 8, 9, 5, 13, 13,
+ 1, 42, 38, 29, 22, 17, 11, 72, 79, 88, 117, 107, 82, 62, 62, 62, 62},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, 53, 14, 3, 64,
+ 6, 16, 0, 67, 66, 76, 92, 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0,
+ 76, 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, 76, 88,
+ 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 52, 7,
+ 69, 100, 81, 82, 0, 74, 84, 78, 89, 66, 84, 81, 80, 96, 96, 97, 97, 19,
+ 64, 3, 83, 65, 80, 74, 80, 72, 87, 80, 95, 14, 74, 65, 90, 82, 69, 72,
+ 0, 7, 2, 65, 12, 9, 73, 0, 1, 65, 2, 74, 12, 1, 13, 19, 8, 17,
+ 17, 12, 65, 11, 3, 1, 5, 83, 87, 76, 80, 70, 75, 72, 4, 70, 72, 66,
+ 64, 71, 72, 66, 87, 89, 76, 95, 68, 75, 6, 66, 69, 15, 1, 65, 69, 15,
+ 71, 79, 1, 90, 26, 31, 26, 25, 31, 24, 11, 27, 25, 64, 10, 12, 4, 1,
+ 71, 7, 1, 1, 4, 64, 70, 4, 64, 80, 70, 70, 77, 72, 89, 42, 46, 40,
+ 42, 40, 35, 33, 35, 29, 21, 23, 16, 5, 3, 81, 23, 18, 1, 22, 13, 12,
+ 7, 3, 64, 65, 70, 82, 69, 79, 92, 86, 100, 66, 31, 21, 14, 5, 5, 64,
+ 68, 72, 76, 4, 44, 29, 23, 17, 24, 8, 1, 67, 70, 73, 32, 19, 11, 5,
+ 9, 0, 69, 73, 83, 79, 11, 2, 0, 67, 65, 75, 79, 87, 65, 38, 22, 14,
+ 6, 13, 0, 67, 69, 75, 62, 83, 74, 66, 66, 69, 1, 7, 8, 67, 6, 12,
+ 12, 77, 71, 72, 4, 12, 4, 2, 11, 16, 18, 67, 3, 14, 14, 77, 72, 78,
+ 85, 79, 71, 77, 72, 74, 70, 67, 72, 72, 71, 66, 73, 74, 81, 88, 73, 98,
+ 76, 66, 70, 6, 69, 65, 12, 66, 68, 66, 9, 72, 71, 88, 34, 35, 37, 31,
+ 22, 32, 28, 24, 22, 20, 20, 16, 65, 66, 73, 9, 10, 2, 75, 0, 64, 71,
+ 72, 73, 73, 75, 89, 83, 90, 42, 41, 39, 36, 27, 28, 25, 16, 19, 14, 12,
+ 2, 64, 70, 78, 21, 23, 64, 22, 24, 13, 7, 8, 5, 2, 4, 65, 71, 75,
+ 79, 84, 95, 69, 79, 89, 93, 80, 85, 67, 68, 67, 33, 6, 5, 68, 15, 45,
+ 31, 51, 7, 41, 36, 16, 1, 71, 76, 102, 105, 111, 70, 42, 28, 19, 9, 12,
+ 2, 65, 68, 77, 84, 76, 66, 71, 4, 6, 64, 64, 6, 9, 10, 5, 14, 13,
+ 1, 41, 37, 28, 21, 15, 9, 74, 81, 88, 116, 105, 81, 62, 62, 62, 62},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, 53, 14, 6, 65,
+ 7, 16, 0, 68, 66, 77, 93, 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0,
+ 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, 76, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 52, 7,
+ 69, 99, 80, 82, 1, 72, 83, 76, 88, 65, 83, 79, 78, 95, 95, 96, 97, 20,
+ 64, 4, 82, 65, 80, 73, 78, 72, 87, 79, 94, 14, 73, 64, 89, 81, 69, 72,
+ 1, 7, 2, 64, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, 12, 19, 8, 17,
+ 17, 11, 67, 11, 2, 64, 4, 84, 86, 75, 79, 69, 74, 71, 5, 69, 71, 65,
+ 0, 71, 72, 65, 88, 89, 75, 95, 68, 75, 6, 66, 70, 16, 1, 65, 71, 16,
+ 71, 80, 1, 91, 24, 30, 25, 24, 30, 23, 10, 26, 25, 65, 9, 12, 4, 1,
+ 72, 6, 1, 0, 4, 65, 71, 3, 65, 82, 71, 71, 78, 73, 89, 40, 45, 38,
+ 40, 38, 33, 30, 33, 26, 19, 21, 13, 3, 1, 83, 21, 17, 64, 19, 11, 10,
+ 5, 0, 66, 68, 72, 85, 70, 80, 94, 87, 100, 66, 31, 22, 14, 5, 5, 64,
+ 68, 72, 76, 5, 45, 29, 23, 17, 25, 8, 2, 67, 69, 72, 33, 20, 11, 5,
+ 10, 0, 68, 73, 82, 79, 12, 2, 0, 67, 64, 74, 79, 86, 65, 39, 22, 14,
+ 6, 14, 1, 66, 68, 74, 62, 83, 74, 66, 66, 69, 1, 7, 8, 66, 6, 12,
+ 12, 77, 71, 72, 3, 13, 3, 1, 10, 15, 18, 68, 2, 13, 14, 78, 73, 78,
+ 84, 79, 70, 76, 72, 73, 70, 66, 72, 72, 71, 66, 74, 74, 81, 87, 72, 98,
+ 76, 65, 70, 6, 69, 65, 13, 66, 68, 66, 10, 72, 72, 89, 33, 35, 36, 30,
+ 21, 31, 27, 23, 21, 19, 19, 15, 66, 67, 74, 7, 8, 1, 77, 64, 65, 72,
+ 73, 74, 73, 75, 89, 83, 89, 40, 39, 37, 33, 24, 26, 23, 13, 17, 12, 10,
+ 0, 66, 72, 79, 19, 21, 65, 20, 22, 11, 5, 6, 3, 0, 2, 67, 74, 77,
+ 81, 86, 96, 71, 81, 90, 92, 79, 84, 67, 67, 66, 35, 7, 6, 68, 16, 46,
+ 33, 52, 7, 39, 34, 13, 65, 74, 79, 105, 107, 112, 70, 42, 28, 19, 9, 12,
+ 2, 65, 68, 77, 83, 75, 65, 70, 5, 7, 64, 0, 7, 10, 11, 6, 14, 14,
+ 1, 39, 35, 26, 19, 13, 7, 76, 83, 89, 115, 104, 81, 62, 62, 62, 62},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, 53, 14, 8, 65,
+ 7, 17, 0, 69, 66, 78, 94, 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0,
+ 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, 75, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 52, 7,
+ 69, 98, 80, 82, 1, 71, 81, 74, 86, 64, 81, 78, 76, 94, 94, 95, 96, 21,
+ 64, 5, 82, 64, 79, 73, 76, 72, 86, 79, 93, 14, 73, 64, 87, 81, 68, 71,
+ 1, 7, 2, 0, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, 12, 19, 7, 17,
+ 17, 11, 69, 11, 2, 66, 3, 85, 86, 74, 79, 69, 73, 71, 6, 69, 71, 65,
+ 2, 71, 72, 65, 89, 88, 74, 95, 68, 75, 7, 65, 71, 16, 1, 65, 72, 17,
+ 72, 81, 1, 92, 23, 29, 25, 24, 29, 23, 10, 25, 24, 66, 8, 12, 4, 1,
+ 72, 5, 0, 64, 3, 65, 72, 2, 65, 84, 72, 71, 79, 74, 89, 39, 43, 37,
+ 38, 36, 31, 28, 31, 24, 16, 19, 11, 0, 65, 86, 19, 15, 65, 17, 8, 7,
+ 2, 65, 69, 70, 75, 87, 71, 82, 95, 88, 100, 65, 32, 22, 15, 5, 5, 64,
+ 68, 72, 75, 5, 45, 30, 23, 17, 26, 9, 2, 66, 69, 71, 34, 20, 12, 5,
+ 11, 1, 68, 72, 81, 78, 13, 3, 1, 67, 64, 74, 78, 84, 64, 39, 22, 14,
+ 7, 14, 1, 65, 68, 73, 62, 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12,
+ 13, 77, 71, 73, 3, 13, 2, 0, 9, 14, 18, 69, 1, 13, 14, 78, 74, 79,
+ 83, 78, 69, 76, 71, 73, 69, 66, 72, 71, 70, 65, 74, 74, 81, 87, 71, 98,
+ 76, 65, 70, 7, 69, 65, 14, 67, 68, 66, 10, 73, 72, 90, 32, 34, 36, 29,
+ 20, 31, 27, 22, 20, 19, 18, 14, 67, 68, 75, 6, 7, 64, 79, 66, 67, 73,
+ 73, 74, 73, 75, 88, 84, 88, 38, 37, 35, 31, 21, 24, 21, 11, 15, 9, 8,
+ 66, 68, 73, 79, 18, 20, 67, 18, 19, 9, 3, 4, 1, 65, 64, 69, 76, 79,
+ 83, 87, 98, 73, 83, 92, 91, 78, 83, 66, 66, 65, 36, 8, 7, 68, 17, 48,
+ 34, 54, 8, 38, 33, 11, 68, 77, 81, 108, 109, 114, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 76, 82, 75, 64, 69, 6, 7, 0, 1, 7, 10, 11, 6, 15, 14,
+ 1, 38, 34, 24, 17, 12, 6, 79, 84, 90, 114, 102, 80, 62, 62, 62, 62},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, 53, 14, 10, 65,
+ 8, 18, 0, 70, 66, 79, 95, 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0,
+ 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, 75, 88,
+ 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 52, 7,
+ 69, 97, 79, 82, 2, 70, 79, 72, 85, 0, 79, 77, 74, 93, 94, 94, 95, 21,
+ 64, 6, 81, 64, 79, 72, 74, 72, 86, 78, 92, 14, 73, 0, 86, 80, 67, 71,
+ 1, 7, 2, 0, 14, 11, 75, 64, 1, 65, 2, 74, 12, 64, 11, 19, 6, 17,
+ 17, 11, 71, 11, 1, 68, 2, 86, 85, 73, 78, 68, 73, 70, 7, 68, 70, 64,
+ 3, 71, 72, 65, 90, 88, 73, 95, 68, 75, 8, 65, 72, 17, 1, 65, 73, 18,
+ 72, 82, 1, 93, 21, 28, 24, 23, 28, 22, 9, 24, 24, 68, 7, 11, 4, 1,
+ 73, 4, 64, 65, 2, 66, 73, 1, 66, 86, 73, 72, 80, 75, 89, 37, 42, 35,
+ 36, 34, 29, 26, 29, 21, 14, 17, 8, 65, 67, 88, 17, 13, 67, 15, 6, 5,
+ 0, 67, 71, 73, 77, 90, 72, 84, 96, 89, 100, 65, 32, 22, 15, 5, 5, 64,
+ 68, 72, 75, 5, 45, 30, 23, 17, 27, 9, 3, 66, 68, 71, 35, 21, 12, 5,
+ 11, 1, 67, 72, 80, 77, 14, 4, 1, 67, 0, 73, 77, 83, 64, 39, 22, 14,
+ 7, 15, 2, 65, 67, 72, 62, 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12,
+ 13, 77, 71, 73, 2, 14, 1, 64, 8, 13, 18, 71, 0, 13, 14, 79, 75, 79,
+ 83, 77, 68, 75, 71, 72, 69, 65, 73, 71, 70, 65, 75, 74, 81, 86, 70, 98,
+ 76, 65, 70, 8, 69, 65, 15, 67, 69, 66, 11, 74, 72, 91, 31, 34, 35, 28,
+ 19, 30, 26, 21, 19, 18, 17, 13, 68, 69, 76, 4, 6, 65, 81, 67, 68, 74,
+ 74, 75, 73, 75, 88, 84, 88, 35, 34, 33, 29, 18, 22, 19, 8, 13, 7, 6,
+ 68, 70, 75, 80, 16, 18, 68, 16, 17, 7, 1, 1, 64, 67, 66, 71, 79, 81,
+ 85, 89, 99, 75, 85, 93, 90, 77, 82, 65, 65, 64, 38, 9, 8, 68, 18, 49,
+ 36, 55, 9, 36, 31, 8, 71, 80, 84, 111, 111, 115, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 76, 81, 74, 0, 69, 7, 8, 0, 2, 8, 11, 12, 6, 15, 14,
+ 1, 37, 32, 22, 15, 10, 4, 81, 86, 91, 113, 101, 79, 62, 62, 62, 62},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, 53, 14, 13, 66,
+ 9, 18, 0, 70, 65, 80, 96, 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0,
+ 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 52, 7,
+ 69, 96, 78, 82, 2, 68, 78, 70, 83, 1, 78, 75, 72, 92, 93, 93, 95, 22,
+ 64, 7, 80, 64, 78, 71, 72, 72, 86, 78, 90, 15, 72, 0, 85, 80, 67, 71,
+ 2, 8, 3, 1, 14, 11, 75, 65, 1, 65, 2, 74, 12, 64, 10, 19, 6, 17,
+ 17, 10, 73, 11, 1, 69, 1, 87, 84, 72, 77, 67, 72, 69, 8, 67, 70, 0,
+ 4, 71, 72, 64, 91, 87, 72, 95, 67, 75, 8, 65, 73, 18, 1, 65, 75, 19,
+ 73, 83, 1, 93, 20, 27, 24, 22, 27, 21, 8, 24, 24, 69, 6, 11, 4, 1,
+ 73, 4, 64, 66, 2, 67, 74, 1, 67, 88, 74, 73, 81, 76, 89, 35, 41, 33,
+ 34, 33, 27, 23, 27, 19, 12, 15, 6, 68, 69, 91, 15, 12, 69, 12, 4, 3,
+ 65, 70, 73, 76, 79, 92, 73, 85, 98, 89, 100, 65, 32, 23, 15, 5, 5, 64,
+ 68, 72, 74, 6, 46, 30, 23, 17, 28, 10, 4, 66, 67, 70, 36, 22, 12, 6,
+ 12, 2, 67, 71, 79, 77, 16, 4, 1, 66, 1, 72, 77, 82, 0, 40, 23, 14,
+ 7, 16, 3, 64, 66, 71, 62, 82, 73, 64, 66, 69, 1, 7, 8, 65, 7, 13,
+ 14, 77, 71, 73, 1, 14, 0, 65, 7, 13, 18, 72, 64, 12, 14, 80, 76, 80,
+ 82, 77, 67, 75, 70, 72, 68, 64, 73, 71, 70, 65, 76, 74, 81, 86, 69, 98,
+ 76, 64, 70, 8, 69, 65, 16, 67, 69, 66, 12, 74, 73, 91, 30, 34, 35, 28,
+ 18, 29, 25, 20, 19, 17, 16, 12, 69, 70, 77, 3, 4, 67, 83, 68, 69, 75,
+ 75, 75, 73, 74, 88, 85, 87, 33, 32, 31, 26, 16, 20, 17, 6, 11, 5, 4,
+ 70, 72, 76, 81, 14, 16, 69, 14, 15, 5, 64, 64, 66, 69, 68, 73, 81, 83,
+ 87, 91, 100, 77, 87, 95, 89, 75, 81, 65, 64, 0, 40, 10, 9, 68, 19, 51,
+ 37, 57, 9, 35, 29, 6, 74, 82, 87, 113, 113, 116, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 75, 80, 73, 1, 68, 8, 9, 1, 3, 9, 12, 13, 7, 16, 15,
+ 1, 35, 31, 21, 14, 8, 2, 83, 88, 92, 112, 100, 79, 62, 62, 62, 62},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, 53, 14, 15, 66,
+ 10, 19, 0, 71, 65, 81, 97, 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0,
+ 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 52, 7,
+ 69, 95, 77, 82, 3, 67, 76, 68, 82, 2, 76, 74, 70, 91, 92, 92, 94, 23,
+ 64, 8, 79, 64, 78, 71, 70, 72, 85, 77, 89, 15, 72, 1, 83, 79, 66, 71,
+ 2, 8, 3, 2, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, 10, 19, 5, 17,
+ 17, 10, 75, 11, 0, 71, 0, 88, 83, 71, 76, 66, 71, 69, 9, 67, 69, 1,
+ 5, 71, 72, 64, 92, 87, 71, 95, 67, 75, 9, 65, 74, 19, 1, 65, 76, 20,
+ 73, 84, 1, 94, 18, 26, 23, 21, 26, 20, 8, 23, 23, 70, 5, 11, 4, 1,
+ 74, 3, 65, 67, 1, 68, 75, 0, 67, 90, 75, 73, 82, 77, 89, 34, 39, 32,
+ 32, 31, 25, 21, 25, 16, 9, 13, 3, 70, 72, 93, 13, 10, 70, 10, 2, 0,
+ 68, 72, 76, 78, 81, 95, 74, 87, 99, 90, 100, 65, 33, 23, 15, 5, 5, 64,
+ 68, 72, 74, 6, 46, 30, 23, 17, 29, 10, 4, 65, 67, 69, 37, 22, 13, 6,
+ 13, 2, 66, 71, 78, 76, 17, 5, 2, 66, 2, 71, 76, 81, 0, 40, 23, 14,
+ 7, 17, 3, 0, 65, 70, 62, 81, 72, 64, 66, 69, 1, 7, 8, 65, 7, 13,
+ 14, 77, 71, 73, 1, 15, 64, 66, 6, 12, 18, 73, 65, 12, 14, 80, 77, 80,
+ 81, 76, 66, 74, 70, 71, 68, 0, 73, 71, 70, 64, 76, 74, 81, 85, 68, 98,
+ 76, 64, 70, 9, 69, 65, 17, 67, 69, 66, 13, 75, 73, 92, 29, 33, 34, 27,
+ 17, 28, 24, 19, 18, 16, 15, 11, 70, 71, 78, 1, 3, 68, 85, 70, 70, 76,
+ 75, 76, 73, 74, 88, 85, 86, 31, 30, 29, 24, 13, 18, 15, 3, 9, 3, 2,
+ 73, 74, 78, 82, 12, 15, 71, 12, 13, 3, 66, 66, 68, 71, 70, 75, 84, 85,
+ 89, 93, 101, 79, 89, 96, 88, 74, 80, 64, 0, 1, 41, 11, 10, 68, 20, 52,
+ 39, 58, 10, 33, 28, 3, 77, 85, 90, 116, 115, 117, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 75, 79, 72, 2, 67, 9, 9, 1, 4, 9, 12, 13, 7, 16, 15,
+ 1, 34, 29, 19, 12, 6, 0, 85, 90, 93, 111, 98, 78, 62, 62, 62, 62},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, 53, 14, 17, 66,
+ 11, 20, 0, 72, 65, 82, 98, 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0,
+ 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 52, 7,
+ 69, 94, 76, 82, 3, 66, 74, 66, 80, 3, 74, 73, 68, 90, 91, 91, 93, 24,
+ 64, 9, 78, 64, 77, 70, 68, 72, 85, 77, 88, 15, 72, 1, 82, 79, 65, 71,
+ 2, 8, 3, 3, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, 9, 19, 4, 17,
+ 17, 10, 77, 11, 0, 73, 64, 89, 82, 70, 75, 65, 70, 68, 10, 66, 69, 2,
+ 6, 71, 72, 64, 93, 86, 70, 95, 67, 75, 10, 65, 75, 20, 1, 65, 77, 21,
+ 74, 85, 1, 95, 17, 25, 23, 20, 25, 19, 7, 22, 23, 71, 4, 11, 4, 1,
+ 74, 2, 66, 68, 0, 69, 76, 64, 68, 92, 76, 74, 83, 78, 89, 32, 38, 30,
+ 30, 29, 23, 19, 23, 14, 7, 11, 1, 73, 74, 96, 11, 8, 72, 8, 0, 65,
+ 70, 74, 78, 81, 83, 97, 75, 89, 100, 91, 100, 65, 33, 23, 15, 5, 5, 64,
+ 68, 72, 73, 6, 46, 30, 23, 17, 30, 11, 5, 65, 66, 68, 38, 23, 13, 6,
+ 14, 3, 66, 70, 77, 75, 18, 6, 2, 66, 3, 70, 75, 80, 1, 40, 23, 14,
+ 7, 18, 4, 1, 64, 69, 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13,
+ 15, 77, 71, 73, 0, 15, 65, 67, 5, 11, 18, 74, 66, 12, 14, 81, 78, 81,
+ 80, 75, 65, 74, 69, 71, 67, 1, 73, 71, 70, 64, 77, 74, 81, 85, 67, 98,
+ 76, 64, 70, 10, 69, 65, 18, 67, 69, 66, 14, 76, 73, 93, 28, 33, 34, 26,
+ 16, 27, 23, 18, 17, 15, 14, 10, 71, 72, 79, 0, 2, 70, 87, 71, 71, 77,
+ 76, 76, 73, 74, 88, 86, 85, 29, 28, 27, 22, 10, 16, 13, 1, 7, 1, 0,
+ 75, 76, 79, 83, 10, 13, 72, 10, 11, 1, 68, 68, 70, 73, 72, 77, 86, 87,
+ 91, 95, 102, 81, 91, 98, 87, 73, 79, 0, 1, 2, 43, 12, 11, 68, 21, 54,
+ 40, 60, 11, 32, 26, 1, 80, 88, 93, 119, 117, 118, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 74, 78, 71, 3, 66, 10, 10, 2, 5, 10, 13, 14, 7, 17, 15,
+ 1, 33, 28, 17, 10, 4, 65, 87, 92, 94, 110, 97, 77, 62, 62, 62, 62},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, 52, 14, 19, 67,
+ 11, 20, 64, 73, 65, 84, 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, 64,
+ 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, 77, 75, 88,
+ 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 52, 6,
+ 69, 93, 76, 82, 3, 65, 73, 65, 79, 4, 73, 72, 67, 89, 91, 90, 93, 24,
+ 64, 9, 78, 64, 77, 70, 67, 72, 85, 77, 87, 15, 72, 1, 81, 79, 65, 71,
+ 2, 8, 3, 3, 15, 12, 77, 66, 1, 66, 2, 74, 11, 66, 8, 19, 3, 16,
+ 17, 9, 79, 10, 64, 75, 65, 90, 82, 70, 75, 65, 70, 68, 11, 66, 69, 2,
+ 7, 72, 72, 64, 95, 86, 70, 95, 67, 76, 10, 65, 76, 20, 1, 65, 79, 21,
+ 75, 86, 1, 96, 15, 24, 22, 19, 24, 18, 6, 21, 22, 73, 3, 10, 3, 1,
+ 75, 1, 67, 69, 64, 70, 77, 65, 69, 94, 78, 75, 85, 80, 89, 30, 36, 28,
+ 28, 27, 20, 16, 20, 11, 4, 8, 65, 76, 77, 99, 9, 6, 74, 5, 66, 68,
+ 73, 77, 81, 84, 86, 100, 76, 91, 102, 92, 101, 65, 33, 23, 15, 5, 5, 65,
+ 68, 72, 73, 6, 46, 30, 23, 17, 31, 11, 5, 65, 66, 68, 38, 23, 13, 6,
+ 14, 3, 66, 70, 76, 75, 19, 6, 2, 66, 3, 70, 75, 79, 1, 40, 23, 14,
+ 7, 18, 4, 1, 64, 69, 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13,
+ 15, 77, 71, 74, 64, 15, 66, 68, 4, 10, 17, 76, 68, 11, 13, 82, 80, 82,
+ 80, 75, 64, 74, 69, 71, 67, 1, 74, 71, 70, 64, 78, 74, 81, 85, 67, 99,
+ 76, 64, 70, 10, 70, 65, 18, 68, 70, 66, 14, 77, 74, 94, 27, 32, 33, 25,
+ 14, 26, 22, 17, 16, 14, 13, 9, 72, 74, 81, 65, 0, 72, 89, 73, 73, 78,
+ 77, 77, 73, 74, 88, 87, 85, 26, 25, 25, 19, 7, 13, 10, 65, 4, 65, 66,
+ 78, 79, 81, 84, 8, 11, 74, 8, 8, 65, 71, 71, 73, 75, 75, 80, 89, 89,
+ 94, 97, 104, 83, 93, 100, 86, 72, 78, 0, 1, 2, 44, 12, 11, 68, 21, 55,
+ 41, 61, 11, 30, 24, 65, 84, 91, 96, 122, 120, 120, 69, 42, 27, 18, 9, 12,
+ 2, 66, 68, 74, 78, 71, 3, 66, 11, 10, 2, 5, 10, 13, 14, 7, 17, 15,
+ 0, 31, 26, 15, 8, 2, 67, 90, 94, 95, 110, 96, 77, 62, 62, 62, 62},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, 52, 14, 22, 67,
+ 12, 21, 64, 73, 64, 85, 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, 64,
+ 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 52, 6,
+ 69, 91, 75, 82, 4, 0, 71, 0, 77, 6, 71, 70, 65, 87, 90, 89, 92, 25,
+ 0, 10, 77, 0, 76, 69, 65, 71, 84, 76, 85, 16, 71, 2, 79, 78, 64, 70,
+ 3, 9, 4, 4, 16, 13, 77, 66, 2, 66, 2, 73, 11, 66, 8, 19, 3, 16,
+ 17, 9, 80, 10, 64, 76, 66, 90, 81, 69, 74, 64, 69, 67, 12, 65, 68, 3,
+ 9, 72, 72, 0, 96, 85, 69, 95, 66, 76, 11, 64, 76, 21, 1, 65, 80, 22,
+ 75, 87, 1, 96, 14, 24, 22, 19, 24, 18, 6, 21, 22, 74, 3, 10, 3, 1,
+ 75, 1, 67, 69, 64, 70, 78, 65, 69, 95, 79, 75, 86, 81, 89, 29, 35, 27,
+ 27, 26, 18, 14, 18, 9, 2, 6, 67, 78, 79, 101, 8, 5, 75, 3, 68, 70,
+ 75, 79, 83, 86, 88, 102, 76, 92, 103, 92, 101, 64, 34, 24, 16, 6, 5, 65,
+ 67, 71, 72, 7, 47, 31, 24, 17, 32, 12, 6, 64, 65, 67, 39, 24, 14, 7,
+ 15, 4, 65, 69, 74, 74, 21, 7, 3, 65, 4, 69, 74, 77, 2, 41, 24, 15,
+ 8, 19, 5, 2, 0, 68, 62, 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14,
+ 16, 76, 71, 74, 64, 16, 66, 68, 3, 10, 17, 77, 69, 11, 13, 82, 81, 82,
+ 79, 74, 0, 73, 68, 70, 66, 2, 74, 70, 69, 0, 78, 73, 80, 84, 66, 99,
+ 76, 0, 70, 11, 70, 65, 19, 68, 70, 65, 15, 77, 74, 94, 27, 32, 33, 25,
+ 13, 26, 22, 17, 16, 14, 13, 9, 72, 75, 82, 66, 64, 73, 90, 74, 74, 78,
+ 77, 77, 72, 73, 87, 87, 84, 24, 23, 23, 17, 5, 11, 8, 67, 2, 67, 68,
+ 80, 81, 82, 84, 7, 10, 75, 7, 6, 67, 73, 73, 75, 77, 77, 82, 91, 90,
+ 96, 98, 105, 84, 94, 101, 84, 70, 76, 1, 2, 3, 46, 13, 12, 68, 22, 57,
+ 43, 62, 12, 29, 23, 67, 87, 93, 98, 124, 122, 121, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 73, 77, 70, 4, 65, 13, 11, 3, 6, 11, 14, 15, 8, 18, 16,
+ 0, 30, 25, 14, 7, 1, 68, 92, 95, 95, 109, 94, 76, 62, 62, 62, 62},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, 52, 14, 24, 67,
+ 13, 22, 64, 74, 64, 86, 102, 1, 2, 122, 124, 123, 34, 2, 69, 13, 22, 64,
+ 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 52, 6,
+ 69, 90, 74, 82, 4, 1, 69, 2, 76, 7, 69, 69, 0, 86, 89, 88, 91, 26,
+ 0, 11, 76, 0, 76, 68, 0, 71, 84, 76, 84, 16, 71, 2, 78, 78, 0, 70,
+ 3, 9, 4, 5, 16, 13, 78, 66, 2, 66, 2, 73, 11, 66, 7, 19, 2, 16,
+ 17, 9, 82, 10, 64, 78, 67, 91, 80, 68, 73, 0, 68, 66, 13, 64, 68, 4,
+ 10, 72, 72, 0, 97, 85, 68, 95, 66, 76, 12, 64, 77, 22, 1, 65, 81, 23,
+ 76, 88, 1, 97, 12, 23, 21, 18, 23, 17, 5, 20, 22, 75, 2, 10, 3, 1,
+ 75, 0, 68, 70, 65, 71, 79, 66, 70, 97, 80, 76, 87, 82, 89, 27, 34, 25,
+ 25, 24, 16, 12, 16, 6, 0, 4, 70, 81, 81, 104, 6, 3, 77, 1, 70, 72,
+ 77, 81, 85, 89, 90, 104, 77, 94, 104, 93, 101, 64, 34, 24, 16, 6, 5, 65,
+ 67, 71, 71, 7, 47, 31, 24, 17, 33, 12, 7, 64, 64, 66, 40, 25, 14, 7,
+ 16, 4, 65, 68, 73, 73, 22, 8, 3, 65, 5, 68, 73, 76, 2, 41, 24, 15,
+ 8, 20, 6, 3, 1, 67, 62, 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14,
+ 17, 76, 71, 74, 65, 16, 67, 69, 2, 9, 17, 78, 70, 11, 13, 83, 82, 83,
+ 78, 73, 1, 73, 68, 70, 65, 3, 74, 70, 69, 0, 79, 73, 80, 84, 65, 99,
+ 76, 0, 70, 12, 70, 65, 20, 68, 70, 65, 16, 78, 74, 95, 26, 32, 33, 24,
+ 12, 25, 21, 16, 15, 13, 12, 8, 73, 76, 83, 68, 65, 75, 92, 75, 75, 79,
+ 78, 77, 72, 73, 87, 88, 83, 22, 21, 21, 15, 2, 9, 6, 70, 0, 69, 70,
+ 82, 83, 83, 85, 5, 8, 76, 5, 4, 69, 75, 75, 77, 79, 79, 84, 93, 92,
+ 98, 100, 106, 86, 96, 103, 83, 69, 75, 2, 3, 4, 48, 14, 13, 68, 23, 58,
+ 44, 62, 13, 28, 21, 70, 90, 96, 101, 126, 124, 122, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 72, 76, 69, 5, 64, 14, 12, 4, 7, 12, 15, 16, 8, 19, 16,
+ 0, 29, 23, 12, 5, 64, 70, 94, 97, 96, 108, 93, 75, 62, 62, 62, 62},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, 18, 52, 14, 26, 67,
+ 14, 23, 64, 75, 64, 87, 103, 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, 64,
+ 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, 64, 77, 74, 88,
+ 12, 0, 65, 69, 7, 3, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 52, 6,
+ 69, 89, 73, 82, 5, 2, 67, 4, 74, 8, 67, 68, 2, 85, 88, 87, 90, 27,
+ 0, 12, 75, 0, 75, 68, 2, 71, 83, 75, 83, 16, 71, 3, 76, 77, 1, 70,
+ 3, 9, 4, 6, 17, 14, 78, 66, 2, 66, 2, 73, 11, 67, 7, 19, 1, 16,
+ 17, 9, 84, 10, 65, 80, 68, 92, 79, 67, 72, 1, 67, 66, 14, 64, 67, 5,
+ 11, 72, 72, 0, 98, 84, 67, 95, 66, 76, 13, 64, 78, 23, 1, 65, 82, 24,
+ 76, 89, 1, 98, 11, 22, 21, 17, 22, 16, 5, 19, 21, 76, 1, 10, 3, 1,
+ 76, 64, 69, 71, 66, 72, 80, 67, 70, 99, 81, 76, 88, 83, 89, 26, 32, 24,
+ 23, 22, 14, 10, 14, 4, 66, 2, 72, 83, 84, 106, 4, 1, 78, 64, 72, 75,
+ 80, 83, 88, 91, 92, 107, 78, 96, 105, 94, 101, 64, 35, 24, 16, 6, 5, 65,
+ 67, 71, 71, 7, 47, 31, 24, 17, 34, 13, 7, 0, 64, 65, 41, 25, 15, 7,
+ 17, 5, 64, 68, 72, 72, 23, 9, 4, 65, 6, 67, 72, 75, 3, 41, 24, 15,
+ 8, 21, 6, 4, 2, 66, 62, 79, 70, 2, 66, 68, 1, 8, 9, 64, 8, 14,
+ 17, 76, 71, 74, 65, 17, 68, 70, 1, 8, 17, 79, 71, 11, 13, 83, 83, 83,
+ 77, 72, 2, 72, 67, 69, 65, 4, 74, 70, 69, 1, 79, 73, 80, 83, 64, 99,
+ 76, 0, 70, 13, 70, 65, 21, 68, 70, 65, 17, 79, 74, 96, 25, 31, 32, 23,
+ 11, 24, 20, 15, 14, 12, 11, 7, 74, 77, 84, 69, 66, 76, 94, 77, 76, 80,
+ 78, 78, 72, 73, 87, 88, 82, 20, 19, 19, 13, 64, 7, 4, 72, 65, 71, 72,
+ 85, 85, 85, 86, 3, 7, 78, 3, 2, 71, 77, 77, 79, 81, 81, 86, 96, 94,
+ 100, 102, 107, 88, 98, 104, 82, 68, 74, 3, 4, 5, 49, 15, 14, 68, 24, 60,
+ 46, 62, 14, 26, 20, 72, 93, 99, 104, 126, 126, 123, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 72, 75, 68, 6, 0, 15, 12, 4, 8, 12, 15, 16, 8, 19, 16,
+ 0, 28, 22, 10, 3, 66, 72, 96, 99, 97, 107, 91, 74, 62, 62, 62, 62},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, 16, 52, 14,
+ 29, 68, 15, 23, 64, 76, 64, 88, 104, 0, 65, 125, 126, 124, 40, 4,
+ 69, 15, 23, 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5,
+ 69, 71, 65, 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, 0,
+ 1, 95, 97, 7, 70, 68, 52, 6, 69, 88, 72, 82, 5, 4, 66, 6,
+ 73, 9, 66, 66, 4, 84, 88, 86, 90, 27, 0, 13, 74, 0, 75, 67,
+ 4, 71, 83, 75, 82, 16, 70, 3, 75, 77, 1, 70, 4, 9, 4, 6,
+ 17, 14, 79, 67, 2, 66, 2, 73, 11, 67, 6, 19, 1, 16, 17, 8,
+ 86, 10, 65, 82, 69, 93, 78, 66, 71, 2, 67, 65, 15, 0, 67, 6,
+ 12, 72, 72, 1, 99, 84, 66, 95, 66, 76, 13, 64, 79, 24, 1, 65,
+ 84, 25, 77, 90, 1, 99, 9, 21, 20, 16, 21, 15, 4, 18, 21, 78,
+ 0, 9, 3, 1, 76, 65, 69, 72, 66, 73, 81, 68, 71, 101, 82, 77,
+ 89, 84, 89, 24, 31, 22, 21, 20, 12, 7, 12, 1, 68, 0, 75, 86,
+ 86, 109, 2, 0, 80, 67, 74, 77, 82, 86, 90, 94, 94, 109, 79, 97,
+ 107, 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31,
+ 24, 17, 35, 13, 8, 0, 0, 65, 42, 26, 15, 7, 17, 5, 64, 67,
+ 71, 72, 24, 9, 4, 65, 7, 66, 72, 74, 3, 42, 24, 15, 8, 22,
+ 7, 4, 3, 65, 62, 79, 70, 2, 66, 68, 1, 8, 9, 0, 8, 14,
+ 18, 76, 71, 74, 66, 17, 69, 71, 0, 7, 17, 81, 72, 10, 13, 84,
+ 84, 84, 77, 72, 3, 72, 67, 69, 64, 5, 75, 70, 69, 1, 80, 73,
+ 80, 83, 0, 99, 76, 1, 70, 13, 70, 65, 22, 68, 71, 65, 18, 79,
+ 75, 97, 24, 31, 32, 22, 10, 23, 19, 14, 13, 11, 10, 6, 75, 78,
+ 85, 71, 68, 78, 96, 78, 77, 81, 79, 78, 72, 73, 87, 89, 82, 17,
+ 16, 17, 10, 67, 5, 2, 75, 67, 73, 74, 87, 87, 86, 87, 1, 5,
+ 79, 1, 0, 73, 79, 80, 81, 83, 83, 88, 98, 96, 102, 104, 108, 90,
+ 100, 106, 81, 67, 73, 3, 5, 6, 51, 16, 15, 68, 25, 61, 47, 62,
+ 14, 25, 18, 75, 96, 102, 107, 126, 126, 124, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 71, 74, 67, 7, 0, 16, 13, 5, 9, 13, 16, 17, 9,
+ 20, 17, 0, 26, 20, 8, 1, 68, 74, 98, 101, 98, 106, 90, 74, 62,
+ 62, 62, 62},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, 52, 14,
+ 31, 68, 16, 24, 64, 76, 0, 89, 105, 0, 67, 126, 126, 124, 43, 6,
+ 69, 16, 24, 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, 5,
+ 69, 70, 65, 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0,
+ 1, 95, 97, 8, 71, 68, 52, 6, 69, 87, 71, 82, 6, 5, 64, 8,
+ 71, 10, 64, 65, 6, 83, 87, 85, 89, 28, 0, 14, 73, 0, 74, 66,
+ 6, 71, 83, 74, 80, 17, 70, 4, 74, 76, 2, 70, 4, 10, 5, 7,
+ 18, 15, 79, 67, 2, 66, 2, 73, 11, 68, 5, 19, 0, 16, 17, 8,
+ 88, 10, 66, 83, 70, 94, 77, 65, 70, 3, 66, 64, 16, 1, 66, 7,
+ 13, 72, 72, 1, 100, 83, 65, 95, 65, 76, 14, 64, 80, 25, 1, 65,
+ 85, 26, 77, 91, 1, 99, 8, 20, 20, 15, 20, 14, 3, 18, 21, 79,
+ 64, 9, 3, 1, 77, 65, 70, 73, 67, 74, 82, 68, 72, 103, 83, 78,
+ 90, 85, 89, 22, 30, 20, 19, 19, 10, 5, 10, 64, 70, 65, 77, 88,
+ 88, 111, 0, 65, 82, 69, 76, 79, 84, 88, 92, 97, 96, 112, 80, 99,
+ 108, 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31,
+ 24, 17, 36, 14, 9, 0, 1, 64, 43, 27, 15, 8, 18, 6, 0, 67,
+ 70, 71, 26, 10, 4, 64, 8, 65, 71, 73, 4, 42, 25, 15, 8, 23,
+ 8, 5, 4, 64, 62, 79, 70, 3, 66, 68, 1, 8, 9, 0, 8, 15,
+ 18, 76, 71, 74, 67, 18, 70, 72, 64, 7, 17, 82, 73, 10, 13, 85,
+ 85, 84, 76, 71, 4, 71, 66, 68, 64, 6, 75, 70, 69, 1, 81, 73,
+ 80, 82, 1, 99, 76, 1, 70, 14, 70, 65, 23, 68, 71, 65, 19, 80,
+ 75, 97, 23, 31, 31, 22, 9, 22, 18, 13, 13, 10, 9, 5, 76, 79,
+ 86, 72, 69, 79, 98, 79, 78, 82, 80, 79, 72, 72, 87, 89, 81, 15,
+ 14, 15, 8, 69, 3, 0, 77, 69, 75, 76, 89, 89, 88, 88, 64, 3,
+ 80, 64, 65, 75, 81, 82, 83, 85, 85, 90, 101, 98, 104, 106, 109, 92,
+ 102, 107, 80, 65, 72, 4, 6, 7, 53, 17, 16, 68, 26, 62, 49, 62,
+ 15, 23, 16, 77, 99, 104, 110, 126, 126, 125, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 71, 73, 66, 8, 1, 17, 14, 5, 10, 14, 17, 18, 9,
+ 20, 17, 0, 25, 19, 7, 0, 70, 76, 100, 103, 99, 105, 89, 73, 62,
+ 62, 62, 62},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, 52, 14,
+ 33, 68, 16, 25, 64, 77, 0, 90, 106, 64, 68, 126, 126, 125, 46, 7,
+ 69, 16, 25, 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, 5,
+ 68, 70, 65, 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0,
+ 2, 95, 97, 8, 71, 69, 52, 6, 69, 86, 71, 82, 6, 6, 1, 10,
+ 70, 11, 1, 64, 8, 82, 86, 84, 88, 29, 0, 15, 73, 1, 74, 66,
+ 8, 71, 82, 74, 79, 17, 70, 4, 72, 76, 3, 69, 4, 10, 5, 8,
+ 18, 15, 80, 67, 2, 66, 2, 73, 11, 68, 5, 19, 64, 16, 17, 8,
+ 90, 10, 66, 85, 71, 95, 77, 64, 70, 3, 65, 64, 17, 1, 66, 7,
+ 15, 72, 72, 1, 101, 83, 64, 95, 65, 76, 15, 0, 81, 25, 1, 65,
+ 86, 27, 78, 92, 1, 100, 6, 19, 19, 15, 19, 14, 3, 17, 20, 80,
+ 65, 9, 3, 1, 77, 66, 71, 74, 68, 74, 83, 69, 72, 105, 84, 78,
+ 91, 86, 89, 21, 28, 19, 17, 17, 8, 3, 8, 67, 73, 67, 80, 91,
+ 91, 114, 65, 67, 83, 71, 79, 82, 87, 90, 95, 99, 99, 114, 81, 101,
+ 109, 96, 101, 0, 36, 25, 17, 6, 5, 65, 67, 71, 69, 8, 48, 32,
+ 24, 17, 37, 14, 9, 1, 1, 0, 44, 27, 16, 8, 19, 6, 0, 66,
+ 69, 70, 27, 11, 5, 64, 8, 65, 70, 71, 4, 42, 25, 15, 9, 23,
+ 8, 6, 4, 0, 62, 78, 69, 3, 66, 68, 1, 8, 9, 0, 9, 15,
+ 19, 76, 71, 75, 67, 18, 71, 73, 65, 6, 17, 83, 74, 10, 13, 85,
+ 86, 85, 75, 70, 5, 71, 66, 68, 0, 6, 75, 69, 68, 2, 81, 73,
+ 80, 82, 2, 99, 76, 1, 70, 15, 70, 65, 24, 69, 71, 65, 19, 81,
+ 75, 98, 22, 30, 31, 21, 8, 22, 18, 12, 12, 10, 8, 4, 77, 80,
+ 87, 74, 70, 81, 100, 81, 80, 83, 80, 79, 72, 72, 86, 90, 80, 13,
+ 12, 13, 6, 72, 1, 65, 80, 71, 78, 78, 92, 91, 89, 88, 65, 2,
+ 82, 66, 68, 77, 83, 84, 85, 87, 88, 92, 103, 100, 106, 107, 111, 94,
+ 104, 109, 79, 64, 71, 5, 7, 8, 54, 18, 17, 68, 27, 62, 50, 62,
+ 16, 22, 15, 80, 102, 107, 112, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 70, 72, 66, 9, 2, 18, 14, 6, 11, 14, 17, 18, 9,
+ 21, 17, 0, 24, 17, 5, 65, 71, 77, 103, 104, 100, 104, 87, 72, 62,
+ 62, 62, 62},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, 52, 14,
+ 36, 69, 17, 25, 64, 78, 0, 91, 107, 64, 70, 126, 126, 125, 49, 8,
+ 69, 17, 25, 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5,
+ 68, 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 52, 6, 69, 85, 70, 82, 7, 8, 2, 12,
+ 68, 12, 2, 1, 10, 81, 85, 83, 88, 30, 0, 16, 72, 1, 73, 65,
+ 10, 71, 82, 73, 78, 17, 69, 5, 71, 75, 3, 69, 5, 10, 5, 9,
+ 19, 16, 80, 68, 2, 66, 2, 73, 11, 69, 4, 19, 64, 16, 17, 7,
+ 92, 10, 67, 87, 72, 96, 76, 0, 69, 4, 64, 0, 18, 2, 65, 8,
+ 16, 72, 72, 2, 102, 82, 0, 95, 65, 76, 15, 0, 82, 26, 1, 65,
+ 88, 28, 78, 93, 1, 101, 5, 18, 19, 14, 18, 13, 2, 16, 20, 81,
+ 66, 9, 3, 1, 78, 67, 71, 75, 68, 75, 84, 70, 73, 107, 85, 79,
+ 92, 87, 89, 19, 27, 17, 15, 15, 6, 0, 6, 69, 75, 69, 82, 93,
+ 93, 116, 67, 68, 85, 74, 81, 84, 89, 93, 97, 102, 101, 117, 82, 102,
+ 111, 97, 101, 0, 36, 26, 17, 6, 5, 65, 67, 71, 69, 9, 49, 32,
+ 24, 17, 38, 15, 10, 1, 2, 1, 45, 28, 16, 8, 20, 7, 1, 66,
+ 68, 70, 28, 11, 5, 64, 9, 64, 70, 70, 5, 43, 25, 15, 9, 24,
+ 9, 7, 5, 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15,
+ 19, 76, 71, 75, 68, 19, 72, 74, 66, 5, 17, 84, 75, 9, 13, 86,
+ 87, 85, 74, 70, 6, 70, 65, 67, 0, 7, 75, 69, 68, 2, 82, 73,
+ 80, 81, 3, 99, 76, 2, 70, 15, 70, 65, 25, 69, 71, 65, 20, 81,
+ 76, 99, 21, 30, 30, 20, 7, 21, 17, 11, 11, 9, 7, 3, 78, 81,
+ 88, 75, 72, 82, 102, 82, 81, 84, 81, 80, 72, 72, 86, 90, 79, 11,
+ 10, 11, 3, 75, 64, 67, 82, 73, 80, 80, 94, 93, 91, 89, 67, 0,
+ 83, 68, 70, 79, 85, 86, 87, 89, 90, 94, 106, 102, 108, 109, 112, 96,
+ 106, 110, 78, 0, 70, 5, 8, 9, 56, 19, 18, 68, 28, 62, 52, 62,
+ 16, 20, 13, 82, 105, 110, 115, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 70, 71, 65, 10, 3, 19, 15, 6, 12, 15, 18, 19, 10,
+ 21, 18, 0, 22, 16, 3, 67, 73, 79, 105, 106, 101, 103, 86, 72, 62,
+ 62, 62, 62},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, 52, 14,
+ 38, 69, 18, 26, 64, 79, 0, 92, 109, 65, 72, 126, 126, 126, 51, 9,
+ 69, 18, 26, 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5,
+ 68, 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 52, 6, 69, 84, 69, 82, 7, 9, 4, 14,
+ 67, 13, 4, 2, 11, 80, 85, 82, 87, 30, 0, 17, 71, 1, 73, 65,
+ 11, 71, 82, 73, 77, 17, 69, 5, 70, 75, 4, 69, 5, 10, 5, 9,
+ 19, 16, 81, 68, 2, 66, 2, 73, 11, 69, 3, 19, 65, 16, 17, 7,
+ 94, 10, 67, 89, 73, 97, 75, 1, 68, 5, 64, 0, 19, 2, 65, 9,
+ 17, 72, 72, 2, 104, 82, 1, 95, 65, 77, 16, 0, 83, 27, 1, 65,
+ 89, 29, 79, 94, 1, 102, 3, 17, 18, 13, 17, 12, 1, 15, 19, 83,
+ 67, 8, 3, 1, 78, 68, 72, 76, 69, 76, 85, 71, 74, 109, 87, 80,
+ 93, 88, 89, 17, 25, 15, 13, 13, 4, 65, 4, 72, 78, 71, 85, 96,
+ 96, 119, 69, 70, 87, 76, 83, 87, 92, 95, 100, 105, 103, 119, 83, 104,
+ 112, 98, 102, 0, 36, 26, 17, 6, 5, 65, 67, 71, 68, 9, 49, 32,
+ 24, 17, 39, 15, 10, 1, 2, 1, 46, 28, 16, 8, 20, 7, 1, 65,
+ 67, 69, 29, 12, 5, 64, 10, 0, 69, 69, 5, 43, 25, 15, 9, 25,
+ 9, 7, 6, 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15,
+ 20, 76, 71, 75, 69, 19, 73, 75, 67, 4, 17, 86, 77, 9, 13, 87,
+ 88, 86, 74, 69, 7, 70, 65, 67, 1, 8, 76, 69, 68, 2, 83, 73,
+ 80, 81, 3, 100, 76, 2, 70, 16, 70, 65, 25, 69, 72, 65, 21, 82,
+ 76, 100, 20, 29, 30, 19, 5, 20, 16, 10, 10, 8, 6, 2, 79, 82,
+ 89, 77, 73, 84, 104, 84, 82, 85, 82, 80, 72, 72, 86, 91, 79, 8,
+ 7, 9, 1, 78, 67, 70, 85, 75, 82, 82, 97, 95, 92, 90, 69, 65,
+ 85, 70, 72, 82, 88, 89, 90, 91, 92, 97, 108, 104, 111, 111, 113, 98,
+ 108, 112, 77, 1, 69, 6, 9, 9, 57, 20, 18, 68, 28, 62, 53, 62,
+ 17, 19, 11, 85, 108, 113, 118, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 69, 71, 64, 11, 3, 20, 15, 7, 12, 15, 18, 19, 10,
+ 22, 18, 64, 21, 14, 1, 69, 75, 81, 107, 108, 102, 103, 85, 71, 62,
+ 62, 62, 62},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, 52, 14,
+ 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, 74, 126, 126, 126, 54, 11,
+ 69, 19, 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5,
+ 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 52, 6, 69, 83, 68, 82, 7, 10, 6, 16,
+ 65, 15, 6, 3, 13, 79, 84, 81, 86, 31, 1, 18, 70, 1, 72, 64,
+ 13, 71, 81, 73, 75, 18, 69, 5, 68, 75, 5, 69, 5, 11, 6, 10,
+ 19, 16, 81, 68, 3, 66, 2, 72, 11, 69, 3, 19, 66, 16, 17, 7,
+ 96, 10, 67, 90, 74, 97, 74, 2, 67, 6, 0, 1, 20, 3, 65, 10,
+ 18, 72, 72, 2, 105, 81, 2, 95, 64, 77, 17, 0, 84, 28, 1, 65,
+ 90, 30, 80, 95, 1, 102, 2, 16, 18, 12, 16, 11, 1, 15, 19, 84,
+ 68, 8, 3, 1, 78, 68, 73, 77, 70, 77, 86, 71, 74, 110, 88, 80,
+ 94, 89, 89, 16, 24, 14, 12, 12, 2, 67, 2, 74, 80, 73, 87, 99,
+ 98, 122, 70, 72, 88, 78, 85, 89, 94, 97, 102, 107, 105, 121, 83, 106,
+ 113, 98, 102, 0, 37, 26, 17, 7, 5, 65, 66, 71, 67, 9, 49, 32,
+ 25, 17, 40, 16, 11, 2, 3, 2, 47, 29, 17, 9, 21, 8, 1, 64,
+ 66, 68, 31, 13, 6, 0, 11, 1, 68, 68, 6, 43, 26, 16, 9, 26,
+ 10, 8, 7, 2, 62, 77, 68, 5, 66, 68, 1, 9, 10, 1, 9, 16,
+ 21, 76, 71, 75, 69, 19, 74, 75, 68, 4, 17, 87, 78, 9, 13, 87,
+ 89, 87, 73, 68, 8, 70, 64, 67, 2, 9, 76, 69, 68, 3, 83, 73,
+ 80, 81, 4, 100, 76, 2, 70, 17, 70, 65, 26, 69, 72, 65, 22, 83,
+ 76, 100, 19, 29, 30, 19, 4, 19, 15, 9, 10, 7, 5, 2, 79, 83,
+ 90, 78, 74, 86, 106, 85, 83, 85, 82, 80, 71, 71, 86, 92, 78, 6,
+ 5, 7, 64, 80, 69, 72, 87, 77, 84, 84, 99, 97, 93, 91, 71, 66,
+ 86, 72, 74, 84, 90, 91, 92, 93, 94, 99, 110, 105, 113, 113, 114, 100,
+ 110, 114, 76, 3, 67, 7, 10, 10, 59, 21, 19, 68, 29, 62, 54, 62,
+ 18, 18, 10, 87, 111, 115, 121, 126, 126, 126, 67, 43, 27, 18, 9, 14,
+ 2, 66, 68, 68, 70, 0, 12, 4, 22, 16, 8, 13, 16, 19, 20, 10,
+ 23, 18, 64, 20, 13, 0, 70, 77, 83, 109, 110, 102, 102, 83, 70, 62,
+ 62, 62, 62},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, 52, 14,
+ 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, 76, 126, 126, 126, 57, 12,
+ 69, 20, 27, 64, 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5,
+ 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 52, 6, 69, 82, 67, 82, 8, 12, 7, 18,
+ 64, 16, 7, 5, 15, 78, 83, 80, 86, 32, 1, 19, 69, 1, 72, 0,
+ 15, 71, 81, 72, 74, 18, 68, 6, 67, 74, 5, 69, 6, 11, 6, 11,
+ 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, 2, 19, 66, 16, 17, 6,
+ 98, 10, 68, 92, 75, 98, 73, 3, 66, 7, 1, 2, 21, 4, 64, 11,
+ 19, 72, 72, 3, 106, 81, 3, 95, 64, 77, 17, 0, 85, 29, 1, 65,
+ 92, 31, 80, 96, 1, 103, 0, 15, 17, 11, 15, 10, 0, 14, 19, 85,
+ 69, 8, 3, 1, 79, 69, 73, 78, 70, 78, 87, 72, 75, 112, 89, 81,
+ 95, 90, 89, 14, 23, 12, 10, 10, 0, 70, 0, 77, 82, 75, 90, 101,
+ 100, 124, 72, 73, 90, 81, 87, 91, 96, 100, 104, 110, 107, 124, 84, 107,
+ 115, 99, 102, 0, 37, 27, 17, 7, 5, 65, 66, 71, 67, 10, 50, 32,
+ 25, 17, 41, 16, 12, 2, 4, 3, 48, 30, 17, 9, 22, 8, 2, 64,
+ 65, 68, 32, 13, 6, 0, 12, 2, 68, 67, 6, 44, 26, 16, 9, 27,
+ 11, 9, 8, 3, 62, 77, 68, 5, 66, 68, 1, 9, 10, 2, 9, 16,
+ 21, 76, 71, 75, 70, 20, 75, 76, 69, 3, 17, 88, 79, 8, 13, 88,
+ 90, 87, 72, 68, 9, 69, 64, 66, 2, 10, 76, 69, 68, 3, 84, 73,
+ 80, 80, 5, 100, 76, 3, 70, 17, 70, 65, 27, 69, 72, 65, 23, 83,
+ 77, 101, 18, 29, 29, 18, 3, 18, 14, 8, 9, 6, 4, 1, 80, 84,
+ 91, 80, 76, 87, 108, 86, 84, 86, 83, 81, 71, 71, 86, 92, 77, 4,
+ 3, 5, 67, 83, 71, 74, 90, 79, 86, 86, 101, 99, 95, 92, 73, 68,
+ 87, 74, 76, 86, 92, 93, 94, 95, 96, 101, 113, 107, 115, 115, 115, 102,
+ 112, 115, 75, 4, 66, 7, 11, 11, 61, 22, 20, 68, 30, 62, 56, 62,
+ 18, 16, 8, 90, 114, 118, 124, 126, 126, 126, 67, 43, 27, 18, 9, 14,
+ 2, 66, 68, 68, 69, 1, 13, 5, 23, 17, 8, 14, 17, 20, 21, 11,
+ 23, 19, 64, 18, 11, 65, 72, 79, 85, 111, 112, 103, 101, 82, 70, 62,
+ 62, 62, 62},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, 52, 14,
+ 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, 77, 126, 126, 126, 60, 13,
+ 69, 20, 28, 64, 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5,
+ 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 52, 6, 69, 81, 67, 82, 8, 13, 9, 20,
+ 1, 17, 9, 6, 17, 77, 82, 79, 85, 33, 1, 20, 69, 2, 71, 0,
+ 17, 71, 80, 72, 73, 18, 68, 6, 65, 74, 6, 68, 6, 11, 6, 12,
+ 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, 2, 19, 67, 16, 17, 6,
+ 100, 10, 68, 94, 76, 99, 73, 4, 66, 7, 2, 2, 22, 4, 64, 11,
+ 21, 72, 72, 3, 107, 80, 4, 95, 64, 77, 18, 1, 86, 29, 1, 65,
+ 93, 32, 81, 97, 1, 104, 64, 14, 17, 11, 14, 10, 0, 13, 18, 86,
+ 70, 8, 3, 1, 79, 70, 74, 79, 71, 78, 88, 73, 75, 114, 90, 81,
+ 96, 91, 89, 13, 21, 11, 8, 8, 65, 72, 65, 79, 85, 77, 92, 104,
+ 103, 126, 74, 75, 91, 83, 90, 94, 99, 102, 107, 112, 110, 126, 85, 109,
+ 116, 100, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, 10, 50, 33,
+ 25, 17, 42, 17, 12, 3, 4, 4, 49, 30, 18, 9, 23, 9, 2, 0,
+ 64, 67, 33, 14, 7, 0, 12, 2, 67, 65, 7, 44, 26, 16, 10, 27,
+ 11, 10, 8, 4, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, 16,
+ 22, 76, 71, 76, 70, 20, 76, 77, 70, 2, 17, 89, 80, 8, 13, 88,
+ 91, 88, 71, 67, 10, 69, 0, 66, 3, 10, 76, 68, 67, 4, 84, 73,
+ 80, 80, 6, 100, 76, 3, 70, 18, 70, 65, 28, 70, 72, 65, 23, 84,
+ 77, 102, 17, 28, 29, 17, 2, 18, 14, 7, 8, 6, 3, 0, 81, 85,
+ 92, 81, 77, 89, 110, 88, 86, 87, 83, 81, 71, 71, 85, 93, 76, 2,
+ 1, 3, 69, 86, 73, 76, 92, 81, 89, 88, 104, 101, 96, 92, 74, 69,
+ 89, 76, 79, 88, 94, 95, 96, 97, 99, 103, 115, 109, 117, 116, 117, 104,
+ 114, 117, 74, 5, 65, 8, 12, 12, 62, 23, 21, 68, 31, 62, 57, 62,
+ 19, 15, 7, 92, 117, 121, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 67, 68, 1, 14, 6, 24, 17, 9, 15, 17, 20, 21, 11,
+ 24, 19, 64, 17, 10, 67, 74, 80, 86, 114, 113, 104, 100, 80, 69, 62,
+ 62, 62, 62},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, 52, 14,
+ 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, 79, 126, 126, 126, 62, 14,
+ 69, 21, 29, 64, 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5,
+ 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 52, 6, 69, 80, 66, 82, 9, 14, 11, 22,
+ 2, 18, 11, 7, 19, 76, 82, 78, 84, 33, 1, 21, 68, 2, 71, 1,
+ 19, 71, 80, 71, 72, 18, 68, 7, 64, 73, 7, 68, 6, 11, 6, 12,
+ 21, 18, 83, 69, 3, 66, 2, 72, 11, 71, 1, 19, 68, 16, 17, 6,
+ 102, 10, 69, 96, 77, 100, 72, 5, 65, 8, 2, 3, 23, 5, 0, 12,
+ 22, 72, 72, 3, 108, 80, 5, 95, 64, 77, 19, 1, 87, 30, 1, 65,
+ 94, 33, 81, 98, 1, 105, 66, 13, 16, 10, 13, 9, 64, 12, 18, 88,
+ 71, 7, 3, 1, 80, 71, 75, 80, 72, 79, 89, 74, 76, 116, 91, 82,
+ 97, 92, 89, 11, 20, 9, 6, 6, 67, 74, 67, 82, 87, 79, 95, 106,
+ 105, 126, 76, 77, 93, 85, 92, 96, 101, 104, 109, 115, 112, 126, 86, 111,
+ 117, 101, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, 10, 50, 33,
+ 25, 17, 43, 17, 13, 3, 5, 4, 50, 31, 18, 9, 23, 9, 3, 0,
+ 0, 66, 34, 15, 7, 0, 13, 3, 66, 64, 7, 44, 26, 16, 10, 28,
+ 12, 10, 9, 5, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, 16,
+ 22, 76, 71, 76, 71, 21, 77, 78, 71, 1, 17, 91, 81, 8, 13, 89,
+ 92, 88, 71, 66, 11, 68, 0, 65, 3, 11, 77, 68, 67, 4, 85, 73,
+ 80, 79, 7, 100, 76, 3, 70, 19, 70, 65, 29, 70, 73, 65, 24, 85,
+ 77, 103, 16, 28, 28, 16, 1, 17, 13, 6, 7, 5, 2, 64, 82, 86,
+ 93, 83, 78, 90, 112, 89, 87, 88, 84, 82, 71, 71, 85, 93, 76, 64,
+ 65, 1, 71, 89, 75, 78, 95, 83, 91, 90, 106, 103, 98, 93, 76, 71,
+ 90, 78, 81, 90, 96, 98, 98, 99, 101, 105, 118, 111, 119, 118, 118, 106,
+ 116, 118, 73, 6, 64, 9, 13, 13, 62, 24, 22, 68, 32, 62, 59, 62,
+ 20, 13, 5, 95, 120, 124, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 67, 67, 2, 15, 6, 25, 18, 9, 16, 18, 21, 22, 11,
+ 24, 19, 64, 16, 8, 69, 76, 82, 88, 116, 115, 105, 99, 79, 68, 62,
+ 62, 62, 62},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, 52, 14,
+ 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, 81, 126, 126, 126, 62, 16,
+ 69, 22, 29, 64, 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 52, 6, 69, 79, 65, 82, 9, 16, 12, 24,
+ 4, 19, 12, 9, 21, 75, 81, 77, 84, 34, 1, 22, 67, 2, 70, 2,
+ 21, 71, 80, 71, 70, 19, 67, 7, 0, 73, 7, 68, 7, 12, 7, 13,
+ 21, 18, 83, 70, 3, 66, 2, 72, 11, 71, 0, 19, 68, 16, 17, 5,
+ 104, 10, 69, 97, 78, 101, 71, 6, 64, 9, 3, 4, 24, 6, 0, 13,
+ 23, 72, 72, 4, 109, 79, 6, 95, 0, 77, 19, 1, 88, 31, 1, 65,
+ 96, 34, 82, 99, 1, 105, 67, 12, 16, 9, 12, 8, 65, 12, 18, 89,
+ 72, 7, 3, 1, 80, 71, 75, 81, 72, 80, 90, 74, 77, 118, 92, 83,
+ 98, 93, 89, 9, 19, 7, 4, 5, 69, 77, 69, 84, 89, 81, 97, 109,
+ 107, 126, 78, 78, 95, 88, 94, 98, 103, 107, 111, 118, 114, 126, 87, 112,
+ 119, 101, 102, 1, 38, 28, 18, 7, 5, 65, 66, 71, 65, 11, 51, 33,
+ 25, 17, 44, 18, 14, 3, 6, 5, 51, 32, 18, 10, 24, 10, 3, 1,
+ 1, 66, 36, 15, 7, 1, 14, 4, 66, 0, 8, 45, 27, 16, 10, 29,
+ 13, 11, 10, 6, 62, 76, 67, 7, 66, 68, 1, 9, 10, 3, 10, 17,
+ 23, 76, 71, 76, 72, 21, 78, 79, 72, 1, 17, 92, 82, 7, 13, 90,
+ 93, 89, 70, 66, 12, 68, 1, 65, 4, 12, 77, 68, 67, 4, 86, 73,
+ 80, 79, 8, 100, 76, 4, 70, 19, 70, 65, 30, 70, 73, 65, 25, 85,
+ 78, 103, 15, 28, 28, 16, 0, 16, 12, 5, 7, 4, 1, 65, 83, 87,
+ 94, 84, 80, 92, 114, 90, 88, 89, 85, 82, 71, 70, 85, 94, 75, 66,
+ 67, 64, 74, 91, 77, 80, 97, 85, 93, 92, 108, 105, 99, 94, 78, 73,
+ 91, 80, 83, 92, 98, 100, 100, 101, 103, 107, 120, 113, 121, 120, 119, 108,
+ 118, 120, 72, 8, 0, 9, 14, 14, 62, 25, 23, 68, 33, 62, 60, 62,
+ 20, 12, 3, 97, 123, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 66, 66, 3, 16, 7, 26, 19, 10, 17, 19, 22, 23, 12,
+ 25, 20, 64, 14, 7, 70, 77, 84, 90, 118, 117, 106, 98, 78, 68, 62,
+ 62, 62, 62},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, 52, 14,
+ 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, 83, 126, 126, 126, 62, 17,
+ 69, 23, 30, 64, 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 52, 6, 69, 78, 64, 82, 10, 17, 14, 26,
+ 5, 20, 14, 10, 23, 74, 80, 76, 83, 35, 1, 23, 66, 2, 70, 2,
+ 23, 71, 79, 70, 69, 19, 67, 8, 2, 72, 8, 68, 7, 12, 7, 14,
+ 22, 19, 84, 70, 3, 66, 2, 72, 11, 72, 0, 19, 69, 16, 17, 5,
+ 106, 10, 70, 99, 79, 102, 70, 7, 0, 10, 4, 4, 25, 6, 1, 14,
+ 24, 72, 72, 4, 110, 79, 7, 95, 0, 77, 20, 1, 89, 32, 1, 65,
+ 97, 35, 82, 100, 1, 106, 69, 11, 15, 8, 11, 7, 65, 11, 17, 90,
+ 73, 7, 3, 1, 81, 72, 76, 82, 73, 81, 91, 75, 77, 120, 93, 83,
+ 99, 94, 89, 8, 17, 6, 2, 3, 71, 79, 71, 87, 92, 83, 100, 111,
+ 110, 126, 80, 80, 96, 90, 96, 101, 106, 109, 114, 120, 116, 126, 88, 114,
+ 120, 102, 102, 1, 39, 28, 18, 7, 5, 65, 66, 71, 65, 11, 51, 33,
+ 25, 17, 45, 18, 14, 4, 6, 6, 52, 32, 19, 10, 25, 10, 4, 1,
+ 2, 65, 37, 16, 8, 1, 15, 5, 65, 1, 8, 45, 27, 16, 10, 30,
+ 13, 12, 11, 7, 62, 75, 66, 7, 66, 68, 1, 9, 10, 3, 10, 17,
+ 23, 76, 71, 76, 72, 22, 79, 80, 73, 0, 17, 93, 83, 7, 13, 90,
+ 94, 89, 69, 65, 13, 67, 1, 64, 4, 13, 77, 68, 67, 5, 86, 73,
+ 80, 78, 9, 100, 76, 4, 70, 20, 70, 65, 31, 70, 73, 65, 26, 86,
+ 78, 104, 14, 27, 27, 15, 64, 15, 11, 4, 6, 3, 0, 66, 84, 88,
+ 95, 86, 81, 93, 116, 92, 89, 90, 85, 83, 71, 70, 85, 94, 74, 68,
+ 69, 66, 76, 94, 79, 82, 100, 87, 95, 94, 111, 107, 101, 95, 80, 74,
+ 93, 82, 85, 94, 100, 102, 102, 103, 105, 109, 123, 115, 123, 122, 120, 110,
+ 120, 121, 71, 9, 1, 10, 15, 15, 62, 26, 24, 68, 34, 62, 62, 62,
+ 21, 10, 2, 100, 126, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 66, 65, 4, 17, 8, 27, 19, 10, 18, 19, 22, 23, 12,
+ 25, 20, 64, 13, 5, 72, 79, 86, 92, 120, 119, 107, 97, 76, 67, 62,
+ 62, 62, 62},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, 2, 52, 14,
+ 54, 71, 24, 31, 64, 84, 2, 99, 116, 69, 85, 126, 126, 126, 62, 18,
+ 69, 24, 31, 64, 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5,
+ 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 52, 6, 69, 77, 0, 82, 10, 18, 16, 28,
+ 7, 21, 16, 11, 25, 73, 79, 75, 82, 36, 1, 24, 65, 2, 69, 3,
+ 25, 71, 79, 70, 68, 19, 67, 8, 3, 72, 9, 68, 7, 12, 7, 15,
+ 22, 19, 84, 70, 3, 66, 2, 72, 11, 72, 64, 19, 70, 16, 17, 5,
+ 108, 10, 70, 101, 80, 103, 69, 8, 1, 11, 5, 5, 26, 7, 1, 15,
+ 25, 72, 72, 4, 111, 78, 8, 95, 0, 77, 21, 1, 90, 33, 1, 65,
+ 98, 36, 83, 101, 1, 107, 70, 10, 15, 7, 10, 6, 66, 10, 17, 91,
+ 74, 7, 3, 1, 81, 73, 77, 83, 74, 82, 92, 76, 78, 122, 94, 84,
+ 100, 95, 89, 6, 16, 4, 0, 1, 73, 81, 73, 89, 94, 85, 102, 114,
+ 112, 126, 82, 82, 98, 92, 98, 103, 108, 111, 116, 123, 118, 126, 89, 116,
+ 121, 103, 102, 1, 39, 28, 18, 7, 5, 65, 66, 71, 64, 11, 51, 33,
+ 25, 17, 46, 19, 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2,
+ 3, 64, 38, 17, 8, 1, 16, 6, 64, 2, 9, 45, 27, 16, 10, 31,
+ 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, 10, 3, 10, 17,
+ 24, 76, 71, 76, 73, 22, 80, 81, 74, 64, 17, 94, 84, 7, 13, 91,
+ 95, 90, 68, 64, 14, 67, 2, 64, 5, 14, 77, 68, 67, 5, 87, 73,
+ 80, 78, 10, 100, 76, 4, 70, 21, 70, 65, 32, 70, 73, 65, 27, 87,
+ 78, 105, 13, 27, 27, 14, 65, 14, 10, 3, 5, 2, 64, 67, 85, 89,
+ 96, 87, 82, 95, 118, 93, 90, 91, 86, 83, 71, 70, 85, 95, 73, 70,
+ 71, 68, 78, 97, 81, 84, 102, 89, 97, 96, 113, 109, 102, 96, 82, 76,
+ 94, 84, 87, 96, 102, 104, 104, 105, 107, 111, 125, 117, 125, 124, 121, 112,
+ 122, 123, 70, 10, 2, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, 62,
+ 22, 9, 0, 102, 126, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 65, 64, 5, 18, 9, 28, 20, 11, 19, 20, 23, 24, 12,
+ 26, 20, 64, 12, 4, 74, 81, 88, 94, 122, 121, 108, 96, 75, 66, 62,
+ 62, 62, 62},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, 0, 51, 14,
+ 56, 72, 24, 31, 65, 85, 2, 101, 118, 70, 87, 126, 126, 126, 62, 19,
+ 70, 24, 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5,
+ 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 52, 5, 69, 76, 0, 82, 10, 19, 17, 29,
+ 8, 22, 17, 12, 26, 72, 79, 74, 82, 36, 1, 24, 65, 2, 69, 3,
+ 26, 71, 79, 70, 67, 19, 67, 8, 4, 72, 9, 68, 7, 12, 7, 15,
+ 22, 19, 85, 71, 3, 67, 2, 72, 10, 73, 65, 19, 71, 15, 17, 4,
+ 110, 9, 71, 103, 81, 104, 69, 8, 1, 11, 5, 5, 27, 7, 1, 15,
+ 26, 73, 72, 4, 113, 78, 8, 95, 0, 78, 21, 1, 91, 33, 1, 65,
+ 100, 36, 84, 102, 1, 108, 72, 9, 14, 6, 9, 5, 67, 9, 16, 93,
+ 75, 6, 2, 1, 82, 74, 78, 84, 75, 83, 93, 77, 79, 124, 96, 85,
+ 102, 97, 89, 4, 14, 2, 65, 64, 76, 84, 76, 92, 97, 88, 105, 117,
+ 115, 126, 84, 84, 100, 95, 101, 106, 111, 114, 119, 126, 121, 126, 90, 118,
+ 123, 104, 103, 1, 39, 28, 18, 7, 5, 66, 66, 71, 64, 11, 51, 33,
+ 25, 17, 47, 19, 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2,
+ 4, 64, 39, 17, 8, 1, 16, 6, 64, 3, 9, 45, 27, 16, 10, 31,
+ 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, 10, 3, 10, 17,
+ 24, 76, 71, 77, 74, 22, 81, 82, 75, 65, 16, 96, 86, 6, 12, 92,
+ 97, 91, 68, 64, 15, 67, 2, 64, 5, 14, 78, 68, 67, 5, 88, 73,
+ 80, 78, 10, 101, 76, 4, 70, 21, 71, 65, 32, 71, 74, 65, 27, 88,
+ 79, 106, 12, 26, 26, 13, 67, 13, 9, 2, 4, 1, 65, 68, 86, 91,
+ 98, 89, 84, 97, 120, 95, 92, 92, 87, 84, 71, 70, 85, 96, 73, 73,
+ 74, 70, 81, 100, 84, 87, 105, 92, 100, 99, 116, 112, 104, 97, 84, 78,
+ 96, 86, 90, 99, 105, 107, 107, 107, 110, 114, 126, 119, 126, 126, 123, 114,
+ 124, 125, 69, 11, 3, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, 62,
+ 22, 7, 65, 105, 126, 126, 126, 126, 126, 126, 66, 43, 26, 17, 9, 14,
+ 2, 67, 68, 65, 64, 5, 18, 9, 29, 20, 11, 19, 20, 23, 24, 12,
+ 26, 20, 65, 10, 2, 76, 83, 90, 96, 125, 123, 109, 96, 74, 66, 62,
+ 62, 62, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, 64, 51, 14,
+ 59, 72, 25, 32, 65, 85, 3, 102, 119, 70, 88, 126, 126, 126, 62, 21,
+ 70, 25, 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5,
+ 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 52, 5, 69, 74, 1, 82, 11, 21, 19, 31,
+ 10, 24, 19, 14, 28, 70, 78, 73, 81, 37, 2, 25, 64, 3, 68, 4,
+ 28, 70, 78, 69, 65, 20, 66, 9, 6, 71, 10, 67, 8, 13, 8, 16,
+ 23, 20, 85, 71, 4, 67, 2, 71, 10, 73, 65, 19, 71, 15, 17, 4,
+ 111, 9, 71, 104, 82, 104, 68, 9, 2, 12, 6, 6, 28, 8, 2, 16,
+ 28, 73, 72, 5, 114, 77, 9, 95, 1, 78, 22, 2, 91, 34, 1, 65,
+ 101, 37, 84, 103, 1, 108, 73, 9, 14, 6, 9, 5, 67, 9, 16, 94,
+ 75, 6, 2, 1, 82, 74, 78, 84, 75, 83, 94, 77, 79, 125, 97, 85,
+ 103, 98, 89, 3, 13, 1, 66, 65, 78, 86, 78, 94, 99, 90, 107, 119,
+ 117, 126, 85, 85, 101, 97, 103, 108, 113, 116, 121, 126, 123, 126, 90, 119,
+ 124, 104, 103, 2, 40, 29, 19, 8, 5, 66, 65, 70, 0, 12, 52, 34,
+ 26, 17, 48, 20, 16, 5, 8, 8, 54, 34, 20, 11, 27, 12, 5, 3,
+ 6, 0, 41, 18, 9, 2, 17, 7, 0, 5, 10, 46, 28, 17, 11, 32,
+ 15, 14, 13, 9, 62, 74, 65, 9, 66, 67, 1, 10, 11, 4, 11, 18,
+ 25, 75, 71, 77, 74, 23, 81, 82, 76, 65, 16, 97, 87, 6, 12, 92,
+ 98, 91, 67, 0, 16, 66, 3, 0, 6, 15, 78, 67, 66, 6, 88, 72,
+ 79, 77, 11, 101, 76, 5, 70, 22, 71, 65, 33, 71, 74, 64, 28, 88,
+ 79, 106, 12, 26, 26, 13, 68, 13, 9, 2, 4, 1, 65, 68, 86, 92,
+ 99, 90, 85, 98, 121, 96, 93, 92, 87, 84, 70, 69, 84, 96, 72, 75,
+ 76, 72, 83, 102, 86, 89, 107, 94, 102, 101, 118, 114, 105, 97, 85, 79,
+ 97, 87, 92, 101, 107, 109, 109, 109, 112, 116, 126, 120, 126, 126, 124, 115,
+ 125, 126, 67, 13, 5, 12, 17, 17, 62, 28, 26, 68, 36, 62, 62, 62,
+ 23, 6, 66, 107, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 64, 0, 6, 19, 10, 31, 21, 12, 20, 21, 24, 25, 13,
+ 27, 21, 65, 9, 1, 77, 84, 91, 97, 126, 124, 109, 95, 72, 65, 62,
+ 62, 62, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, 65, 51, 14,
+ 61, 72, 26, 33, 65, 86, 3, 103, 120, 71, 90, 126, 126, 126, 62, 22,
+ 70, 26, 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 52, 5, 69, 73, 2, 82, 11, 22, 21, 33,
+ 11, 25, 21, 15, 30, 69, 77, 72, 80, 38, 2, 26, 0, 3, 68, 5,
+ 30, 70, 78, 69, 64, 20, 66, 9, 7, 71, 11, 67, 8, 13, 8, 17,
+ 23, 20, 86, 71, 4, 67, 2, 71, 10, 73, 66, 19, 72, 15, 17, 4,
+ 113, 9, 71, 106, 83, 105, 67, 10, 3, 13, 7, 7, 29, 9, 2, 17,
+ 29, 73, 72, 5, 115, 77, 10, 95, 1, 78, 23, 2, 92, 35, 1, 65,
+ 102, 38, 85, 104, 1, 109, 75, 8, 13, 5, 8, 4, 68, 8, 16, 95,
+ 76, 6, 2, 1, 82, 75, 79, 85, 76, 84, 95, 78, 80, 126, 98, 86,
+ 104, 99, 89, 1, 12, 64, 68, 67, 80, 88, 80, 97, 101, 92, 110, 122,
+ 119, 126, 87, 87, 103, 99, 105, 110, 115, 118, 123, 126, 125, 126, 91, 121,
+ 125, 105, 103, 2, 40, 29, 19, 8, 5, 66, 65, 70, 1, 12, 52, 34,
+ 26, 17, 49, 20, 17, 5, 9, 9, 55, 35, 20, 11, 28, 12, 5, 4,
+ 7, 1, 42, 19, 9, 2, 18, 8, 1, 6, 10, 46, 28, 17, 11, 33,
+ 16, 15, 14, 10, 62, 74, 65, 9, 66, 67, 1, 10, 11, 4, 11, 18,
+ 26, 75, 71, 77, 75, 23, 82, 83, 77, 66, 16, 98, 88, 6, 12, 93,
+ 99, 92, 66, 1, 17, 66, 3, 0, 7, 16, 78, 67, 66, 6, 89, 72,
+ 79, 77, 12, 101, 76, 5, 70, 23, 71, 65, 34, 71, 74, 64, 29, 89,
+ 79, 107, 11, 26, 26, 12, 69, 12, 8, 1, 3, 0, 66, 69, 87, 93,
+ 100, 92, 86, 100, 123, 97, 94, 93, 88, 84, 70, 69, 84, 97, 71, 77,
+ 78, 74, 85, 105, 88, 91, 110, 96, 104, 103, 120, 116, 106, 98, 87, 81,
+ 98, 89, 94, 103, 109, 111, 111, 111, 114, 118, 126, 122, 126, 126, 125, 117,
+ 126, 126, 66, 14, 6, 13, 18, 18, 62, 29, 27, 68, 37, 62, 62, 62,
+ 24, 5, 68, 110, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 0, 1, 7, 20, 11, 32, 22, 13, 21, 22, 25, 26, 13,
+ 28, 21, 65, 8, 64, 79, 86, 93, 99, 126, 126, 110, 94, 71, 64, 62,
+ 62, 62, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, 66, 51, 14,
+ 62, 72, 27, 34, 65, 87, 3, 104, 121, 71, 92, 126, 126, 126, 62, 23,
+ 70, 27, 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 52, 5, 69, 72, 3, 82, 12, 23, 23, 35,
+ 13, 26, 23, 16, 32, 68, 76, 71, 79, 39, 2, 27, 1, 3, 67, 5,
+ 32, 70, 77, 68, 0, 20, 66, 10, 9, 70, 12, 67, 8, 13, 8, 18,
+ 24, 21, 86, 71, 4, 67, 2, 71, 10, 74, 66, 19, 73, 15, 17, 4,
+ 115, 9, 72, 108, 84, 106, 66, 11, 4, 14, 8, 7, 30, 9, 3, 18,
+ 30, 73, 72, 5, 116, 76, 11, 95, 1, 78, 24, 2, 93, 36, 1, 65,
+ 103, 39, 85, 105, 1, 110, 76, 7, 13, 4, 7, 3, 68, 7, 15, 96,
+ 77, 6, 2, 1, 83, 76, 80, 86, 77, 85, 96, 79, 80, 126, 99, 86,
+ 105, 100, 89, 0, 10, 65, 70, 69, 82, 90, 82, 99, 104, 94, 112, 124,
+ 122, 126, 89, 89, 104, 101, 107, 113, 118, 120, 126, 126, 126, 126, 92, 123,
+ 126, 106, 103, 2, 41, 29, 19, 8, 5, 66, 65, 70, 1, 12, 52, 34,
+ 26, 17, 50, 21, 17, 6, 9, 10, 56, 35, 21, 11, 29, 13, 6, 4,
+ 8, 2, 43, 20, 10, 2, 19, 9, 2, 7, 11, 46, 28, 17, 11, 34,
+ 16, 16, 15, 11, 62, 73, 64, 10, 66, 67, 1, 10, 11, 4, 11, 18,
+ 26, 75, 71, 77, 75, 24, 83, 84, 78, 67, 16, 99, 89, 6, 12, 93,
+ 100, 92, 65, 2, 18, 65, 4, 1, 7, 17, 78, 67, 66, 7, 89, 72,
+ 79, 76, 13, 101, 76, 5, 70, 24, 71, 65, 35, 71, 74, 64, 30, 90,
+ 79, 108, 10, 25, 25, 11, 70, 11, 7, 0, 2, 64, 67, 70, 88, 94,
+ 101, 93, 87, 101, 125, 99, 95, 94, 88, 85, 70, 69, 84, 97, 70, 79,
+ 80, 76, 87, 108, 90, 93, 112, 98, 106, 105, 123, 118, 108, 99, 89, 82,
+ 100, 91, 96, 105, 111, 113, 113, 113, 116, 120, 126, 124, 126, 126, 126, 119,
+ 126, 126, 65, 15, 7, 14, 19, 19, 62, 30, 28, 68, 38, 62, 62, 62,
+ 25, 3, 69, 112, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 0, 2, 8, 21, 12, 33, 22, 13, 22, 22, 25, 26, 13,
+ 28, 21, 65, 7, 65, 81, 88, 95, 101, 126, 126, 111, 93, 69, 0, 62,
+ 62, 62, 62},
+
+ },
+
+};
diff --git a/common/svc/isvc_cabac_tables.h b/common/svc/isvc_cabac_tables.h
new file mode 100644
index 0000000..6557b07
--- /dev/null
+++ b/common/svc/isvc_cabac_tables.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file isvc_cabac_tables.h
+*
+* @brief
+* This file contains enumerations, macros and extern declarations of H264
+* cabac tables
+*
+* @author
+* Ittiam
+*
+* @remarks
+* none
+******************************************************************************
+*/
+
+#ifndef _ISVC_CABAC_TABLES_H_
+#define _ISVC_CABAC_TABLES_H_
+
+#include "ih264_cabac_tables.h"
+/**
+******************************************************************************
+* @brief max range of cabac contexts in H264 (0-459)
+******************************************************************************
+*/
+#define NUM_SVC_CABAC_CTXTS 467
+
+extern const UWORD32 (*gau4_isvc_cabac_table)[4];
+
+/*****************************************************************************/
+/* Cabac tables for context initialization depending upon type of Slice, */
+/* cabac init Idc value and Qp. */
+/*****************************************************************************/
+extern const UWORD8 gau1_isvc_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE]
+ [NUM_SVC_CABAC_CTXTS];
+
+#endif
diff --git a/common/svc/isvc_common_tables.c b/common/svc/isvc_common_tables.c
new file mode 100644
index 0000000..580a2e4
--- /dev/null
+++ b/common/svc/isvc_common_tables.c
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvc_common_tables.c
+*
+* @brief
+* Contains common global tables
+*
+* @author
+* Harish M
+*
+* @par List of Functions:
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_macros.h"
+#include "isvc_structs.h"
+#include "ih264_common_tables.h"
+#include "isvc_common_tables.h"
+
+/*****************************************************************************/
+/* Extern global definitions */
+/*****************************************************************************/
+
+/**
+ ******************************************************************************
+ * @brief while encoding, basing on the input configuration parameters, the
+ * the level of the bitstream is computed basing on the table below.
+ * input : table_idx
+ * output : level_idc or cpb size
+ * @remarks Table A-1 – level table limits
+ ******************************************************************************
+ */
+const level_tables_t gas_isvc_lvl_tbl[16] = {
+ {IH264_LEVEL_10, 1485, 99, 396, 64, 175, 64},
+ {IH264_LEVEL_1B, 1485, 99, 396, 128, 350, 64},
+ {IH264_LEVEL_11, 3000, 396, 900, 192, 500, 128},
+ {IH264_LEVEL_12, 6000, 396, 2376, 384, 1000, 128},
+ {IH264_LEVEL_13, 11880, 396, 2376, 768, 2000, 128},
+ {IH264_LEVEL_20, 11880, 396, 2376, 2000, 2000, 128},
+ {IH264_LEVEL_21, 19800, 792, 4752, 4000, 4000, 256},
+ {IH264_LEVEL_22, 20250, 1620, 8100, 4000, 4000, 256},
+ {IH264_LEVEL_30, 40500, 1620, 8100, 10000, 10000, 256},
+ {IH264_LEVEL_31, 108000, 3600, 18000, 14000, 14000, 512},
+ {IH264_LEVEL_32, 216000, 5120, 20480, 20000, 20000, 512},
+ {IH264_LEVEL_40, 245760, 8192, 32768, 20000, 25000, 512},
+ {IH264_LEVEL_41, 245760, 8192, 32768, 50000, 62500, 512},
+ {IH264_LEVEL_42, 522240, 8704, 34816, 50000, 62500, 512},
+ {IH264_LEVEL_50, 589824, 22080, 110400, 135000, 135000, 512},
+ {IH264_LEVEL_51, 983040, 36864, 184320, 240000, 240000, 512},
+};
diff --git a/common/svc/isvc_common_tables.h b/common/svc/isvc_common_tables.h
new file mode 100644
index 0000000..ed4c8f4
--- /dev/null
+++ b/common/svc/isvc_common_tables.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvc_common_tables.h
+*
+* @brief
+* Common tables
+*
+* @author
+* Harish
+*
+* @par List of Functions:
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVC_COMMON_TABLES_H_
+#define _ISVC_COMMON_TABLES_H_
+
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+
+#include "ih264_common_tables.h"
+
+extern const level_tables_t gas_isvc_lvl_tbl[16];
+
+#endif
diff --git a/common/svc/isvc_defs.h b/common/svc/isvc_defs.h
new file mode 100644
index 0000000..0b55ac4
--- /dev/null
+++ b/common/svc/isvc_defs.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvc_defs.h
+*
+* @brief
+* Contains macro defintions, and other typedefs used for SVC encoding
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVC_DEFS_H_
+#define _ISVC_DEFS_H_
+
+#define MAX_NUM_TEMPORAL_LAYERS 3
+
+#define MAX_NUM_SPATIAL_LAYERS 3
+
+#define MAX_VUI_EXT_NUM_ENTRIES (MAX_NUM_TEMPORAL_LAYERS * MAX_NUM_SPATIAL_LAYERS)
+
+#define SVC_INTER_MB (1 << 0) /*!< Intra MBs other than IPCM and I_BL */
+
+#define SVC_INTRA_MB (1 << 1) /*!< P or B MBs decoded or inferred*/
+
+#define SVC_IPCM_MB (1 << 2) /*!< IPCM_MB decoder or inferred*/
+
+#define SVC_IBL_MB (1 << 3) /*!< I_BL MB always inferred */
+
+#define SVC_INTRA_INTER_MB \
+ (1 << 4) /*!< Intra Inter MB will have an alternate prediction \
+ process*/
+
+#define MB_WIDTH_SHIFT 4
+
+#define MB_HEIGHT_SHIFT 4
+
+#define UV 1
+
+#define NUM_SP_COMPONENTS 2
+
+#define NUM_COMPONENTS 3
+
+#define SVC_EXTRACT_MB_MODE(x) ((x) &0x1F)
+
+#define GET_BIT_TX_SIZE(x, y) ((x) & (1 << (7 - (y))))
+
+typedef enum SVC_PROFILES_T
+{
+ IH264_SCALABLE_BASELINE = 83,
+ IH264_SCALABLE_HIGH_PROFILE = 86
+} SVC_PROFILES_T;
+
+typedef enum PRED_MODE_T
+{
+ L0 = 0,
+ L1 = 1,
+ BI = 2,
+ NUM_PRED_DIRS = 2,
+ INVALID_PRED_MODE = 4,
+} PRED_MODE_T;
+
+#endif
diff --git a/common/svc/isvc_inter_pred_filters.h b/common/svc/isvc_inter_pred_filters.h
new file mode 100644
index 0000000..7573560
--- /dev/null
+++ b/common/svc/isvc_inter_pred_filters.h
@@ -0,0 +1,219 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvc_inter_pred_filters.h
+ *
+ * @brief
+ * Declarations of functions used for inter prediction
+ *
+ * @author
+ * Ittiam
+ *
+ * @par List of Functions:
+ * -ih264_inter_pred_luma_copy
+ * -ih264_interleave_copy
+ * -ih264_inter_pred_luma_horz
+ * -ih264_inter_pred_luma_vert
+ * -ih264_inter_pred_luma_horz_hpel_vert_hpel
+ * -ih264_inter_pred_luma_vert_qpel
+ * -ih264_inter_pred_luma_horz_qpel
+ * -ih264_inter_pred_luma_horz_qpel_vert_qpel
+ * -ih264_inter_pred_luma_horz_qpel_vert_hpel
+ * -ih264_inter_pred_luma_horz_hpel_vert_qpel
+ * -ih264_inter_pred_luma_bilinear
+ * -ih264_inter_pred_chroma
+ * -ih264_inter_pred_luma_copy_a9q
+ * -ih264_interleave_copy_a9
+ * -ih264_inter_pred_luma_horz_a9q
+ * -ih264_inter_pred_luma_vert_a9q
+ * -ih264_inter_pred_luma_bilinear_a9q
+ * -ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q
+ * -ih264_inter_pred_luma_horz_qpel_a9q
+ * -ih264_inter_pred_luma_vert_qpel_a9q
+ * -ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q
+ * -ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q
+ * -ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q
+ * -ih264_inter_pred_chroma_a9q
+ * -ih264_inter_pred_luma_copy_av8
+ * -ih264_interleave_copy_av8
+ * -ih264_inter_pred_luma_horz_av8
+ * -ih264_inter_pred_luma_vert_av8
+ * -ih264_inter_pred_luma_bilinear_av8
+ * -ih264_inter_pred_luma_horz_hpel_vert_hpel_av8
+ * -ih264_inter_pred_luma_horz_qpel_av8
+ * -ih264_inter_pred_luma_vert_qpel_av8
+ * -ih264_inter_pred_luma_horz_qpel_vert_qpel_av8
+ * -ih264_inter_pred_luma_horz_qpel_vert_hpel_av8
+ * -ih264_inter_pred_luma_horz_hpel_vert_qpel_av8
+ * -ih264_inter_pred_chroma_av8
+ * -ih264_inter_pred_chroma_dx_zero_av8
+ * -ih264_inter_pred_chroma_dy_zero_av8
+ * -ih264_inter_pred_luma_copy_ssse3
+ * -ih264_inter_pred_luma_copy_ssse3
+ * -ih264_inter_pred_luma_horz_ssse3
+ * -ih264_inter_pred_luma_vert_ssse3
+ * -ih264_inter_pred_luma_bilinear_ssse3
+ * -ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3
+ * -ih264_inter_pred_luma_horz_qpel_ssse3
+ * -ih264_inter_pred_luma_vert_qpel_ssse3
+ * -ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3
+ * -ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3
+ * -ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3
+ * -ih264_inter_pred_chroma_ssse3
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVC_INTER_PRED_FILTERS_H_
+#define _ISVC_INTER_PRED_FILTERS_H_
+
+/*****************************************************************************/
+/* Constant Data variables */
+/*****************************************************************************/
+
+extern const WORD32 ih264_g_six_tap[3]; /* coefficients for 6 tap filtering*/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+typedef void FT_INTER_PRED_LUMA(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd,
+ WORD32 ht, WORD32 wd, UWORD8 *pu1_tmp, WORD32 dydx);
+
+typedef void FT_INTERLEAVE_COPY(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd,
+ WORD32 ht, WORD32 wd);
+
+typedef void FT_INTER_PRED_LUMA_BILINEAR(UWORD8 *pu1_src1, UWORD8 *pu1_src2, UWORD8 *pu1_dst,
+ WORD32 src_strd1, WORD32 src_strd2, WORD32 dst_strd,
+ WORD32 height, WORD32 width);
+
+typedef void FT_INTER_PRED_CHROMA(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd,
+ WORD32 dst_strd, WORD32 dx, WORD32 dy, WORD32 ht, WORD32 wd);
+
+/* No NEON Declarations */
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_copy;
+
+FT_INTERLEAVE_COPY ih264_interleave_copy;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_hpel;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_qpel;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_qpel;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_hpel;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_qpel;
+
+FT_INTER_PRED_LUMA_BILINEAR ih264_inter_pred_luma_bilinear;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma;
+
+/* A9 NEON Declarations */
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_copy_a9q;
+
+FT_INTERLEAVE_COPY ih264_interleave_copy_a9;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_a9q;
+
+FT_INTER_PRED_LUMA_BILINEAR ih264_inter_pred_luma_bilinear_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_qpel_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma_a9q;
+
+/* AV8 NEON Declarations */
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_copy_av8;
+
+FT_INTERLEAVE_COPY ih264_interleave_copy_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_hpel_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_qpel_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_qpel_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_hpel_av8;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_qpel_av8;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma_av8;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma_dx_zero_av8;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma_dy_zero_av8;
+
+/* SSSE3 Intrinsic Declarations */
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_copy_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_ssse3;
+
+FT_INTER_PRED_LUMA_BILINEAR ih264_inter_pred_luma_bilinear_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_vert_qpel_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3;
+
+FT_INTER_PRED_LUMA ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3;
+
+FT_INTER_PRED_CHROMA ih264_inter_pred_chroma_ssse3;
+
+/** Nothing past this point */
+
+#endif
diff --git a/common/svc/isvc_intra_resample.c b/common/svc/isvc_intra_resample.c
new file mode 100644
index 0000000..a643b36
--- /dev/null
+++ b/common/svc/isvc_intra_resample.c
@@ -0,0 +1,3257 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_resamp_svc.c
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author
+ **************************************************************************
+ */
+#include <assert.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvc_intra_resample.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+
+#define NUM_SEGMENTS 16
+#define NUM_INTRA_SAMP_FXNS 32
+#define INTERPOL_FILTER_SIZE_LUMA 64
+#define INTERPOL_FILTER_SIZE_CHROMA 32
+
+typedef void(PF_INTRA_SAMP_PADDING)(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+static const WORD8 g_ai1_interp_filter_luma[INTERPOL_FILTER_SIZE_LUMA] = {
+ 0, -1, -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, -1, -1, -1, -1, 32, 32, 31, 30, 28, 26,
+ 24, 22, 19, 16, 14, 11, 8, 6, 4, 2, 0, 2, 4, 6, 8, 11, 14, 16, 19, 22, 24, 26,
+ 28, 30, 31, 32, 0, -1, -1, -1, -1, -1, -2, -3, -3, -3, -4, -4, -3, -3, -2, -1};
+
+static const UWORD8 g_au1_interp_filter_chroma[INTERPOL_FILTER_SIZE_CHROMA] = {
+ 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2,
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
+
+static const UWORD32 gu4_valid_segs_lookup[NUM_SEGMENTS] = {
+ 0x0F000000, 0xCF000000, 0x3F000000, 0xFF000000, 0x0F000000, 0xCF000000, 0x3F000000, 0xFF000000,
+ 0x0F000000, 0x8F000000, 0x6F000000, 0xEF000000, 0x1F000000, 0x9F000000, 0x7F000000, 0xFF000000};
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_copy_data */
+/* */
+/* Description : this module copies the data from source to destination */
+/* the amount of data to be copied is passed as input */
+/* */
+/* Inputs : pu1_src : pointer to the source buffer */
+/* u2_src_stride : source buffer stride */
+/* pu1_dst : pointer to the destination buffer */
+/* u2_dst_stride : destination buffer stride */
+/* u4_num_bytes : number of bytes to be copied */
+/* u4_num_lines : number of lines to be copied */
+/* Globals : none */
+/* Processing : it does a memcpy from source to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : both buffers are assumed to be 2-D buffers */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 29 04 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+/** \brief performs the 2-D memory transfer */
+static void isvc_copy_data(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst,
+ WORD32 i4_dst_stride, WORD32 i4_num_bytes, WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines;
+ ASSERT(NULL != pu1_src);
+ ASSERT(NULL != pu1_dst);
+
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ memcpy(pu1_dst, pu1_src, i4_num_bytes);
+ pu1_src += i4_src_stride;
+ pu1_dst += i4_dst_stride;
+ }
+}
+
+static void isvc_copy_data_semiplanr(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst1,
+ UWORD8 *pu1_dst2, WORD32 i4_dst_stride, WORD32 i4_num_bytes,
+ WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines, u4_i;
+
+ ASSERT(NULL != pu1_src);
+ ASSERT(NULL != pu1_dst1);
+ ASSERT(NULL != pu1_dst2);
+
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ for(u4_i = 0; u4_i < i4_num_bytes; u4_i++)
+ {
+ *(pu1_dst1 + u4_i) = *(pu1_src + (2 * u4_i));
+ *(pu1_dst2 + u4_i) = *(pu1_src + (2 * u4_i) + 1);
+ }
+ pu1_src += i4_src_stride;
+ pu1_dst1 += i4_dst_stride;
+ pu1_dst2 += i4_dst_stride;
+ }
+}
+
+static void isvc_left_right_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(i1_yd_index);
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + i1_xd_index;
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - i1_xd_index;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst, *pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ pu1_src += i4_refarray_stride;
+ }
+}
+
+static void isvc_left_right_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i1_yd_index);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_src_cb = pu1_dst_cb + i1_xd_index;
+
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i1_xd_index;
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_CHROMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_CHROMA);
+ pu1_dst_cb = pu1_src_cb - i1_xd_index;
+ pu1_dst_cr = pu1_src_cr - i1_xd_index;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst_cb, *pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ pu1_src_cb += i4_refarray_stride;
+
+ memset(pu1_dst_cr, *pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ pu1_src_cr += i4_refarray_stride;
+ }
+}
+
+static void isvc_top_bot_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(i1_xd_index);
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + (i1_yd_index * i4_refarray_stride);
+
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - (i1_yd_index * i4_refarray_stride);
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memcpy(pu1_dst, pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+}
+
+static void isvc_top_bot_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i1_xd_index);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_src_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i4_tmp;
+
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_CHROMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_CHROMA);
+
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_dst_cb = pu1_src_cb - i4_tmp;
+
+ pu1_dst_cr = pu1_src_cr - i4_tmp;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memcpy(pu1_dst_cb, pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+}
+
+static void isvc_diag_reconstruction(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_i;
+ UWORD8 *pu1_src_1, *pu1_src_2, *pu1_dst;
+ UWORD8 u1_filter_delay_buf[18];
+ UWORD8 u1_out_buf[16];
+ WORD32 i4_width, i4_height;
+ WORD32 i4_x_off, i4_y_off;
+ WORD32 i4_block_size = BLK_SIZE;
+
+ UNUSED(pu1_refarray_2);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src_1 = pu1_dst + i1_xd_index;
+ pu1_src_2 = pu1_dst + (i1_yd_index * i4_refarray_stride);
+
+ i4_width = MAX(u1_seg_wd, (((i4_mb_adjoin_x >> 3) ^ 1) * i4_block_size));
+ i4_height = MAX(u1_seg_ht, (((i4_mb_adjoin_y >> 4) ^ 1) * i4_block_size));
+
+ i4_x_off = (i4_width - u1_seg_wd);
+ i4_y_off = (i4_height - u1_seg_ht);
+
+ if(i1_xd_index > 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 1 Processing */
+
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf[0], pu1_src_2, (i4_width + 1));
+ for(i4_i = i4_height; i4_i > 0; i4_i--)
+ {
+ u1_filter_delay_buf[i4_width + i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_width] =
+ (u1_filter_delay_buf[i4_width - 1] + u1_filter_delay_buf[i4_width + 1] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_height - i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index < 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 2 Processing */
+ /* load the pixel in the filter delay buffer */
+ for(i4_i = 0; i4_i < (i4_height + 1); i4_i++)
+ {
+ u1_filter_delay_buf[i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ pu1_src_2 -= i4_x_off;
+ memcpy(&u1_filter_delay_buf[i4_i], pu1_src_2, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_i - 1] =
+ (u1_filter_delay_buf[i4_i] + u1_filter_delay_buf[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index < 0)
+ {
+ /* Quadrant 3 Processing */
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf[0], pu1_src_2, (i4_width + 1));
+
+ pu1_src_1 -= (i4_y_off * i4_refarray_stride);
+ for(i4_i = 1; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf[i4_width + i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_width] =
+ (u1_filter_delay_buf[i4_width - 1] + u1_filter_delay_buf[i4_width + 1] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else
+ {
+ /* Quadrant 4 Processing */
+ /* load the pixel in the filter delay buffer */
+ pu1_src_1 += ((u1_seg_ht - 1) * i4_refarray_stride);
+ for(i4_i = 0; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf[i4_i] = *pu1_src_1;
+ pu1_src_1 -= i4_refarray_stride;
+ }
+
+ pu1_src_2 -= i4_x_off;
+ memcpy(&u1_filter_delay_buf[i4_i], pu1_src_2, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_i - 1] =
+ (u1_filter_delay_buf[i4_i] + u1_filter_delay_buf[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+}
+
+static void isvc_diag_reconstruction_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_i;
+ UWORD8 u1_filter_delay_buf_cb[18], u1_filter_delay_buf_cr[18];
+ UWORD8 u1_out_buf_cb[16], u1_out_buf_cr[16];
+ WORD32 i4_width, i4_height;
+ WORD32 i4_x_off, i4_y_off;
+ WORD32 i4_block_size = BLK_SIZE >> 1;
+ UWORD8 *pu1_src_1_cb, *pu1_src_2_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_1_cr, *pu1_src_2_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+
+ pu1_src_1_cb = pu1_dst_cb + i1_xd_index;
+ pu1_src_1_cr = pu1_dst_cr + i1_xd_index;
+
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_src_2_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_2_cr = pu1_dst_cr + i4_tmp;
+
+ i4_width = MAX(u1_seg_wd, (((i4_mb_adjoin_x >> 3) ^ 1) * i4_block_size));
+ i4_height = MAX(u1_seg_ht, (((i4_mb_adjoin_y >> 4) ^ 1) * i4_block_size));
+
+ i4_x_off = (i4_width - u1_seg_wd);
+ i4_y_off = (i4_height - u1_seg_ht);
+
+ if(i1_xd_index < 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 1 Processing */
+
+ /* load the pixel in the filter delay buffer */
+ for(i4_i = 0; i4_i < (i4_height + 1); i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ pu1_src_2_cb -= i4_x_off;
+ pu1_src_2_cr -= i4_x_off;
+
+ memcpy(&u1_filter_delay_buf_cb[i4_i], pu1_src_2_cb, i4_width);
+ memcpy(&u1_filter_delay_buf_cr[i4_i], pu1_src_2_cr, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_i - 1] =
+ (u1_filter_delay_buf_cb[i4_i] + u1_filter_delay_buf_cb[i4_i - 2] + 1) >> 1;
+
+ u1_filter_delay_buf_cr[i4_i - 1] =
+ (u1_filter_delay_buf_cr[i4_i] + u1_filter_delay_buf_cr[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 2 Processing */
+
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf_cb[0], pu1_src_2_cb, (i4_width + 1));
+ memcpy(&u1_filter_delay_buf_cr[0], pu1_src_2_cr, (i4_width + 1));
+
+ for(i4_i = i4_height; i4_i > 0; i4_i--)
+ {
+ u1_filter_delay_buf_cb[i4_width + i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_width + i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_width] =
+ (u1_filter_delay_buf_cb[i4_width - 1] + u1_filter_delay_buf_cb[i4_width + 1] + 1) >>
+ 1;
+
+ u1_filter_delay_buf_cr[i4_width] =
+ (u1_filter_delay_buf_cr[i4_width - 1] + u1_filter_delay_buf_cr[i4_width + 1] + 1) >>
+ 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_height - i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_height - i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index < 0)
+ {
+ /* Quadrant 3 Processing */
+
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf_cb[0], pu1_src_2_cb, (i4_width + 1));
+ memcpy(&u1_filter_delay_buf_cr[0], pu1_src_2_cr, (i4_width + 1));
+
+ i4_tmp = (i4_y_off * i4_refarray_stride);
+ pu1_src_1_cb -= i4_tmp;
+ pu1_src_1_cr -= i4_tmp;
+ for(i4_i = 1; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_width + i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_width + i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_width] =
+ (u1_filter_delay_buf_cb[i4_width - 1] + u1_filter_delay_buf_cb[i4_width + 1] + 1) >>
+ 1;
+
+ u1_filter_delay_buf_cr[i4_width] =
+ (u1_filter_delay_buf_cr[i4_width - 1] + u1_filter_delay_buf_cr[i4_width + 1] + 1) >>
+ 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else
+ {
+ /* Quadrant 4 Processing */
+
+ /* load the pixel in the filter delay buffer */
+ i4_tmp = ((u1_seg_ht - 1) * i4_refarray_stride);
+ pu1_src_1_cb += i4_tmp;
+ pu1_src_1_cr += i4_tmp;
+
+ for(i4_i = 0; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb -= i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr -= i4_refarray_stride;
+ }
+
+ pu1_src_2_cb -= i4_x_off;
+ pu1_src_2_cr -= i4_x_off;
+
+ memcpy(&u1_filter_delay_buf_cb[i4_i], pu1_src_2_cb, i4_width);
+ memcpy(&u1_filter_delay_buf_cr[i4_i], pu1_src_2_cr, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_i - 1] =
+ (u1_filter_delay_buf_cb[i4_i] + u1_filter_delay_buf_cb[i4_i - 2] + 1) >> 1;
+
+ u1_filter_delay_buf_cr[i4_i - 1] =
+ (u1_filter_delay_buf_cr[i4_i] + u1_filter_delay_buf_cr[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+}
+
+static void isvc_diag_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + i1_xd_index + (i1_yd_index * i4_refarray_stride);
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - i1_xd_index - (i1_yd_index * i4_refarray_stride);
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst, *pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+}
+
+static void isvc_diag_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+
+ i4_tmp = i1_xd_index + (i1_yd_index * i4_refarray_stride);
+ pu1_src_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i4_tmp;
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+
+ i4_tmp = (i1_xd_index + (i1_yd_index * i4_refarray_stride));
+ pu1_dst_cb = pu1_src_cb - i4_tmp;
+ pu1_dst_cr = pu1_src_cr - i4_tmp;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst_cb, *pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memset(pu1_dst_cr, *pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+}
+
+static PF_INTRA_SAMP_PADDING *gpf_lookup_fxns_luma[NUM_INTRA_SAMP_FXNS] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &isvc_left_right_padding,
+ NULL,
+ &isvc_diag_reconstruction,
+ NULL,
+ &isvc_left_right_padding,
+ NULL,
+ &isvc_diag_reconstruction,
+ NULL,
+ NULL,
+ &isvc_top_bot_padding,
+ &isvc_diag_reconstruction,
+ NULL,
+ NULL,
+ &isvc_top_bot_padding,
+ &isvc_diag_reconstruction,
+ NULL,
+ &isvc_left_right_padding,
+ &isvc_top_bot_padding,
+ &isvc_diag_reconstruction,
+ &isvc_diag_padding,
+ &isvc_left_right_padding,
+ &isvc_top_bot_padding,
+ &isvc_diag_reconstruction,
+};
+
+static PF_INTRA_SAMP_PADDING *gpf_lookup_fxns_chroma[NUM_INTRA_SAMP_FXNS] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &isvc_left_right_padding_chroma,
+ NULL,
+ &isvc_diag_reconstruction_chroma,
+ NULL,
+ &isvc_left_right_padding_chroma,
+ NULL,
+ &isvc_diag_reconstruction_chroma,
+ NULL,
+ NULL,
+ &isvc_top_bot_padding_chroma,
+ &isvc_diag_reconstruction_chroma,
+ NULL,
+ NULL,
+ &isvc_top_bot_padding_chroma,
+ &isvc_diag_reconstruction_chroma,
+ NULL,
+ &isvc_left_right_padding_chroma,
+ &isvc_top_bot_padding_chroma,
+ &isvc_diag_reconstruction_chroma,
+ &isvc_diag_padding_chroma,
+ &isvc_left_right_padding_chroma,
+ &isvc_top_bot_padding_chroma,
+ &isvc_diag_reconstruction_chroma,
+};
+
+static void isvc_get_ref_layer_avlblty_dyadic(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_ref_mb_x,
+ WORD32 i4_ref_mb_y, WORD32 *pi4_avlblty,
+ WORD8 i1_curr_slice_id, WORD8 i1_cons_intr_samp_flag)
+{
+ WORD8 i1_mb_mode;
+
+ pi1_ref_mb_modes += (i4_ref_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_ref_mb_x * i4_element_size);
+ i1_mb_mode = *pi1_ref_mb_modes;
+ i1_mb_mode = (i1_mb_mode < 0) ? i1_mb_mode : SVC_EXTRACT_MB_MODE(*pi1_ref_mb_modes);
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ *pi4_avlblty = 0;
+ }
+ else
+ {
+ *pi4_avlblty = 1;
+ }
+
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ if(1 == *pi4_avlblty)
+ {
+ if(i1_mb_mode != i1_curr_slice_id)
+ {
+ *pi4_avlblty = 0;
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_diagonal_construct_dyadic */
+/* */
+/* Description : This function fills the unavaible pixels in the reference*/
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray : popinter to reference array */
+/* i4_refarray_wd: width of the reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : constructed pixel */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+static UWORD8 isvc_diagonal_construct_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xd_index,
+ WORD32 i4_yd_index, UWORD8 *pu1_refarray,
+ WORD32 i4_refarray_wd)
+{
+ WORD32 i4_diff_hor_ver, i4_sgn_xy;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_samp1, i4_samp2, i4_samp3;
+ WORD32 i4_result;
+ UWORD8 *pu1_tmp;
+
+ i4_diff_hor_ver = ABS(i4_xd_index) - ABS(i4_yd_index);
+ i4_sgn_xy = SIGN(i4_xd_index * i4_yd_index);
+
+ if(i4_diff_hor_ver > 0)
+ {
+ i4_xc = i4_x - (i4_sgn_xy * i4_yd_index);
+ i4_yc = i4_y - i4_yd_index;
+
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc - 1];
+ i4_samp2 = pu1_tmp[i4_xc];
+ i4_samp3 = pu1_tmp[i4_xc + 1];
+ }
+ else if(i4_diff_hor_ver < 0)
+ {
+ i4_xc = i4_x - i4_xd_index;
+ i4_yc = i4_y - (i4_sgn_xy * i4_xd_index);
+
+ pu1_tmp = pu1_refarray + ((i4_yc - 1) * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp2 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp3 = pu1_tmp[i4_xc];
+ }
+ else
+ {
+ WORD32 i4_ref_xd, i4_ref_yd;
+
+ i4_ref_xd = i4_x - i4_xd_index;
+ i4_ref_yd = i4_y - i4_yd_index;
+
+ i4_xc = i4_ref_xd + SIGN(i4_xd_index);
+ i4_yc = i4_ref_yd + SIGN(i4_yd_index);
+
+ pu1_tmp = pu1_refarray + (i4_ref_yd * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc];
+ i4_samp2 = pu1_tmp[i4_ref_xd];
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+ i4_samp3 = pu1_tmp[i4_ref_xd];
+ }
+
+ i4_result = (i4_samp1 + (i4_samp2 << 1) + i4_samp3 + 2) >> 2;
+
+ pu1_tmp = pu1_refarray + (i4_y * i4_refarray_wd);
+ /* Store the filled sample */
+ pu1_tmp[i4_x] = i4_result;
+
+ return i4_result;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_corner_samp_dyadic */
+/* */
+/* Description : This function fills the corner sample in the reference */
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray_y : pointer to luma reference array */
+/* pu1_refarray_cb : pointer to Cb reference array */
+/* pu1_refarray_cr : pointer to Cr reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+static void isvc_corner_samp_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xD, WORD32 i4_yD,
+ UWORD8 *pu1_refarray_y, UWORD8 *pu1_refarray_cb,
+ UWORD8 *pu1_refarray_cr)
+{
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_c_xc, i4_c_yc;
+ WORD32 i4_samp1, i4_samp2;
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_ref_xD = i4_x - i4_xD;
+ i4_ref_yD = i4_y - i4_yD;
+
+ i4_xc = i4_ref_xD + SIGN(i4_xD);
+ i4_yc = i4_ref_yD + SIGN(i4_yD);
+
+ /* Luma */
+ pu1_tmp_src = pu1_refarray_y + (i4_yc * DYADIC_REF_W_Y);
+ i4_samp1 = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src = pu1_refarray_y + (i4_ref_yD * DYADIC_REF_W_Y);
+ i4_samp2 = pu1_tmp_src[i4_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Chroma */
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_c_xc = i4_c_ref_xD + SIGN(i4_xD);
+ i4_c_yc = i4_c_ref_yD + SIGN(i4_yD);
+
+ /* Cb */
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Cr */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_reflayer_construction_dyadic */
+/* */
+/* Description : This function constructs the reference array buffer */
+/* for dyadic cases used for intra resampling of a */
+/* component in an MB */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_mb_mode_map : ref layer mb mode buffer desc */
+/* pu1_inp_luma : luma input (reference layer data) */
+/* pu1_inp_chroma : chroma input (reference layer data) */
+/* i4_inp_luma_stride : luma input buffer stride */
+/* i4_inp_chroma_stride : chroma input buffer stride */
+/* i4_top : indicates whether the core 8x8 reference block */
+/* is one of 0 and 1 or one of 2 and 3 */
+/* i4_left : indicates whether the core 8x8 reference block */
+/* is one of 0 and 2 or one of 1 and 3 */
+/* ps_ref_mb_coord : coordinates of the reference MB */
+/* Globals : none */
+/* Processing : it fills the reference layer data if they are falling in */
+/* INTRA MB region. If all the pixels are not filled it */
+/* calls the border extension algorithm to fill them */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 02 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+static void isvc_reflayer_construction_dyadic(void *pv_intra_samp_ctxt,
+ mem_element_t *ps_ref_mb_mode_map,
+ UWORD8 *pu1_inp_luma, UWORD8 *pu1_inp_chroma,
+ WORD32 i4_inp_luma_stride,
+ WORD32 i4_inp_chroma_stride, WORD32 i4_top,
+ WORD32 i4_left, UWORD16 u2_mb_x, UWORD16 u2_mb_y)
+{
+ enum
+ {
+ TOPLEFT_MASK = 1,
+ LEFT_MASK = 2,
+ TOP_MASK = 4,
+ TOPRIGHT_MASK = 8,
+ BOTTOMLEFT_MASK = 16
+ };
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_x0, i4_y0;
+ WORD32 i4_xc0, i4_yc0;
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_mbaddr_x;
+
+ WORD32 i4_refarray_wd_luma, i4_refarray_wd_chroma;
+ WORD32 i4_refarray_ht_luma, i4_refarray_ht_chroma;
+ WORD32 i4_avlblty;
+ WORD8 i1_cons_intr_samp_flag;
+ WORD8 i1_slice_id;
+ WORD8 i1_corner_samp_avlbl_flag;
+ UWORD8 u1_ny_avlblty;
+
+ UWORD8 *pu1_refarray_luma;
+ UWORD8 *pu1_refarray_cb, *pu1_refarray_cr;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode_map->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode_map->i4_element_size;
+
+ i1_cons_intr_samp_flag = ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag;
+
+ ASSERT(NULL != pi1_ref_mb_modes);
+
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ i4_mbaddr_x = u2_mb_x;
+ i4_mbaddr_y = u2_mb_y;
+
+ i4_refarray_wd_luma = 20;
+ i4_refarray_ht_luma = 20;
+
+ i4_refarray_wd_chroma = i4_refarray_wd_luma >> 1;
+ i4_refarray_ht_chroma = i4_refarray_ht_luma >> 1;
+
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ WORD8 *pi1_ref_mb_mode_tmp;
+ WORD8 i1_mb_mode;
+
+ pi1_ref_mb_mode_tmp = pi1_ref_mb_modes;
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_x * i4_element_size);
+ i1_mb_mode = *pi1_ref_mb_mode_tmp;
+ i1_mb_mode = (i1_mb_mode < 0) ? i1_mb_mode : SVC_EXTRACT_MB_MODE(*pi1_ref_mb_mode_tmp);
+
+ /* The reference layer MB should be intra */
+ ASSERT(i1_mb_mode >= 0);
+
+ i1_slice_id = i1_mb_mode;
+ }
+ else
+ {
+ i1_slice_id = -1;
+ }
+
+ {
+ UWORD8 *pu1_src, *pu1_dst;
+ WORD32 i4_src_stride, i4_dst_stride;
+
+ /* Copy luma */
+ i4_src_stride = i4_inp_luma_stride;
+ i4_dst_stride = DYADIC_REF_W_Y;
+ pu1_src = pu1_inp_luma;
+ pu1_dst = pu1_refarray_luma;
+
+ isvc_copy_data(pu1_src, i4_src_stride, pu1_dst, i4_dst_stride, i4_refarray_wd_luma,
+ i4_refarray_ht_luma);
+
+ i4_src_stride = i4_inp_chroma_stride;
+ i4_dst_stride = DYADIC_REF_W_C;
+ pu1_src = pu1_inp_chroma;
+ isvc_copy_data_semiplanr(pu1_src, i4_src_stride, pu1_refarray_cb, pu1_refarray_cr,
+ i4_dst_stride, i4_refarray_wd_chroma, i4_refarray_ht_chroma);
+ }
+
+ {
+ /* mb_x + left, mb_y + top */
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty = i4_avlblty;
+
+ /* mb_x + left, mb_y */
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 1);
+
+ /* mb_x, mb_y + top */
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 2);
+
+ /* mb_x - left, mb_y + top */
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x - i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 3);
+
+ /* mb_x + left, mb_y - top */
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y - i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 4);
+ }
+
+ if((TOP_MASK | TOPLEFT_MASK | LEFT_MASK) == u1_ny_avlblty)
+ {
+ return;
+ }
+
+ if(!(u1_ny_avlblty & (TOP_MASK | TOPLEFT_MASK | LEFT_MASK)))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Set the 4 corner samples to (x-xD,y-yD) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Set the corner sample of Cb and Cr to (x-xD,y-yD) */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ }
+
+ if(!(u1_ny_avlblty & (TOP_MASK | TOPLEFT_MASK)))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD), ..., (x0+7,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), (x0+1,y0+1), ..., (x0+7,y0+1) */
+ i4_x0 = 2;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ }
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ for(i4_x = i4_x0; i4_x < i4_x0 + 8; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src[i4_x];
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src1[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src2[i4_x];
+ }
+ }
+
+ if(!(u1_ny_avlblty & (TOPLEFT_MASK | LEFT_MASK)))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0); */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1); ... ;*/
+ /* copy (ref_xD,y0+7) to (x0,y0+7) and (x0+1,y0+7) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ }
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src;
+
+ for(i4_y = i4_y0; i4_y < i4_y0 + 8; i4_y++)
+ {
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst1 += DYADIC_REF_W_Y;
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ pu1_tmp_src1 += DYADIC_REF_W_C;
+ pu1_tmp_src2 += DYADIC_REF_W_C;
+ pu1_tmp_dst1 += DYADIC_REF_W_C;
+ pu1_tmp_dst2 += DYADIC_REF_W_C;
+ }
+ }
+
+ if(!(u1_ny_avlblty & TOP_MASK))
+ {
+ if(!(u1_ny_avlblty & TOPRIGHT_MASK))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD) and (x0+1,ref_yD) to (x0,y0) and (x0+1,y0), and */
+ /* to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+ }
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x - i4_left, i4_mbaddr_y, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+ i4_ref_xD = i4_x0 - (i4_left * 7) - (i4_left >> 1);
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if not available */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvc_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvc_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+ }
+ }
+
+ if(!(u1_ny_avlblty & LEFT_MASK))
+ {
+ if(!(u1_ny_avlblty & BOTTOMLEFT_MASK))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0), (x0+1,y0), and */
+ /* copy (ref_xD,y0+1) to (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+ }
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ isvc_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x, i4_mbaddr_y - i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - (i4_top * 7) - (i4_top >> 1);
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvc_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal consrtuction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvc_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+ }
+ }
+
+ if(u1_ny_avlblty & TOPLEFT_MASK)
+ {
+ if(!(u1_ny_avlblty & LEFT_MASK))
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 4) >> 2;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ i4_ref_yD = 1;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ i4_ref_yD = 18;
+ }
+
+ i4_ref_xD = i4_x0 - (i4_left) - (i4_left >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if unavailable */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvc_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 8 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 */
+ /* (x0,y0) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0+1), ..., (x0,y0+7) and */
+ /* (x0+1,y0), ..., (x0+1,y0+6) */
+ for(i4_y = i4_y0 + 1; i4_y < i4_y0 + 8; i4_y++)
+ {
+ i4_yD++;
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ }
+
+ /* (x0+1,y0+7) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x0 + 1, i4_y0 + 7, i4_xD + 1, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 */
+ /* (x0+1,y0) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0 + 1, i4_y0, i4_xD + 1, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 7; i4_y++)
+ {
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ i4_yD++;
+ }
+
+ /* (x0,y0+7) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0, i4_y0 + 7, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_yD++;
+ }
+ }
+
+ if(!(u1_ny_avlblty & TOP_MASK))
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 2) >> 1;
+
+ i4_y0 = 9 + (i4_top << 3) + (i4_top);
+ i4_x0 = 2;
+ i4_ref_xD = 1;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ i4_ref_xD = 18;
+ }
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvc_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 2 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 */
+ /* (x0,y0) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), ..., (x0+6,y0+1) */
+ for(i4_x = i4_x0 + 1; i4_x < i4_x0 + 8; i4_x++)
+ {
+ i4_xD++;
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x - 1] = u1_filled_samp;
+ }
+
+ /* (x0+7,y0+1) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x0 + 7, i4_y0 + 1, i4_xD, i4_yD + 1, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 */
+ /* (x0,y0+1) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0, i4_y0 + 1, i4_xD, i4_yD + 1,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_x = i4_x0; i4_x < i4_x0 + 7; i4_x++)
+ {
+ u1_filled_samp = isvc_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst[i4_x + 1] = u1_filled_samp;
+ i4_xD++;
+ }
+
+ /* (x0+7,y0) */
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x0 + 7, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = isvc_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_xD++;
+ }
+ }
+ }
+
+ if(!(u1_ny_avlblty & TOPLEFT_MASK))
+ {
+ UWORD8 *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ if(u1_ny_avlblty & LEFT_MASK)
+ {
+ /* (mb_x+left,mb_y) available, (mb_x,mb_y+top) unavailable */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), and (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_xc0];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_xc0];
+ }
+ else if(u1_ny_avlblty & TOP_MASK)
+ {
+ /* (mb_x+left,mb_y) unavailable,
+ (mb_x,mb_y+top) available */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0) */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_tmp_src1 + DYADIC_REF_W_Y;
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src2[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src2[i4_ref_xD];
+
+ /* Copy Cb and Cr */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ }
+ else if(u1_ny_avlblty & (TOP_MASK | LEFT_MASK))
+ {
+ /* (mb_x+left,mb_y) available,
+ (mb_x,mb_y+top) available */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvc_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvc_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_get_ref_layer_mbtype */
+/* */
+/* Description : This function is used to find the mb type of the */
+/* corresponding MB in the reference layer */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra samp context */
+/* pi1_ref_mb_modes : ref mb modes buffer pointer */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_x_ref : reference location X */
+/* i4_y_ref : reference location Y */
+/* pi4_mb_type : pointer to store the mb type */
+/* i4_chroma_flag : chroma flag */
+/* Globals : none */
+/* Processing : it derives the bit corresponding to reference MB and */
+/* stores the mbtype as INTRA if the bit is set */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+static WORD8 isvc_get_ref_layer_mbtype(WORD8 *pi1_ref_mb_modes, WORD32 *pi4_mb_type,
+ WORD8 i1_curr_slice_id, WORD8 i1_cons_intr_samp_flag)
+{
+ WORD8 i1_intra_slice_id;
+ WORD8 i1_mb_mode;
+
+ i1_mb_mode = *pi1_ref_mb_modes;
+ i1_mb_mode = (i1_mb_mode < 0) ? i1_mb_mode : SVC_EXTRACT_MB_MODE(*pi1_ref_mb_modes);
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ *pi4_mb_type = SVC_INTER_MB;
+ i1_intra_slice_id = -1;
+ }
+ else
+ {
+ *pi4_mb_type = SVC_INTRA_MB;
+ i1_intra_slice_id = i1_mb_mode;
+
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ if(i1_mb_mode != i1_curr_slice_id)
+ {
+ *pi4_mb_type = SVC_INTER_MB;
+ }
+ }
+ }
+ return i1_intra_slice_id;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_fill_non_ava_pixel */
+/* */
+/* Description : This function does the core pixel level processing */
+/* while filling the non available pixel */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* i4_refarray_wd : width of the reference array */
+/* i4_refarray_ht : height of the reference array */
+/* ps_mb_coord : current mb coord structure */
+/* i4_chroma_flag : chroam processing flag */
+/* Globals : none */
+/* Processing : based on the map buffer values the non available pixels */
+/* are filled using border extension algorithm */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* 07 03 2011 A.D.Almeida Optimized the filling pixels */
+/* */
+/*****************************************************************************/
+static void isvc_fill_non_avail_pixel(intra_samp_lyr_ctxt *ps_lyr_ctxt, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_chroma_flag, UWORD8 u1_avail_map[4][4])
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_corner_pixel_available;
+
+ seg_lookup_desc_t *ps_segments_x;
+ seg_lookup_desc_t *ps_segments_y;
+ seg_description_t *ps_seg_desc_x, *ps_seg_desc_y;
+ seg_description_t *ps_seg_x_tmp, *ps_seg_y_tmp;
+ UWORD8 u1_num_sgmts_x, u1_num_sgmts_y;
+
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refmb_wd;
+ WORD32 i4_refmb_ht;
+ WORD32 i4_xr_index, i4_yr_index;
+ WORD32 i4_j, i4_i;
+ WORD32 i4_cur_x;
+ UWORD32 u4_lookup_4bit, u4_lookup_5bit, u4_4thbit;
+ WORD32 i4_pad_size;
+
+ WORD32 i4_x_min;
+ WORD32 i4_y_min;
+ WORD32 i4_x_start_pos, i4_y_start_pos;
+
+ UWORD8 *pu1_ref_idx_x, *pu1_ref_idx_y;
+
+ PF_INTRA_SAMP_PADDING *pf_intra_samp_padding;
+ PF_INTRA_SAMP_PADDING **pf_intra_samp_lookup;
+
+ i4_x_offset = ps_lyr_ctxt->ps_offsets->i4_abscissa;
+ i4_y_offset = ps_lyr_ctxt->ps_offsets->i4_ordinate;
+
+ i4_refmb_wd = (MB_SIZE >> i4_chroma_flag) - 1;
+ i4_refmb_ht = (MB_SIZE >> i4_chroma_flag) - 1;
+
+ if(0 == i4_chroma_flag)
+ {
+ pf_intra_samp_lookup = gpf_lookup_fxns_luma;
+ }
+ else
+ {
+ pf_intra_samp_lookup = gpf_lookup_fxns_chroma;
+ }
+
+ i4_x_min = ps_lyr_ctxt->i2_x_min_pos;
+ i4_y_min = ps_lyr_ctxt->i2_y_min_pos;
+
+ i4_pad_size = 2 >> i4_chroma_flag;
+ i4_x_start_pos = (i4_x_min - i4_pad_size);
+ i4_y_start_pos = (i4_y_min - i4_pad_size);
+
+ i4_xr_index = (i4_x_start_pos + i4_x_offset) & i4_refmb_wd;
+ i4_yr_index = (i4_y_start_pos + i4_y_offset) & i4_refmb_ht;
+
+ ps_segments_x = (ps_lyr_ctxt->as_seg_lookup_horz + i4_xr_index);
+ ps_segments_y = (ps_lyr_ctxt->as_seg_lookup_vert + i4_yr_index);
+
+ u1_num_sgmts_x = ps_segments_x->u1_num_segments;
+ u1_num_sgmts_y = ps_segments_y->u1_num_segments;
+
+ ps_seg_desc_x = ps_segments_x->s_segments;
+ ps_seg_desc_y = ps_segments_y->s_segments;
+
+ pu1_ref_idx_x = &(ps_lyr_ctxt->au1_refarray_x_idx[0]);
+ pu1_ref_idx_y = &(ps_lyr_ctxt->au1_refarray_y_idx[0]);
+
+ i4_cur_x = pu1_ref_idx_x[i4_x_start_pos];
+
+ u4_4thbit = ps_segments_x->u4_start_pos;
+
+ for(i4_j = 0; i4_j < u1_num_sgmts_y; i4_j++)
+ {
+ UWORD8 i4_idx_a, i4_idx_b;
+ UWORD8 u1_seg_ht, u1_seg_wd;
+ UWORD8 u1_mb_adjoin_x, u1_mb_adjoin_y;
+ WORD8 i1_nearst_mb_bdry_x, i1_nearst_mb_bdry_y;
+ UWORD32 u4_num_valid_segs;
+ WORD32 i4_idx_a_plus_ny, i4_idx_b_plus_nx, i4_index;
+ WORD8 i1_yd_index, i1_xd_index;
+
+ ps_seg_y_tmp = &ps_seg_desc_y[i4_j];
+
+ i4_y = i4_y_start_pos + ps_seg_y_tmp->u1_seg_off;
+ u1_seg_ht = ps_seg_y_tmp->u1_seg_dim;
+ i1_yd_index = ps_seg_y_tmp->i1_dist_idx;
+ i1_nearst_mb_bdry_y = ps_seg_y_tmp->i1_nearst_mb_bdry;
+ u1_mb_adjoin_y = ps_seg_y_tmp->u1_mb_adjoin;
+
+ i4_idx_a = pu1_ref_idx_y[i4_y];
+
+ i4_idx_a_plus_ny = (i4_idx_a + i1_nearst_mb_bdry_y);
+
+ /* Pack the availabilities of the next three horizontal MBs in 3bit
+ format and 4th bit indicating if the start position is greater
+ than the mb_width/2
+ */
+ u4_lookup_4bit = u4_4thbit | u1_avail_map[i4_idx_a][i4_cur_x + 2] << 2 |
+ u1_avail_map[i4_idx_a][i4_cur_x + 1] << 1 |
+ u1_avail_map[i4_idx_a][i4_cur_x];
+
+ u4_num_valid_segs = gu4_valid_segs_lookup[u4_lookup_4bit];
+
+ i4_i = CLZ(~u4_num_valid_segs);
+ u4_num_valid_segs <<= (i4_i + 1);
+
+ for(; i4_i < u1_num_sgmts_x; i4_i++)
+ {
+ ps_seg_x_tmp = &ps_seg_desc_x[i4_i];
+
+ i4_x = i4_x_start_pos + ps_seg_x_tmp->u1_seg_off;
+ i4_idx_b = pu1_ref_idx_x[i4_x];
+
+ u1_seg_wd = ps_seg_x_tmp->u1_seg_dim;
+ i1_xd_index = ps_seg_x_tmp->i1_dist_idx;
+ i1_nearst_mb_bdry_x = ps_seg_x_tmp->i1_nearst_mb_bdry;
+ u1_mb_adjoin_x = ps_seg_x_tmp->u1_mb_adjoin;
+
+ i4_idx_b_plus_nx = (i4_idx_b + i1_nearst_mb_bdry_x);
+
+ /* Find the avalability of (x,y-Yd),(x-Xd,y),(x-Xd,y-Yd) and pack
+ it to 3 bits.
+ */
+ u4_lookup_5bit = u1_avail_map[i4_idx_a_plus_ny][i4_idx_b_plus_nx] << 2 |
+ u1_avail_map[i4_idx_a_plus_ny][i4_idx_b] << 1 |
+ u1_avail_map[i4_idx_a][i4_idx_b_plus_nx] | u1_mb_adjoin_x |
+ u1_mb_adjoin_y;
+
+ i4_corner_pixel_available = u1_avail_map[i4_idx_a_plus_ny][i4_idx_b_plus_nx];
+
+ /* Use a function pointer table based on lookup to compute
+ Left,Top,Bottom,Right,Diagonal padding.
+ */
+ pf_intra_samp_padding = pf_intra_samp_lookup[u4_lookup_5bit];
+
+ if(pf_intra_samp_padding != NULL)
+ {
+ pf_intra_samp_padding(i4_x, i4_y, i1_xd_index, i1_yd_index, u1_seg_wd, u1_seg_ht,
+ pu1_refarray_1, pu1_refarray_2, i4_refarray_stride,
+ u1_mb_adjoin_x, u1_mb_adjoin_y, i4_corner_pixel_available);
+ }
+
+ /* increment to the next unavailable segment */
+ i4_index = CLZ(~u4_num_valid_segs);
+ u4_num_valid_segs <<= (i4_index + 1);
+ i4_i += i4_index;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_intra_resamp_generate_segment_lookup */
+/* */
+/* Description : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* */
+/* Inputs : pv_lookup_table : look up table */
+/* i4_dimension : dimension of the block which is used in*/
+/* resampling process. */
+/* i4_mb_size : size of the mb */
+/* Globals : None */
+/* Processing : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 03 2011 A.D.Almeida Creation */
+/* */
+void isvc_intra_resamp_generate_segment_lookup(seg_lookup_desc_t *ps_seg_lookup_table,
+ WORD32 i4_dimension, WORD32 i4_mb_size,
+ WORD32 i4_shift_val)
+{
+ WORD32 i4_x;
+ WORD32 i4_position, i4_dist_prev_mb, i4_dist_next_mb;
+ UWORD8 u1_seg_dim;
+ UWORD8 u1_num_sgmts;
+ WORD32 i4_block_size = i4_mb_size >> 1;
+ UWORD8 u1_offset = 0;
+ seg_lookup_desc_t *ps_segments;
+ seg_description_t *ps_seg_desc;
+
+ memset(ps_seg_lookup_table, 0, i4_mb_size * sizeof(seg_lookup_desc_t));
+
+ for(i4_x = 0; i4_x < i4_mb_size; i4_x++)
+ {
+ ps_segments = &ps_seg_lookup_table[i4_x];
+ ps_seg_desc = ps_segments->s_segments;
+ i4_position = i4_x;
+
+ if(i4_x >= i4_block_size)
+ {
+ /* set the fourth bit so that later it can be directly OR ed */
+ ps_segments->u4_start_pos = 8;
+ }
+ else
+ {
+ ps_segments->u4_start_pos = 0;
+ }
+
+ u1_num_sgmts = 0;
+ u1_offset = 0;
+
+ while(i4_position < (i4_x + i4_dimension))
+ {
+ /* check and fill the nearest mb boundry flag */
+ if((i4_position & (i4_mb_size - 1)) < i4_block_size)
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = -1;
+ }
+ else
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = 1;
+ }
+
+ /* find the distance from the previous MB for start of segment*/
+ i4_dist_prev_mb = (i4_position & (i4_mb_size - 1));
+
+ ps_seg_desc->i1_dist_idx =
+ ((i4_dist_prev_mb >= i4_mb_size >> 1) ? (i4_mb_size - i4_dist_prev_mb)
+ : -(i4_dist_prev_mb + 1));
+
+ /* find the size of the segment */
+ u1_seg_dim = (i4_block_size - (i4_position & (i4_block_size - 1)));
+ i4_position += u1_seg_dim;
+ if(i4_position > (i4_x + i4_dimension))
+ {
+ i4_position = (i4_x + i4_dimension);
+ u1_seg_dim = (i4_position & (i4_block_size - 1));
+ }
+
+ /* find the distance from the next MB for end of segment */
+ i4_dist_next_mb = (i4_position & (i4_mb_size - 1));
+
+ ps_seg_desc->u1_seg_dim = u1_seg_dim;
+ ps_seg_desc->u1_seg_off = u1_offset;
+
+ /* check if the segment has a adjoining MB edge */
+ if(i4_dist_prev_mb == 0)
+ {
+ if(0 == u1_num_sgmts)
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else if(i4_dist_next_mb == 0)
+ {
+ if(i4_position == (i4_x + i4_dimension))
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+
+ u1_offset += u1_seg_dim;
+ u1_num_sgmts++;
+ ps_seg_desc++;
+ }
+
+ /* fill the number of segments for this position */
+ ps_segments->u1_num_segments = u1_num_sgmts;
+ }
+}
+
+static void isvc_reflayer_construction(void *pv_intra_samp_ctxt, UWORD8 *pu1_inp_1,
+ WORD32 i4_inp_stride, WORD32 i4_refarray_stride,
+ mem_element_t *ps_ref_mb_mode_map, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x, i4_y;
+
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes, *pi1_ref_mb_modes_bkp_1;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_dummy;
+ WORD32 i4_mb_ht, i4_mb_wd;
+
+ /* 4x4 mb grid buffer to store the mb availablity */
+ UWORD8 u1_map_buf[BLK_SIZE][BLK_SIZE];
+ WORD32 i4_ref_wd;
+ WORD32 i4_ref_ht;
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refarray_wd;
+ WORD32 i4_refarray_ht;
+ WORD32 i4_mb_type;
+ WORD8 i1_cons_intr_samp_flag;
+ WORD8 i1_slice_id = 0;
+ WORD32 i4_mb_wd_sft, i4_mb_ht_sft;
+
+ WORD32 i4_unfill_check;
+ UWORD8 *pu1_refarray_1, *pu1_refarray_2;
+
+ UNUSED(i4_dummy);
+ memset(&u1_map_buf[0][0], 0, 16);
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode_map->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode_map->i4_element_size;
+
+ /* get the condtrained intra sampling flag */
+ i1_cons_intr_samp_flag = ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag;
+
+ ASSERT(NULL != pi1_ref_mb_modes);
+
+ {
+ WORD32 i4_base_width = ps_lyr_ctxt->i4_ref_width;
+ WORD32 i4_base_height = ps_lyr_ctxt->i4_ref_height;
+
+ i4_ref_wd = i4_base_width >> i4_chroma_flag;
+ i4_ref_ht = i4_base_height >> i4_chroma_flag;
+
+ i4_mb_wd_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
+ i4_mb_ht_sft = (MB_HEIGHT_SHIFT - i4_chroma_flag);
+ }
+
+ i4_x_offset = ps_lyr_ctxt->ps_offsets->i4_abscissa;
+ i4_y_offset = ps_lyr_ctxt->ps_offsets->i4_ordinate;
+ i4_refarray_wd = ps_lyr_ctxt->ps_ref_array_dims->i4_abscissa;
+ i4_refarray_ht = ps_lyr_ctxt->ps_ref_array_dims->i4_ordinate;
+
+ i4_mb_wd = (MB_SIZE >> i4_chroma_flag);
+ i4_mb_ht = (MB_SIZE >> i4_chroma_flag);
+
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ WORD32 i4_x_min, i4_x_max;
+ WORD32 i4_y_min, i4_y_max;
+
+ i4_x_min = ps_lyr_ctxt->i2_x_min_pos;
+ i4_x_max = ps_lyr_ctxt->i2_x_max_pos;
+ i4_y_min = ps_lyr_ctxt->i2_y_min_pos;
+ i4_y_max = ps_lyr_ctxt->i2_y_max_pos;
+
+ i4_mb_type = SVC_INTER_MB;
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_mb_x, i4_mb_y;
+
+ /* derive local varaibles */
+ i4_y_ref = (i4_y_min + 1) + i4_y_offset;
+ i4_x_ref = (i4_x_min + 1) + i4_x_offset;
+
+ i4_mb_x = (i4_x_ref >> i4_mb_wd_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_ht_sft);
+
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_element_size);
+ }
+
+ for(i4_y = (i4_y_min + 1); i4_y <= (i4_y_max - 1);)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_distleftX, i4_rangeX;
+ WORD32 i4_disttopY, i4_rangeY;
+
+ i4_y_ref = (i4_y + i4_y_offset);
+ i4_disttopY = (i4_y_ref) & (i4_mb_ht - 1);
+ i4_rangeY = (i4_mb_ht - i4_disttopY);
+
+ pi1_ref_mb_modes_bkp_1 = pi1_ref_mb_modes;
+
+ for(i4_x = (i4_x_min + 1); i4_x <= (i4_x_max - 1);)
+ {
+ i4_x_ref = (i4_x + i4_x_offset);
+ i4_distleftX = (i4_x_ref) & (i4_mb_wd - 1);
+ i4_rangeX = (i4_mb_wd - i4_distleftX);
+
+ /* get the referecne layer mb type */
+ i1_slice_id =
+ isvc_get_ref_layer_mbtype(pi1_ref_mb_modes_bkp_1, &i4_mb_type, i1_slice_id, 0);
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ break;
+ }
+ i4_x += i4_rangeX;
+ pi1_ref_mb_modes_bkp_1 += i4_element_size;
+ }
+
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ break;
+ }
+
+ i4_y += i4_rangeY;
+ pi1_ref_mb_modes += (i4_ref_mode_stride * i4_element_size);
+ }
+ }
+ else
+ {
+ i1_slice_id = -1;
+ }
+
+ i4_unfill_check = 0;
+
+ /* --------------------------------------------------------------------- */
+ /* Copying the data from recon buffer to refSample Array.
+ */
+ /* NOTE: The copying of the data from recon buffer to refSample Array */
+ /* can be optimized by bring in data at N-MB level,thus taking */
+ /* advantage of the overlapping data which now gets copied every
+ * MB*/
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_x_ref_start, i4_x_ref_end;
+ WORD32 i4_y_ref_start, i4_y_ref_end;
+ WORD32 i4_rangeW, i4_rangeH;
+ WORD32 i4_offset;
+ UWORD8 *pu1_src, *pu1_dst;
+ UWORD8 *pu1_dst1, *pu1_dst2;
+
+ /* Copy (refW x refH) dimension into reference sample array */
+ i4_x_ref_start = MAX(0, MIN((i4_ref_wd - 1), i4_x_offset));
+ i4_x_ref_end = MAX(0, MIN((i4_ref_wd - 1), (i4_refarray_wd - 1) + i4_x_offset));
+ i4_y_ref_start = MAX(0, MIN((i4_ref_ht - 1), i4_y_offset));
+ i4_y_ref_end = MAX(0, MIN((i4_ref_ht - 1), (i4_refarray_ht - 1) + i4_y_offset));
+
+ /* find the actual data to be copied */
+ i4_rangeW = (i4_x_ref_end - i4_x_ref_start + 1);
+ i4_rangeH = (i4_y_ref_end - i4_y_ref_start + 1);
+
+ /* get the reconbuffer pointer and ref sample array pointer */
+ i4_offset =
+ (i4_x_ref_start - i4_x_offset) + ((i4_y_ref_start - i4_y_offset) * i4_refarray_stride);
+
+ if(0 == i4_chroma_flag)
+ {
+ pu1_refarray_1 = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_2 = NULL;
+
+ pu1_src = pu1_inp_1;
+ pu1_dst = pu1_refarray_1 + i4_offset;
+
+ /* Copy luma data into refsample array */
+ isvc_copy_data(pu1_src, i4_inp_stride, pu1_dst, i4_refarray_stride, i4_rangeW,
+ i4_rangeH);
+ }
+ else
+ {
+ pu1_refarray_1 = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_2 = ps_ctxt->pu1_refarray_cb;
+
+ pu1_src = pu1_inp_1;
+ pu1_dst1 = pu1_refarray_1 + i4_offset;
+
+ pu1_dst2 = pu1_refarray_2 + i4_offset;
+
+ isvc_copy_data_semiplanr(pu1_src, i4_inp_stride, pu1_dst1, pu1_dst2, i4_refarray_stride,
+ i4_rangeW, i4_rangeH);
+ }
+ }
+ {
+ WORD32 i4_i, i4_j;
+ UWORD8 *pu1_ref_idx_x, *pu1_ref_idx_y;
+
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_mb_x, i4_mb_y;
+
+ i4_y_ref = i4_y_offset;
+ i4_x_ref = i4_x_offset;
+
+ i4_mb_x = (i4_x_ref >> i4_mb_wd_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_ht_sft);
+
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_element_size);
+
+ pu1_ref_idx_x = &(ps_lyr_ctxt->au1_refarray_x_idx[0]);
+ pu1_ref_idx_y = &(ps_lyr_ctxt->au1_refarray_y_idx[0]);
+
+ i4_j = 0;
+ for(i4_y = 0; i4_y < i4_refarray_ht;)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_distleftX, i4_rangeX;
+ WORD32 i4_disttopY, i4_rangeY;
+
+ i4_y_ref = i4_y + i4_y_offset;
+ i4_disttopY = (i4_y_ref) & (i4_mb_ht - 1);
+ i4_rangeY = (i4_mb_ht - i4_disttopY);
+
+ memset(pu1_ref_idx_y, i4_j, i4_rangeY);
+ pu1_ref_idx_y += i4_rangeY;
+
+ i4_i = 0;
+ pi1_ref_mb_modes_bkp_1 = pi1_ref_mb_modes;
+ for(i4_x = 0; i4_x < i4_refarray_wd;)
+ {
+ i4_x_ref = i4_x + i4_x_offset;
+ i4_distleftX = (i4_x_ref) & (i4_mb_wd - 1);
+ i4_rangeX = (i4_mb_wd - i4_distleftX);
+
+ if(0 == i4_j)
+ {
+ memset(pu1_ref_idx_x, i4_i, i4_rangeX);
+ pu1_ref_idx_x += i4_rangeX;
+ }
+
+ isvc_get_ref_layer_mbtype(pi1_ref_mb_modes_bkp_1, &i4_mb_type, i1_slice_id,
+ i1_cons_intr_samp_flag);
+
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ u1_map_buf[i4_j][i4_i] = 1;
+ i4_dummy = 1;
+ }
+ else
+ {
+ i4_unfill_check = 1;
+ }
+
+ i4_x = i4_x + i4_rangeX;
+ i4_i++;
+ pi1_ref_mb_modes_bkp_1 += i4_element_size;
+ }
+ i4_j++;
+ i4_y = i4_y + i4_rangeY;
+ pi1_ref_mb_modes += (i4_ref_mode_stride * i4_element_size);
+ }
+ ASSERT(1 == i4_dummy);
+ }
+
+ if(i4_unfill_check == 1)
+ {
+ isvc_fill_non_avail_pixel(ps_lyr_ctxt, pu1_refarray_1, pu1_refarray_2, i4_refarray_stride,
+ i4_chroma_flag, u1_map_buf);
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_interpolate_base_luma_dyadic */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* intra resampling for dyadic scaling ratios */
+/* Inputs : pu1_inp_buf : ptr to the 12x12 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 12x16 buffer to hold the */
+/* vertically interpolated data */
+/* pu1_out_buf : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void isvc_interpolate_base_luma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1, i4_samp_2, i4_samp_3;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ /* Filter coefficient values for phase 4 */
+ i4_coeff_0 = -3;
+ i4_coeff_1 = 28;
+ i4_coeff_2 = 8;
+ i4_coeff_3 = -1;
+
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 12; i4_x++)
+ {
+ /* y = 0, y_phase = 12 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_2 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_3 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase 12 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ }
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ }
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ /* x = 0, x_phase = 12 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+ i4_samp_2 = *pi2_tmp++;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* since x_phase 12 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_1 += 512;
+
+ i4_rslt_1 >>= 10;
+ pu1_out[0] = CLIPUCHAR(i4_rslt_1);
+
+ for(i4_x = 1; i4_x < 15; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* x_phase is 4 for odd values of x */
+ /* and 12 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_2 += 512;
+
+ i4_rslt_1 >>= 10;
+ i4_rslt_2 >>= 10;
+
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+ pu1_out[i4_x + 1] = CLIPUCHAR(i4_rslt_2);
+ }
+
+ /* x = 15 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_1 >>= 10;
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+ pu1_out += i4_out_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_vert_interpol_chroma_dyadic */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* 1 2 */
+/* 2 1 */
+/* 2 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void isvc_vert_interpol_chroma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 16 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 16 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ /* y = 0, y_phase = phase_0 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase = phase_0 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 7; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ }
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_horz_interpol_chroma_dyadic */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* horizontal intra resampling for dyadic scaling ratios for*/
+/* chroma with following ref_lyr_chroma_phase_x_plus1_flag */
+/* and chroma_phase_x_plus1_flag: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* Inputs : pi2_tmp_filt_buf : ptr to the 6x8 buffer containing the */
+/* vertically interpolated data */
+/* pu1_out_buf : pointer to the output buffer */
+/* i4_out_stride : output buffer stride */
+/* i4_phase_0 : x phase for even values of x */
+/* i4_phase_1 : x phase for odd values of x */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void isvc_horz_interpol_chroma_dyadic(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 16 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 16 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y++)
+ {
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_0 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 128;
+ i4_rslt_1 >>= 8;
+
+ pu1_out[0] = i4_rslt_1;
+
+ for(i4_x = 1; i4_x < 7; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* x_phase is phase_1 for odd values of x */
+ /* and phase_0 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ /* Rounding to 8-bit values */
+ i4_rslt_1 += 128;
+ i4_rslt_1 >>= 8;
+ i4_rslt_2 += 128;
+ i4_rslt_2 >>= 8;
+
+ pu1_out[2 * i4_x] = i4_rslt_1;
+ pu1_out[2 * (i4_x + 1)] = i4_rslt_2;
+ }
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_1 for x = 7 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 128;
+ i4_rslt_1 >>= 8;
+
+ pu1_out[2 * 7] = i4_rslt_1;
+ pu1_out += i4_dst_stride;
+ }
+}
+
+static void isvc_interpolate_intra_base(void *pv_intra_samp_ctxt, UWORD8 *pu1_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd,
+ WORD32 i4_chroma_flag, WORD32 i4_refarray_flag)
+{
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD32 i4_x, i4_y;
+ UWORD8 *pu1_refarray;
+ coordinates_t *ps_phase;
+
+ WORD32 i4_temp_array_ht;
+ WORD32 *pi4_interp_buff;
+ WORD32 *pi4_interp_buff_temp;
+
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+
+ WORD32 i4_x_min, i4_x_max;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ if(0 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_buffer;
+ }
+ else
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_cb;
+ }
+
+ i4_mb_wd = MB_SIZE >> i4_chroma_flag;
+ i4_mb_ht = MB_SIZE >> i4_chroma_flag;
+
+ i4_x_min = ps_lyr_ctxt->i2_x_min_pos;
+ i4_x_max = ps_lyr_ctxt->i2_x_max_pos;
+
+ ps_phase = ps_lyr_ctxt->ps_phase;
+
+ i4_temp_array_ht = i4_mb_ht;
+ pi4_interp_buff = ps_ctxt->pi4_temp_interpolation_buffer;
+ pi4_interp_buff_temp = pi4_interp_buff;
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ for(i4_x = (i4_x_min - 1); i4_x <= (i4_x_max + 2); i4_x++)
+ {
+ WORD32 i4_y_ref = ps_lyr_ctxt->pi4_ref_array_positions_y[i4_y];
+ WORD32 i4_y_phase =
+ ps_phase[(ps_lyr_ctxt->ps_mb_pos->i4_ordinate * i4_mb_ht + i4_y) % 3].i4_ordinate;
+ UWORD8 *pu1_refarray_temp = pu1_refarray + i4_x + (i4_y_ref * i4_refarray_wd);
+
+ if(0 == i4_chroma_flag)
+ {
+ *(pi4_interp_buff + i4_x) =
+ (g_ai1_interp_filter_luma[i4_y_phase]) *
+ (*(pu1_refarray_temp - i4_refarray_wd)) +
+
+ (g_ai1_interp_filter_luma[16 + i4_y_phase]) * (*(pu1_refarray_temp)) +
+
+ (g_ai1_interp_filter_luma[32 + i4_y_phase]) *
+ (*(pu1_refarray_temp + i4_refarray_wd)) +
+
+ (g_ai1_interp_filter_luma[48 + i4_y_phase]) *
+ (*(pu1_refarray_temp + (2 * i4_refarray_wd)));
+ }
+ else
+ {
+ *(pi4_interp_buff + i4_x) =
+ (g_au1_interp_filter_chroma[i4_y_phase]) * (*(pu1_refarray_temp)) +
+ (g_au1_interp_filter_chroma[16 + i4_y_phase]) *
+ (*(pu1_refarray_temp + i4_refarray_wd));
+ }
+ }
+
+ pi4_interp_buff = pi4_interp_buff + i4_refarray_wd;
+ }
+
+ pi4_interp_buff = pi4_interp_buff_temp;
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ WORD32 i4_x_ref = ps_lyr_ctxt->pi4_ref_array_positions_y[i4_x];
+ WORD32 i4_x_phase =
+ ps_phase[(ps_lyr_ctxt->ps_mb_pos->i4_abscissa * MAX_REF_ARR_WD_HT + i4_x) % 3]
+ .i4_ordinate;
+
+ pi4_interp_buff_temp = pi4_interp_buff + i4_x_ref;
+
+ if(0 == i4_chroma_flag)
+ {
+ *(pu1_out + i4_x + (i4_y * i4_out_stride)) = CLIPUCHAR(
+ ((g_ai1_interp_filter_luma[i4_x_phase]) * (*(pi4_interp_buff_temp - 1)) +
+ (g_ai1_interp_filter_luma[16 + i4_x_phase]) * (*(pi4_interp_buff_temp)) +
+ (g_ai1_interp_filter_luma[32 + i4_x_phase]) * (*(pi4_interp_buff_temp + 1)) +
+ (g_ai1_interp_filter_luma[48 + i4_x_phase]) * (*(pi4_interp_buff_temp + 2)) +
+ 512) >>
+ 10);
+ }
+ else
+ {
+ *(pu1_out + (2 * i4_x) + (i4_y * i4_out_stride)) = CLIPUCHAR(
+ ((g_au1_interp_filter_chroma[i4_x_phase]) * (*(pi4_interp_buff_temp)) +
+ (g_au1_interp_filter_chroma[16 + i4_x_phase]) * (*(pi4_interp_buff_temp + 1)) +
+ 512) >>
+ 10);
+ }
+ }
+
+ pi4_interp_buff = pi4_interp_buff + i4_refarray_wd;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_intra_samp_mb_dyadic */
+/* */
+/* Description : MB level function which performs the intra resampling */
+/* of data of an MB (luma and chroma inclusive) for dyadic */
+/* scaling ratios */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_mb_mode_map : ref layer mb mode map buff desc */
+/* ps_curr_luma : current layer out luma buffer desc */
+/* ps_curr_chroma : current layer out chroma buffer desc */
+/* x,y : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interpolation function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void isvc_intra_samp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y,
+ WORD32 i4_scaled_ref_layer_left_offset,
+ WORD32 i4_scaled_ref_layer_top_offset)
+{
+ UWORD8 *pu1_inp_luma, *pu1_inp_chroma;
+ UWORD8 *pu1_out_luma, *pu1_out_chroma;
+ UWORD8 *pu1_out_cb, *pu1_out_cr;
+ UWORD8 *pu1_refarray_luma, *pu1_refarray_cb, *pu1_refarray_cr;
+ WORD16 *pi2_tmp_filt_buf;
+ WORD32 i4_inp_luma_stride, i4_inp_chroma_stride;
+ WORD32 i4_out_luma_stride, i4_out_chroma_stride;
+ UWORD16 u2_mb_x_ref, u2_mb_y_ref;
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD32 i4_scaled_mb_x, i4_scaled_mb_y;
+ WORD32 i4_top, i4_left;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ i4_scaled_mb_x = u2_mb_x - (i4_scaled_ref_layer_left_offset >> 4);
+ i4_scaled_mb_y = u2_mb_y - (i4_scaled_ref_layer_top_offset >> 4);
+
+ if(i4_scaled_mb_x & 0x1)
+ {
+ i4_left = 1;
+ }
+ else
+ {
+ i4_left = -1;
+ }
+ if(i4_scaled_mb_y & 0x1)
+ {
+ i4_top = 1;
+ }
+ else
+ {
+ i4_top = -1;
+ }
+
+ u2_mb_x_ref = (i4_scaled_mb_x >> 1);
+ u2_mb_y_ref = (i4_scaled_mb_y >> 1);
+
+ pu1_inp_luma = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_inp_chroma = (UWORD8 *) ps_ref_chroma->pv_buffer;
+
+ i4_inp_luma_stride = ps_ref_luma->i4_num_element_stride;
+ i4_inp_chroma_stride = ps_ref_chroma->i4_num_element_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ isvc_reflayer_construction_dyadic(pv_intra_samp_ctxt, ps_ref_mb_mode_map, pu1_inp_luma,
+ pu1_inp_chroma, i4_inp_luma_stride, i4_inp_chroma_stride,
+ i4_top, i4_left, u2_mb_x_ref, u2_mb_y_ref);
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ if(1 == i4_top)
+ {
+ pu1_refarray_luma += (DYADIC_REF_W_Y << 3);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_luma += 8;
+ }
+ pu1_out_luma = (UWORD8 *) ps_curr_luma->pv_buffer;
+ i4_out_luma_stride = ps_curr_luma->i4_num_element_stride;
+ pi2_tmp_filt_buf = (WORD16 *) ps_ctxt->pi4_temp_interpolation_buffer;
+
+ ps_lyr_ctxt->pf_interpolate_luma(pu1_refarray_luma, pi2_tmp_filt_buf, pu1_out_luma,
+ i4_out_luma_stride);
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_out_chroma = (UWORD8 *) ps_curr_chroma->pv_buffer;
+ i4_out_chroma_stride = ps_curr_chroma->i4_num_element_stride;
+
+ /* CB */
+ pu1_out_cb = pu1_out_chroma;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cb += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cb += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_interpol_chroma(pu1_refarray_cb, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_interpol_chroma(pi2_tmp_filt_buf, pu1_out_cb, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+
+ /* CR */
+ pu1_out_cr = pu1_out_chroma + 1;
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cr += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cr += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_interpol_chroma(pu1_refarray_cr, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_interpol_chroma(pi2_tmp_filt_buf, pu1_out_cr, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvc_intra_samp_mb */
+/* */
+/* Description : MB level function which performs the intra resampling */
+/* of data of an MB (luma and chroma inclusive) */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_mb_mode_map : ref layer mb mode map buff desc */
+/* ps_curr_luma : current layer out luma buffer desc */
+/* ps_curr_chroma : current layer out chroma buffer desc */
+/* x,y : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interpolation function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void isvc_intra_samp_mb(void *pv_intra_samp_ctxt_luma, void *pv_intra_samp_ctxt_chroma,
+ mem_element_t *ps_ref_luma, mem_element_t *ps_ref_chroma,
+ mem_element_t *ps_ref_mb_mode_map, mem_element_t *ps_curr_luma,
+ mem_element_t *ps_curr_chroma)
+{
+ UWORD8 *pu1_inp_luma, *pu1_inp_chroma;
+ UWORD8 *pu1_out_luma, *pu1_out_chroma;
+ UWORD8 *pu1_out_cb, *pu1_out_cr;
+ WORD32 i4_inp_luma_stride, i4_inp_chroma_stride;
+ WORD32 i4_out_luma_stride, i4_out_chroma_stride;
+ WORD32 i4_chroma_flag, i4_refarray_stride;
+
+ intra_sampling_ctxt_t *ps_ctxt_luma;
+ intra_sampling_ctxt_t *ps_ctxt_chroma;
+
+ ps_ctxt_luma = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt_luma;
+ ps_ctxt_chroma = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt_chroma;
+
+ i4_refarray_stride = ps_ctxt_luma->i4_refarray_stride;
+
+ pu1_inp_luma = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_inp_chroma = (UWORD8 *) ps_ref_chroma->pv_buffer;
+
+ i4_inp_luma_stride = ps_ref_luma->i4_num_element_stride;
+ i4_inp_chroma_stride = ps_ref_chroma->i4_num_element_stride;
+
+ pu1_out_luma = (UWORD8 *) ps_curr_luma->pv_buffer;
+ i4_out_luma_stride = ps_curr_luma->i4_num_element_stride;
+
+ i4_chroma_flag = 0;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ isvc_reflayer_construction(pv_intra_samp_ctxt_luma, pu1_inp_luma, i4_inp_luma_stride,
+ i4_refarray_stride, ps_ref_mb_mode_map, i4_chroma_flag);
+
+ /* ---- Interpolation process for Intra_Base prediction ------ */
+ isvc_interpolate_intra_base(pv_intra_samp_ctxt_luma, pu1_out_luma, i4_out_luma_stride,
+ i4_refarray_stride, i4_chroma_flag, 0);
+
+ pu1_out_chroma = (UWORD8 *) ps_curr_chroma->pv_buffer;
+ i4_out_chroma_stride = ps_curr_chroma->i4_num_element_stride;
+
+ pu1_out_cb = pu1_out_chroma;
+ pu1_out_cr = pu1_out_cb + 1;
+
+ i4_refarray_stride = ps_ctxt_chroma->i4_refarray_stride;
+
+ i4_chroma_flag = 1;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ isvc_reflayer_construction(pv_intra_samp_ctxt_chroma, pu1_inp_chroma, i4_inp_chroma_stride,
+ i4_refarray_stride, ps_ref_mb_mode_map, i4_chroma_flag);
+
+ /* ---- Cb Interpolation process for Intra_Base prediction ------ */
+ isvc_interpolate_intra_base(pv_intra_samp_ctxt_chroma, pu1_out_cb, i4_out_chroma_stride,
+ i4_refarray_stride, i4_chroma_flag, 0);
+
+ /* ---- Cr Interpolation process for Intra_Base prediction ------ */
+ isvc_interpolate_intra_base(pv_intra_samp_ctxt_chroma, pu1_out_cr, i4_out_chroma_stride,
+ i4_refarray_stride, i4_chroma_flag, 1);
+}
diff --git a/common/svc/isvc_intra_resample.h b/common/svc/isvc_intra_resample.h
new file mode 100644
index 0000000..b78055c
--- /dev/null
+++ b/common/svc/isvc_intra_resample.h
@@ -0,0 +1,251 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _ISVC_INTRA_RESAMPLE_H_
+#define _ISVC_INTRA_RESAMPLE_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvc_structs.h"
+
+#define DYADIC_REF_W_Y 20
+#define DYADIC_REF_H_Y 20
+#define DYADIC_REF_W_C 10
+#define DYADIC_REF_H_C 10
+
+#define MAX_NUM_RES_LYRS 4
+
+#define MAX_PIX_FILL_LUMA 4
+#define MAX_PIX_FILL_CHROMA 2
+
+#define MAX_REF_ARR_WD_HT 48
+#define MAX_REF_IDX_ARRAY (MAX_REF_ARR_WD_HT + MB_SIZE)
+
+#define CLIPUCHAR(x) CLIP3(0, 255, (x))
+
+#define REF_ARRAY_WIDTH 48
+#define REF_ARRAY_HEIGHT 48
+
+typedef void FT_INTERPOLATE_LUMA_2X(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride);
+
+typedef void FT_VERT_INTERPOLATE_CHROMA_2X(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1);
+
+typedef void FT_HORZ_INTERPOLATE_CHROMA_2X(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1);
+
+typedef struct mem_element_t
+{
+ /* Buffer pointer */
+ void *pv_buffer;
+
+ /* size of the structure or unit */
+ WORD32 i4_element_size;
+
+ /* Stride of buffer in terms of number of elements.*/
+ WORD32 i4_num_element_stride;
+} mem_element_t;
+
+typedef struct seg_description_t
+{
+ /* describes segment dimension */
+ UWORD8 u1_seg_dim;
+
+ /* describes offset from start */
+ UWORD8 u1_seg_off;
+
+ /* describes whether mb is adjoining the segment
+ 0 => not adjoining 1 => adjoining */
+ UWORD8 u1_mb_adjoin;
+
+ /* distance to nearest MB */
+ WORD8 i1_dist_idx;
+
+ /* describes the nearest mb boundary
+ +1 => rightMB/bottomMB
+ -1 => leftMB/topMB */
+ WORD8 i1_nearst_mb_bdry;
+} seg_description_t;
+
+typedef struct seg_lookup_desc_t
+{
+ /* place holder to store the number of segments */
+ UWORD8 u1_num_segments;
+
+ /* this variable indicates where is start locatiion of the segment with
+ respect to less the block_width or greater than block width*/
+ UWORD8 u4_start_pos;
+
+ /* place holder to store per segment description */
+ seg_description_t s_segments[4];
+} seg_lookup_desc_t;
+
+typedef struct intra_samp_lyr_ctxt
+{
+ /* mb position */
+ coordinates_t *ps_mb_pos;
+
+ /* reference layer width in terms luma samples */
+ WORD32 i4_ref_width;
+
+ /* reference layer height in terms luma samples */
+ WORD32 i4_ref_height;
+
+ /* Constrained intra resampling flag. Range is [0,1]. */
+ WORD8 i1_constrained_intra_rsmpl_flag;
+
+ /* Chroma xPhase for even values of x for dyadic cases */
+ WORD32 i4_x_phase_0;
+
+ /* Chroma xPhase for odd values of x for dyadic cases */
+ WORD32 i4_x_phase_1;
+
+ /* Chroma yPhase for even values of y for dyadic cases */
+ WORD32 i4_y_phase_0;
+
+ /* Chroma yPhase for odd values of y for dyadic cases */
+ WORD32 i4_y_phase_1;
+
+ FT_INTERPOLATE_LUMA_2X *pf_interpolate_luma;
+
+ FT_VERT_INTERPOLATE_CHROMA_2X *pf_vert_interpol_chroma;
+
+ FT_HORZ_INTERPOLATE_CHROMA_2X *pf_horz_interpol_chroma;
+
+ WORD16 i2_x_min_pos;
+
+ WORD16 i2_x_max_pos;
+
+ WORD16 i2_y_min_pos;
+
+ WORD16 i2_y_max_pos;
+
+ coordinates_t *ps_phase;
+
+ WORD32 *pi4_ref_array_positions_x;
+
+ WORD32 *pi4_ref_array_positions_y;
+
+ coordinates_t *ps_offsets;
+
+ coordinates_t *ps_ref_array_dims;
+
+ /* buffers to store lookup for horizontal segment description */
+ seg_lookup_desc_t as_seg_lookup_horz[MB_SIZE];
+
+ /* buffers to store lookup for vertical segment description */
+ seg_lookup_desc_t as_seg_lookup_vert[MB_SIZE];
+
+ /* buffers to store lookup for x indexes to get
+ availability from 4x4 availability grid */
+ UWORD8 au1_refarray_x_idx[MAX_REF_IDX_ARRAY];
+
+ /* buffers to store lookup for y indexes to get
+ availability from 4x4 availability grid */
+ UWORD8 au1_refarray_y_idx[MAX_REF_IDX_ARRAY];
+} intra_samp_lyr_ctxt;
+
+typedef struct intra_sampling_ctxt_t
+{
+ /* Array of resolution layer ctxt. */
+ intra_samp_lyr_ctxt as_res_lyrs[MAX_NUM_RES_LYRS];
+
+ /* pointer to array of SPS */
+ void *ps_sps;
+
+ /* buffer to store the reference layer data before intra sampling */
+ UWORD8 *pu1_refarray_buffer;
+
+ /* buffer to hold the reference layer Cb data before intra
+ resampling (used for dyadic cases only) */
+ UWORD8 *pu1_refarray_cb;
+
+ /* buffer to hold the reference layer Cr data before intra
+ resampling (used for dyadic cases only) */
+ UWORD8 *pu1_refarray_cr;
+
+ /* intermideate buffer for interpolation */
+ WORD32 *pi4_temp_interpolation_buffer;
+
+ /* resolution id of the layer which is to be processed */
+ WORD32 i4_res_lyr_id;
+
+ /* reference layer width in terms luma samples */
+ WORD32 i4_ref_width;
+
+ /* reference layer width in terms luma samples */
+ WORD32 i4_refarray_stride;
+
+ /* reference layer height in terms luma samples */
+ WORD32 i4_ref_height;
+} intra_sampling_ctxt_t;
+
+typedef struct inter_lyr_mb_prms_t
+{
+ /* NNZs of Chroma. Here each bit corresonds
+ to a NNZs of 4x4 sub block. Lower 4 bits are
+ used for Cb and upper are used for Cr */
+ UWORD8 u1_chroma_nnz;
+
+ /* NNZs of Luma. Here each bit corresonds
+ to a NNZs of 4x4 sub block in raster scan order. */
+ UWORD16 u2_luma_nnz;
+
+ /* Packed MB mode transform size of an MB */
+ WORD8 i1_mb_mode;
+} inter_lyr_mb_prms_t;
+
+/* Function declarations */
+extern void isvc_intra_samp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma,
+ mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y,
+ WORD32 i4_scaled_ref_layer_left_offset,
+ WORD32 i4_scaled_ref_layer_top_offset);
+
+extern void isvc_intra_samp_mb(void *pv_intra_samp_ctxt_luma, void *pv_intra_samp_ctxt_chroma,
+ mem_element_t *ps_ref_luma, mem_element_t *ps_ref_chroma,
+ mem_element_t *ps_ref_mb_mode_map, mem_element_t *ps_curr_luma,
+ mem_element_t *ps_curr_chroma);
+
+extern void isvc_intra_resamp_generate_segment_lookup(seg_lookup_desc_t *ps_seg_lookup_table,
+ WORD32 i4_dimension, WORD32 i4_mb_size,
+ WORD32 i4_shift_val);
+
+/* C Declarations */
+extern FT_INTERPOLATE_LUMA_2X isvc_interpolate_base_luma_dyadic;
+extern FT_VERT_INTERPOLATE_CHROMA_2X isvc_vert_interpol_chroma_dyadic;
+extern FT_HORZ_INTERPOLATE_CHROMA_2X isvc_horz_interpol_chroma_dyadic;
+
+/* SSE42 Declarations */
+extern FT_INTERPOLATE_LUMA_2X isvc_interpolate_base_luma_dyadic_sse42;
+extern FT_VERT_INTERPOLATE_CHROMA_2X isvc_vert_interpol_chroma_dyadic_sse42;
+extern FT_HORZ_INTERPOLATE_CHROMA_2X isvc_horz_interpol_chroma_dyadic_sse42;
+
+/* NEON Declarations */
+extern FT_INTERPOLATE_LUMA_2X isvc_interpolate_base_luma_dyadic_neon;
+extern FT_VERT_INTERPOLATE_CHROMA_2X isvc_vert_interpol_chroma_dyadic_neon;
+extern FT_HORZ_INTERPOLATE_CHROMA_2X isvc_horz_interpol_chroma_dyadic_neon;
+
+#endif
diff --git a/common/svc/isvc_iquant_itrans_recon.c b/common/svc/isvc_iquant_itrans_recon.c
new file mode 100644
index 0000000..a3a25d5
--- /dev/null
+++ b/common/svc/isvc_iquant_itrans_recon.c
@@ -0,0 +1,1094 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * ih264_iquant_itrans_recon.c
+ *
+ * @brief
+ * Contains definition of functions for h264 inverse quantization inverse
+ *transformation and recon
+ *
+ * @author
+ * Ittiam
+ *
+ * @par List of Functions:
+ * - ih264_iquant_itrans_recon_4x4()
+ * - ih264_iquant_itrans_recon_8x8()
+ * - ih264_iquant_itrans_recon_4x4_dc()
+ * - ih264_iquant_itrans_recon_8x8_dc()
+ * - ih264_iquant_itrans_recon_chroma_4x4()
+ * -ih264_iquant_itrans_recon_chroma_4x4_dc()
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <stdint.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[in] pi2_res
+ * residue 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] i4_res_stride
+ * residue buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi2_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ if(i == 0 && i4_iq_start_idx == 1) q0 = pi2_dc_src[0]; // Restoring dc value for intra case
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += i4_src_stride;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_res_ptr = pi2_res;
+ pi2_res_pred_ptr = pi2_res_pred;
+ pu1_out = pu1_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr++;
+ pu1_pred++;
+ pi2_res++;
+ pi2_res_pred++;
+ }
+}
+
+void isvc_iquant_itrans_recon_4x4_dc(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD32 q0;
+ WORD16 i_macro, i;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(i4_iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ }
+ i_macro = ((q0 + 32) >> 6);
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_res_ptr = pi2_res;
+ pi2_res_pred_ptr = pi2_res_pred;
+ pu1_out = pu1_out_ptr;
+
+ /* inverse prediction */
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+
+ pu1_out_ptr++;
+ pu1_pred++;
+ pi2_res++;
+ pi2_res_pred++;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs inverse quant and Inverse transform type Ci4 for 8x8
+ *block
+ *
+ * @par Description:
+ * Performs inverse transform Ci8 and adds the residue to get the
+ * reconstructed block
+ *
+ * @param[in] pi2_src
+ * Input 8x8coefficients
+ *
+ * @param[in] pu1_pred
+ * Prediction 8x8 block
+ *
+ * @param[out] pu1_recon
+ * Output 8x8 block
+ *
+ * @param[in] q_div
+ * QP/6
+ *
+ * @param[in] q_rem
+ * QP%6
+ *
+ * @param[in] q_lev
+ * Quantizer level
+ *
+ * @param[in] src_strd
+ * Input stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction stride
+ *
+ * @param[in] i4_out_stride
+ * Output Stride
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16 we dont need a bigger blcok since we reuse
+ * the tmp for each block
+ *
+ * @param[in] pu4_iquant_mat
+ * Pointer to the inverse quantization matrix
+ *
+ * @returns Void
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_8x8(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD32 i;
+ WORD16 i_z0, i_z1, i_z2, i_z3, i_z4, i_z5, i_z6, i_z7;
+ WORD16 i_y0, i_y1, i_y2, i_y3, i_y4, i_y5, i_y6, i_y7;
+ WORD16 i_macro;
+ WORD32 q;
+
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD32 rnd_fact = (u4_qp_div_6 < 6) ? (1 << (5 - u4_qp_div_6)) : 0;
+ UNUSED(i4_iq_start_idx);
+ UNUSED(pi2_dc_src);
+
+ ASSERT(ps_src->i4_data_stride == SUB_BLK_WIDTH_8x8);
+
+ /*************************************************************/
+ /* De quantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ for(i = 0; i < (SUB_BLK_WIDTH_8x8 * SUB_BLK_WIDTH_8x8); i++)
+ {
+ q = pi2_src[i];
+ INV_QUANT(q, pu2_iscal_mat[i], pu2_weigh_mat[i], u4_qp_div_6, rnd_fact, 6);
+ pi2_tmp_ptr[i] = q;
+ }
+
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ /* y2 = w0 - w4 */
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ /* y4 = (w2 >> 1) - w6 */
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ /* y6 = w2 + (w6 >> 1) */
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4]);
+
+ i_y1 =
+ ((WORD32) (-pi2_tmp_ptr[3]) + pi2_tmp_ptr[5] - pi2_tmp_ptr[7] - (pi2_tmp_ptr[7] >> 1));
+
+ i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4]);
+
+ i_y3 = ((WORD32) pi2_tmp_ptr[1] + pi2_tmp_ptr[7] - pi2_tmp_ptr[3] - (pi2_tmp_ptr[3] >> 1));
+
+ i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6]);
+
+ i_y5 =
+ ((WORD32) (-pi2_tmp_ptr[1]) + pi2_tmp_ptr[7] + pi2_tmp_ptr[5] + (pi2_tmp_ptr[5] >> 1));
+
+ i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+
+ i_y7 = ((WORD32) pi2_tmp_ptr[3] + pi2_tmp_ptr[5] + pi2_tmp_ptr[1] + (pi2_tmp_ptr[1] >> 1));
+
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ /* z1 = y1 + (y7 >> 2) */
+ /* z2 = y2 + y4 */
+ /* z3 = y3 + (y5 >> 2) */
+ /* z4 = y2 - y4 */
+ /* z5 = (y3 >> 2) - y5 */
+ /* z6 = y0 - y6 */
+ /* z7 = y7 - (y1 >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ /* x1 = z2 + z5 */
+ /* x2 = z4 + z3 */
+ /* x3 = z6 + z1 */
+ /* x4 = z6 - z1 */
+ /* x5 = z4 - z3 */
+ /* x6 = z2 - z5 */
+ /* x7 = z0 - z7 */
+ /*------------------------------------------------------------------*/
+ pi2_tmp_ptr[0] = i_z0 + i_z7;
+ pi2_tmp_ptr[1] = i_z2 + i_z5;
+ pi2_tmp_ptr[2] = i_z4 + i_z3;
+ pi2_tmp_ptr[3] = i_z6 + i_z1;
+ pi2_tmp_ptr[4] = i_z6 - i_z1;
+ pi2_tmp_ptr[5] = i_z4 - i_z3;
+ pi2_tmp_ptr[6] = i_z2 - i_z5;
+ pi2_tmp_ptr[7] = i_z0 - i_z7;
+
+ /* move to the next row */
+ // pi2_src_ptr += SUB_BLK_WIDTH_8x8;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_8x8;
+ }
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_res_ptr = pi2_res;
+ pi2_res_pred_ptr = pi2_res_pred;
+ pu1_out = pu1_out_ptr;
+ /*------------------------------------------------------------------*/
+ /* y0j = w0j + w4j */
+ /* y1j = -w3j + w5j -w7j -(w7j >> 1) */
+ /* y2j = w0j -w4j */
+ /* y3j = w1j + w7j -w3j -(w3j >> 1) */
+ /* y4j = ( w2j >> 1 ) -w6j */
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ /* y6j = w2j + ( w6j >> 1 ) */
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = pi2_tmp_ptr[0] + pi2_tmp_ptr[32];
+
+ i_y1 = (WORD32) (-pi2_tmp_ptr[24]) + pi2_tmp_ptr[40] - pi2_tmp_ptr[56] -
+ (pi2_tmp_ptr[56] >> 1);
+
+ i_y2 = pi2_tmp_ptr[0] - pi2_tmp_ptr[32];
+
+ i_y3 = (WORD32) pi2_tmp_ptr[8] + pi2_tmp_ptr[56] - pi2_tmp_ptr[24] - (pi2_tmp_ptr[24] >> 1);
+
+ i_y4 = (pi2_tmp_ptr[16] >> 1) - pi2_tmp_ptr[48];
+
+ i_y5 =
+ (WORD32) (-pi2_tmp_ptr[8]) + pi2_tmp_ptr[56] + pi2_tmp_ptr[40] + (pi2_tmp_ptr[40] >> 1);
+
+ i_y6 = pi2_tmp_ptr[16] + (pi2_tmp_ptr[48] >> 1);
+
+ i_y7 = (WORD32) pi2_tmp_ptr[24] + pi2_tmp_ptr[40] + pi2_tmp_ptr[8] + (pi2_tmp_ptr[8] >> 1);
+
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ /* z1j = y1j + (y7j >> 2) */
+ /* z2j = y2j + y4j */
+ /* z3j = y3j + (y5j >> 2) */
+ /* z4j = y2j -y4j */
+ /* z5j = (y3j >> 2) -y5j */
+ /* z6j = y0j -y6j */
+ /* z7j = y7j -(y1j >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ /* x1j = z2j + z5j */
+ /* x2j = z4j + z3j */
+ /* x3j = z6j + z1j */
+ /* x4j = z6j -z1j */
+ /* x5j = z4j -z3j */
+ /* x6j = z2j -z5j */
+ /* x7j = z0j -z7j */
+ /*------------------------------------------------------------------*/
+ i_macro = ((i_z0 + i_z7 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z2 + i_z5 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z4 + i_z3 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z6 + i_z1 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z6 - i_z1 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z4 - i_z3 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z2 - i_z5 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = ((i_z0 - i_z7 + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr++;
+ pu1_pred++;
+ pi2_res++;
+ pi2_res_pred++;
+ }
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_chroma_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ UNUSED(i4_iq_start_idx);
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ if(i == 0)
+ {
+ q0 = pi2_dc_src[0];
+ }
+ else
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += i4_src_stride;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_res_ptr = pi2_res;
+ pi2_res_pred_ptr = pi2_res_pred;
+ pu1_out = pu1_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr += 2; // Interleaved store for output
+ pu1_pred += 2; // Interleaved load for pred buffer
+ pi2_res += 2;
+ pi2_res_pred += 2;
+ }
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer if only dc value is present for residue
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized,
+ * This inverse quantized content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized dc coefficient
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block in interleaved format
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride in interleaved format
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+
+void isvc_iquant_itrans_recon_chroma_4x4_dc(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD32 q0;
+ WORD16 i_macro, i;
+
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_out_ptr = pu1_out;
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = ((q0 + 32) >> 6);
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_res_ptr = pi2_res;
+ pi2_res_pred_ptr = pi2_res_pred;
+ pu1_out = pu1_out_ptr;
+
+ /* inverse prediction */
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+ pu1_pred_ptr += i4_pred_stride;
+ pu1_out += i4_out_stride;
+ pi2_res_ptr += i4_res_stride;
+ pi2_res_pred_ptr += i4_res_pred_stride;
+
+ pi2_res_ptr[0] = isvc_get_residue(i_macro, pi2_res_pred_ptr[0], u1_res_accumulate);
+ *pu1_out = CLIP_U8(pi2_res_ptr[0] + pu1_pred_ptr[0]);
+
+ pu1_out_ptr += 2;
+ pu1_pred += 2;
+ pi2_res += 2;
+ pi2_res_pred += 2;
+ }
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized residue and
+ * prediction buffer assuming cbf=0
+ *
+ * @param[in] ps_src
+ * quantized 4x4 block
+ *
+ * @param[in] ps_pred
+ * prediction 4x4 block
+ *
+ * @param[in] ps_res
+ * residue 4x4 block
+ *
+ * @param[in] ps_res_pred
+ * residual pred 4x4 block
+ *
+ * @param[out] ps_out
+ * reconstructed 4x4 block
+ *
+ * @param[out] ps_iq_it_res_rec_constants
+ * reconstructed 4x4 block
+ *
+ * @param[out] pi2_tmp
+ * scratch buf
+ *
+ * @param[out] pi2_dc_src
+ * Pointer to dc coeff location
+ *
+ * @param[out] i4_iq_start_idx
+ * Idx of first coeff
+ *
+ * @param[in] pi2_tmp
+ * temporary buffer of size 1*16
+ *
+ * @param[in] u1_res_accumulate
+ * Flag to control residual accumulation
+ *
+ * @returns none
+ *
+ *******************************************************************************
+ */
+void isvc_zcbf_iquant_itrans_recon_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD32 i, j;
+
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+
+ UNUSED(ps_src);
+ UNUSED(ps_iq_it_res_rec_constants);
+ UNUSED(pi2_tmp);
+ UNUSED(pi2_dc_src);
+ UNUSED(i4_iq_start_idx);
+
+ if(u1_res_accumulate)
+ {
+ for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
+ {
+ for(j = 0; j < SUB_BLK_WIDTH_4x4; j++)
+ {
+ pi2_res[j + i * i4_res_stride] = isvc_get_residue(
+ 0, pi2_res_pred[j + i * i4_res_pred_stride], u1_res_accumulate);
+ pu1_out[j + i * i4_out_stride] =
+ CLIP3(0, UINT8_MAX,
+ pu1_pred[j + i * i4_pred_stride] + pi2_res[j + i * i4_res_stride]);
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
+ {
+ for(j = 0; j < SUB_BLK_WIDTH_4x4; j++)
+ {
+ pi2_res[j + i * i4_res_stride] = 0;
+ pu1_out[j + i * i4_out_stride] = pu1_pred[j + i * i4_pred_stride];
+ }
+ }
+ }
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized residue and
+ * prediction buffer assuming cbf=0
+ *
+ * @param[in] ps_src
+ * quantized 4x4 block
+ *
+ * @param[in] ps_pred
+ * prediction 4x4 block
+ *
+ * @param[in] ps_res
+ * residue 4x4 block
+ *
+ * @param[in] ps_res_pred
+ * residual pred 4x4 block
+ *
+ * @param[out] ps_out
+ * reconstructed 4x4 block
+ *
+ * @param[out] ps_iq_it_res_rec_constants
+ * reconstructed 4x4 block
+ *
+ * @param[out] pi2_tmp
+ * scratch buf
+ *
+ * @param[out] pi2_dc_src
+ * Pointer to dc coeff location
+ *
+ * @param[out] i4_iq_start_idx
+ * Idx of first coeff
+ *
+ * @param[in] pi2_tmp
+ * temporary buffer of size 1*16
+ *
+ * @param[in] u1_res_accumulate
+ * Flag to control residual accumulation
+ *
+ * @returns none
+ *
+ *******************************************************************************
+ */
+void isvc_chroma_zcbf_iquant_itrans_recon_4x4(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD32 i, j;
+
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+
+ UNUSED(ps_src);
+ UNUSED(ps_iq_it_res_rec_constants);
+ UNUSED(pi2_tmp);
+ UNUSED(pi2_dc_src);
+ UNUSED(i4_iq_start_idx);
+
+ if(u1_res_accumulate)
+ {
+ for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
+ {
+ for(j = 0; j < SUB_BLK_WIDTH_4x4 * 2; j += 2)
+ {
+ pi2_res[j + i * i4_res_stride] = isvc_get_residue(
+ 0, pi2_res_pred[j + i * i4_res_pred_stride], u1_res_accumulate);
+ pu1_out[j + i * i4_out_stride] = CLIP3(
+ 0, UINT8_MAX,
+ ((WORD16) pu1_pred[j + i * i4_pred_stride]) + pi2_res[j + i * i4_res_stride]);
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < SUB_BLK_HEIGHT_4x4; i++)
+ {
+ for(j = 0; j < SUB_BLK_WIDTH_4x4 * 2; j += 2)
+ {
+ pi2_res[j + i * i4_res_stride] = 0;
+ pu1_out[j + i * i4_out_stride] = pu1_pred[j + i * i4_pred_stride];
+ }
+ }
+ }
+}
diff --git a/common/svc/isvc_macros.h b/common/svc/isvc_macros.h
new file mode 100644
index 0000000..4bcab00
--- /dev/null
+++ b/common/svc/isvc_macros.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvc_macros.h
+*
+* @brief
+* Contains macro definitions used in SVC
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVC_MACROS_H_
+#define _ISVC_MACROS_H_
+
+#define FORCEINLINE __attribute__((always_inline)) inline
+
+#endif
diff --git a/common/svc/isvc_mem_fns.c b/common/svc/isvc_mem_fns.c
new file mode 100644
index 0000000..345715a
--- /dev/null
+++ b/common/svc/isvc_mem_fns.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_mem_fns.c
+ *
+ * @brief
+ * Functions used for memory operations
+ *
+ * @author
+ * Ittiam
+ *
+ * @par List of Functions:
+ * isvc_memcpy()
+ * isvc_memcpy_mul_8()
+ * isvc_memset()
+ * isvc_memset_mul_8()
+ * isvc_memset_16bit()
+ * isvc_memset_16bit_mul_8()
+ * isvc_memory_alloc()
+ * isvc_memory_free()
+ *
+ * @remarks
+ * None
+ *
+ ******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+/* System include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvc_mem_fns.h"
+
+/**
+********************************************************************************
+* @brief copies a 2d blk from one location to another
+*
+* @param[out] pu1_dst : dst pointer
+*
+* @param[in] i4_dst_stride: stride of destination
+*
+* @param[in] pu1_src : src ptr
+*
+* @param[in] i4_src_stride: stride of src
+*
+* @param[in] i4_blk_wd : blk width
+*
+* @param[in] i4_blk_ht : blk height
+*
+* @return void
+********************************************************************************
+*/
+
+void isvc_copy_2d(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 *pu1_src, WORD32 i4_src_stride,
+ WORD32 i4_blk_wd, WORD32 i4_blk_ht)
+{
+ WORD32 i;
+
+ for(i = 0; i < i4_blk_ht; i++)
+ {
+ memmove(pu1_dst, pu1_src, i4_blk_wd * sizeof(pu1_dst[0]));
+
+ pu1_dst += i4_dst_stride;
+ pu1_src += i4_src_stride;
+ }
+}
+
+/**
+********************************************************************************
+* @brief memsets a 2d blk
+*
+* @param[out] pu1_dst : dst pointer
+*
+* @param[in] i4_dst_stride: stride of destination
+*
+* @param[in] i4_blk_wd : blk width
+*
+* @param[in] i4_blk_ht : blk height
+*
+* @return void
+********************************************************************************
+*/
+void isvc_memset_2d(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 u1_val, WORD32 i4_blk_wd,
+ WORD32 i4_blk_ht)
+{
+ WORD32 i;
+
+ for(i = 0; i < i4_blk_ht; i++)
+ {
+ memset(pu1_dst, u1_val, i4_blk_wd);
+
+ pu1_dst += i4_dst_stride;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Function for copying to an interleaved destination
+ *
+ * @par Description:
+ * Copies the array of width 'wd' and height 'ht' from the location pointed
+ * by 'src' to the location pointed by 'dst'
+ *
+ * @param[in] pu1_src
+ * UWORD8 pointer to the source
+ *
+ * @param[out] pu1_dst
+ * UWORD8 pointer to the destination
+ *
+ * @param[in] src_strd
+ * integer source stride
+ *
+ * @param[in] dst_strd
+ * integer destination stride
+ *
+ * @param[in] ht
+ * integer height of the array
+ *
+ * @param[in] wd
+ * integer width of the array
+ *
+ * @returns
+ *
+ * @remarks
+ * The alternate elements of src will be copied to alternate locations in dsr
+ * Other locations are not touched
+ *
+ *******************************************************************************
+ */
+void isvc_interleaved_copy(UWORD8 *pu1_src, UWORD8 *pu1_dst, WORD32 src_strd, WORD32 dst_strd,
+ WORD32 ht, WORD32 wd)
+{
+ WORD32 row, col;
+ wd *= 2;
+
+ for(row = 0; row < ht; row++)
+ {
+ for(col = 0; col < wd; col += 2)
+ {
+ pu1_dst[col] = pu1_src[col];
+ }
+
+ pu1_src += src_strd;
+ pu1_dst += dst_strd;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Function for copying to an interleaved destination
+ *
+ * @par Description:
+ * Copies the array of width 'wd' and height 'ht' from the location pointed
+ * by 'src' to the location pointed by 'dst'
+ *
+ * @param[in] pu1_src
+ * UWORD8 pointer to the source
+ *
+ * @param[out] pu1_dst
+ * UWORD8 pointer to the destination
+ *
+ * @param[in] src_strd
+ * integer source stride
+ *
+ * @param[in] dst_strd
+ * integer destination stride
+ *
+ * @param[in] ht
+ * integer height of the array
+ *
+ * @param[in] wd
+ * integer width of the array
+ *
+ * @returns
+ *
+ * @remarks
+ * The alternate elements of src will be copied to alternate locations in dsr
+ * Other locations are not touched
+ *
+ *******************************************************************************
+ */
+void isvc_16bit_interleaved_copy(WORD16 *pi2_src, WORD16 *pi2_dst, WORD32 src_strd, WORD32 dst_strd,
+ WORD32 ht, WORD32 wd)
+{
+ WORD32 row, col;
+ wd *= 2;
+
+ for(row = 0; row < ht; row++)
+ {
+ for(col = 0; col < wd; col += 2)
+ {
+ pi2_dst[col] = pi2_src[col];
+ }
+
+ pi2_src += src_strd;
+ pi2_dst += dst_strd;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Function for memsetting to an interleaved destination
+ *
+ * @par Description:
+ * Memsets the array of width 'wd' and height 'ht' pointed by 'src'
+ *
+ * @param[in] pu1_src
+ * UWORD8 pointer to the source
+ *
+ * @param[in] src_strd
+ * integer source stride
+ *
+ * @param[in] value
+ * Value to set
+ *
+ * @param[in] ht
+ * integer height of the array
+ *
+ * @param[in] wd
+ * integer width of the array
+ *
+ * @returns
+ *
+ * @remarks
+ * The alternate elements of src will be copied to alternate locations in dsr
+ * Other locations are not touched
+ *
+ *******************************************************************************
+ */
+void isvc_16bit_interleaved_memset(WORD16 *pi2_src, WORD32 i4_src_strd, WORD16 i2_value,
+ WORD32 i4_wd, WORD32 i4_ht)
+{
+ WORD32 row, col;
+
+ i4_wd *= 2;
+
+ for(row = 0; row < i4_ht; row++)
+ {
+ for(col = 0; col < i4_wd; col += 2)
+ {
+ pi2_src[col] = i2_value;
+ }
+
+ pi2_src += i4_src_strd;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Checks if any pixel in a block is non-zero
+ *
+ * @param[in] pu1_data
+ * UWORD8 pointer to the block to be checked
+ *
+ * @param[in] i4_data_strd
+ * Stride of data buffer
+ *
+ * @param[in] u4_wd
+ * Width of the block
+ *
+ * @param[in] u4_ht
+ * Height of the block
+ *
+ *******************************************************************************
+ */
+UWORD8 isvc_is_nonzero_blk(UWORD8 *pu1_data, WORD32 i4_data_strd, UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 i, j;
+
+ for(i = 0; i < u4_ht; i++)
+ {
+ for(j = 0; j < u4_wd; j++)
+ {
+ if(pu1_data[j + i * i4_data_strd])
+ {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/common/svc/isvc_mem_fns.h b/common/svc/isvc_mem_fns.h
new file mode 100644
index 0000000..a4d95f7
--- /dev/null
+++ b/common/svc/isvc_mem_fns.h
@@ -0,0 +1,109 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvc_mem_fns.h
+*
+* @brief
+* Function declarations used for memory functions
+*
+* @author
+* Ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+#ifndef _ISVC_MEM_FNS_H_
+#define _ISVC_MEM_FNS_H_
+
+#include "ih264_typedefs.h"
+
+typedef void *FT_MEM_ALLOC(UWORD32 u4_size);
+
+typedef void FT_MEM_FREE(void *pv_mem);
+
+typedef void FT_MEMCPY(UWORD8 *pu1_dst, UWORD8 *pu1_src, UWORD32 num_bytes);
+
+typedef void FT_COPY_2D(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 *pu1_src,
+ WORD32 i4_src_stride, WORD32 i4_blk_wd, WORD32 i4_blk_ht);
+
+typedef void FT_MEMSET_2D(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 u1_val, WORD32 i4_blk_wd,
+ WORD32 i4_blk_ht);
+
+typedef void FT_MEMSET(UWORD8 *pu1_dst, UWORD8 value, UWORD32 num_bytes);
+
+typedef void FT_MEMSET_16BIT(UWORD16 *pu2_dst, UWORD16 value, UWORD32 num_words);
+
+typedef void FT_16BIT_INTERLEAVED_COPY(WORD16 *pi2_src, WORD16 *pi2_dst, WORD32 src_strd,
+ WORD32 dst_strd, WORD32 ht, WORD32 wd);
+
+typedef void FT_16BIT_INTERLEAVED_MEMSET(WORD16 *pi2_src, WORD32 i4_src_strd, WORD16 i2_value,
+ WORD32 i4_wd, WORD32 i4_ht);
+
+typedef UWORD8 FT_NONZERO_CHECKER(UWORD8 *pu1_data, WORD32 i4_data_strd, UWORD32 u4_wd,
+ UWORD32 u4_ht);
+
+/* C function declarations */
+extern FT_MEMCPY ih264_memcpy;
+extern FT_MEMCPY ih264_memcpy_mul_8;
+extern FT_MEMSET ih264_memset;
+extern FT_MEMSET ih264_memset_mul_8;
+extern FT_MEMSET_16BIT ih264_memset_16bit;
+extern FT_MEMSET_16BIT ih264_memset_16bit_mul_8;
+extern FT_COPY_2D isvc_copy_2d;
+extern FT_MEMSET_2D isvc_memset_2d;
+extern FT_16BIT_INTERLEAVED_COPY isvc_16bit_interleaved_copy;
+extern FT_16BIT_INTERLEAVED_MEMSET isvc_16bit_interleaved_memset;
+extern FT_NONZERO_CHECKER isvc_is_nonzero_blk;
+extern FT_MEM_ALLOC isvc_memory_alloc;
+extern FT_MEM_FREE isvc_memory_free;
+
+/* A9 Q function declarations */
+extern FT_MEMCPY isvc_memcpy_a9q;
+extern FT_MEMCPY ih264_memcpy_mul_8_a9q;
+extern FT_MEMSET ih264_memset_a9q;
+extern FT_MEMSET ih264_memset_mul_8_a9q;
+extern FT_MEMSET_16BIT ih264_memset_16bit_a9q;
+extern FT_MEMSET_16BIT ih264_memset_16bit_mul_8_a9q;
+
+/* AV8 function declarations */
+extern FT_MEMCPY ih264_memcpy_av8;
+extern FT_MEMCPY ih264_memcpy_mul_8_av8;
+extern FT_MEMSET ih264_memset_av8;
+extern FT_MEMSET ih264_memset_mul_8_av8;
+extern FT_MEMSET_16BIT ih264_memset_16bit_av8;
+extern FT_MEMSET_16BIT ih264_memset_16bit_mul_8_av8;
+
+/* NEON function declarations */
+extern FT_MEMSET_2D isvc_memset_2d_neon;
+
+/* SSSE3 variants */
+extern FT_MEMCPY ih264_memcpy_mul_8_ssse3;
+extern FT_MEMSET ih264_memset_mul_8_ssse3;
+extern FT_MEMSET_16BIT ih264_memset_16bit_mul_8_ssse3;
+extern FT_COPY_2D isvc_copy_2d_ssse3;
+
+/* SSE4.2 variants */
+extern FT_MEMSET_2D isvc_memset_2d_sse42;
+
+#endif
diff --git a/common/svc/isvc_resi_trans_quant.c b/common/svc/isvc_resi_trans_quant.c
new file mode 100644
index 0000000..0b48779
--- /dev/null
+++ b/common/svc/isvc_resi_trans_quant.c
@@ -0,0 +1,840 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * ih264_resi_trans_quant.c
+ *
+ * @brief
+ * Contains function definitions single stage forward transform for H.264
+ * It will calculate the residue, do the cf and then do quantization
+ *
+ * @author
+ * Ittiam
+ *
+ * @par List of Functions:
+ * - ih264_resi_trans_quant_4x4()
+ * - ih264_resi_trans_quant_chroma_4x4
+ * - ih264_hadamard_quant_4x4
+ * - ih264_hadamard_quant_2x2_uv
+ * - ih264_resi_trans_quant_8x8
+ *
+ * @remarks
+ *******************************************************************************
+ */
+/* System include files */
+#include <stdbool.h>
+#include <stddef.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_size_defs.h"
+#include "ih264_macros.h"
+#include "ih264_trans_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+static FORCEINLINE WORD16 isvc_subtract_upsampled_res(WORD16 i2_residue, WORD16 i2_upsampled_res)
+{
+ return (CLIP3(-((WORD16) UINT8_MAX), ((WORD16) UINT8_MAX), i2_residue - i2_upsampled_res));
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs forward transform and quantization on a 4*4 block
+ *
+ * @par Description:
+ * The function accepts source buffer and estimation buffer. From these, it
+ * computes the residue. This is residue is then transformed and quantized.
+ * The transform and quantization are in placed computed. They use the residue
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+ *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ * @param[in] pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in] i4_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ * Quantization Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero coefficients in the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvc_resi_trans_quant_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out, buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz,
+ WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ UWORD32 i;
+ WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
+ WORD32 i4_value;
+
+ UWORD8 *pu1_src = ps_src->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ WORD16 *pi2_out = ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ WORD16 *pi2_out_tmp = pi2_out;
+ UWORD32 u4_nonzero_coeff = 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ /* computing prediction error (residue) */
+ x4 = pu1_src[0] - pu1_pred[0];
+ x5 = pu1_src[1] - pu1_pred[1];
+ x6 = pu1_src[2] - pu1_pred[2];
+ x7 = pu1_src[3] - pu1_pred[3];
+
+ if(u1_use_upsampled_res)
+ {
+ x4 = isvc_subtract_upsampled_res(x4, pi2_upsampled_res[0]);
+ x5 = isvc_subtract_upsampled_res(x5, pi2_upsampled_res[1]);
+ x6 = isvc_subtract_upsampled_res(x6, pi2_upsampled_res[2]);
+ x7 = isvc_subtract_upsampled_res(x7, pi2_upsampled_res[3]);
+ }
+
+ /* Horizontal transform */
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ pi2_out_tmp[0] = x0 + x1;
+ pi2_out_tmp[1] = (x3 << 1) + x2;
+ pi2_out_tmp[2] = x0 - x1;
+ pi2_out_tmp[3] = x3 - (x2 << 1);
+
+ /* pointing to next row; */
+ pu1_src += i4_src_stride;
+ pu1_pred += i4_pred_stride;
+ pi2_out_tmp += 4;
+ pi2_upsampled_res += i4_upsampled_res_stride;
+ }
+
+ pi2_out_tmp = pi2_out;
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ /* Vertical transform and quantization */
+ x4 = pi2_out_tmp[0];
+ x5 = pi2_out_tmp[4];
+ x6 = pi2_out_tmp[8];
+ x7 = pi2_out_tmp[12];
+
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ /* quantization is done in place */
+
+ i4_value = x0 + x1;
+
+ if(i == 0)
+ {
+ (*pi2_dc_out) = i4_value;
+ }
+
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[0] = i4_value;
+
+ i4_value = (x3 << 1) + x2;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[4], pu2_scale_matrix[4], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[4] = i4_value;
+
+ i4_value = x0 - x1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[8] = i4_value;
+
+ i4_value = x3 - (x2 << 1);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[12], pu2_scale_matrix[12], u4_round_factor,
+ u4_qbits, u4_nonzero_coeff);
+ pi2_out_tmp[12] = i4_value;
+
+ pi2_out_tmp++;
+ pu2_scale_matrix++;
+ pu2_threshold_matrix++;
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs forward transform and quantization on a 4*4 chroma
+ *block with interleaved values
+ *
+ * @par Description:
+ * The function accepts source buffer and estimation buffer. From these, it
+ * computes the residue. This is residue is then transformed and quantized.
+ * The transform and quantization are in placed computed. They use the residue
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+ *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ * @param[in] pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in] i4_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ * Quantization Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero coefficients in the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvc_resi_trans_quant_chroma_4x4(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out,
+ UWORD8 u1_use_upsampled_res)
+{
+ UWORD32 i;
+ WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
+ WORD32 i4_value;
+
+ UWORD8 *pu1_src = ps_src->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ WORD16 *pi2_out = ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ WORD16 *pi2_out_tmp = pi2_out;
+ UWORD32 u4_nonzero_coeff = 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ /* computing prediction error (residue) */
+ x4 = pu1_src[0] - pu1_pred[0];
+ x5 = pu1_src[2] - pu1_pred[2];
+ x6 = pu1_src[4] - pu1_pred[4];
+ x7 = pu1_src[6] - pu1_pred[6];
+
+ if(u1_use_upsampled_res)
+ {
+ x4 = isvc_subtract_upsampled_res(x4, pi2_upsampled_res[0]);
+ x5 = isvc_subtract_upsampled_res(x5, pi2_upsampled_res[1]);
+ x6 = isvc_subtract_upsampled_res(x6, pi2_upsampled_res[2]);
+ x7 = isvc_subtract_upsampled_res(x7, pi2_upsampled_res[3]);
+ }
+
+ /* Horizontal transform */
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ pi2_out_tmp[0] = x0 + x1;
+ pi2_out_tmp[1] = (x3 << 1) + x2;
+ pi2_out_tmp[2] = x0 - x1;
+ pi2_out_tmp[3] = x3 - (x2 << 1);
+
+ /* pointing to next row; */
+ pu1_src += i4_src_stride;
+ pu1_pred += i4_pred_stride;
+ pi2_out_tmp += 4;
+ pi2_upsampled_res += i4_upsampled_res_stride;
+ }
+ pi2_out_tmp = pi2_out;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ /* Vertical transform and quantization */
+ x4 = pi2_out_tmp[0];
+ x5 = pi2_out_tmp[4];
+ x6 = pi2_out_tmp[8];
+ x7 = pi2_out_tmp[12];
+
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ /* quantization is done in place */
+
+ i4_value = x0 + x1;
+
+ if(i == 0)
+ {
+ *pi2_dc_out = i4_value;
+ }
+
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[0] = i4_value;
+
+ i4_value = (x3 << 1) + x2;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[4], pu2_scale_matrix[4], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[4] = i4_value;
+
+ i4_value = x0 - x1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[8] = i4_value;
+
+ i4_value = x3 - (x2 << 1);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[12], pu2_scale_matrix[12], u4_round_factor,
+ u4_qbits, u4_nonzero_coeff);
+ pi2_out_tmp[12] = i4_value;
+
+ pi2_out_tmp++;
+ pu2_scale_matrix++;
+ pu2_threshold_matrix++;
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs forward hadamard transform and quantization on a 4*4
+ *block
+ *
+ * @par Description:
+ * The function accepts source buffer and estimation buffer. From these, it
+ * computes the residue. This is residue is then transformed and quantized.
+ * The transform and quantization are in placed computed. They use the residue
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+ *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ * @param[in] pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in] i4_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ * Quantization Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero coefficients in the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ */
+
+void isvc_hadamard_quant_4x4(WORD16 *pi2_src, WORD16 *pi2_dst,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz)
+{
+ WORD32 i;
+ WORD32 x0, x1, x2, x3, x4, x5, x6, x7, i4_value;
+
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ *pu1_nnz = 0;
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ x4 = pi2_src[0];
+ x5 = pi2_src[1];
+ x6 = pi2_src[2];
+ x7 = pi2_src[3];
+
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ pi2_dst[0] = x0 + x1;
+ pi2_dst[1] = x3 + x2;
+ pi2_dst[2] = x0 - x1;
+ pi2_dst[3] = x3 - x2;
+
+ pi2_src += 4;
+ pi2_dst += 4;
+ }
+
+ /* Vertical transform and quantization */
+ pi2_dst -= SUB_BLK_WIDTH_4x4 << 2;
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ x4 = pi2_dst[0];
+ x5 = pi2_dst[4];
+ x6 = pi2_dst[8];
+ x7 = pi2_dst[12];
+
+ x0 = x4 + x7;
+ x1 = x5 + x6;
+ x2 = x5 - x6;
+ x3 = x4 - x7;
+
+ i4_value = (x0 + x1) >> 1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[0]);
+ pi2_dst[0] = i4_value;
+
+ i4_value = (x3 + x2) >> 1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[0]);
+ pi2_dst[4] = i4_value;
+
+ i4_value = (x0 - x1) >> 1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[0]);
+ pi2_dst[8] = i4_value;
+
+ i4_value = (x3 - x2) >> 1;
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[0]);
+ pi2_dst[12] = i4_value;
+
+ pi2_dst++;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs forward hadamard transform and quantization on a 2*2
+ *block for both U and V planes
+ *
+ * @par Description:
+ * The function accepts source buffer and estimation buffer. From these, it
+ * computes the residue. This is residue is then transformed and quantized.
+ * The transform and quantization are in placed computed. They use the residue
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+ *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ * @param[in] pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in] i4_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ * Quantization Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero coefficients in the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ * NNZ for dc is populated at 0 and 5th position of pu1_nnz
+ *
+ */
+
+void isvc_hadamard_quant_2x2_uv(WORD16 *pi2_src, WORD16 *pi2_dst,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz)
+{
+ WORD32 x0, x1, x2, x3, x4, x5, x6, x7;
+ WORD32 i4_value, plane;
+
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ for(plane = 0; plane < 2; plane++)
+ {
+ pu1_nnz[plane] = 0;
+
+ /* Horizontal transform */
+ x4 = pi2_src[0];
+ x5 = pi2_src[1];
+ x6 = pi2_src[2];
+ x7 = pi2_src[3];
+
+ x0 = x4 + x5;
+ x1 = x4 - x5;
+ x2 = x6 + x7;
+ x3 = x6 - x7;
+
+ /* Vertical transform and quantization */
+ i4_value = (x0 + x2);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[plane]);
+ pi2_dst[0] = i4_value;
+
+ i4_value = (x0 - x2);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[plane]);
+ pi2_dst[2] = i4_value;
+
+ i4_value = (x1 - x3);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[plane]);
+ pi2_dst[3] = i4_value;
+
+ i4_value = (x1 + x3);
+ FWD_QUANT(i4_value, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ pu1_nnz[plane]);
+ pi2_dst[1] = i4_value;
+
+ pi2_dst += 4;
+ pi2_src += 4;
+ }
+}
+
+/*
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs Single stage forward transform CF8 and quantization
+ *on 8*8 blocks for h.264
+ *
+ * @par Description:
+ * Performs single stage 8x8 forward transform CF8 after calculating the
+ *residue The result is then quantized
+ *
+ * @param[in] pu1_src
+ * Input 8x8 pixels
+ *
+ * @param[in] pu1_pred
+ * Input 8x8 pixels
+ *
+ * @param[in] pi1_out
+ * Output 8x8 pixels
+ *
+ * @param[in] u4_thresh
+ * Threshold under which the coeffs are not quantized
+ *
+ * @param[in] u4_qp_div
+ * QP/6
+ *
+ * @param[in] u4_qp_rem
+ * QP%6
+ *
+ * @param[in] u2_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * stride for prediciton buffer
+ *
+ * @param[in] dst_strd
+ * stride for destination buffer
+ *
+ * @param[in] pu4_quant_mat
+ * Pointer to the 4x4 quantization matrix
+ *
+ * @returns Void
+ *
+ *
+ *******************************************************************************
+ */
+void isvc_resi_trans_quant_8x8(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out, buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz,
+ WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ UWORD32 i;
+ WORD32 a0, a1, a2, a3, a4, a5, a6, a7;
+ WORD32 r0, r1, r2, r3, r4, r5, r6, r7;
+
+ UWORD8 *pu1_src = ps_src->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ WORD16 *pi2_out = ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ WORD16 *pi2_out_tmp = pi2_out;
+ UWORD32 u4_nonzero_coeff = 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+
+ UNUSED(pi2_dc_out);
+
+ /*Horizontal transform */
+ /* we are going to use the a's and r's in a twisted way since */
+ /*i dont want to declare more variables */
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; ++i)
+ {
+ r0 = pu1_src[0];
+ r0 -= pu1_pred[0];
+ r1 = pu1_src[1];
+ r1 -= pu1_pred[1];
+ r2 = pu1_src[2];
+ r2 -= pu1_pred[2];
+ r3 = pu1_src[3];
+ r3 -= pu1_pred[3];
+ r4 = pu1_src[4];
+ r4 -= pu1_pred[4];
+ r5 = pu1_src[5];
+ r5 -= pu1_pred[5];
+ r6 = pu1_src[6];
+ r6 -= pu1_pred[6];
+ r7 = pu1_src[7];
+ r7 -= pu1_pred[7];
+
+ if(u1_use_upsampled_res)
+ {
+ r0 = isvc_subtract_upsampled_res(r0, pi2_upsampled_res[0]);
+ r1 = isvc_subtract_upsampled_res(r1, pi2_upsampled_res[1]);
+ r2 = isvc_subtract_upsampled_res(r2, pi2_upsampled_res[2]);
+ r3 = isvc_subtract_upsampled_res(r3, pi2_upsampled_res[3]);
+ r4 = isvc_subtract_upsampled_res(r4, pi2_upsampled_res[4]);
+ r5 = isvc_subtract_upsampled_res(r5, pi2_upsampled_res[5]);
+ r6 = isvc_subtract_upsampled_res(r6, pi2_upsampled_res[6]);
+ r7 = isvc_subtract_upsampled_res(r7, pi2_upsampled_res[7]);
+ }
+
+ a0 = r0 + r7;
+ a1 = r1 + r6;
+ a2 = r2 + r5;
+ a3 = r3 + r4;
+
+ a4 = a0 + a3;
+ a5 = a1 + a2;
+ a6 = a0 - a3;
+ a7 = a1 - a2;
+
+ pi2_out_tmp[0] = a4 + a5;
+
+ pi2_out_tmp[2] = a6 + (a7 >> 1);
+ pi2_out_tmp[4] = a4 - a5;
+ pi2_out_tmp[6] = (a6 >> 1) - a7;
+
+ a0 = r0 - r7;
+ a1 = r1 - r6;
+ a2 = r2 - r5;
+ a3 = r3 - r4;
+
+ a4 = a1 + a2 + ((a0 >> 1) + a0);
+ a5 = a0 - a3 - ((a2 >> 1) + a2);
+ a6 = a0 + a3 - ((a1 >> 1) + a1);
+ a7 = a1 - a2 + ((a3 >> 1) + a3);
+
+ pi2_out_tmp[1] = a4 + (a7 >> 2);
+ pi2_out_tmp[3] = a5 + (a6 >> 2);
+ pi2_out_tmp[5] = a6 - (a5 >> 2);
+ pi2_out_tmp[7] = (a4 >> 2) - a7;
+
+ pu1_src += i4_src_stride;
+ pu1_pred += i4_pred_stride;
+ pi2_out_tmp += 8;
+ pi2_upsampled_res += i4_upsampled_res_stride;
+ }
+
+ /*vertical transform and quant */
+
+ pi2_out_tmp = pi2_out;
+
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; ++i)
+ {
+ r0 = pi2_out_tmp[0];
+ r1 = pi2_out_tmp[8];
+ r2 = pi2_out_tmp[16];
+ r3 = pi2_out_tmp[24];
+ r4 = pi2_out_tmp[32];
+ r5 = pi2_out_tmp[40];
+ r6 = pi2_out_tmp[48];
+ r7 = pi2_out_tmp[56];
+
+ a0 = r0 + r7;
+ a1 = r1 + r6;
+ a2 = r2 + r5;
+ a3 = r3 + r4;
+
+ a4 = a0 + a3;
+ a5 = a1 + a2;
+ a6 = a0 - a3;
+ a7 = a1 - a2;
+
+ a0 = r0 - r7;
+ a1 = r1 - r6;
+ a2 = r2 - r5;
+ a3 = r3 - r4;
+
+ r0 = a4 + a5;
+ r2 = a6 + (a7 >> 1);
+ r4 = a4 - a5;
+ r6 = (a6 >> 1) - a7;
+
+ a4 = a1 + a2 + ((a0 >> 1) + a0);
+ a5 = a0 - a3 - ((a2 >> 1) + a2);
+ a6 = a0 + a3 - ((a1 >> 1) + a1);
+ a7 = a1 - a2 + ((a3 >> 1) + a3);
+
+ r1 = a4 + (a7 >> 2);
+ r3 = a5 + (a6 >> 2);
+ r5 = a6 - (a5 >> 2);
+ r7 = (a4 >> 2) - a7;
+
+ FWD_QUANT(r0, pu2_threshold_matrix[0], pu2_scale_matrix[0], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[0] = r0;
+
+ FWD_QUANT(r1, pu2_threshold_matrix[8], pu2_scale_matrix[8], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[8] = r1;
+
+ FWD_QUANT(r2, pu2_threshold_matrix[16], pu2_scale_matrix[16], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[16] = r2;
+
+ FWD_QUANT(r3, pu2_threshold_matrix[24], pu2_scale_matrix[24], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[24] = r3;
+
+ FWD_QUANT(r4, pu2_threshold_matrix[32], pu2_scale_matrix[32], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[32] = r4;
+
+ FWD_QUANT(r5, pu2_threshold_matrix[40], pu2_scale_matrix[40], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[40] = r5;
+
+ FWD_QUANT(r6, pu2_threshold_matrix[48], pu2_scale_matrix[48], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[48] = r6;
+
+ FWD_QUANT(r7, pu2_threshold_matrix[56], pu2_scale_matrix[56], u4_round_factor, u4_qbits,
+ u4_nonzero_coeff);
+ pi2_out_tmp[56] = r7;
+
+ pi2_out_tmp++;
+ pu2_scale_matrix++;
+ pu2_threshold_matrix++;
+ }
+ /* Return total nonzero coefficients in the current sub block */
+ *pu1_nnz = u4_nonzero_coeff;
+}
diff --git a/common/svc/isvc_structs.h b/common/svc/isvc_structs.h
new file mode 100644
index 0000000..7bdad1e
--- /dev/null
+++ b/common/svc/isvc_structs.h
@@ -0,0 +1,335 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvc_structs.h
+*
+* @brief
+* Contains struct definition used for SVC
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVC_STRUCTS_H_
+#define _ISVC_STRUCTS_H_
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+#include "isvc_defs.h"
+
+typedef struct buffer_container_t
+{
+ void *pv_data;
+
+ WORD32 i4_data_stride;
+
+} buffer_container_t;
+
+typedef struct yuv_buf_props_t
+{
+ buffer_container_t as_component_bufs[NUM_COMPONENTS];
+
+ IV_COLOR_FORMAT_T e_color_format;
+
+ UWORD32 u4_width;
+
+ UWORD32 u4_height;
+
+ UWORD8 u1_bit_depth;
+} yuv_buf_props_t;
+
+typedef struct nal_unit_header_t
+{
+ UWORD8 u1_nal_ref_idc;
+
+ UWORD8 u1_nal_unit_type;
+} nal_unit_header_t;
+
+typedef struct coordinates_t
+{
+ WORD32 i4_abscissa;
+
+ WORD32 i4_ordinate;
+} coordinates_t;
+
+typedef struct svc_au_buf_t
+{
+ /* Array of structs that contain properties of the buffers used for storing */
+ yuv_buf_props_t *ps_layer_yuv_buf_props;
+
+ /* Temporal ID */
+ WORD8 i1_temporal_id;
+
+ /* Num Spatial Layers */
+ UWORD8 u1_num_spatial_layers;
+
+ /* Resolution ration b/w spatial layers */
+ DOUBLE d_spatial_res_ratio;
+
+ /* absolute value of POC */
+ WORD32 i4_abs_poc;
+
+ /* POC % MaxPicOrderCntLSB */
+ WORD32 i4_poc_lsb;
+
+ /* Lower 32 bits of time stamp */
+ UWORD32 u4_timestamp_low;
+
+ /* Higher 32 bits of time stamp */
+ UWORD32 u4_timestamp_high;
+
+ /* Is Pic used as refPic for future frames? */
+ WORD32 i4_used_as_ref;
+
+ /* frame_num in the slice header */
+ WORD32 i4_frame_num;
+
+ /*
+ * 0: Top Field
+ * 1: Bottom Field
+ */
+ WORD8 i1_field_type;
+
+ /* buffer ID from frame buffer manager */
+ WORD32 i4_buf_id;
+
+} svc_au_buf_t;
+
+typedef struct svc_nalu_ext_t
+{
+ nal_unit_header_t s_nalu_header;
+
+ /* idr_flag */
+ UWORD8 u1_idr_flag;
+
+ /* priority_id (Range = [0, 63]) */
+ UWORD8 u1_priority_id;
+
+ /* no_inter_layer_pred_flag */
+ UWORD8 u1_no_inter_layer_pred_flag;
+
+ /* dependency_id (Range = [0, 7]) */
+ UWORD8 u1_dependency_id;
+
+ /* quality_id (Range = [0, 15]) */
+ UWORD8 u1_quality_id;
+
+ /* temporal_id (Range = [0, 7]) */
+ UWORD8 u1_temporal_id;
+
+ /* use_ref_base_pic_flag */
+ UWORD8 u1_use_ref_base_pic_flag;
+
+ /* discardable_flag */
+ UWORD8 u1_discardable_flag;
+
+ /* output_flag */
+ UWORD8 u1_output_flag;
+
+ /* reserved_three_2bits */
+ UWORD8 u1_reserved_three_2bits;
+
+} svc_nalu_ext_t;
+
+typedef struct svc_vui_ext_t
+{
+ /* specifies the maximum layers in the SVC bitstream */
+ UWORD32 u4_vui_ext_num_entries_minus1;
+
+ /* specifies the dependency ID for each layer */
+ UWORD8 u1_vui_ext_dependency_id[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the quality ID for each layer */
+ UWORD8 u1_vui_ext_quality_id[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the temporal ID for each layer */
+ UWORD8 u1_vui_ext_temporal_id[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the timing_info_present_flag value of the i-th sub-bitstream */
+ UWORD8 u1_vui_ext_timing_info_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the num_units_in_tick value of the i-th sub-bitstream */
+ UWORD32 u4_vui_ext_num_units_in_tick[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the time_scale value of the i-th sub-bitstream */
+ UWORD32 u4_vui_ext_time_scale[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the fixed_frame_rate_flag value of the i-th sub-bitstream */
+ UWORD8 u1_vui_ext_fixed_frame_rate_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the nal_hrd_parameters_present_flag value of the i-th */
+ UWORD8 u1_vui_ext_nal_hrd_params_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the vcl_hrd_parameters_present_flag value of the i-th */
+ UWORD8 u1_vui_ext_vcl_hrd_params_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the low_delay_hrd_flag value of the i-th sub-bitstream */
+ UWORD8 u1_vui_ext_low_delay_hrd_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+ /* specifies the pic_struct_present_flag value of the i-th sub-bitstream */
+ UWORD8 u1_vui_ext_pic_struct_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+
+} svc_vui_ext_t;
+
+typedef struct sps_svc_ext_t
+{
+ /* inter_layer_deblocking_filter_control_present_flag */
+ UWORD8 u1_inter_layer_deblocking_filter_control_present_flag;
+
+ /* extended_spatial_scalability_idc */
+ UWORD8 u1_extended_spatial_scalability_idc;
+
+ /* chroma_phase_x_plus1_flag */
+ UWORD8 u1_chroma_phase_x_plus1;
+
+ /* chroma_phase_y_plus1 */
+ UWORD8 u1_chroma_phase_y_plus1;
+
+ /* seq_ref_layer_chroma_phase_x_plus1_flag */
+ UWORD8 u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+
+ /* seq_ref_layer_chroma_phase_y_plus1 */
+ UWORD8 u1_seq_ref_layer_chroma_phase_y_plus1;
+
+ /* seq_scaled_ref_layer_left_offset */
+ WORD32 i4_seq_scaled_ref_layer_left_offset;
+
+ /* seq_scaled_ref_layer_top_offset */
+ WORD32 i4_seq_scaled_ref_layer_top_offset;
+
+ /* seq_scaled_ref_layer_right_offset */
+ WORD32 i4_seq_scaled_ref_layer_right_offset;
+
+ /* seq_scaled_ref_layer_bottom_offset */
+ WORD32 i4_seq_scaled_ref_layer_bottom_offset;
+
+ /* seq_tcoeff_level_prediction_flag */
+ WORD8 i1_seq_tcoeff_level_prediction_flag;
+
+ /* adaptive_tcoeff_level_prediction_flag */
+ WORD8 i1_adaptive_tcoeff_level_prediction_flag;
+
+ /* slice_header_restriction_flag */
+ WORD8 i1_slice_header_restriction_flag;
+
+} sps_svc_ext_t;
+
+typedef struct subset_sps_t
+{
+ /* SPS structure */
+ sps_t s_sps;
+
+ /* Structure containing flags specific to SVC SPS */
+ sps_svc_ext_t s_sps_svc_ext;
+
+ /* svc_vui_parameters_present_flag */
+ WORD8 i1_svc_vui_parameters_present_flag;
+
+ svc_vui_ext_t s_svc_vui;
+
+ /* additional_extension2_data_flag */
+ WORD8 i1_additional_extension2_flag;
+
+} subset_sps_t;
+
+typedef struct svc_slice_header_t
+{
+ /* ref_layer_dq_id */
+ UWORD32 u4_ref_layer_dq_id;
+
+ /* disable_inter_layer_deblocking_filter_idc */
+ UWORD32 u4_disable_inter_layer_deblocking_filter_idc;
+
+ /* inter_layer_slice_alpha_c0_offset_div2 */
+ WORD32 i4_inter_layer_slice_alpha_c0_offset_div2;
+
+ /* inter_layer_slice_beta_offset_div2 */
+ WORD32 i4_inter_layer_slice_beta_offset_div2;
+
+ /* constrained_intra_resampling_flag */
+ WORD8 i1_constrained_intra_resampling_flag;
+
+ /* ref_layer_chroma_phase_x_plus1_flag */
+ WORD8 i1_ref_layer_chroma_phase_x_plus1_flag;
+
+ /* ref_layer_chroma_phase_y_plus1 */
+ WORD8 i1_ref_layer_chroma_phase_y_plus1;
+
+ /* scaled_ref_layer_left_offset */
+ WORD32 i4_scaled_ref_layer_left;
+
+ /* scaled_ref_layer_top_offset */
+ WORD32 i4_scaled_ref_layer_top;
+
+ /* scaled_ref_layer_right_offset */
+ WORD32 i4_scaled_ref_layer_right;
+
+ /* scaled_ref_layer_bottom_offset */
+ WORD32 i4_scaled_ref_layer_bottom;
+
+ /* slice_skip_flag */
+ WORD8 i1_slice_skip_flag;
+
+ /* num_mbs_in_slice_minus1 */
+ UWORD32 u4_num_mbs_in_slice_minus1;
+
+ /* adaptive_base_mode_flag */
+ WORD8 i1_adaptive_base_mode_flag;
+
+ /* default_base_mode_flag */
+ WORD8 i1_default_base_mode_flag;
+
+ /* adaptive_motion_prediction_flag */
+ WORD8 i1_adaptive_motion_prediction_flag;
+
+ /* default_motion_prediction_flag */
+ WORD8 i1_default_motion_prediction_flag;
+
+ /* adaptive_residual_prediction_flag */
+ WORD8 i1_adaptive_residual_prediction_flag;
+
+ /* default_residual_prediction_flag */
+ WORD8 i1_default_residual_prediction_flag;
+
+ /* tcoeff_level_prediction_flag */
+ WORD8 i1_tcoeff_level_prediction_flag;
+
+ /* scan_idx_start */
+ UWORD32 u4_scan_idx_start;
+
+ /* scan_idx_end */
+ UWORD32 u4_scan_idx_end;
+
+ WORD32 i4_store_ref_base_pic_flag;
+
+ slice_header_t s_slice_header;
+} svc_slice_header_t;
+
+#endif
diff --git a/common/svc/isvc_trans_quant_itrans_iquant.h b/common/svc/isvc_trans_quant_itrans_iquant.h
new file mode 100644
index 0000000..fd15dcc
--- /dev/null
+++ b/common/svc/isvc_trans_quant_itrans_iquant.h
@@ -0,0 +1,253 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_trans_quant.h
+ *
+ * @brief
+ * Contains declarations for forward and inverse transform paths for H264
+ *
+ * @author
+ * Ittiam
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVC_TRANS_QUANT_ITRANS_IQUANT_H_
+#define _ISVC_TRANS_QUANT_ITRANS_IQUANT_H_
+
+#include <stdint.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_macros.h"
+#include "isvc_macros.h"
+#include "isvc_structs.h"
+
+/* With and without residual_pred use */
+#define NUM_RESI_TRANS_QUANT_VARIANTS 2
+
+#define NUM_IQ_IT_RECON_VARIANTS 3
+
+/* Structs */
+typedef struct resi_trans_quant_constants_t
+{
+ const UWORD16 *pu2_scale_matrix;
+
+ const UWORD16 *pu2_threshold_matrix;
+
+ UWORD32 u4_qbits;
+
+ UWORD32 u4_round_factor;
+} resi_trans_quant_constants_t;
+
+typedef struct iq_it_res_rec_constants_t
+{
+ const UWORD16 *pu2_iscal_mat;
+
+ const UWORD16 *pu2_weigh_mat;
+
+ UWORD32 u4_qp_div_6;
+} iq_it_res_rec_constants_t;
+
+/* Typedefs */
+typedef void FT_RESI_TRANS_DCTRANS_QUANT(UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out,
+ WORD32 src_strd, WORD32 pred_strd, WORD32 dst_strd,
+ const UWORD16 *pu2_scale_mat,
+ const UWORD16 *pu2_thresh_mat, UWORD32 u4_qbit,
+ UWORD32 u4_round_fact, UWORD8 *pu1_nnz);
+
+typedef void FT_IDCTRANS_IQUANT_ITRANS_RECON(WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out,
+ WORD32 src_strd, WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ UWORD32 pi4_cntrl, WORD32 *pi4_tmp);
+
+typedef void FT_RESI_TRANS_QUANT(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out, buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz,
+ WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res);
+
+typedef void FT_LUMA_16X16_RESI_TRANS_DCTRANS_QUANT(
+ UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, WORD32 src_strd, WORD32 pred_strd,
+ WORD32 dst_strd, const UWORD16 *pu2_scale_matrix, const UWORD16 *pu2_threshold_matrix,
+ UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD8 *pu1_nnz, UWORD32 u4_dc_flag);
+
+typedef void FT_CHROMA_8X8_RESI_TRANS_DCTRANS_QUANT(
+ UWORD8 *pu1_src, UWORD8 *pu1_pred, WORD16 *pi2_out, WORD32 src_strd, WORD32 pred_strd,
+ WORD32 dst_strd, const UWORD16 *pu2_scale_matrix, const UWORD16 *pu2_threshold_matrix,
+ UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD8 *pu1_nnz);
+
+typedef void FT_IQ_IT_RECON(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp,
+ WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate);
+
+typedef void FT_LUMA_16X16_IDCTRANS_IQUANT_ITRANS_RECON(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, WORD32 src_strd, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ UWORD32 pi4_cntrl, UWORD32 u4_dc_trans_flag, WORD32 *pi4_tmp);
+
+typedef void FT_CHROMA_8X8_IDCTRANS_IQUANT_ITRANS_RECON(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, UWORD8 *pu1_out, WORD32 src_strd, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ UWORD32 pi4_cntrl, WORD32 *pi4_tmp);
+
+typedef void FT_IHADAMARD_SCALING(WORD16 *pi2_src, WORD16 *pi2_out, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD32 *pi4_tmp);
+
+typedef void FT_HADAMARD_QUANT(WORD16 *pi2_src, WORD16 *pi2_dst,
+ resi_trans_quant_constants_t *ps_quant_constants, UWORD8 *pu1_nnz);
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_8x8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc;
+extern FT_IQ_IT_RECON isvc_zcbf_iquant_itrans_recon_4x4;
+extern FT_IQ_IT_RECON isvc_chroma_zcbf_iquant_itrans_recon_4x4;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_4x4;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_2x2_uv;
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_4x4;
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_2x2_uv;
+
+/* A9 Declarations */
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_a9;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_dc_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_a9;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_a9;
+extern FT_LUMA_16X16_RESI_TRANS_DCTRANS_QUANT isvc_luma_16x16_resi_trans_dctrans_quant_a9;
+extern FT_CHROMA_8X8_RESI_TRANS_DCTRANS_QUANT isvc_chroma_8x8_resi_trans_dctrans_quant_a9;
+extern FT_LUMA_16X16_IDCTRANS_IQUANT_ITRANS_RECON isvc_luma_16x16_idctrans_iquant_itrans_recon_a9;
+extern FT_CHROMA_8X8_IDCTRANS_IQUANT_ITRANS_RECON isvc_chroma_8x8_idctrans_iquant_itrans_recon_a9;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_4x4_a9;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_2x2_uv_a9;
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_4x4_a9;
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_2x2_uv_a9;
+
+/* Av8 Declarations */
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_av8;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_dc_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_av8;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_av8;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_4x4_av8;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_2x2_uv_av8;
+
+/* NEON Declarations */
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_neon;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_with_residual_sub_neon;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_neon;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_with_residual_sub_neon;
+
+/* SSSE3 Declarations */
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_ssse3;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_ssse3;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_ssse3;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_8x8_dc_ssse3;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_ssse3;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_4x4_ssse3;
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_2x2_uv_ssse3;
+
+/* SSSE42 Declarations */
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_sse42;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_4x4_with_res_pred_sse42;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_sse42;
+extern FT_RESI_TRANS_QUANT isvc_resi_trans_quant_chroma_4x4_with_res_pred_sse42;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_4x4_with_res_acc_sse42;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_chroma_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_chroma_4x4_with_res_acc_sse42;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_dc_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_dc_4x4_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_dc_with_res_acc_4x4_sse42;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_chroma_4x4_dc_sse42;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_res_chroma_4x4_dc_with_res_acc_sse42;
+
+extern FT_IHADAMARD_SCALING ih264_ihadamard_scaling_4x4_sse42;
+
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_4x4_sse42;
+extern FT_HADAMARD_QUANT isvc_hadamard_quant_2x2_uv_sse42;
+
+/* NEON Declarations */
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_with_res_output_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_with_res_accumulate_neon;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_with_res_output_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_with_res_accumulate_neon;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_with_res_output_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_4x4_dc_with_res_accumulate_neon;
+
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_output_neon;
+extern FT_IQ_IT_RECON isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_accumulate_neon;
+
+static FORCEINLINE UWORD8 isvc_get_resi_trans_quant_variant_idx(UWORD8 u1_use_upsampled_res)
+{
+ return u1_use_upsampled_res;
+}
+
+static FORCEINLINE UWORD8 isvc_get_iq_it_recon_variant_idx(UWORD8 u1_is_intra,
+ UWORD8 u1_res_accumulate)
+{
+ ASSERT(!((1 == u1_is_intra) && (1 == u1_res_accumulate)));
+
+ return u1_is_intra * 2 + u1_res_accumulate;
+}
+
+static FORCEINLINE WORD16 isvc_get_residue(WORD16 i2_it_out, WORD16 i2_res_pred,
+ UWORD8 u1_res_accumulate)
+{
+ return (u1_res_accumulate
+ ? (CLIP3(-((WORD16) UINT8_MAX), ((WORD16) UINT8_MAX), i2_it_out + i2_res_pred))
+ : (CLIP3(-((WORD16) UINT8_MAX), ((WORD16) UINT8_MAX), i2_it_out)));
+}
+
+#endif
diff --git a/common/svccommon.cmake b/common/svccommon.cmake
new file mode 100644
index 0000000..89785db
--- /dev/null
+++ b/common/svccommon.cmake
@@ -0,0 +1,39 @@
+# src files
+list(
+ APPEND
+ LIBAVC_COMMON_SRCS
+ "${AVC_ROOT}/common/svc/isvc_common_tables.c"
+ "${AVC_ROOT}/common/svc/isvc_cabac_tables.c"
+ "${AVC_ROOT}/common/svc/isvc_intra_resample.c"
+ "${AVC_ROOT}/common/svc/isvc_iquant_itrans_recon.c"
+ "${AVC_ROOT}/common/svc/isvc_mem_fns.c"
+ "${AVC_ROOT}/common/svc/isvc_resi_trans_quant.c")
+
+include_directories(${AVC_ROOT}/common/svc)
+
+# arm/x86 sources
+if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR
+ "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch32")
+ list(
+ APPEND
+ LIBAVC_COMMON_ASMS
+ "${AVC_ROOT}/common/arm/svc/isvc_intra_sampling_neon.c"
+ "${AVC_ROOT}/common/arm/svc/isvc_iquant_itrans_recon_neon.c"
+ "${AVC_ROOT}/common/arm/svc/isvc_mem_fns_neon.c"
+ "${AVC_ROOT}/common/arm/svc/isvc_resi_trans_quant_neon.c")
+ include_directories(${AVC_ROOT}/common/arm/svc)
+else()
+ list(
+ APPEND
+ LIBAVC_COMMON_SRCS
+ "${AVC_ROOT}/common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_iquant_itrans_recon_sse42.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_iquant_itrans_recon_ssse3.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_mem_fns_sse42.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_mem_fns_ssse3.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_padding_ssse3.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_resi_trans_quant_sse42.c"
+ "${AVC_ROOT}/common/x86/svc/isvc_intra_resample_sse42.c")
+
+ include_directories(${AVC_ROOT}/common/x86/svc)
+endif()
diff --git a/common/x86/svc/isvc_intra_resample_sse42.c b/common/x86/svc/isvc_intra_resample_sse42.c
new file mode 100644
index 0000000..cc790da
--- /dev/null
+++ b/common/x86/svc/isvc_intra_resample_sse42.c
@@ -0,0 +1,658 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+
+ * * \file ih264d_resamp_svc.c
+ *
+ * \brief
+ * Contains routines that
+ * resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ *
+ * \author
+
+ * **************************************************************************
+
+ */
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "isvc_intra_resample.h"
+
+void isvc_interpolate_base_luma_dyadic_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_y;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3;
+ __m128i i4_samp_8x16b_0, i4_samp_8x16b_1, i4_samp_8x16b_2, i4_samp_8x16b_3;
+ __m128i i4_res_8x16b_r1_1, i4_res_8x16b_r1_2, i4_res_8x16b_r1_3;
+ __m128i i4_res_8x16b_r2_1, i4_res_8x16b_r2_2, i4_res_8x16b_r2_3;
+
+ /* Filter coefficient values for phase 4 */
+ __m128i i4_coeff_8x16b_0 = _mm_set1_epi16(-3);
+ __m128i i4_coeff_8x16b_1 = _mm_set1_epi16(28);
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+
+ /* Initializing pointers */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ /*First 64 bit */
+ /* y = 0, y_phase = 12 */
+ i4_samp_16x8b_0 = _mm_loadl_epi64((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadl_epi64((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ pu1_inp += (i4_src_stride << 2);
+ i4_samp_8x16b_0 = _mm_cvtepu8_epi16(i4_samp_16x8b_0);
+ i4_samp_8x16b_1 = _mm_cvtepu8_epi16(i4_samp_16x8b_1);
+ i4_samp_8x16b_2 = _mm_cvtepu8_epi16(i4_samp_16x8b_2);
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(i4_samp_16x8b_3);
+
+ /* since y_phase 12 for y = 0 */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_0);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ //*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ /* Store the output */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ /*Remaining 32 bit */
+ pu1_inp += 8;
+ pi2_tmp += 8;
+
+ /* y = 0, y_phase = 12 */
+ i4_samp_16x8b_0 = _mm_loadl_epi64((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadl_epi64((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 =
+ _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ pu1_inp += (i4_src_stride << 2);
+ i4_samp_8x16b_0 = _mm_cvtepu8_epi16(i4_samp_16x8b_0);
+ i4_samp_8x16b_1 = _mm_cvtepu8_epi16(i4_samp_16x8b_1);
+ i4_samp_8x16b_2 = _mm_cvtepu8_epi16(i4_samp_16x8b_2);
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(i4_samp_16x8b_3);
+
+ /* since y_phase 12 for y = 0 */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_0);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ //*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ /* Store the output */
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ {
+ __m128i coeff_c0_c1_8x16b = _mm_set_epi16(28, -3, 28, -3, 28, -3, 28, -3);
+ __m128i coeff_c2_c3_8x16b = _mm_set_epi16(-1, 8, -1, 8, -1, 8, -1, 8);
+ __m128i coeff_c3_c2_8x16b = _mm_set_epi16(8, -1, 8, -1, 8, -1, 8, -1);
+ __m128i coeff_c1_c0_8x16b = _mm_set_epi16(-3, 28, -3, 28, -3, 28, -3, 28);
+
+ __m128i i4_samp_8x16b_rpart1_0, i4_samp_8x16b_rpart2_0;
+ __m128i i4_samp_8x16b_rpart1_1, i4_samp_8x16b_rpart2_1;
+ __m128i i4_samp_8x16b_rpart1_2, i4_samp_8x16b_rpart2_2;
+ __m128i i4_samp_8x16b_rpart1_3, i4_samp_8x16b_rpart2_3;
+ __m128i i4_samp_8x16b_rpart1_4, i4_samp_8x16b_rpart2_4;
+
+ __m128i i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart2_0;
+ __m128i i4_res_4x32b_rpart1_1, i4_res_4x32b_rpart2_1;
+ __m128i i4_res_4x32b_rpart1_2, i4_res_4x32b_rpart2_2;
+ __m128i i4_res_4x32b_rpart1_3, i4_res_4x32b_rpart2_3;
+
+ __m128i res_512 = _mm_set1_epi32(512);
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ i4_samp_8x16b_rpart1_0 = _mm_loadu_si128((__m128i *) pi2_tmp);
+ i4_samp_8x16b_rpart2_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 4));
+
+ i4_samp_8x16b_rpart1_1 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 2);
+ i4_samp_8x16b_rpart1_2 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 4);
+ i4_samp_8x16b_rpart1_3 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 6);
+ i4_samp_8x16b_rpart1_4 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 8);
+
+ i4_samp_8x16b_rpart2_1 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 2);
+ i4_samp_8x16b_rpart2_2 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 4);
+ i4_samp_8x16b_rpart2_3 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 6);
+ i4_samp_8x16b_rpart2_4 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 8);
+
+ i4_samp_8x16b_rpart1_0 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_0, i4_samp_8x16b_rpart1_1);
+ i4_samp_8x16b_rpart1_1 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_1, i4_samp_8x16b_rpart1_2);
+ i4_samp_8x16b_rpart1_2 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_2, i4_samp_8x16b_rpart1_3);
+ i4_samp_8x16b_rpart1_3 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_3, i4_samp_8x16b_rpart1_4);
+
+ i4_samp_8x16b_rpart2_0 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_0, i4_samp_8x16b_rpart2_1);
+ i4_samp_8x16b_rpart2_1 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_1, i4_samp_8x16b_rpart2_2);
+ i4_samp_8x16b_rpart2_2 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_2, i4_samp_8x16b_rpart2_3);
+ i4_samp_8x16b_rpart2_3 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_3, i4_samp_8x16b_rpart2_4);
+
+ i4_res_4x32b_rpart1_0 = _mm_madd_epi16(i4_samp_8x16b_rpart1_0, coeff_c3_c2_8x16b);
+ i4_res_4x32b_rpart1_2 = _mm_madd_epi16(i4_samp_8x16b_rpart1_2, coeff_c1_c0_8x16b);
+
+ i4_res_4x32b_rpart1_1 = _mm_madd_epi16(i4_samp_8x16b_rpart1_1, coeff_c0_c1_8x16b);
+ i4_res_4x32b_rpart1_3 = _mm_madd_epi16(i4_samp_8x16b_rpart1_3, coeff_c2_c3_8x16b);
+
+ i4_res_4x32b_rpart2_0 = _mm_madd_epi16(i4_samp_8x16b_rpart2_0, coeff_c3_c2_8x16b);
+ i4_res_4x32b_rpart2_2 = _mm_madd_epi16(i4_samp_8x16b_rpart2_2, coeff_c1_c0_8x16b);
+
+ i4_res_4x32b_rpart2_1 = _mm_madd_epi16(i4_samp_8x16b_rpart2_1, coeff_c0_c1_8x16b);
+ i4_res_4x32b_rpart2_3 = _mm_madd_epi16(i4_samp_8x16b_rpart2_3, coeff_c2_c3_8x16b);
+
+ i4_res_4x32b_rpart1_0 = _mm_add_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_2);
+ i4_res_4x32b_rpart1_1 = _mm_add_epi32(i4_res_4x32b_rpart1_1, i4_res_4x32b_rpart1_3);
+
+ i4_res_4x32b_rpart2_0 = _mm_add_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_2);
+ i4_res_4x32b_rpart2_1 = _mm_add_epi32(i4_res_4x32b_rpart2_1, i4_res_4x32b_rpart2_3);
+
+ i4_res_4x32b_rpart1_2 =
+ _mm_unpacklo_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1);
+ i4_res_4x32b_rpart1_3 =
+ _mm_unpackhi_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1);
+
+ i4_res_4x32b_rpart2_2 =
+ _mm_unpacklo_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1);
+ i4_res_4x32b_rpart2_3 =
+ _mm_unpackhi_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1);
+
+ i4_res_4x32b_rpart1_0 = _mm_add_epi32(i4_res_4x32b_rpart1_2, res_512);
+ i4_res_4x32b_rpart1_1 = _mm_add_epi32(i4_res_4x32b_rpart1_3, res_512);
+
+ i4_res_4x32b_rpart1_0 = _mm_srai_epi32(i4_res_4x32b_rpart1_0, 10);
+ i4_res_4x32b_rpart1_1 = _mm_srai_epi32(i4_res_4x32b_rpart1_1, 10);
+
+ i4_res_4x32b_rpart2_0 = _mm_add_epi32(i4_res_4x32b_rpart2_2, res_512);
+ i4_res_4x32b_rpart2_1 = _mm_add_epi32(i4_res_4x32b_rpart2_3, res_512);
+
+ i4_res_4x32b_rpart2_0 = _mm_srai_epi32(i4_res_4x32b_rpart2_0, 10);
+ i4_res_4x32b_rpart2_1 = _mm_srai_epi32(i4_res_4x32b_rpart2_1, 10);
+
+ _mm_storeu_si128(
+ (__m128i *) pu1_out,
+ _mm_packus_epi16(_mm_packus_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1),
+ _mm_packus_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1)));
+
+ pi2_tmp += i4_filt_stride;
+ pu1_out += i4_out_stride;
+
+ } /* End of loop over y */
+ }
+}
+
+void isvc_vert_interpol_chroma_dyadic_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD8 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3, i4_samp_16x8b_4,
+ i4_samp_16x8b_5;
+ __m128i i4_res_8x16b_r0, i4_res_8x16b_r1, i4_res_8x16b_r2, i4_res_8x16b_r3, i4_res_8x16b_r4,
+ i4_res_8x16b_r5, i4_res_8x16b_r6, i4_res_8x16b_r7;
+ __m128i i4_res_8x16b_r7_temp;
+ __m128i i4_c0_c1_16x8b, i4_c2_c3_16x8b;
+
+ i4_coeff_0 = (WORD8) (16 - i4_phase_0);
+ i4_coeff_1 = (WORD8) (i4_phase_0);
+ i4_coeff_2 = (WORD8) (16 - i4_phase_1);
+ i4_coeff_3 = (WORD8) (i4_phase_1);
+
+ i4_c0_c1_16x8b =
+ _mm_set_epi8(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ i4_c2_c3_16x8b =
+ _mm_set_epi8(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2);
+
+ /* Initializing pointers */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ i4_samp_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ i4_samp_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 2)));
+ i4_samp_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 2) + i4_src_stride));
+
+ i4_samp_16x8b_0 = _mm_unpacklo_epi8(i4_samp_16x8b_0, i4_samp_16x8b_1);
+ i4_res_8x16b_r0 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp), i4_res_8x16b_r0);
+
+ i4_samp_16x8b_1 = _mm_unpacklo_epi8(i4_samp_16x8b_1, i4_samp_16x8b_2);
+ i4_res_8x16b_r1 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r1);
+
+ i4_res_8x16b_r2 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1)), i4_res_8x16b_r2);
+
+ i4_samp_16x8b_2 = _mm_unpacklo_epi8(i4_samp_16x8b_2, i4_samp_16x8b_3);
+ i4_res_8x16b_r3 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1) + i4_filt_stride),
+ i4_res_8x16b_r3);
+
+ i4_res_8x16b_r4 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2)), i4_res_8x16b_r4);
+
+ i4_samp_16x8b_3 = _mm_unpacklo_epi8(i4_samp_16x8b_3, i4_samp_16x8b_4);
+ i4_res_8x16b_r5 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + i4_filt_stride),
+ i4_res_8x16b_r5);
+
+ i4_res_8x16b_r6 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c0_c1_16x8b);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1)),
+ i4_res_8x16b_r6);
+
+ i4_res_8x16b_r6 = _mm_shuffle_epi32(i4_res_8x16b_r6, 78);
+
+ i4_samp_16x8b_4 = _mm_unpacklo_epi8(i4_samp_16x8b_4, i4_samp_16x8b_5);
+
+ i4_res_8x16b_r7 = _mm_maddubs_epi16(i4_samp_16x8b_4, i4_c2_c3_16x8b);
+
+ i4_res_8x16b_r7 = _mm_shuffle_epi32(i4_res_8x16b_r7, 147);
+
+ i4_res_8x16b_r7_temp = _mm_blend_epi16(i4_res_8x16b_r6, i4_res_8x16b_r7, 252);
+
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1) + 4),
+ i4_res_8x16b_r7_temp);
+}
+
+void isvc_horz_interpol_chroma_dyadic_sse42(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_dst_stride, i4_dst_stride2, i4_dst_stride4;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ __m128i i4_samp_8x16b_r1_0, i4_samp_8x16b_r1_1, i4_samp_8x16b_r1_2;
+ __m128i i4_samp_8x16b_r2_0, i4_samp_8x16b_r2_1, i4_samp_8x16b_r2_2;
+ __m128i i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1, i4_samp_8x16b_r3_2;
+ __m128i i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1, i4_samp_8x16b_r4_2;
+ __m128i i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1, i4_samp_8x16b_r5_2;
+ __m128i i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1, i4_samp_8x16b_r6_2;
+ __m128i i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1, i4_samp_8x16b_r7_2;
+ __m128i i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1, i4_samp_8x16b_r8_2;
+
+ __m128i i4_res_4x32b_r1_0, i4_res_4x32b_r1_1;
+ __m128i i4_res_4x32b_r2_0, i4_res_4x32b_r2_1;
+ __m128i i4_res_4x32b_r3_0, i4_res_4x32b_r3_1;
+ __m128i i4_res_4x32b_r4_0, i4_res_4x32b_r4_1;
+ __m128i i4_res_4x32b_r5_0, i4_res_4x32b_r5_1;
+ __m128i i4_res_4x32b_r6_0, i4_res_4x32b_r6_1;
+ __m128i i4_res_4x32b_r7_0, i4_res_4x32b_r7_1;
+ __m128i i4_res_4x32b_r8_0, i4_res_4x32b_r8_1;
+
+ __m128i i4_res_final_8x16b_r1, i4_res_final_8x16b_r2, i4_res_final_8x16b_r3,
+ i4_res_final_8x16b_r4, i4_res_final_8x16b_r5, i4_res_final_8x16b_r6, i4_res_final_8x16b_r7,
+ i4_res_final_8x16b_r8;
+
+ __m128i out_16x8b_r1, out_16x8b_r2, out_16x8b_r3, out_16x8b_r4, out_16x8b_r5, out_16x8b_r6,
+ out_16x8b_r7, out_16x8b_r8;
+
+ __m128i i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1;
+ __m128i i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1;
+ __m128i i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1;
+ __m128i i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1;
+ __m128i chroma_mask, chroma_mask2;
+
+ WORD32 i4_coeff_0 = 16 - i4_phase_0;
+ WORD32 i4_coeff_1 = i4_phase_0;
+ WORD32 i4_coeff_2 = 16 - i4_phase_1;
+ WORD32 i4_coeff_3 = i4_phase_1;
+ __m128i coeff_c0_c1_8x16b = _mm_set_epi16(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ __m128i coeff_c2_c3_8x16b = _mm_set_epi16(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2);
+ __m128i res_128 = _mm_set1_epi32(128);
+ UWORD32 u4_norm_factor = 8;
+
+ /* Initializing pointers */
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_dst_stride = i4_out_stride;
+
+ i4_dst_stride2 = i4_dst_stride << 1;
+ i4_dst_stride4 = i4_dst_stride << 2;
+
+ /* Horizontal interpolation */
+ i4_samp_8x16b_r1_0 = _mm_loadu_si128((__m128i *) pi2_tmp);
+ i4_samp_8x16b_r2_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 6));
+ i4_samp_8x16b_r3_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 12));
+ i4_samp_8x16b_r4_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 18));
+ i4_samp_8x16b_r5_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 24));
+ i4_samp_8x16b_r6_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 30));
+ i4_samp_8x16b_r7_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 36));
+ i4_samp_8x16b_r8_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 42));
+
+ i4_samp_8x16b_r1_1 = _mm_srli_si128(i4_samp_8x16b_r1_0, 2);
+ i4_samp_8x16b_r1_2 = _mm_srli_si128(i4_samp_8x16b_r1_0, 4);
+
+ i4_samp_8x16b_r2_1 = _mm_srli_si128(i4_samp_8x16b_r2_0, 2);
+ i4_samp_8x16b_r2_2 = _mm_srli_si128(i4_samp_8x16b_r2_0, 4);
+
+ i4_samp_8x16b_r3_1 = _mm_srli_si128(i4_samp_8x16b_r3_0, 2);
+ i4_samp_8x16b_r3_2 = _mm_srli_si128(i4_samp_8x16b_r3_0, 4);
+
+ i4_samp_8x16b_r4_1 = _mm_srli_si128(i4_samp_8x16b_r4_0, 2);
+ i4_samp_8x16b_r4_2 = _mm_srli_si128(i4_samp_8x16b_r4_0, 4);
+
+ i4_samp_8x16b_r5_1 = _mm_srli_si128(i4_samp_8x16b_r5_0, 2);
+ i4_samp_8x16b_r5_2 = _mm_srli_si128(i4_samp_8x16b_r5_0, 4);
+
+ i4_samp_8x16b_r6_1 = _mm_srli_si128(i4_samp_8x16b_r6_0, 2);
+ i4_samp_8x16b_r6_2 = _mm_srli_si128(i4_samp_8x16b_r6_0, 4);
+
+ i4_samp_8x16b_r7_1 = _mm_srli_si128(i4_samp_8x16b_r7_0, 2);
+ i4_samp_8x16b_r7_2 = _mm_srli_si128(i4_samp_8x16b_r7_0, 4);
+
+ i4_samp_8x16b_r8_1 = _mm_srli_si128(i4_samp_8x16b_r8_0, 2);
+ i4_samp_8x16b_r8_2 = _mm_srli_si128(i4_samp_8x16b_r8_0, 4);
+
+ i4_samp_8x16b_r1_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r1_0, i4_samp_8x16b_r1_1);
+ i4_samp_8x16b_r2_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r2_0, i4_samp_8x16b_r2_1);
+ i4_samp_8x16b_r3_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1);
+ i4_samp_8x16b_r4_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1);
+ i4_samp_8x16b_r5_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1);
+ i4_samp_8x16b_r6_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1);
+ i4_samp_8x16b_r7_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1);
+ i4_samp_8x16b_r8_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1);
+
+ i4_samp_8x16b_r1_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r1_1, i4_samp_8x16b_r1_2);
+ i4_samp_8x16b_r2_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r2_1, i4_samp_8x16b_r2_2);
+ i4_samp_8x16b_r3_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r3_1, i4_samp_8x16b_r3_2);
+ i4_samp_8x16b_r4_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r4_1, i4_samp_8x16b_r4_2);
+ i4_samp_8x16b_r5_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r5_1, i4_samp_8x16b_r5_2);
+ i4_samp_8x16b_r6_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r6_1, i4_samp_8x16b_r6_2);
+ i4_samp_8x16b_r7_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r7_1, i4_samp_8x16b_r7_2);
+ i4_samp_8x16b_r8_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r8_1, i4_samp_8x16b_r8_2);
+
+ // a0c0 + a1c1 a1c0 + a2c1 a2c0 + a3c1 a3c0 + a4c1
+ i4_res_4x32b_r1_0 = _mm_madd_epi16(i4_samp_8x16b_r1_0, coeff_c0_c1_8x16b);
+ // b0c0+b1c1 b1c0+b2c1 b2c0+b3c1 b3c0+b4c1
+ i4_res_4x32b_r2_0 = _mm_madd_epi16(i4_samp_8x16b_r2_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r3_0 = _mm_madd_epi16(i4_samp_8x16b_r3_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r4_0 = _mm_madd_epi16(i4_samp_8x16b_r4_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r5_0 = _mm_madd_epi16(i4_samp_8x16b_r5_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r6_0 = _mm_madd_epi16(i4_samp_8x16b_r6_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r7_0 = _mm_madd_epi16(i4_samp_8x16b_r7_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r8_0 = _mm_madd_epi16(i4_samp_8x16b_r8_0, coeff_c0_c1_8x16b);
+
+ // a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3
+ i4_res_4x32b_r1_1 = _mm_madd_epi16(i4_samp_8x16b_r1_1, coeff_c2_c3_8x16b);
+ // b1c2+b2c3 b2c2+b3c3 b3c2+b4c3 b4c2+b5c3
+ i4_res_4x32b_r2_1 = _mm_madd_epi16(i4_samp_8x16b_r2_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r3_1 = _mm_madd_epi16(i4_samp_8x16b_r3_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r4_1 = _mm_madd_epi16(i4_samp_8x16b_r4_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r5_1 = _mm_madd_epi16(i4_samp_8x16b_r5_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r6_1 = _mm_madd_epi16(i4_samp_8x16b_r6_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r7_1 = _mm_madd_epi16(i4_samp_8x16b_r7_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r8_1 = _mm_madd_epi16(i4_samp_8x16b_r8_1, coeff_c2_c3_8x16b);
+
+ i4_res_4x32b_r1_0 = _mm_add_epi32(i4_res_4x32b_r1_0, res_128);
+ i4_res_4x32b_r2_0 = _mm_add_epi32(i4_res_4x32b_r2_0, res_128);
+ i4_res_4x32b_r3_0 = _mm_add_epi32(i4_res_4x32b_r3_0, res_128);
+ i4_res_4x32b_r4_0 = _mm_add_epi32(i4_res_4x32b_r4_0, res_128);
+ i4_res_4x32b_r5_0 = _mm_add_epi32(i4_res_4x32b_r5_0, res_128);
+ i4_res_4x32b_r6_0 = _mm_add_epi32(i4_res_4x32b_r6_0, res_128);
+ i4_res_4x32b_r7_0 = _mm_add_epi32(i4_res_4x32b_r7_0, res_128);
+ i4_res_4x32b_r8_0 = _mm_add_epi32(i4_res_4x32b_r8_0, res_128);
+
+ i4_res_4x32b_r1_1 = _mm_add_epi32(i4_res_4x32b_r1_1, res_128);
+ i4_res_4x32b_r2_1 = _mm_add_epi32(i4_res_4x32b_r2_1, res_128);
+ i4_res_4x32b_r3_1 = _mm_add_epi32(i4_res_4x32b_r3_1, res_128);
+ i4_res_4x32b_r4_1 = _mm_add_epi32(i4_res_4x32b_r4_1, res_128);
+ i4_res_4x32b_r5_1 = _mm_add_epi32(i4_res_4x32b_r5_1, res_128);
+ i4_res_4x32b_r6_1 = _mm_add_epi32(i4_res_4x32b_r6_1, res_128);
+ i4_res_4x32b_r7_1 = _mm_add_epi32(i4_res_4x32b_r7_1, res_128);
+ i4_res_4x32b_r8_1 = _mm_add_epi32(i4_res_4x32b_r8_1, res_128);
+
+ i4_res_4x32b_r1_0 = _mm_srai_epi32(i4_res_4x32b_r1_0, u4_norm_factor);
+ i4_res_4x32b_r2_0 = _mm_srai_epi32(i4_res_4x32b_r2_0, u4_norm_factor);
+ i4_res_4x32b_r3_0 = _mm_srai_epi32(i4_res_4x32b_r3_0, u4_norm_factor);
+ i4_res_4x32b_r4_0 = _mm_srai_epi32(i4_res_4x32b_r4_0, u4_norm_factor);
+ i4_res_4x32b_r5_0 = _mm_srai_epi32(i4_res_4x32b_r5_0, u4_norm_factor);
+ i4_res_4x32b_r6_0 = _mm_srai_epi32(i4_res_4x32b_r6_0, u4_norm_factor);
+ i4_res_4x32b_r7_0 = _mm_srai_epi32(i4_res_4x32b_r7_0, u4_norm_factor);
+ i4_res_4x32b_r8_0 = _mm_srai_epi32(i4_res_4x32b_r8_0, u4_norm_factor);
+
+ i4_res_4x32b_r1_1 = _mm_srai_epi32(i4_res_4x32b_r1_1, u4_norm_factor);
+ i4_res_4x32b_r2_1 = _mm_srai_epi32(i4_res_4x32b_r2_1, u4_norm_factor);
+ i4_res_4x32b_r3_1 = _mm_srai_epi32(i4_res_4x32b_r3_1, u4_norm_factor);
+ i4_res_4x32b_r4_1 = _mm_srai_epi32(i4_res_4x32b_r4_1, u4_norm_factor);
+ i4_res_4x32b_r5_1 = _mm_srai_epi32(i4_res_4x32b_r5_1, u4_norm_factor);
+ i4_res_4x32b_r6_1 = _mm_srai_epi32(i4_res_4x32b_r6_1, u4_norm_factor);
+ i4_res_4x32b_r7_1 = _mm_srai_epi32(i4_res_4x32b_r7_1, u4_norm_factor);
+ i4_res_4x32b_r8_1 = _mm_srai_epi32(i4_res_4x32b_r8_1, u4_norm_factor);
+
+ i4_res_final_8x16b_r12_0 = _mm_packs_epi32(i4_res_4x32b_r1_0, i4_res_4x32b_r2_0);
+ i4_res_final_8x16b_r34_0 = _mm_packs_epi32(i4_res_4x32b_r3_0, i4_res_4x32b_r4_0);
+ i4_res_final_8x16b_r56_0 = _mm_packs_epi32(i4_res_4x32b_r5_0, i4_res_4x32b_r6_0);
+ i4_res_final_8x16b_r67_0 = _mm_packs_epi32(i4_res_4x32b_r7_0, i4_res_4x32b_r8_0);
+
+ i4_res_final_8x16b_r12_1 = _mm_packs_epi32(i4_res_4x32b_r1_1, i4_res_4x32b_r2_1);
+ i4_res_final_8x16b_r34_1 = _mm_packs_epi32(i4_res_4x32b_r3_1, i4_res_4x32b_r4_1);
+ i4_res_final_8x16b_r56_1 = _mm_packs_epi32(i4_res_4x32b_r5_1, i4_res_4x32b_r6_1);
+ i4_res_final_8x16b_r67_1 = _mm_packs_epi32(i4_res_4x32b_r7_1, i4_res_4x32b_r8_1);
+
+ i4_res_final_8x16b_r1 = _mm_unpacklo_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r2 = _mm_unpackhi_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r3 = _mm_unpacklo_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r4 = _mm_unpackhi_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r5 = _mm_unpacklo_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r6 = _mm_unpackhi_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r7 = _mm_unpacklo_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+ i4_res_final_8x16b_r8 = _mm_unpackhi_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ chroma_mask2 = _mm_set1_epi16(0x00FF);
+ out_16x8b_r1 = _mm_loadu_si128((__m128i *) (&pu1_out[0]));
+ out_16x8b_r2 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride]));
+ out_16x8b_r3 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2]));
+ out_16x8b_r4 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2 + i4_dst_stride]));
+ out_16x8b_r5 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4]));
+ out_16x8b_r6 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride]));
+ out_16x8b_r7 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2]));
+ out_16x8b_r8 =
+ _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2 + i4_dst_stride]));
+
+ out_16x8b_r1 = _mm_and_si128(out_16x8b_r1, chroma_mask);
+ out_16x8b_r2 = _mm_and_si128(out_16x8b_r2, chroma_mask);
+ out_16x8b_r3 = _mm_and_si128(out_16x8b_r3, chroma_mask);
+ out_16x8b_r4 = _mm_and_si128(out_16x8b_r4, chroma_mask);
+ out_16x8b_r5 = _mm_and_si128(out_16x8b_r5, chroma_mask);
+ out_16x8b_r6 = _mm_and_si128(out_16x8b_r6, chroma_mask);
+ out_16x8b_r7 = _mm_and_si128(out_16x8b_r7, chroma_mask);
+ out_16x8b_r8 = _mm_and_si128(out_16x8b_r8, chroma_mask);
+
+ i4_res_final_8x16b_r1 = _mm_and_si128(i4_res_final_8x16b_r1, chroma_mask2);
+ i4_res_final_8x16b_r2 = _mm_and_si128(i4_res_final_8x16b_r2, chroma_mask2);
+ i4_res_final_8x16b_r3 = _mm_and_si128(i4_res_final_8x16b_r3, chroma_mask2);
+ i4_res_final_8x16b_r4 = _mm_and_si128(i4_res_final_8x16b_r4, chroma_mask2);
+ i4_res_final_8x16b_r5 = _mm_and_si128(i4_res_final_8x16b_r5, chroma_mask2);
+ i4_res_final_8x16b_r6 = _mm_and_si128(i4_res_final_8x16b_r6, chroma_mask2);
+ i4_res_final_8x16b_r7 = _mm_and_si128(i4_res_final_8x16b_r7, chroma_mask2);
+ i4_res_final_8x16b_r8 = _mm_and_si128(i4_res_final_8x16b_r8, chroma_mask2);
+
+ out_16x8b_r1 = _mm_add_epi8(i4_res_final_8x16b_r1, out_16x8b_r1);
+ out_16x8b_r2 = _mm_add_epi8(i4_res_final_8x16b_r2, out_16x8b_r2);
+ out_16x8b_r3 = _mm_add_epi8(i4_res_final_8x16b_r3, out_16x8b_r3);
+ out_16x8b_r4 = _mm_add_epi8(i4_res_final_8x16b_r4, out_16x8b_r4);
+ out_16x8b_r5 = _mm_add_epi8(i4_res_final_8x16b_r5, out_16x8b_r5);
+ out_16x8b_r6 = _mm_add_epi8(i4_res_final_8x16b_r6, out_16x8b_r6);
+ out_16x8b_r7 = _mm_add_epi8(i4_res_final_8x16b_r7, out_16x8b_r7);
+ out_16x8b_r8 = _mm_add_epi8(i4_res_final_8x16b_r8, out_16x8b_r8);
+
+ _mm_storeu_si128((__m128i *) pu1_out, out_16x8b_r1);
+ _mm_storeu_si128((__m128i *) (pu1_out + i4_dst_stride), out_16x8b_r2);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 2)), out_16x8b_r3);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 3)), out_16x8b_r4);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 4)), out_16x8b_r5);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 5)), out_16x8b_r6);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 6)), out_16x8b_r7);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 7)), out_16x8b_r8);
+}
diff --git a/common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c b/common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c
new file mode 100644
index 0000000..e4e6c27
--- /dev/null
+++ b/common/x86/svc/isvc_iquant_itrans_recon_dc_ssse3.c
@@ -0,0 +1,548 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_iquant_itrans_recon_dc_ssse3.c
+ *
+ * @brief
+ * Contains function definitions for inverse quantization, inverse
+ * transform and reconstruction
+ *
+ * @author
+ * Mohit [100664]
+ *
+ * @par List of Functions:
+ * - isvc_iquant_itrans_recon_4x4_dc_ssse3()
+ * - isvc_iquant_itrans_recon_8x8_dc_ssse3()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer for dc input pattern only, i.e. only the (0,0) element of
+ *the input 4x4 block is non-zero. For complete function, refer
+ *isvc_iquant_itrans_recon_ssse3.c
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_4x4_dc_ssse3(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ WORD32 q0 = pi2_src[0];
+ WORD16 i_macro, rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ __m128i predload_r, pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp4, temp5, temp6, temp7;
+ __m128i value_add;
+
+ UNUSED(pi2_tmp);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_src_stride);
+ UNUSED(i4_res_stride);
+ UNUSED(i4_res_pred_stride);
+ UNUSED(pi2_res);
+ UNUSED(pi2_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /* Implement residue accumulation */
+ ASSERT(0);
+
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+
+ if(i4_iq_start_idx != 0) q0 = pi2_dc_src[0]; // Restoring dc value for intra case
+
+ i_macro = ((q0 + 32) >> 6);
+
+ value_add = _mm_set1_epi16(i_macro);
+
+ zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // Load pred buffer
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[0])); // p00 p01 p02 p03 0 0 0 0 0
+ // 0 0 0 -- all 8 bits
+ pred_r0 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p00 p01 p02 p03 0 0 0 0 -- all 16 bits
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride])); // p10 p11 p12 p13 0 0 0 0 0 0
+ // 0 0 -- all 8 bits
+ pred_r1 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p10 p11 p12 p13 0 0 0 0 -- all 16 bits
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride])); // p20 p21 p22 p23 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p20 p21 p22 p23 0 0 0 0 -- all 16 bits
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride])); // p30 p31 p32 p33 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p30 p31 p32 p33 0 0 0 0 -- all 16 bits
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1); // p00 p01 p02 p03 p10 p11 p12 p13
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3); // p20 p21 p22p p23 p30 p31 p32 p33
+
+ temp4 = _mm_add_epi16(value_add, pred_r0);
+ temp5 = _mm_add_epi16(value_add, pred_r2);
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b); // sign check
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b); // sign check
+ temp5 = _mm_and_si128(temp5, sign_reg);
+
+ temp4 = _mm_packus_epi16(temp4, temp5);
+ temp5 = _mm_srli_si128(temp4, 4);
+ temp6 = _mm_srli_si128(temp5, 4);
+ temp7 = _mm_srli_si128(temp6, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(temp4);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp5);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp6);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp7);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs inverse quant and Inverse transform type Ci4 for 8x8
+ *block for dc input pattern only, i.e. only the (0,0) element of the input 8x8
+ *block is non-zero. For complete function, refer
+ *isvc_iquant_itrans_recon_ssse3.c
+ *
+ * @par Description:
+ * Performs inverse transform Ci8 and adds the residue to get the
+ * reconstructed block
+ *
+ * @param[in] pi2_src
+ * Input 8x8coefficients
+ *
+ * @param[in] pu1_pred
+ * Prediction 8x8 block
+ *
+ * @param[out] pu1_recon
+ * Output 8x8 block
+ *
+ * @param[in] q_div
+ * QP/6
+ *
+ * @param[in] q_rem
+ * QP%6
+ *
+ * @param[in] q_lev
+ * Quantizer level
+ *
+ * @param[in] u4_src_stride
+ * Input stride
+ *
+ * @param[in] u4_pred_stride,
+ * Prediction stride
+ *
+ * @param[in] u4_out_stride
+ * Output Stride
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*64
+ * the tmp for each block
+ *
+ * @param[in] pu4_iquant_mat
+ * Pointer to the inverse quantization matrix
+ *
+ * @returns Void
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+void isvc_iquant_itrans_recon_8x8_dc_ssse3(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD32 q0 = pi2_src[0];
+ WORD16 i_macro, rnd_fact = (u4_qp_div_6 < 6) ? 1 << (5 - u4_qp_div_6) : 0;
+
+ __m128i predload_r, pred_r0, pred_r1, pred_r2, pred_r3, pred_r4, pred_r5, pred_r6, pred_r7;
+ __m128i sign_reg;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+ __m128i value_add;
+
+ UNUSED(pi2_tmp);
+ UNUSED(pi2_dc_src);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_src_stride);
+ UNUSED(i4_res_stride);
+ UNUSED(i4_res_pred_stride);
+ UNUSED(pi2_res);
+ UNUSED(pi2_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /* Implement residue accumulation */
+ ASSERT(0);
+
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 6);
+ i_macro = ((q0 + 32) >> 6);
+
+ value_add = _mm_set1_epi16(i_macro);
+
+ // Load pred buffer row 0
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[0])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0
+ // -- all 8 bits
+ pred_r0 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 1
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r1 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 2
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[2 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 3
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[3 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 4
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[4 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r4 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 5
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[5 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0
+ // 0 0 0 0 0 0 0 -- all 8 bit
+ pred_r5 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 6
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[6 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r6 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 7
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[7 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r7 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+
+ temp1 = _mm_add_epi16(value_add, pred_r0);
+
+ temp2 = _mm_add_epi16(value_add, pred_r1);
+
+ temp3 = _mm_add_epi16(value_add, pred_r2);
+
+ temp4 = _mm_add_epi16(value_add, pred_r3);
+
+ temp5 = _mm_add_epi16(value_add, pred_r4);
+
+ temp6 = _mm_add_epi16(value_add, pred_r5);
+
+ temp7 = _mm_add_epi16(value_add, pred_r6);
+
+ temp8 = _mm_add_epi16(value_add, pred_r7);
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b); // sign check
+ temp1 = _mm_and_si128(temp1, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp2, zero_8x16b); // sign check
+ temp2 = _mm_and_si128(temp2, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp3, zero_8x16b); // sign check
+ temp3 = _mm_and_si128(temp3, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b); // sign check
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b); // sign check
+ temp5 = _mm_and_si128(temp5, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp6, zero_8x16b); // sign check
+ temp6 = _mm_and_si128(temp6, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp7, zero_8x16b); // sign check
+ temp7 = _mm_and_si128(temp7, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp8, zero_8x16b); // sign check
+ temp8 = _mm_and_si128(temp8, sign_reg);
+
+ temp1 = _mm_packus_epi16(temp1, zero_8x16b);
+ temp2 = _mm_packus_epi16(temp2, zero_8x16b);
+ temp3 = _mm_packus_epi16(temp3, zero_8x16b);
+ temp4 = _mm_packus_epi16(temp4, zero_8x16b);
+ temp5 = _mm_packus_epi16(temp5, zero_8x16b);
+ temp6 = _mm_packus_epi16(temp6, zero_8x16b);
+ temp7 = _mm_packus_epi16(temp7, zero_8x16b);
+ temp8 = _mm_packus_epi16(temp8, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), temp1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), temp2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), temp3);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), temp4);
+ _mm_storel_epi64((__m128i *) (&pu1_out[4 * i4_out_stride]), temp5);
+ _mm_storel_epi64((__m128i *) (&pu1_out[5 * i4_out_stride]), temp6);
+ _mm_storel_epi64((__m128i *) (&pu1_out[6 * i4_out_stride]), temp7);
+ _mm_storel_epi64((__m128i *) (&pu1_out[7 * i4_out_stride]), temp8);
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized chroma
+ *resiude and prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_chroma_4x4_dc_ssse3(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ WORD16 q0 = pi2_dc_src[0]; // DC value won't be dequantized for chroma
+ // inverse transform
+ WORD16 i_macro = ((q0 + 32) >> 6);
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3, sign_reg;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i value_add = _mm_set1_epi16(i_macro);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_src_stride);
+ UNUSED(i4_res_stride);
+ UNUSED(i4_res_pred_stride);
+ UNUSED(pi2_res);
+ UNUSED(pi2_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /* Implement residue accumulation */
+ ASSERT(0);
+
+ // Load pred buffer
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0])); // p00 p01 p02 p03 0 0 0 0 0
+ // 0 0 0 -- all 8 bits
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride])); // p10 p11 p12 p13 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r2 =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride])); // p20 p21 p22 p23 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r3 =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride])); // p30 p31 p32 p33 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1); // p00 p01 p02 p03 p10 p11 p12 p13
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3); // p20 p21 p22p p23 p30 p31 p32 p33
+
+ pred_r0 = _mm_add_epi16(value_add, pred_r0);
+ pred_r2 = _mm_add_epi16(value_add, pred_r2);
+
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(pred_r0, zero_8x16b); // sign check
+ pred_r0 = _mm_and_si128(pred_r0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(pred_r2, zero_8x16b);
+ pred_r2 = _mm_and_si128(pred_r2, sign_reg);
+
+ pred_r0 = _mm_packus_epi16(pred_r0, pred_r2);
+ pred_r1 = _mm_srli_si128(pred_r0, 4);
+ pred_r2 = _mm_srli_si128(pred_r1, 4);
+ pred_r3 = _mm_srli_si128(pred_r2, 4);
+
+ pred_r0 = _mm_unpacklo_epi8(pred_r0, zero_8x16b); // p00 p01 p02 p03 -- all 16 bits
+ pred_r1 = _mm_unpacklo_epi8(pred_r1, zero_8x16b); // p10 p11 p12 p13 -- all 16 bits
+ pred_r2 = _mm_unpacklo_epi8(pred_r2, zero_8x16b); // p20 p21 p22 p23 -- all 16 bits
+ pred_r3 = _mm_unpacklo_epi8(pred_r3, zero_8x16b); // p30 p31 p32 p33 -- all 16 bits
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ out_r0 = _mm_add_epi8(out_r0, pred_r0);
+ out_r1 = _mm_add_epi8(out_r1, pred_r1);
+ out_r2 = _mm_add_epi8(out_r2, pred_r2);
+ out_r3 = _mm_add_epi8(out_r3, pred_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
diff --git a/common/x86/svc/isvc_iquant_itrans_recon_sse42.c b/common/x86/svc/isvc_iquant_itrans_recon_sse42.c
new file mode 100644
index 0000000..829952b
--- /dev/null
+++ b/common/x86/svc/isvc_iquant_itrans_recon_sse42.c
@@ -0,0 +1,2849 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_iquant_itrans_recon_sse42.c
+ *
+ * @brief
+ * Contains function definitions for inverse quantization, inverse
+ * transform and reconstruction
+ *
+ * @author
+ * Mohit [100664]
+ *
+ * @par List of Functions:
+ * - isvc_iquant_itrans_recon_4x4_sse42()
+ * - isvc_iquant_itrans_recon_chroma_4x4_sse42()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+
+void isvc_iquant_itrans_recon_4x4_sse42(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ /* b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ b12*q12 b13*q13 -- 16 bit result */
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+
+ /* b20*q20 b21*q21 b22*q22 b23*q23 b30*q30 b31*q31
+ b32*q32 b33*q33 -- 16 bit result */
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(i4_iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r1 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp4 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp4 = _mm_min_epi16(temp4, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp5 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp5 = _mm_min_epi16(temp5, pos_255_8x16b);
+
+ temp0 = _mm_add_epi16(temp4, pred_r0);
+ temp1 = _mm_add_epi16(temp5, pred_r1);
+
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(resq_r0);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r1);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r2);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r3);
+}
+
+void isvc_iquant_itrans_recon_res_4x4_sse42(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ /* b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ b12*q12 b13*q13 -- 16 bit result */
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+
+ /* b20*q20 b21*q21 b22*q22 b23*q23 b30*q30 b31*q31
+ b32*q32 b33*q33 -- 16 bit result */
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(i4_iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ _mm_storel_epi64((__m128i *) (&pi2_res[0]), temp0);
+ _mm_storel_epi64((__m128i *) (&pi2_res[2 * i4_res_stride]), temp1);
+
+ temp4 = _mm_add_epi16(temp0, pred_r0);
+ temp0 = _mm_srli_si128(temp0, 8);
+ _mm_storel_epi64((__m128i *) (&pi2_res[i4_res_stride]), temp0);
+
+ temp6 = _mm_add_epi16(temp1, pred_r2);
+ temp1 = _mm_srli_si128(temp1, 8);
+ _mm_storel_epi64((__m128i *) (&pi2_res[3 * i4_res_stride]), temp1);
+
+ temp5 = _mm_add_epi16(temp0, pred_r1);
+ temp7 = _mm_add_epi16(temp1, pred_r3);
+
+ temp4 = _mm_cvtepi16_epi32(temp4);
+ temp5 = _mm_cvtepi16_epi32(temp5);
+ temp6 = _mm_cvtepi16_epi32(temp6);
+ temp7 = _mm_cvtepi16_epi32(temp7);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(resq_r0);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r1);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r2);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r3);
+}
+
+void isvc_iquant_itrans_recon_res_4x4_with_res_acc_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i res_pred_r0, res_pred_r1, res_pred_r2, res_pred_r3;
+ __m128i res_r0, res_r1, res_r2, res_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(1 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ /* b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ b12*q12 b13*q13 -- 16 bit result */
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+
+ /* b20*q20 b21*q21 b22*q22 b23*q23 b30*q30 b31*q31
+ b32*q32 b33*q33 -- 16 bit result */
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(i4_iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp_ptr[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ res_r0 = temp4;
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ res_r1 = temp5;
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ res_r2 = temp6;
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ res_r3 = temp7;
+
+ /* Accumulating res */
+ res_pred_r0 = _mm_loadl_epi64((__m128i *) &pi2_res_pred[0]);
+ res_pred_r1 = _mm_loadl_epi64((__m128i *) &pi2_res_pred[i4_res_pred_stride]);
+ res_pred_r2 = _mm_loadl_epi64((__m128i *) &pi2_res_pred[2 * i4_res_pred_stride]);
+ res_pred_r3 = _mm_loadl_epi64((__m128i *) &pi2_res_pred[3 * i4_res_pred_stride]);
+
+ res_pred_r0 = _mm_cvtepi16_epi32(res_pred_r0);
+ res_pred_r1 = _mm_cvtepi16_epi32(res_pred_r1);
+ res_pred_r2 = _mm_cvtepi16_epi32(res_pred_r2);
+ res_pred_r3 = _mm_cvtepi16_epi32(res_pred_r3);
+
+ temp0 = _mm_add_epi32(res_r0, res_pred_r0);
+ temp1 = _mm_add_epi32(res_r1, res_pred_r1);
+ temp2 = _mm_add_epi32(res_r2, res_pred_r2);
+ temp3 = _mm_add_epi32(res_r3, res_pred_r3);
+
+ temp0 = _mm_packs_epi32(temp0, temp1);
+ temp1 = _mm_packs_epi32(temp2, temp3);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ _mm_storel_epi64((__m128i *) (&pi2_res[0]), temp0);
+ _mm_storel_epi64((__m128i *) (&pi2_res[2 * i4_res_stride]), temp1);
+
+ temp4 = _mm_add_epi16(temp0, pred_r0);
+ temp0 = _mm_srli_si128(temp0, 8);
+ _mm_storel_epi64((__m128i *) (&pi2_res[i4_res_stride]), temp0);
+
+ temp6 = _mm_add_epi16(temp1, pred_r2);
+ temp1 = _mm_srli_si128(temp1, 8);
+ _mm_storel_epi64((__m128i *) (&pi2_res[3 * i4_res_stride]), temp1);
+
+ temp5 = _mm_add_epi16(temp0, pred_r1);
+ temp7 = _mm_add_epi16(temp1, pred_r3);
+
+ temp4 = _mm_cvtepi16_epi32(temp4);
+ temp5 = _mm_cvtepi16_epi32(temp5);
+ temp6 = _mm_cvtepi16_epi32(temp6);
+ temp7 = _mm_cvtepi16_epi32(temp7);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(resq_r0);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r1);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r2);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r3);
+}
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized chroma
+ *resiude and prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_chroma_4x4_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(u1_res_accumulate);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1,
+ dequant_r0_r1); // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ // b12*q12 b13*q13 -- 16 bit result
+
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r1 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp4 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp4 = _mm_min_epi16(temp4, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp5 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp5 = _mm_min_epi16(temp5, pos_255_8x16b);
+
+ temp0 = _mm_add_epi16(temp4, pred_r0);
+ temp1 = _mm_add_epi16(temp5, pred_r1);
+
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ resq_r0 = _mm_cvtepu8_epi16(resq_r0);
+ resq_r1 = _mm_cvtepu8_epi16(resq_r1);
+ resq_r2 = _mm_cvtepu8_epi16(resq_r2);
+ resq_r3 = _mm_cvtepu8_epi16(resq_r3);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ out_r0 = _mm_add_epi8(out_r0, resq_r0);
+ out_r1 = _mm_add_epi8(out_r1, resq_r1);
+ out_r2 = _mm_add_epi8(out_r2, resq_r2);
+ out_r3 = _mm_add_epi8(out_r3, resq_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
+
+void isvc_iquant_itrans_recon_res_chroma_4x4_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_ptr = pi2_res;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+ __m128i res_r0, res_r1, res_r2, res_r3;
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(u1_res_accumulate);
+ UNUSED(ps_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1,
+ dequant_r0_r1); // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ // b12*q12 b13*q13 -- 16 bit result
+
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ pred_r0 = _mm_cvtepu16_epi32(pred_r0);
+ pred_r1 = _mm_cvtepu16_epi32(pred_r1);
+ pred_r2 = _mm_cvtepu16_epi32(pred_r2);
+ pred_r3 = _mm_cvtepu16_epi32(pred_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+
+ /* 32-bit to 16-bit conversion */
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ chroma_mask = _mm_set1_epi32(0xffff0000);
+ out_r0 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[0 * i4_res_stride]));
+ out_r1 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[1 * i4_res_stride]));
+ out_r2 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]));
+ out_r3 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ res_r0 = _mm_cvtepu16_epi32(temp0);
+ res_r2 = _mm_cvtepu16_epi32(temp1);
+ res_r1 = _mm_srli_si128(temp0, 8);
+ res_r3 = _mm_srli_si128(temp1, 8);
+ res_r1 = _mm_cvtepu16_epi32(res_r1);
+ res_r3 = _mm_cvtepu16_epi32(res_r3);
+
+ out_r0 = _mm_add_epi16(out_r0, res_r0);
+ out_r1 = _mm_add_epi16(out_r1, res_r1);
+ out_r2 = _mm_add_epi16(out_r2, res_r2);
+ out_r3 = _mm_add_epi16(out_r3, res_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[0 * i4_res_stride]), out_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[1 * i4_res_stride]), out_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]), out_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]), out_r3);
+
+ resq_r0 = _mm_add_epi16(pred_r0, res_r0);
+ resq_r1 = _mm_add_epi16(pred_r1, res_r1);
+ resq_r2 = _mm_add_epi16(pred_r2, res_r2);
+ resq_r3 = _mm_add_epi16(pred_r3, res_r3);
+
+ temp0 = _mm_packus_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packus_epi32(resq_r2, resq_r3);
+
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ resq_r0 = _mm_cvtepu8_epi16(resq_r0);
+ resq_r1 = _mm_cvtepu8_epi16(resq_r1);
+ resq_r2 = _mm_cvtepu8_epi16(resq_r2);
+ resq_r3 = _mm_cvtepu8_epi16(resq_r3);
+
+ chroma_mask = _mm_set1_epi16(0xff00);
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ out_r0 = _mm_add_epi8(out_r0, resq_r0);
+ out_r1 = _mm_add_epi8(out_r1, resq_r1);
+ out_r2 = _mm_add_epi8(out_r2, resq_r2);
+ out_r3 = _mm_add_epi8(out_r3, resq_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
+
+void isvc_iquant_itrans_recon_res_chroma_4x4_with_res_acc_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i res_pred_r0, res_pred_r1, res_pred_r2, res_pred_r3;
+ __m128i res_r0, res_r1, res_r2, res_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i reg_chroma = _mm_set1_epi32(0xFFFF);
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+ __m128i mask_r0;
+
+ ASSERT(4 == i4_src_stride);
+ ASSERT(1 == u1_res_accumulate);
+
+ UNUSED(i4_src_stride);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_iq_start_idx);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ /* a00 a01 a02 a03 a10 a11 a12 a13 -- the source
+ matrix 0th,1st row */
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+
+ /* a20 a21 a22 a23 a30 a31 a32 a33 -- the
+ source matrix 2nd,3rd row */
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33 --b12 b13 -- the
+ the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+
+ /* q00 q01 q02 q03 q10 q11
+ q12 q13 -- all 16 bits */
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+
+ /* q20 q21 q22 q23 q30 q31
+ q32 q33 -- all 16 bits */
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1,
+ dequant_r0_r1); // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ // b12*q12 b13*q13 -- 16 bit result
+
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+
+ /* b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long */
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+
+ /* b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long */
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ /* a00 0 a01 0 a02 0 a03 0 -- 16 bit long */
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b);
+ /* a10 0 a11 0 a12 0 a13 0 -- 16 bit long */
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b);
+ /* a20 0 a21 0 a22 0 a23 0 -- 16 bit long */
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b);
+ /* a30 0 a31 0 a32 0 a33 0 -- 16 bit long */
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b);
+
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 a1 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* c0 d0 c1 d1 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* a2 b2 a3 b3 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 d2 c3 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 b0 c0 d0 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* a1 b1 c1 d1 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* a2 b2 c2 d2 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* a3 b3 c3 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform starts -- horizontal transform */
+
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1);
+ /* a2 a3 b2 b3 */
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3);
+ /* c0 c1 d0 d1 */
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1);
+ /* c2 c3 d2 d3 */
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3);
+ /* a0 a1 a2 a3 */
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3);
+ /* b0 b1 b2 b3 */
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3);
+ /* c0 c1 c2 c3 */
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4);
+ /* d0 d1 d2 d3 */
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4);
+ /* Transform ends -- horizontal transform */
+
+ temp0 = _mm_packs_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packs_epi32(resq_r2, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_tmp[2 * 4]), temp1);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1);
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1);
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ res_r0 = temp4;
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ res_r1 = temp5;
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ res_r2 = temp6;
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ res_r3 = temp7;
+
+ res_pred_r0 = _mm_loadu_si128((__m128i *) &pi2_res_pred[0 * i4_res_pred_stride]);
+ res_pred_r1 = _mm_loadu_si128((__m128i *) &pi2_res_pred[1 * i4_res_pred_stride]);
+ res_pred_r2 = _mm_loadu_si128((__m128i *) &pi2_res_pred[2 * i4_res_pred_stride]);
+ res_pred_r3 = _mm_loadu_si128((__m128i *) &pi2_res_pred[3 * i4_res_pred_stride]);
+
+ res_pred_r0 = _mm_and_si128(res_pred_r0, reg_chroma);
+ res_pred_r1 = _mm_and_si128(res_pred_r1, reg_chroma);
+ res_pred_r2 = _mm_and_si128(res_pred_r2, reg_chroma);
+ res_pred_r3 = _mm_and_si128(res_pred_r3, reg_chroma);
+
+ temp0 = _mm_packs_epi32(res_r0, res_r1);
+ temp1 = _mm_packs_epi32(res_r2, res_r3);
+
+ res_r0 = _mm_cvtepu16_epi32(temp0);
+ res_r2 = _mm_cvtepu16_epi32(temp1);
+ res_r1 = _mm_srli_si128(temp0, 8);
+ res_r3 = _mm_srli_si128(temp1, 8);
+ res_r1 = _mm_cvtepu16_epi32(res_r1);
+ res_r3 = _mm_cvtepu16_epi32(res_r3);
+
+ res_r0 = _mm_add_epi16(res_pred_r0, res_r0);
+ res_r1 = _mm_add_epi16(res_pred_r1, res_r1);
+ res_r2 = _mm_add_epi16(res_pred_r2, res_r2);
+ res_r3 = _mm_add_epi16(res_pred_r3, res_r3);
+
+ temp0 = _mm_packus_epi32(res_r0, res_r1);
+ temp1 = _mm_packus_epi32(res_r2, res_r3);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ res_r0 = _mm_cvtepu16_epi32(temp0);
+ res_r1 = _mm_srli_si128(temp0, 8);
+ res_r1 = _mm_cvtepu16_epi32(res_r1);
+
+ res_r2 = _mm_cvtepu16_epi32(temp1);
+ res_r3 = _mm_srli_si128(temp1, 8);
+ res_r3 = _mm_cvtepu16_epi32(res_r3);
+
+ chroma_mask = _mm_set1_epi32(0xffff0000);
+ out_r0 = _mm_loadu_si128((__m128i *) (&pi2_res[0 * i4_res_stride]));
+ out_r1 = _mm_loadu_si128((__m128i *) (&pi2_res[1 * i4_res_stride]));
+ out_r2 = _mm_loadu_si128((__m128i *) (&pi2_res[2 * i4_res_stride]));
+ out_r3 = _mm_loadu_si128((__m128i *) (&pi2_res[3 * i4_res_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ out_r0 = _mm_add_epi16(out_r0, res_r0);
+ out_r1 = _mm_add_epi16(out_r1, res_r1);
+ out_r2 = _mm_add_epi16(out_r2, res_r2);
+ out_r3 = _mm_add_epi16(out_r3, res_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res[0 * i4_res_stride]), out_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_res[1 * i4_res_stride]), out_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_res[2 * i4_res_stride]), out_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_res[3 * i4_res_stride]), out_r3);
+
+ pred_r0 = _mm_cvtepu16_epi32(pred_r0);
+ pred_r1 = _mm_cvtepu16_epi32(pred_r1);
+ pred_r2 = _mm_cvtepu16_epi32(pred_r2);
+ pred_r3 = _mm_cvtepu16_epi32(pred_r3);
+
+ resq_r0 = _mm_add_epi16(pred_r0, res_r0);
+ resq_r1 = _mm_add_epi16(pred_r1, res_r1);
+ resq_r2 = _mm_add_epi16(pred_r2, res_r2);
+ resq_r3 = _mm_add_epi16(pred_r3, res_r3);
+
+ temp0 = _mm_packus_epi32(resq_r0, resq_r1);
+ temp1 = _mm_packus_epi32(resq_r2, resq_r3);
+
+ /* Clipping the results to 8 bits */
+ mask_r0 = _mm_cmpgt_epi16(temp0, zero_8x16b);
+ temp0 = _mm_and_si128(temp0, mask_r0);
+ mask_r0 = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, mask_r0);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ resq_r0 = _mm_cvtepu8_epi16(resq_r0);
+ resq_r1 = _mm_cvtepu8_epi16(resq_r1);
+ resq_r2 = _mm_cvtepu8_epi16(resq_r2);
+ resq_r3 = _mm_cvtepu8_epi16(resq_r3);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0 * i4_out_stride]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[1 * i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ out_r0 = _mm_add_epi8(out_r0, resq_r0);
+ out_r1 = _mm_add_epi8(out_r1, resq_r1);
+ out_r2 = _mm_add_epi8(out_r2, resq_r2);
+ out_r3 = _mm_add_epi8(out_r3, resq_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0 * i4_out_stride]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[1 * i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
+
+void isvc_iquant_itrans_recon_dc_4x4_sse42(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ WORD32 q0 = ((WORD16 *) (ps_src->pv_data))[0];
+ WORD16 i_macro, rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i temp4, temp5, temp6, temp7;
+ __m128i value_add;
+
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+
+ /* Restoring dc value for intra case */
+ if(i4_iq_start_idx != 0)
+ {
+ q0 = pi2_dc_src[0];
+ }
+
+ i_macro = ((q0 + 32) >> 6);
+
+ value_add = _mm_set1_epi16(i_macro);
+
+ zero_8x16b = _mm_setzero_si128();
+
+ /* Load pred buffer */
+
+ /* p00 p01 p02 p03 0 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ /* p10 p11 p12 p13 0 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ /* p20 p21 p22 p23 0 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ /* p30 p31 p32 p33 0 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ temp4 = _mm_add_epi16(value_add, pred_r0);
+ temp5 = _mm_add_epi16(value_add, pred_r2);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b);
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b);
+ temp5 = _mm_and_si128(temp5, sign_reg);
+
+ temp4 = _mm_packus_epi16(temp4, temp5);
+ temp5 = _mm_srli_si128(temp4, 4);
+ temp6 = _mm_srli_si128(temp5, 4);
+ temp7 = _mm_srli_si128(temp6, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(temp4);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp5);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp6);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp7);
+}
+
+void isvc_iquant_itrans_recon_res_dc_4x4_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_ptr = pi2_res;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ WORD32 q0 = ((WORD16 *) (ps_src->pv_data))[0];
+ WORD16 i_macro, rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i temp4, temp5, temp6, temp7;
+ __m128i value_add;
+
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res_pred);
+ UNUSED(u1_res_accumulate);
+
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+
+ /* Restoring dc value for intra case */
+ if(i4_iq_start_idx != 0) q0 = pi2_dc_src[0];
+
+ i_macro = ((q0 + 32) >> 6);
+
+ value_add = _mm_set1_epi16(isvc_get_residue(i_macro, 0, 0));
+
+ zero_8x16b = _mm_setzero_si128();
+
+ /* Load pred buffer */
+
+ /* p00 p01 p02 p03 0 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ /* p10 p11 p12 p13 0 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ /* p20 p21 p22 p23 0 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ /* p30 p31 p32 p33 0 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ temp4 = _mm_add_epi16(value_add, pred_r0);
+ temp5 = _mm_add_epi16(value_add, pred_r2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[0]), value_add);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[i4_res_stride]), value_add);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]), value_add);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]), value_add);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b);
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b);
+ temp5 = _mm_and_si128(temp5, sign_reg);
+
+ temp4 = _mm_packus_epi16(temp4, temp5);
+ temp5 = _mm_srli_si128(temp4, 4);
+ temp6 = _mm_srli_si128(temp5, 4);
+ temp7 = _mm_srli_si128(temp6, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(temp4);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp5);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp6);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp7);
+}
+
+void isvc_iquant_itrans_recon_res_dc_with_res_acc_4x4_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_ptr = pi2_res;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ WORD16 *pi2_res_pred_ptr = pi2_res_pred;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ WORD32 q0 = ((WORD16 *) (ps_src->pv_data))[0];
+ WORD16 i_macro, rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i temp4, temp5, temp6, temp7;
+ __m128i value_add;
+ __m128i res_pred_r0, res_pred_r1, res_pred_r2, res_pred_r3;
+ __m128i temp0, temp1;
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+
+ ASSERT(1 == u1_res_accumulate);
+
+ UNUSED(pi2_tmp);
+ UNUSED(u1_res_accumulate);
+
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+
+ /* Restoring dc value for intra case */
+ if(i4_iq_start_idx != 0) q0 = pi2_dc_src[0];
+
+ i_macro = ((q0 + 32) >> 6);
+
+ value_add = _mm_set1_epi16(i_macro);
+
+ zero_8x16b = _mm_setzero_si128();
+
+ /* Load pred buffer */
+
+ /* p00 p01 p02 p03 0 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ /* p10 p11 p12 p13 0 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ /* p20 p21 p22 p23 0 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ /* p30 p31 p32 p33 0 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /* Accumulating res */
+ res_pred_r0 = _mm_loadl_epi64((__m128i *) &pi2_res_pred_ptr[0]);
+ res_pred_r1 = _mm_loadl_epi64((__m128i *) &pi2_res_pred_ptr[i4_res_pred_stride]);
+ res_pred_r2 = _mm_loadl_epi64((__m128i *) &pi2_res_pred_ptr[2 * i4_res_pred_stride]);
+ res_pred_r3 = _mm_loadl_epi64((__m128i *) &pi2_res_pred_ptr[3 * i4_res_pred_stride]);
+
+ res_pred_r0 = _mm_unpacklo_epi64(res_pred_r0, res_pred_r1);
+ res_pred_r1 = _mm_unpacklo_epi64(res_pred_r2, res_pred_r3);
+
+ temp0 = _mm_add_epi16(value_add, res_pred_r0);
+ temp1 = _mm_add_epi16(value_add, res_pred_r1);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]), temp1);
+
+ temp4 = _mm_add_epi16(temp0, pred_r0);
+ temp5 = _mm_add_epi16(temp1, pred_r2);
+
+ temp0 = _mm_srli_si128(temp0, 8);
+ temp1 = _mm_srli_si128(temp1, 8);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[i4_res_stride]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]), temp1);
+
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b);
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b);
+ temp5 = _mm_and_si128(temp5, sign_reg);
+
+ temp4 = _mm_packus_epi16(temp4, temp5);
+ temp5 = _mm_srli_si128(temp4, 4);
+ temp6 = _mm_srli_si128(temp5, 4);
+ temp7 = _mm_srli_si128(temp6, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(temp4);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp5);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp6);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(temp7);
+}
+
+void isvc_iquant_itrans_recon_chroma_4x4_dc_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ /* DC value won't be dequantized for chroma
+ inverse transform */
+ WORD16 q0 = pi2_dc_src[0];
+ WORD16 i_macro = ((q0 + 32) >> 6);
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i value_add = _mm_set1_epi16(i_macro);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res_pred);
+ UNUSED(ps_res);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(u1_res_accumulate);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ /* Mask alternate pred values from the interleaved pred buf */
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ /* Pack the first four 16 bit values of 2 regs into a single reg*/
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /* Compute out pixel by adding res to pred */
+ pred_r0 = _mm_add_epi16(value_add, pred_r0);
+ pred_r2 = _mm_add_epi16(value_add, pred_r2);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ pred_r0 = _mm_packus_epi16(pred_r0, pred_r2);
+ pred_r1 = _mm_srli_si128(pred_r0, 4);
+ pred_r2 = _mm_srli_si128(pred_r1, 4);
+ pred_r3 = _mm_srli_si128(pred_r2, 4);
+
+ /* p00 p01 p02 p03 -- all 16 bits */
+ pred_r0 = _mm_unpacklo_epi8(pred_r0, zero_8x16b);
+ /* p10 p11 p12 p13 -- all 16 bits */
+ pred_r1 = _mm_unpacklo_epi8(pred_r1, zero_8x16b);
+ /* p20 p21 p22 p23 -- all 16 bits */
+ pred_r2 = _mm_unpacklo_epi8(pred_r2, zero_8x16b);
+ /* p30 p31 p32 p33 -- all 16 bits */
+ pred_r3 = _mm_unpacklo_epi8(pred_r3, zero_8x16b);
+
+ /* Load interleaved out buffer */
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ /* Mask the interleaved out buf in order to save the U/V out pixel computed in
+ this function call without thrashing the U/V out pixel that was saved
+ during an earlier function call */
+ chroma_mask = _mm_set1_epi16(0xFF00);
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ /* Save the out pixels in alternate locations */
+ out_r0 = _mm_add_epi8(out_r0, pred_r0);
+ out_r1 = _mm_add_epi8(out_r1, pred_r1);
+ out_r2 = _mm_add_epi8(out_r2, pred_r2);
+ out_r3 = _mm_add_epi8(out_r3, pred_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
+
+void isvc_iquant_itrans_recon_res_chroma_4x4_dc_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_ptr = pi2_res;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ /* DC value won't be dequantized for chroma
+ inverse transform */
+ WORD16 q0 = pi2_dc_src[0];
+ WORD16 i_macro = ((q0 + 32) >> 6);
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3, sign_reg;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i value_add = _mm_set1_epi16(isvc_get_residue(i_macro, 0, 0));
+ __m128i out_r0, out_r1, out_r2, out_r3;
+
+ ASSERT(0 == u1_res_accumulate);
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(ps_res_pred);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(u1_res_accumulate);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ /* Mask alternate pred values from the interleaved pred buf */
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ /* Pack the first four 16 bit values of 2 regs into a single reg*/
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /* Compute out pixel by adding res to pred */
+ pred_r0 = _mm_add_epi16(value_add, pred_r0);
+ pred_r2 = _mm_add_epi16(value_add, pred_r2);
+
+ /* Convert res from 16 bits to 32 bits */
+ value_add = _mm_cvtepu16_epi32(value_add);
+
+ out_r0 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[0 * i4_res_stride]));
+ out_r1 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[1 * i4_res_stride]));
+ out_r2 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]));
+ out_r3 = _mm_loadu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]));
+
+ /* Mask the loaded res in order to save the U/V res data computed in
+ this function call without thrashing the U/V res data that was saved
+ during an earlier function call */
+ chroma_mask = _mm_set1_epi32(0xffff0000);
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ /* Save the res in alternate locations */
+ out_r0 = _mm_add_epi16(out_r0, value_add);
+ out_r1 = _mm_add_epi16(out_r1, value_add);
+ out_r2 = _mm_add_epi16(out_r2, value_add);
+ out_r3 = _mm_add_epi16(out_r3, value_add);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[0 * i4_res_stride]), out_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[1 * i4_res_stride]), out_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[2 * i4_res_stride]), out_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_res_ptr[3 * i4_res_stride]), out_r3);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ sign_reg = _mm_cmpgt_epi16(pred_r0, zero_8x16b);
+ pred_r0 = _mm_and_si128(pred_r0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(pred_r2, zero_8x16b);
+ pred_r2 = _mm_and_si128(pred_r2, sign_reg);
+
+ pred_r0 = _mm_packus_epi16(pred_r0, pred_r2);
+ pred_r1 = _mm_srli_si128(pred_r0, 4);
+ pred_r2 = _mm_srli_si128(pred_r1, 4);
+ pred_r3 = _mm_srli_si128(pred_r2, 4);
+
+ /* p00 p01 p02 p03 -- all 16 bits */
+ pred_r0 = _mm_unpacklo_epi8(pred_r0, zero_8x16b);
+ /* p10 p11 p12 p13 -- all 16 bits */
+ pred_r1 = _mm_unpacklo_epi8(pred_r1, zero_8x16b);
+ /* p20 p21 p22 p23 -- all 16 bits */
+ pred_r2 = _mm_unpacklo_epi8(pred_r2, zero_8x16b);
+ /* p30 p31 p32 p33 -- all 16 bits */
+ pred_r3 = _mm_unpacklo_epi8(pred_r3, zero_8x16b);
+
+ /* Load interleaved out buffer */
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ /* Mask the interleaved out buf in order to save the U/V out pixel computed in
+ this function call without thrashing the U/V out pixel that was saved
+ during an earlier function call */
+ chroma_mask = _mm_set1_epi16(0xFF00);
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ /* Save the out pixels in alternate locations */
+ out_r0 = _mm_add_epi8(out_r0, pred_r0);
+ out_r1 = _mm_add_epi8(out_r1, pred_r1);
+ out_r2 = _mm_add_epi8(out_r2, pred_r2);
+ out_r3 = _mm_add_epi8(out_r3, pred_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
+
+void isvc_iquant_itrans_recon_res_chroma_4x4_dc_with_res_acc_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_res_pred,
+ buffer_container_t *ps_res, buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants, WORD16 *pi2_tmp, WORD16 *pi2_dc_src,
+ WORD32 i4_iq_start_idx, UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = (WORD16 *) ps_src->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD16 *pi2_res_pred = (WORD16 *) ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ UWORD8 *pu1_out = (UWORD8 *) ps_rec->pv_data;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ /* DC value won't be dequantized for chroma
+ inverse transform */
+ WORD16 q0 = pi2_dc_src[0];
+ WORD16 i_macro = ((q0 + 32) >> 6);
+
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+ __m128i reg_chroma = _mm_set_epi16(0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF);
+ __m128i value_add = _mm_set1_epi16(i_macro);
+ __m128i out_r0, out_r1, out_r2, out_r3;
+ __m128i res_r0, res_r1, res_r2, res_r3;
+ __m128i res_pred_r0, res_pred_r1, res_pred_r2, res_pred_r3;
+ __m128i temp0, temp1;
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+
+ ASSERT(1 == u1_res_accumulate);
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(u1_res_accumulate);
+
+ /* Load pred buffer */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+ /* Mask alternate pred values from the interleaved pred buf */
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ /* Pack the first four 16 bit values of 2 regs into a single reg*/
+ pred_r0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r2 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+
+ /* Accumulating res */
+
+ /* load res pred buffer */
+ res_pred_r0 = _mm_loadu_si128((__m128i *) &pi2_res_pred[0 * i4_res_pred_stride]);
+ res_pred_r1 = _mm_loadu_si128((__m128i *) &pi2_res_pred[1 * i4_res_pred_stride]);
+ res_pred_r2 = _mm_loadu_si128((__m128i *) &pi2_res_pred[2 * i4_res_pred_stride]);
+ res_pred_r3 = _mm_loadu_si128((__m128i *) &pi2_res_pred[3 * i4_res_pred_stride]);
+
+ /* Mask res pred and retain alternate values */
+ res_pred_r0 = _mm_and_si128(res_pred_r0, reg_chroma);
+ res_pred_r1 = _mm_and_si128(res_pred_r1, reg_chroma);
+ res_pred_r2 = _mm_and_si128(res_pred_r2, reg_chroma);
+ res_pred_r3 = _mm_and_si128(res_pred_r3, reg_chroma);
+
+ /* Convert to 32 bits */
+ res_r0 = _mm_cvtepu16_epi32(value_add);
+ res_r2 = _mm_cvtepu16_epi32(value_add);
+ res_r1 = _mm_cvtepu16_epi32(value_add);
+ res_r3 = _mm_cvtepu16_epi32(value_add);
+
+ /* Add res pred to the res obtained from inv transform */
+ res_r0 = _mm_add_epi16(res_pred_r0, res_r0);
+ res_r1 = _mm_add_epi16(res_pred_r1, res_r1);
+ res_r2 = _mm_add_epi16(res_pred_r2, res_r2);
+ res_r3 = _mm_add_epi16(res_pred_r3, res_r3);
+
+ /* Convert 32 bit res of the format [a0 0 a1 0 a2 0 a3 0] to
+ 16 bits of the format [a0 a1 a2 a3] using hadd [ao + 0,
+ a1 + 0, a2 + 0, a3 + 0] To be optimized */
+ temp0 = _mm_hadd_epi16(res_r0, res_r1);
+ temp1 = _mm_hadd_epi16(res_r2, res_r3);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp0 = _mm_max_epi16(temp0, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(temp0, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ temp1 = _mm_max_epi16(temp1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp1 = _mm_min_epi16(temp1, pos_255_8x16b);
+
+ /* Compute out pixel by adding res to pred */
+ pred_r0 = _mm_add_epi16(temp0, pred_r0);
+ pred_r2 = _mm_add_epi16(temp1, pred_r2);
+
+ res_r0 = _mm_cvtepu16_epi32(temp0);
+ res_r2 = _mm_cvtepu16_epi32(temp1);
+ res_r1 = _mm_srli_si128(temp0, 8);
+ res_r3 = _mm_srli_si128(temp1, 8);
+ res_r1 = _mm_cvtepu16_epi32(res_r1);
+ res_r3 = _mm_cvtepu16_epi32(res_r3);
+
+ /* Load res buffer */
+ out_r0 = _mm_loadu_si128((__m128i *) (&pi2_res[0 * i4_res_stride]));
+ out_r1 = _mm_loadu_si128((__m128i *) (&pi2_res[1 * i4_res_stride]));
+ out_r2 = _mm_loadu_si128((__m128i *) (&pi2_res[2 * i4_res_stride]));
+ out_r3 = _mm_loadu_si128((__m128i *) (&pi2_res[3 * i4_res_stride]));
+
+ /* Mask the loaded res in order to save the U/V res data computed in
+ this function call without thrashing the U/V res data that was saved
+ during an earlier function call */
+ chroma_mask = _mm_set1_epi32(0xffff0000);
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ /* Save the res in alternate locations */
+ out_r0 = _mm_add_epi16(out_r0, res_r0);
+ out_r1 = _mm_add_epi16(out_r1, res_r1);
+ out_r2 = _mm_add_epi16(out_r2, res_r2);
+ out_r3 = _mm_add_epi16(out_r3, res_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_res[0 * i4_res_stride]), out_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_res[1 * i4_res_stride]), out_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_res[2 * i4_res_stride]), out_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_res[3 * i4_res_stride]), out_r3);
+ /*------------------------------------------------------------------*/
+ /* Clipping the results to 8 bits */
+ pred_r0 = _mm_packus_epi16(pred_r0, pred_r2);
+ pred_r1 = _mm_srli_si128(pred_r0, 4);
+ pred_r2 = _mm_srli_si128(pred_r1, 4);
+ pred_r3 = _mm_srli_si128(pred_r2, 4);
+
+ /* p00 p01 p02 p03 -- all 16 bits */
+ pred_r0 = _mm_unpacklo_epi8(pred_r0, zero_8x16b);
+ /* p10 p11 p12 p13 -- all 16 bits */
+ pred_r1 = _mm_unpacklo_epi8(pred_r1, zero_8x16b);
+ /* p20 p21 p22 p23 -- all 16 bits */
+ pred_r2 = _mm_unpacklo_epi8(pred_r2, zero_8x16b);
+ /* p30 p31 p32 p33 -- all 16 bits */
+ pred_r3 = _mm_unpacklo_epi8(pred_r3, zero_8x16b);
+
+ /* Load interleaved out buffer */
+ out_r0 = _mm_loadl_epi64((__m128i *) (&pu1_out[0]));
+ out_r1 = _mm_loadl_epi64((__m128i *) (&pu1_out[i4_out_stride]));
+ out_r2 = _mm_loadl_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]));
+ out_r3 = _mm_loadl_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]));
+
+ /* Mask the interleaved out buf in order to save the U/V out pixel computed in
+ this function call without thrashing the U/V out pixel that was saved
+ during an earlier function call */
+ chroma_mask = _mm_set1_epi16(0xFF00);
+
+ out_r0 = _mm_and_si128(out_r0, chroma_mask);
+ out_r1 = _mm_and_si128(out_r1, chroma_mask);
+ out_r2 = _mm_and_si128(out_r2, chroma_mask);
+ out_r3 = _mm_and_si128(out_r3, chroma_mask);
+
+ /* Save the out pixels in alternate locations */
+ out_r0 = _mm_add_epi8(out_r0, pred_r0);
+ out_r1 = _mm_add_epi8(out_r1, pred_r1);
+ out_r2 = _mm_add_epi8(out_r2, pred_r2);
+ out_r3 = _mm_add_epi8(out_r3, pred_r3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), out_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), out_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), out_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), out_r3);
+}
diff --git a/common/x86/svc/isvc_iquant_itrans_recon_ssse3.c b/common/x86/svc/isvc_iquant_itrans_recon_ssse3.c
new file mode 100644
index 0000000..2cbdc94
--- /dev/null
+++ b/common/x86/svc/isvc_iquant_itrans_recon_ssse3.c
@@ -0,0 +1,1291 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_iquant_itrans_recon_ssse3.c
+ *
+ * @brief
+ * Contains function definitions for inverse quantization, inverse
+ * transform and reconstruction
+ *
+ * @author
+ * Mohit [100664]
+ *
+ * @par List of Functions:
+ * - isvc_iquant_itrans_recon_4x4_ssse3()
+ * - isvc_iquant_itrans_recon_8x8_ssse3()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/*
+ ********************************************************************************
+ *
+ * @brief This function reconstructs a 4x4 sub block from quantized resiude and
+ * prediction buffer
+ *
+ * @par Description:
+ * The quantized residue is first inverse quantized, then inverse transformed.
+ * This inverse transformed content is added to the prediction buffer to recon-
+ * struct the end output
+ *
+ * @param[in] pi2_src
+ * quantized 4x4 block
+ *
+ * @param[in] pu1_pred
+ * prediction 4x4 block
+ *
+ * @param[out] pu1_out
+ * reconstructed 4x4 block
+ *
+ * @param[in] src_strd
+ * quantization buffer stride
+ *
+ * @param[in] i4_pred_stride,
+ * Prediction buffer stride
+ *
+ * @param[in] i4_out_stride
+ * recon buffer Stride
+ *
+ * @param[in] pu2_scaling_list
+ * pointer to scaling list
+ *
+ * @param[in] pu2_norm_adjust
+ * pointer to inverse scale matrix
+ *
+ * @param[in] u4_qp_div_6
+ * Floor (qp/6)
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*16
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvc_iquant_itrans_recon_4x4_ssse3(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3, predload_r;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+
+ UNUSED(pi2_tmp);
+ UNUSED(pi2_dc_src);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_src_stride);
+ UNUSED(i4_res_stride);
+ UNUSED(i4_res_pred_stride);
+ UNUSED(pi2_res);
+ UNUSED(pi2_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /* Implement residue accumulation */
+ ASSERT(0);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src)); // a00 a01 a02 a03 a10 a11 a12 a13 -- the
+ // source matrix 0th,1st row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8)); // a20 a21 a22 a23 a30 a31 a32 a33 --
+ // the source matrix 2nd,3rd row
+ scalemat_r0_r1 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat)); // b00 b01 b02 b03 b10 b11 b12 b13 -- the
+ // scaling matrix 0th,1st row
+ scalemat_r2_r3 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8)); // b20 b21 b22 b23 b30 b31 b32 b33 --
+ // the scaling matrix 2nd,3rd row
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat)); // q00 q01 q02 q03 q10 q11
+ // q12 q13 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128(
+ (__m128i *) (pu2_weigh_mat + 8)); // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1,
+ dequant_r0_r1); // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ // b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3,
+ dequant_r2_r3); // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11
+ // b12*q12 b13*q13 -- 16 bit result
+
+ temp4 =
+ _mm_unpacklo_epi16(temp0,
+ zero_8x16b); // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp5 =
+ _mm_unpackhi_epi16(temp0,
+ zero_8x16b); // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp6 =
+ _mm_unpacklo_epi16(temp1,
+ zero_8x16b); // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp7 =
+ _mm_unpackhi_epi16(temp1,
+ zero_8x16b); // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ temp4 = _mm_madd_epi16(src_r0, temp4); // a00*b00*q00 a10*b10*q10 a20*b20*q20
+ // a30*b30 q30 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(i4_iq_start_idx == 1)
+ {
+ resq_r0 = _mm_insert_epi16(resq_r0, (WORD32) pi2_src[0], 0);
+ if(pi2_src[0] >= 0)
+ resq_r0 = _mm_insert_epi16(resq_r0, 0, 1);
+ else
+ resq_r0 = _mm_insert_epi16(resq_r0, -1, 1);
+ }
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // Load pred buffer
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[0])); // p00 p01 p02 p03 0 0 0 0 0
+ // 0 0 0 -- all 8 bits
+ pred_r0 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p00 p01 p02 p03 0 0 0 0 -- all 16 bits
+
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride])); // p10 p11 p12 p13 0 0 0 0 0 0
+ // 0 0 -- all 8 bits
+ pred_r1 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p10 p11 p12 p13 0 0 0 0 -- all 16 bits
+
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride])); // p20 p21 p22 p23 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p20 p21 p22 p23 0 0 0 0 -- all 16 bits
+
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride])); // p30 p31 p32 p33 0 0 0 0
+ // 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_unpacklo_epi8(predload_r, zero_8x16b); // p30 p31 p32 p33 0 0 0 0 -- all 16 bits
+ pred_r0 = _mm_unpacklo_epi16(pred_r0, zero_8x16b); // p00 p01 p02 p03 -- 32 bits sign extended
+ pred_r1 = _mm_unpacklo_epi16(pred_r1, zero_8x16b); // p10 p11 p12 p13 -- 32 bits sign extended
+ pred_r2 = _mm_unpacklo_epi16(pred_r2, zero_8x16b); // p20 p21 p22 p23 -- 32 bits sign extended
+ pred_r3 = _mm_unpacklo_epi16(pred_r3, zero_8x16b); // p30 p31 p32 p33 -- 32 bits sign extended
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_add_epi32(temp4, pred_r0);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_add_epi32(temp5, pred_r1);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_add_epi32(temp6, pred_r2);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_add_epi32(temp7, pred_r3);
+
+ // 32-bit to 16-bit conversion
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b); // sign check
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(resq_r0);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r1);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r2);
+ pu1_out += i4_out_stride;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r3);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function performs inverse quant and Inverse transform type Ci4 for 8x8
+ *block
+ *
+ * @par Description:
+ * Performs inverse transform Ci8 and adds the residue to get the
+ * reconstructed block
+ *
+ * @param[in] pi2_src
+ * Input 8x8coefficients
+ *
+ * @param[in] pu1_pred
+ * Prediction 8x8 block
+ *
+ * @param[out] pu1_recon
+ * Output 8x8 block
+ *
+ * @param[in] q_div
+ * QP/6
+ *
+ * @param[in] q_rem
+ * QP%6
+ *
+ * @param[in] q_lev
+ * Quantizer level
+ *
+ * @param[in] u4_src_stride
+ * Input stride
+ *
+ * @param[in] u4_pred_stride,
+ * Prediction stride
+ *
+ * @param[in] u4_out_stride
+ * Output Stride
+ *
+ * @param[in] pi4_tmp
+ * temporary buffer of size 1*64
+ * the tmp for each block
+ *
+ * @param[in] pu4_iquant_mat
+ * Pointer to the inverse quantization matrix
+ *
+ * @returns Void
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+void isvc_iquant_itrans_recon_8x8_ssse3(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res_pred, buffer_container_t *ps_res,
+ buffer_container_t *ps_rec,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src, WORD32 i4_iq_start_idx,
+ UWORD8 u1_res_accumulate)
+{
+ WORD16 *pi2_src = ps_src->pv_data;
+ WORD16 *pi2_res = ps_res->pv_data;
+ WORD16 *pi2_res_pred = ps_res_pred->pv_data;
+ UWORD8 *pu1_pred = ps_pred->pv_data;
+ UWORD8 *pu1_out = ps_rec->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ WORD32 i4_res_pred_stride = ps_res_pred->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_rec->i4_data_stride;
+ const UWORD16 *pu2_iscal_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ __m128i src_r0;
+ __m128i scalemat_r0;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // __m128i one_8x16b = _mm_set1_epi8(255); // all bits set to 1
+ // __m128i one_zero_mask = _mm_unpacklo_epi16(one_8x16b, zero_8x16b); // 1 0 1
+ // 0 1 0 1 0 --- 16 bits size
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 6) ? (1 << (5 - u4_qp_div_6)) : 0);
+ __m128i dequant_r0;
+ __m128i predload_r;
+ __m128i pred_r0_1, pred_r1_1, pred_r2_1, pred_r3_1, pred_r4_1, pred_r5_1, pred_r6_1, pred_r7_1;
+ __m128i sign_reg;
+ __m128i src_r0_1, src_r0_2;
+ __m128i scalemat_r0_1, scalemat_r0_2;
+ __m128i temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+ __m128i temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp20;
+ // To store dequantization results
+ __m128i resq_r0_1, resq_r0_2, resq_r1_1, resq_r1_2, resq_r2_1, resq_r2_2, resq_r3_1, resq_r3_2,
+ resq_r4_1, resq_r4_2, resq_r5_1, resq_r5_2, resq_r6_1, resq_r6_2, resq_r7_1, resq_r7_2;
+
+ UNUSED(pi2_tmp);
+ UNUSED(i4_iq_start_idx);
+ UNUSED(pi2_dc_src);
+ UNUSED(u1_res_accumulate);
+ UNUSED(i4_src_stride);
+ UNUSED(i4_res_stride);
+ UNUSED(i4_res_pred_stride);
+ UNUSED(pi2_res);
+ UNUSED(pi2_res_pred);
+ UNUSED(i4_iq_start_idx);
+
+ /* Implement residue accumulation */
+ ASSERT(0);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+
+ // Row 0 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src)); // a00 a01 a02 a03 a04 a05 a06 a07 -- the
+ // source matrix 0th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat)); // b00 b01 b02 b03 b04 b05 b06 b07
+ // -- the scaling matrix 0th row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[0])); // q0 q1 q2 q3 q4 q5 q6
+ // q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r0_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r0_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r0_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r0_1 =
+ _mm_packs_epi32(resq_r0_1,
+ resq_r0_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 1 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 8)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 1st row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 1st row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[8])); // q0 q1 q2 q3 q4 q5 q6
+ // q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r1_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r1_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r1_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r1_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r1_1 =
+ _mm_packs_epi32(resq_r1_1,
+ resq_r1_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 2 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 16)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 2nd row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 16)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 2nd row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[16])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r2_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r2_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r2_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r2_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r2_1 =
+ _mm_packs_epi32(resq_r2_1,
+ resq_r2_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 3 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 24)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 3rd row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 24)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 3rd row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[24])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 - 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r3_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r3_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r3_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r3_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r3_1 =
+ _mm_packs_epi32(resq_r3_1,
+ resq_r3_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 4 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 32)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 4th row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 32)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 4th row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[32])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r4_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r4_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r4_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r4_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r4_1 =
+ _mm_packs_epi32(resq_r4_1,
+ resq_r4_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 5 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 40)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 5th row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 40)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 5th row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[40])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r5_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r5_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ // resq_r5_1 = _mm_and_si128(resq_r5_1,one_zero_mask);
+ // resq_r5_2 = _mm_and_si128(resq_r5_2,one_zero_mask);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r5_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r5_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r5_1 =
+ _mm_packs_epi32(resq_r5_1,
+ resq_r5_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 6 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 48)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 6th row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 48)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 6th row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[48])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r6_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r6_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ // resq_r6_1 = _mm_and_si128(resq_r6_1,one_zero_mask);
+ // resq_r6_2 = _mm_and_si128(resq_r6_2,one_zero_mask);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r6_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r6_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ // resq_r6_1 = _mm_and_si128(resq_r6_1,one_zero_mask);
+ // resq_r6_2 = _mm_and_si128(resq_r6_2,one_zero_mask);
+ }
+ resq_r6_1 =
+ _mm_packs_epi32(resq_r6_1,
+ resq_r6_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ // Row 7 processing
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 56)); // a00 a01 a02 a03 a04 a05 a06 a07 a08 --
+ // the source matrix 7th row
+ scalemat_r0 =
+ _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 56)); // b00 b01 b02 b03 b04 b05 b06 b07 b08
+ // -- the scaling matrix 7th row
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[56])); // q0 q1 q2 q3 q4 q5
+ // q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ temp10 = _mm_mullo_epi16(scalemat_r0,
+ dequant_r0); // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4
+ // b05*q5 b06*q6 b07*q7 -- 16 bit result
+ scalemat_r0_1 =
+ _mm_unpacklo_epi16(temp10,
+ zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_2 =
+ _mm_unpackhi_epi16(temp10,
+ zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ temp5 = _mm_madd_epi16(src_r0_1,
+ scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2
+ // a03*b03*q3 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2,
+ scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6
+ // a07*b07*q7 -- 32 bits long
+ if(u4_qp_div_6 >= 6)
+ {
+ resq_r7_1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 6);
+ resq_r7_2 = _mm_slli_epi32(temp7, u4_qp_div_6 - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r7_1 = _mm_srai_epi32(temp5, 6 - u4_qp_div_6);
+ resq_r7_2 = _mm_srai_epi32(temp7, 6 - u4_qp_div_6);
+ }
+ resq_r7_1 =
+ _mm_packs_epi32(resq_r7_1,
+ resq_r7_2); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4
+ // a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16 bit long
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3 a4 a5 a6 a7
+ * b0 b1 b2 b3 b4 b5 b6 b7
+ * c0 c1 c2 c3 c4 c5 c6 c7
+ * d0 d1 d2 d3 d4 d5 d6 d7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r0_1, resq_r1_1); // a0 b0 a1 b1 a2 b2 a3 b3
+ temp3 = _mm_unpacklo_epi16(resq_r2_1, resq_r3_1); // c0 d0 c1 d1 c2 d2 c3 d3
+ temp2 = _mm_unpackhi_epi16(resq_r0_1, resq_r1_1); // a4 b4 a5 b5 a6 b6 a7 b7
+ temp4 = _mm_unpackhi_epi16(resq_r2_1, resq_r3_1); // c4 d4 c5 d5 c6 d6 c7 d7
+ resq_r0_1 = _mm_unpacklo_epi32(temp1, temp3); // a0 b0 c0 d0 a1 b1 c1 d1
+ resq_r1_1 = _mm_unpackhi_epi32(temp1, temp3); // a2 b2 c2 d2 a3 b3 c3 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp2, temp4); // a4 b4 c4 d4 a5 b5 c5 d5
+ resq_r3_1 = _mm_unpackhi_epi32(temp2, temp4); // a6 b6 c6 d6 a7 b7 c7 d7
+ /*
+ * e0 e1 e2 e3 e4 e5 e6 e7
+ * f0 f1 f2 f3 f4 f5 f6 f7
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * h0 h1 h2 h3 h4 h5 h6 h7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r4_1, resq_r5_1); // e0 f0 e1 f1 e2 f2 e2 f3
+ temp3 = _mm_unpacklo_epi16(resq_r6_1, resq_r7_1); // g0 h0 g1 h1 g2 h2 g3 h3
+ temp2 = _mm_unpackhi_epi16(resq_r4_1, resq_r5_1); // e4 f4 e5 f5 e6 f6 e7 f7
+ temp4 = _mm_unpackhi_epi16(resq_r6_1, resq_r7_1); // g4 h4 g5 h5 g6 h6 g7 h7
+ resq_r4_1 = _mm_unpacklo_epi32(temp1, temp3); // e0 f0 g0 h0 e1 f1 g1 h1
+ resq_r5_1 = _mm_unpackhi_epi32(temp1, temp3); // e2 f2 g2 h2 e3 f3 g3 h3
+ resq_r6_1 = _mm_unpacklo_epi32(temp2, temp4); // e4 f4 g4 h4 e5 f5 g5 h5
+ resq_r7_1 = _mm_unpackhi_epi32(temp2, temp4); // e6 f6 g6 h6 e7 f7 g7 h7
+ /*
+ * a0 b0 c0 d0 a1 b1 c1 d1
+ * a2 b2 c2 d2 a3 b3 c3 d3
+ * a4 b4 c4 d4 a5 b5 c5 d5
+ * a6 b6 c6 d6 a7 b7 c7 d7
+ * e0 f0 g0 h0 e1 f1 g1 h1
+ * e2 f2 g2 h2 e3 f3 g3 h3
+ * e4 f4 g4 h4 e5 f5 g5 h5
+ * e6 f6 g6 h6 e7 f7 g7 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 b0 c0 d0 e0 f0 g0 h0
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // a1 b1 c1 d1 e1 f1 g1 h1
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // a2 b2 c2 d2 e2 f2 g2 h2
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // a3 b3 c3 d3 e3 f3 g3 h3
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // a4 b4 c4 d4 e4 f4 g4 h4
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // a5 b5 c5 d5 e5 f5 g5 h5
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // a6 b6 c6 d6 e6 f6 g6 h6
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // a7 b7 c7 d7 e7 f7 g7 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2 = w0 - w4 */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4 = (w2 >> 1) - w6 */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6 = w2 + (w6 >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1 = y1 + (y7 >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2 = y2 + y4 */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3 = y3 + (y5 >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4 = y2 - y4 */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5 = (y3 >> 2) - y5 */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6 = y0 - y6 */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7 = y7 - (y1 >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ /* x1 = z2 + z5 */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ /* x2 = z4 + z3 */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ /* x3 = z6 + z1 */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ /* x4 = z6 - z1 */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ /* x5 = z4 - z3 */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ /* x6 = z2 - z5 */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ /* x7 = z0 - z7 */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0 e0 f0 g0 h0
+ * a1 b1 c1 d1 e1 f1 g1 h1
+ * a2 b2 c2 d2 e2 f2 g2 h2
+ * a3 b3 c3 d3 e3 f3 g3 h3
+ */
+ temp17 = _mm_unpacklo_epi16(temp1, temp2); // a0 a1 b0 b1 c0 c1 d0 d1
+ temp19 = _mm_unpacklo_epi16(temp3, temp4); // a2 a3 b2 b3 c2 c3 d2 d3
+ temp18 = _mm_unpackhi_epi16(temp1, temp2); // e0 e1 f0 f1 g0 g1 h0 h1
+ temp20 = _mm_unpackhi_epi16(temp3, temp4); // e2 e3 f2 f3 g2 g3 h2 h3
+
+ resq_r0_1 = _mm_unpacklo_epi32(temp17, temp19); // a0 a1 a2 a3 b0 b1 b2 b3
+ resq_r1_1 = _mm_unpackhi_epi32(temp17, temp19); // c0 c1 c2 c3 d0 d1 d2 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp18, temp20); // e0 e1 e2 e3 f0 f1 f2 f3
+ resq_r3_1 = _mm_unpackhi_epi32(temp18, temp20); // g0 g2 g2 g3 h0 h1 h2 h3
+ /*
+ * a4 b4 c4 d4 e4 f4 g4 h4
+ * a5 b5 c5 d5 e5 f5 g5 h5
+ * a6 b6 c6 d6 e6 f6 g6 h6
+ * a7 b7 c7 d7 e7 f7 g7 h7
+ */
+ temp17 = _mm_unpacklo_epi16(temp5, temp6); // a4 a5 b4 b5 c4 c5 d4 d5
+ temp19 = _mm_unpacklo_epi16(temp7, temp8); // a6 a7 b6 b7 c6 c7 d6 d7
+ temp18 = _mm_unpackhi_epi16(temp5, temp6); // e4 e5 f4 f5 g4 g5 h4 h5
+ temp20 = _mm_unpackhi_epi16(temp7, temp8); // e6 e7 f6 f7 g6 g7 h6 h7
+
+ resq_r4_1 = _mm_unpacklo_epi32(temp17, temp19); // a4 a5 a6 a7 b4 b5 b6 b7
+ resq_r5_1 = _mm_unpackhi_epi32(temp17, temp19); // c4 c5 c6 c7 d4 d5 d6 d7
+ resq_r6_1 = _mm_unpacklo_epi32(temp18, temp20); // e4 e5 e6 e7 f4 f5 f6 f7
+ resq_r7_1 = _mm_unpackhi_epi32(temp18, temp20); // g4 g5 g6 g7 h4 h5 h6 h7
+ /* a0 a1 a2 a3 b0 b1 b2 b3
+ * c0 c1 c2 c3 d0 d1 d2 d3
+ * e0 e1 e2 e3 f0 f1 f2 f3
+ * g0 g2 g2 g3 h0 h1 h2 h3
+ * a4 a5 a6 a7 b4 b5 b6 b7
+ * c4 c5 c6 c7 d4 d5 d6 d7
+ * e4 e5 e6 e7 f4 f5 f6 f7
+ * g4 g5 g6 g7 h4 h5 h6 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 a1 a2 a3 a4 a5 a6 a7
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // b0 b1 b2 b3 b4 b5 b6 b7
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // c0 c1 c2 c3 c4 c5 c6 c7
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // d0 d1 d2 d3 d4 d5 d6 d7
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // e0 e1 e2 e3 e4 e5 e6 e7
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // f0 f1 f2 f3 f4 f5 f6 f7
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // g0 g1 g2 g3 g4 g5 g6 g7
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // h0 h1 h2 h3 h4 h5 h6 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+
+ zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // Load pred buffer row 0
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[0])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0
+ // -- all 8 bits
+ pred_r0_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 1
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r1_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 2
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[2 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r2_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 3
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[3 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r3_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 4
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[4 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r4_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 5
+ predload_r =
+ _mm_loadl_epi64((__m128i *) (&pu1_pred[5 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0
+ // 0 0 0 0 0 0 0 -- all 8 bit
+ pred_r5_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 6
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[6 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r6_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ // Load pred buffer row 7
+ predload_r = _mm_loadl_epi64(
+ (__m128i *) (&pu1_pred[7 * i4_pred_stride])); // p0 p1 p2 p3 p4 p5 p6 p7 0 0
+ // 0 0 0 0 0 0 -- all 8 bits
+ pred_r7_1 =
+ _mm_unpacklo_epi8(predload_r, zero_8x16b); // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ /* y0j = w0j + w4j */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2j = w0j - w4j */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1j = -w3j + w5j - w7j - (w7j >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3j = w1j + w7j - w3j - (w3j >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4j = (w2j >> 1) - w6j */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6j = w2j + (w6j >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1j = y1j + (y7j >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2j = y2j + y4j */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3j = y3j + (y5j >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4j = y2j - y4j */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5j = (y3j >> 2) - y5j */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6j = y0j - y6j */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7j = y7j - (y1j >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp1);
+ temp10 = _mm_unpacklo_epi16(temp1, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp1, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp1 = _mm_add_epi16(temp10, pred_r0_1);
+ /* x1j = z2j + z5j */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp2);
+ temp10 = _mm_unpacklo_epi16(temp2, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp2, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp2 = _mm_add_epi16(temp10, pred_r1_1);
+ /* x2j = z4j + z3j */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp3);
+ temp10 = _mm_unpacklo_epi16(temp3, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp3, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp3 = _mm_add_epi16(temp10, pred_r2_1);
+ /* x3j = z6j + z1j */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp4);
+ temp10 = _mm_unpacklo_epi16(temp4, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp4, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp4 = _mm_add_epi16(temp10, pred_r3_1);
+ /* x4j = z6j - z1j */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp5);
+ temp10 = _mm_unpacklo_epi16(temp5, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp5, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp5 = _mm_add_epi16(temp10, pred_r4_1);
+ /* x5j = z4j - z3j */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp6);
+ temp10 = _mm_unpacklo_epi16(temp6, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp6, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp6 = _mm_add_epi16(temp10, pred_r5_1);
+ /* x6j = z2j - z5j */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp7);
+ temp10 = _mm_unpacklo_epi16(temp7, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp7, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp7 = _mm_add_epi16(temp10, pred_r6_1);
+ /* x7j = z0j - z7j */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp8);
+ temp10 = _mm_unpacklo_epi16(temp8, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp8, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp8 = _mm_add_epi16(temp10, pred_r7_1);
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b); // sign check
+ temp1 = _mm_and_si128(temp1, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp2, zero_8x16b); // sign check
+ temp2 = _mm_and_si128(temp2, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp3, zero_8x16b); // sign check
+ temp3 = _mm_and_si128(temp3, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b); // sign check
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b); // sign check
+ temp5 = _mm_and_si128(temp5, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp6, zero_8x16b); // sign check
+ temp6 = _mm_and_si128(temp6, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp7, zero_8x16b); // sign check
+ temp7 = _mm_and_si128(temp7, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp8, zero_8x16b); // sign check
+ temp8 = _mm_and_si128(temp8, sign_reg);
+
+ resq_r0_2 = _mm_packus_epi16(temp1, zero_8x16b);
+ resq_r1_2 = _mm_packus_epi16(temp2, zero_8x16b);
+ resq_r2_2 = _mm_packus_epi16(temp3, zero_8x16b);
+ resq_r3_2 = _mm_packus_epi16(temp4, zero_8x16b);
+ resq_r4_2 = _mm_packus_epi16(temp5, zero_8x16b);
+ resq_r5_2 = _mm_packus_epi16(temp6, zero_8x16b);
+ resq_r6_2 = _mm_packus_epi16(temp7, zero_8x16b);
+ resq_r7_2 = _mm_packus_epi16(temp8, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), resq_r0_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[i4_out_stride]), resq_r1_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * i4_out_stride]), resq_r2_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * i4_out_stride]), resq_r3_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[4 * i4_out_stride]), resq_r4_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[5 * i4_out_stride]), resq_r5_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[6 * i4_out_stride]), resq_r6_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[7 * i4_out_stride]), resq_r7_2);
+}
diff --git a/common/x86/svc/isvc_mem_fns_sse42.c b/common/x86/svc/isvc_mem_fns_sse42.c
new file mode 100644
index 0000000..cfcd249
--- /dev/null
+++ b/common/x86/svc/isvc_mem_fns_sse42.c
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+
+ * *******************************************************************************
+
+ * * @file
+ * isvc_mem_fns_sse42.c
+ *
+ * @brief
+ * SSE4.2 variants of
+ * functions used for memory operations
+ *
+
+ * *******************************************************************************
+
+ */
+#include <string.h>
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_mem_fns.h"
+
+void isvc_memset_2d_sse42(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 u1_val, WORD32 i4_blk_wd,
+ WORD32 i4_blk_ht)
+{
+ WORD32 i, j;
+
+ if((i4_blk_wd == 4) && (i4_blk_ht == 4))
+ {
+ *((WORD32 *) (pu1_dst)) = _mm_cvtsi128_si32(_mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ *((WORD32 *) (pu1_dst)) = _mm_cvtsi128_si32(_mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ *((WORD32 *) (pu1_dst)) = _mm_cvtsi128_si32(_mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ *((WORD32 *) (pu1_dst)) = _mm_cvtsi128_si32(_mm_set1_epi8(u1_val));
+ }
+ else if((i4_blk_wd == 8) && (i4_blk_ht == 8))
+ {
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ pu1_dst += i4_dst_stride;
+
+ _mm_storel_epi64((__m128i *) (&pu1_dst[0]), _mm_set1_epi8(u1_val));
+ }
+ else if((i4_blk_wd % 16 == 0) && (i4_blk_ht % 16 == 0))
+ {
+ UWORD8 *pu1_dst_col_ptr, *pu1_dst_row_ptr;
+
+ WORD32 i4_width_by_16 = i4_blk_wd / 16;
+ WORD32 i4_height_by_16 = i4_blk_ht / 16;
+
+ for(i = 0; i < i4_height_by_16; i++)
+ {
+ pu1_dst_row_ptr = pu1_dst + i * 16 * i4_dst_stride;
+
+ for(j = 0; j < i4_width_by_16; j++)
+ {
+ pu1_dst_col_ptr = pu1_dst_row_ptr + (j << 4);
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ pu1_dst_col_ptr += i4_dst_stride;
+
+ _mm_storeu_si128((__m128i *) (&pu1_dst_col_ptr[0]), _mm_set1_epi8(u1_val));
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < i4_blk_ht; i++)
+ {
+ memset(pu1_dst, u1_val, i4_blk_wd);
+
+ pu1_dst += i4_dst_stride;
+ }
+ }
+}
diff --git a/common/x86/svc/isvc_mem_fns_ssse3.c b/common/x86/svc/isvc_mem_fns_ssse3.c
new file mode 100644
index 0000000..6467b8d
--- /dev/null
+++ b/common/x86/svc/isvc_mem_fns_ssse3.c
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvc_mem_fns_atom_intr.c
+ *
+ * @brief
+ * Functions used for memory operations
+ *
+ * @author
+ * Ittiam
+ *
+ * @par List of Functions:
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_mem_fns.h"
+
+#include <immintrin.h>
+
+/**
+********************************************************************************
+* @brief copies a 2d blk from one location to another
+*
+* @param[out] pu1_dst : dst pointer
+*
+* @param[in] i4_dst_stride: stride of destination
+*
+* @param[in] pu1_src : src ptr
+*
+* @param[in] i4_src_stride: stride of src
+*
+* @param[in] i4_blk_wd : blk width
+*
+* @param[in] i4_blk_ht : blk height
+*
+* @return void
+********************************************************************************
+*/
+void isvc_copy_2d_ssse3(UWORD8 *pu1_dst, WORD32 i4_dst_stride, UWORD8 *pu1_src,
+ WORD32 i4_src_stride, WORD32 i4_blk_wd, WORD32 i4_blk_ht)
+{
+ WORD32 i, j;
+ /* all 128 bit registers are named with a suffix mxnb, where m is the */
+ /* number of n bits packed in the register */
+
+ if(0 == (i4_blk_wd & 31)) /* wd multiple of 32 case */
+ {
+ __m128i src0_16x8b, src1_16x8b, src2_16x8b, src3_16x8b;
+ __m128i src4_16x8b, src5_16x8b, src6_16x8b, src7_16x8b;
+
+ if(0 == (i4_blk_ht & 7)) /* ht multiple of 8 case */
+ {
+ __m128i src8_16x8b, src9_16x8b, src10_16x8b, src11_16x8b;
+ __m128i src12_16x8b, src13_16x8b, src14_16x8b, src15_16x8b;
+
+ for(i = 0; i < i4_blk_ht; i += 8)
+ {
+ for(j = 0; j < i4_blk_wd; j += 32)
+ {
+ src0_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src)); // i = 0
+ src1_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+ src4_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 4 * i4_src_stride)); // i = 4
+ src5_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 5 * i4_src_stride)); // i = 5
+ src6_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 6 * i4_src_stride)); // i = 6
+ src7_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 7 * i4_src_stride)); // i = 7
+ /* Add 16 as offset */
+ src8_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 16)); // i = 0
+ src9_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + i4_src_stride + 16)); // i = 1
+ src10_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride + 16)); // i = 2
+ src11_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride + 16)); // i = 3
+ src12_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 4 * i4_src_stride + 16)); // i = 4
+ src13_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 5 * i4_src_stride + 16)); // i = 5
+ src14_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 6 * i4_src_stride + 16)); // i = 6
+ src15_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 7 * i4_src_stride + 16)); // i = 7
+
+ _mm_storeu_si128((__m128i *) (pu1_dst), src0_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + i4_dst_stride), src1_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 4 * i4_dst_stride), src4_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 5 * i4_dst_stride), src5_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 6 * i4_dst_stride), src6_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 7 * i4_dst_stride), src7_16x8b);
+
+ _mm_storeu_si128((__m128i *) (pu1_dst + 16), src8_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + i4_dst_stride + 16), src9_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride + 16), src10_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride + 16), src11_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 4 * i4_dst_stride + 16), src12_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 5 * i4_dst_stride + 16), src13_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 6 * i4_dst_stride + 16), src14_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 7 * i4_dst_stride + 16), src15_16x8b);
+
+ pu1_src += 32;
+ pu1_dst += 32;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 8 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 8 * i4_dst_stride;
+ }
+ }
+ else /* ht multiple of 4 case */
+ {
+ for(i = 0; i < i4_blk_ht; i += 4)
+ {
+ for(j = 0; j < i4_blk_wd; j += 32)
+ {
+ src0_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src)); // i = 0
+ src1_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+ /* Add 16 as offset */
+ src4_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 16)); // i = 0
+ src5_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + i4_src_stride + 16)); // i = 1
+ src6_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride + 16)); // i = 2
+ src7_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride + 16)); // i = 3
+
+ _mm_storeu_si128((__m128i *) (pu1_dst), src0_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + i4_dst_stride), src1_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 16), src4_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + i4_dst_stride + 16), src5_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride + 16), src6_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride + 16), src7_16x8b);
+
+ pu1_src += 32;
+ pu1_dst += 32;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 4 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 4 * i4_dst_stride;
+ }
+ }
+ }
+ else if(0 == (i4_blk_wd & 15)) /* wd multiple of 16 case */
+ {
+ __m128i src0_16x8b, src1_16x8b, src2_16x8b, src3_16x8b;
+
+ if(0 == (i4_blk_ht & 7)) /* ht multiple of 8 case */
+ {
+ __m128i src4_16x8b, src5_16x8b, src6_16x8b, src7_16x8b;
+
+ for(i = 0; i < i4_blk_ht; i += 8)
+ {
+ for(j = 0; j < i4_blk_wd; j += 16)
+ {
+ src0_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+ src4_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 4 * i4_src_stride)); // i = 4
+ src5_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 5 * i4_src_stride)); // i = 5
+ src6_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 6 * i4_src_stride)); // i = 6
+ src7_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 7 * i4_src_stride)); // i = 7
+
+ _mm_storeu_si128((__m128i *) (pu1_dst + 0 * i4_dst_stride), src0_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 1 * i4_dst_stride), src1_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 4 * i4_dst_stride), src4_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 5 * i4_dst_stride), src5_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 6 * i4_dst_stride), src6_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 7 * i4_dst_stride), src7_16x8b);
+
+ pu1_src += 16;
+ pu1_dst += 16;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 8 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 8 * i4_dst_stride;
+ }
+ }
+ else /* ht multiple of 4 case */
+ {
+ for(i = 0; i < i4_blk_ht; i += 4)
+ {
+ for(j = 0; j < i4_blk_wd; j += 16)
+ {
+ src0_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadu_si128((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+
+ _mm_storeu_si128((__m128i *) (pu1_dst + 0 * i4_dst_stride), src0_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 1 * i4_dst_stride), src1_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+
+ pu1_src += 16;
+ pu1_dst += 16;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 4 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 4 * i4_dst_stride;
+ }
+ }
+ }
+ else if(0 == (i4_blk_wd & 7)) /* wd multiple of 8 case */
+ {
+ __m128i src0_16x8b, src1_16x8b, src2_16x8b, src3_16x8b;
+
+ if(0 == (i4_blk_ht & 7)) /* ht multiple of 8 case */
+ {
+ __m128i src4_16x8b, src5_16x8b, src6_16x8b, src7_16x8b;
+
+ for(i = 0; i < i4_blk_ht; i += 8)
+ {
+ for(j = 0; j < i4_blk_wd; j += 8)
+ {
+ src0_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+ src4_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 4 * i4_src_stride)); // i = 4
+ src5_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 5 * i4_src_stride)); // i = 5
+ src6_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 6 * i4_src_stride)); // i = 6
+ src7_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 7 * i4_src_stride)); // i = 7
+
+ _mm_storel_epi64((__m128i *) (pu1_dst + 0 * i4_dst_stride), src0_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 1 * i4_dst_stride), src1_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 4 * i4_dst_stride), src4_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 5 * i4_dst_stride), src5_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 6 * i4_dst_stride), src6_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 7 * i4_dst_stride), src7_16x8b);
+
+ pu1_src += 8;
+ pu1_dst += 8;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 8 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 8 * i4_dst_stride;
+ }
+ }
+ else /* ht multiple of 4 case */
+ {
+ for(i = 0; i < i4_blk_ht; i += 4)
+ {
+ for(j = 0; j < i4_blk_wd; j += 8)
+ {
+ src0_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+
+ _mm_storel_epi64((__m128i *) (pu1_dst + 0 * i4_dst_stride), src0_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 1 * i4_dst_stride), src1_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 2 * i4_dst_stride), src2_16x8b);
+ _mm_storel_epi64((__m128i *) (pu1_dst + 3 * i4_dst_stride), src3_16x8b);
+
+ pu1_src += 8;
+ pu1_dst += 8;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 4 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 4 * i4_dst_stride;
+ }
+ }
+ }
+ else /* wd multiple of 4 case */
+ {
+ __m128i src0_16x8b, src1_16x8b, src2_16x8b, src3_16x8b;
+ WORD32 src0, src1, src2, src3;
+ if(0 == (i4_blk_ht & 7)) /* ht multiple of 8 case */
+ {
+ __m128i src4_16x8b, src5_16x8b, src6_16x8b, src7_16x8b;
+ WORD32 src4, src5, src6, src7;
+
+ for(i = 0; i < i4_blk_ht; i += 8)
+ {
+ for(j = 0; j < i4_blk_wd; j += 4)
+ {
+ src0_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+ src4_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 4 * i4_src_stride)); // i = 4
+ src5_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 5 * i4_src_stride)); // i = 5
+ src6_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 6 * i4_src_stride)); // i = 6
+ src7_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 7 * i4_src_stride)); // i = 7
+
+ src0 = _mm_cvtsi128_si32(src0_16x8b);
+ src1 = _mm_cvtsi128_si32(src1_16x8b);
+ src2 = _mm_cvtsi128_si32(src2_16x8b);
+ src3 = _mm_cvtsi128_si32(src3_16x8b);
+ src4 = _mm_cvtsi128_si32(src4_16x8b);
+ src5 = _mm_cvtsi128_si32(src5_16x8b);
+ src6 = _mm_cvtsi128_si32(src6_16x8b);
+ src7 = _mm_cvtsi128_si32(src7_16x8b);
+
+ *(WORD32 *) (&pu1_dst[0 * i4_dst_stride]) = src0;
+ *(WORD32 *) (&pu1_dst[1 * i4_dst_stride]) = src1;
+ *(WORD32 *) (&pu1_dst[2 * i4_dst_stride]) = src2;
+ *(WORD32 *) (&pu1_dst[3 * i4_dst_stride]) = src3;
+ *(WORD32 *) (&pu1_dst[4 * i4_dst_stride]) = src4;
+ *(WORD32 *) (&pu1_dst[5 * i4_dst_stride]) = src5;
+ *(WORD32 *) (&pu1_dst[6 * i4_dst_stride]) = src6;
+ *(WORD32 *) (&pu1_dst[7 * i4_dst_stride]) = src7;
+
+ pu1_src += 4;
+ pu1_dst += 4;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 8 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 8 * i4_dst_stride;
+ }
+ }
+ else /* ht multiple of 4 case */
+ {
+ for(i = 0; i < i4_blk_ht; i += 4)
+ {
+ for(j = 0; j < i4_blk_wd; j += 4)
+ {
+ src0_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 0 * i4_src_stride)); // i = 0
+ src1_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 1 * i4_src_stride)); // i = 1
+ src2_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 2 * i4_src_stride)); // i = 2
+ src3_16x8b =
+ _mm_loadl_epi64((__m128i *) (pu1_src + 3 * i4_src_stride)); // i = 3
+
+ src0 = _mm_cvtsi128_si32(src0_16x8b);
+ src1 = _mm_cvtsi128_si32(src1_16x8b);
+ src2 = _mm_cvtsi128_si32(src2_16x8b);
+ src3 = _mm_cvtsi128_si32(src3_16x8b);
+
+ *(WORD32 *) (&pu1_dst[0 * i4_dst_stride]) = src0;
+ *(WORD32 *) (&pu1_dst[1 * i4_dst_stride]) = src1;
+ *(WORD32 *) (&pu1_dst[2 * i4_dst_stride]) = src2;
+ *(WORD32 *) (&pu1_dst[3 * i4_dst_stride]) = src3;
+
+ pu1_src += 4;
+ pu1_dst += 4;
+ }
+
+ pu1_src = pu1_src - i4_blk_wd + 4 * i4_src_stride;
+ pu1_dst = pu1_dst - i4_blk_wd + 4 * i4_dst_stride;
+ }
+ }
+ }
+}
diff --git a/common/x86/svc/isvc_padding_ssse3.c b/common/x86/svc/isvc_padding_ssse3.c
new file mode 100644
index 0000000..3866301
--- /dev/null
+++ b/common/x86/svc/isvc_padding_ssse3.c
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* ih264_padding_atom_intr.c
+*
+* @brief
+* Contains function definitions for Padding
+*
+* @author
+* Srinivas T
+*
+* @par List of Functions:
+* - isvc_pad_left_luma_ssse3()
+* - isvc_pad_left_chroma_ssse3()
+* - isvc_pad_right_luma_ssse3()
+* - isvc_pad_right_chroma_ssse3()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include <string.h>
+#include <assert.h>
+#include "ih264_typedefs.h"
+#include "ih264_platform_macros.h"
+#include "isvc_mem_fns.h"
+#include "ih264_debug.h"
+
+#include <immintrin.h>
+
+/**
+*******************************************************************************
+*
+* @brief
+* Padding (luma block) at the left of a 2d array
+*
+* @par Description:
+* The left column of a 2d array is replicated for pad_size times at the left
+*
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @param[in] pad_size
+* integer -padding size of the array
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+void isvc_pad_left_luma_ssse3(UWORD8 *pu1_src, WORD32 src_strd, WORD32 ht, WORD32 pad_size)
+{
+ WORD32 row;
+ WORD32 i;
+ UWORD8 *pu1_dst;
+
+ ASSERT(pad_size % 8 == 0);
+
+ for(row = 0; row < ht; row++)
+ {
+ __m128i src_temp0_16x8b;
+
+ pu1_dst = pu1_src - pad_size;
+ src_temp0_16x8b = _mm_set1_epi8(*pu1_src);
+ for(i = 0; i < pad_size; i += 8)
+ {
+ _mm_storel_epi64((__m128i *) (pu1_dst + i), src_temp0_16x8b);
+ }
+ pu1_src += src_strd;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Padding (chroma block) at the left of a 2d array
+*
+* @par Description:
+* The left column of a 2d array is replicated for pad_size times at the left
+*
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array (each colour component)
+*
+* @param[in] pad_size
+* integer -padding size of the array
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+void isvc_pad_left_chroma_ssse3(UWORD8 *pu1_src, WORD32 src_strd, WORD32 ht, WORD32 pad_size)
+{
+ WORD32 row;
+ WORD32 col;
+ UWORD8 *pu1_dst;
+
+ ASSERT(pad_size % 8 == 0);
+ for(row = 0; row < ht; row++)
+ {
+ __m128i src_temp0_16x8b;
+
+ pu1_dst = pu1_src - pad_size;
+ src_temp0_16x8b = _mm_set1_epi16(*((UWORD16 *) pu1_src));
+ for(col = 0; col < pad_size; col += 8)
+ {
+ _mm_storel_epi64((__m128i *) (pu1_dst + col), src_temp0_16x8b);
+ }
+ pu1_src += src_strd;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Padding (luma block) at the right of a 2d array
+*
+* @par Description:
+* The right column of a 2d array is replicated for pad_size times at the right
+*
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @param[in] pad_size
+* integer -padding size of the array
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+void isvc_pad_right_luma_ssse3(UWORD8 *pu1_src, WORD32 src_strd, WORD32 ht, WORD32 pad_size)
+{
+ WORD32 row;
+ WORD32 col;
+ UWORD8 *pu1_dst;
+
+ ASSERT(pad_size % 8 == 0);
+
+ for(row = 0; row < ht; row++)
+ {
+ __m128i src_temp0_16x8b;
+
+ pu1_dst = pu1_src;
+ src_temp0_16x8b = _mm_set1_epi8(*(pu1_src - 1));
+ for(col = 0; col < pad_size; col += 8)
+ {
+ _mm_storel_epi64((__m128i *) (pu1_dst + col), src_temp0_16x8b);
+ }
+ pu1_src += src_strd;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Padding (chroma block) at the right of a 2d array
+*
+* @par Description:
+* The right column of a 2d array is replicated for pad_size times at the right
+*
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array (each colour component)
+*
+* @param[in] pad_size
+* integer -padding size of the array
+*
+* @param[in] ht
+* integer height of the array
+*
+* @param[in] wd
+* integer width of the array
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+void isvc_pad_right_chroma_ssse3(UWORD8 *pu1_src, WORD32 src_strd, WORD32 ht, WORD32 pad_size)
+{
+ WORD32 row;
+ WORD32 col;
+ UWORD8 *pu1_dst;
+
+ ASSERT(pad_size % 8 == 0);
+
+ for(row = 0; row < ht; row++)
+ {
+ __m128i src_temp0_16x8b;
+
+ pu1_dst = pu1_src;
+ src_temp0_16x8b = _mm_set1_epi16(*((UWORD16 *) (pu1_src - 2)));
+ for(col = 0; col < pad_size; col += 8)
+ {
+ _mm_storel_epi64((__m128i *) (pu1_dst + col), src_temp0_16x8b);
+ }
+
+ pu1_src += src_strd;
+ }
+}
diff --git a/common/x86/svc/isvc_resi_trans_quant_sse42.c b/common/x86/svc/isvc_resi_trans_quant_sse42.c
new file mode 100644
index 0000000..d9832f0
--- /dev/null
+++ b/common/x86/svc/isvc_resi_trans_quant_sse42.c
@@ -0,0 +1,1881 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+
+ * *******************************************************************************
+
+ * * @file
+ * isvc_resi_trans_quant_sse42.c
+ *
+ * @brief
+ * Contains function
+ * definitions single stage forward transform for H.264
+ * It will calculate
+ * the residue, do the cf and then do quantization
+ *
+ * @author
+ * Mohit
+ * [100664]
+ *
+ * @par List of Functions:
+ * -
+ * isvc_resi_trans_quant_4x4_sse42()
+ * -
+ * isvc_resi_trans_quant_chroma_4x4_sse42()
+ *
+ * @remarks
+ * None
+ *
+
+ * *******************************************************************************
+
+ */
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/**|
+*******************************************************************************
+*
+*
+* @brief
+* This function performs forward transform and quantization on a 4*4
+* block
+*
+* @par Description:
+* The function accepts source buffer and
+* estimation buffer. From these, it
+* computes the residue. This is residue
+* is then transformed and quantized.
+* The transform and quantization are in
+* placed computed. They use the residue
+* buffer for this.
+*
+* @param[in]
+* pu1_src
+* Pointer to source sub-block
+*
+* @param[in] pu1_pred
+* Pointer
+* to prediction sub-block
+*
+* @param[in] pi2_out
+* Pointer to residual
+* sub-block
+*
+* @param[in] i4_src_stride
+* Source stride
+*
+* @param[in]
+* i4_pred_stride
+* Prediction stride
+*
+* @param[in] dst_strd
+* Destination
+* stride
+*
+* @param[in] u4_qbits
+* QP_BITS_h264_4x4 + floor(QP/6)
+*
+*
+* @param[in] pu2_threshold_matrix
+* Pointer to Forward Quant Threshold
+* Matrix
+*
+* @param[in] pu2_scale_matrix
+* Pointer to Forward Quant Scale
+* Matrix
+*
+* @param[in] u4_round_factor
+* Quantization Round factor
+*
+*
+* @param[out] pu1_nnz
+* Total non-zero coefficients in the current
+* sub-block
+*
+* @returns
+*
+* @remarks
+*
+* None
+*
+*******************************************************************************
+*/
+void isvc_resi_trans_quant_4x4_sse42(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out,
+ UWORD8 u1_use_upsampled_res)
+{
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 tmp_dc, u4_zero_coeff, u4_nonzero_coeff = 0;
+ WORD32 mask0, mask1;
+ __m128i sum0, sum1, sum2, cmp0, cmp1;
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+ __m128i temp_2 = _mm_set1_epi16(2);
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i temp0, temp1, temp2, temp3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i sign_reg0, sign_reg2;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i threshold_r0_r1, threshold_r2_r3;
+ __m128i threshold_mask_r0_r1, threshold_mask_r2_r3;
+
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+
+ ASSERT(0 == u1_use_upsampled_res);
+ ASSERT(4 == i4_out_stride);
+ UNUSED(u1_use_upsampled_res);
+ UNUSED(i4_out_stride);
+ UNUSED(ps_upsampled_res);
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the treshold matrix 0th,1st row */
+ threshold_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the threshold matrix 2nd,3rd row */
+ threshold_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix + 8));
+
+ /* a00 a01 a02 a03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ src_r0 = _mm_loadl_epi64((__m128i *) (&pu1_src[0]));
+
+ /* a10 a11 a12 a13 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r1 = _mm_loadl_epi64((__m128i *) (&pu1_src[i4_src_stride]));
+
+ /* a20 a21 a22 a23 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r2 = _mm_loadl_epi64((__m128i *) (&pu1_src[2 * i4_src_stride]));
+
+ /* a30 a31 a32 a33 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r3 = _mm_loadl_epi64((__m128i *) (&pu1_src[3 * i4_src_stride]));
+
+ src_r0 = _mm_cvtepu8_epi16(src_r0);
+ src_r1 = _mm_cvtepu8_epi16(src_r1);
+ src_r2 = _mm_cvtepu8_epi16(src_r2);
+ src_r3 = _mm_cvtepu8_epi16(src_r3);
+
+ /* p00 p01 p02 p03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ /* p10 p11 p12 p13 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ /* p20 p21 p22 p23 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ /* p30 p31 p32 p33 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ src_r0 = _mm_sub_epi16(src_r0, pred_r0);
+ src_r1 = _mm_sub_epi16(src_r1, pred_r1);
+ src_r2 = _mm_sub_epi16(src_r2, pred_r2);
+ src_r3 = _mm_sub_epi16(src_r3, pred_r3);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 a1 b1 a2 b2 a3 b3 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* c0 d0 c1 d1 c2 d2 c3 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 b0 c0 d0 a1 b1 c1 d1 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* a2 b2 c2 d2 a3 b3 c3 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 b0 c0 d0 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* a1 b1 c1 d1 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* a2 b2 c2 d2 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* a3 b3 c3 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 c0 c1 d0 d1 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* a2 a3 b2 b3 c2 c3 d2 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 a1 a2 a3 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* b0 b1 b2 b3 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* c0 c1 c2 c3 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* d0 d1 d2 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ /* get the first 16 bits from the register */
+ tmp_dc = _mm_extract_epi16(src_r0, 0);
+ *pi2_dc_out = tmp_dc;
+
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ src_r0 = _mm_unpacklo_epi64(src_r0, src_r1);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ src_r2 = _mm_unpacklo_epi64(src_r2, src_r3);
+ sign_reg0 = _mm_cmpgt_epi16(zero_8x16b, src_r0);
+ sign_reg2 = _mm_cmpgt_epi16(zero_8x16b, src_r2);
+
+ sign_reg0 = _mm_mullo_epi16(temp_2, sign_reg0);
+ sign_reg2 = _mm_mullo_epi16(temp_2, sign_reg2);
+
+ sign_reg0 = _mm_add_epi16(temp_1, sign_reg0);
+ sign_reg2 = _mm_add_epi16(temp_1, sign_reg2);
+
+ src_r0 = _mm_abs_epi16(src_r0);
+ src_r2 = _mm_abs_epi16(src_r2);
+
+ threshold_mask_r0_r1 = _mm_cmpgt_epi16(threshold_r0_r1, src_r0);
+ threshold_mask_r2_r3 = _mm_cmpgt_epi16(threshold_r2_r3, src_r2);
+
+ src_r1 = _mm_srli_si128(src_r0, 8);
+ src_r0 = _mm_cvtepu16_epi32(src_r0);
+ src_r1 = _mm_cvtepu16_epi32(src_r1);
+ src_r3 = _mm_srli_si128(src_r2, 8);
+ src_r2 = _mm_cvtepu16_epi32(src_r2);
+ src_r3 = _mm_cvtepu16_epi32(src_r3);
+
+ temp0 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ scalemat_r0_r1 = _mm_srli_si128(scalemat_r0_r1, 8);
+ temp2 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+ scalemat_r2_r3 = _mm_srli_si128(scalemat_r2_r3, 8);
+ temp1 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ temp3 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+
+ temp0 = _mm_mullo_epi32(temp0, src_r0);
+ temp1 = _mm_mullo_epi32(temp1, src_r1);
+ temp2 = _mm_mullo_epi32(temp2, src_r2);
+ temp3 = _mm_mullo_epi32(temp3, src_r3);
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact);
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+ temp2 = _mm_add_epi32(temp2, rnd_fact);
+ temp3 = _mm_add_epi32(temp3, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0, u4_qbits);
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+ temp2 = _mm_srli_epi32(temp2, u4_qbits);
+ temp3 = _mm_srli_epi32(temp3, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1);
+ temp2 = _mm_packs_epi32(temp2, temp3);
+
+ temp0 = _mm_sign_epi16(temp0, sign_reg0);
+ temp2 = _mm_sign_epi16(temp2, sign_reg2);
+
+ temp0 = _mm_andnot_si128(threshold_mask_r0_r1, temp0);
+ temp2 = _mm_andnot_si128(threshold_mask_r2_r3, temp2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[8]), temp2);
+
+ cmp0 = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ cmp1 = _mm_cmpeq_epi16(temp2, zero_8x16b);
+
+ mask0 = _mm_movemask_epi8(cmp0);
+ mask1 = _mm_movemask_epi8(cmp1);
+ u4_zero_coeff = 0;
+
+ if(mask0)
+ {
+ if(mask0 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp0);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ u4_nonzero_coeff = 16 - u4_zero_coeff;
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+void isvc_resi_trans_quant_4x4_with_res_pred_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res, resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 tmp_dc, u4_zero_coeff, u4_nonzero_coeff = 0;
+ WORD32 mask0, mask1;
+ __m128i sum0, sum1, sum2, cmp0, cmp1;
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+ __m128i temp_2 = _mm_set1_epi16(2);
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i temp0, temp1, temp2, temp3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i sign_reg0, sign_reg2;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i upsampled_res0, upsampled_res1, upsampled_res2, upsampled_res3;
+ __m128i threshold_r0_r1, threshold_r2_r3;
+ __m128i threshold_mask_r0_r1, threshold_mask_r2_r3;
+
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? (WORD16 *) ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+
+ ASSERT(1 == u1_use_upsampled_res);
+ ASSERT(4 == i4_out_stride);
+ UNUSED(u1_use_upsampled_res);
+ UNUSED(i4_out_stride);
+ UNUSED(ps_upsampled_res);
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the treshold matrix 0th,1st row */
+ threshold_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the threshold matrix 2nd,3rd row */
+ threshold_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix + 8));
+
+ /* a00 a01 a02 a03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ src_r0 = _mm_loadl_epi64((__m128i *) (&pu1_src[0]));
+
+ /* a10 a11 a12 a13 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r1 = _mm_loadl_epi64((__m128i *) (&pu1_src[i4_src_stride]));
+
+ /* a20 a21 a22 a23 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r2 = _mm_loadl_epi64((__m128i *) (&pu1_src[2 * i4_src_stride]));
+
+ /* a30 a31 a32 a33 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r3 = _mm_loadl_epi64((__m128i *) (&pu1_src[3 * i4_src_stride]));
+
+ src_r0 = _mm_cvtepu8_epi16(src_r0);
+ src_r1 = _mm_cvtepu8_epi16(src_r1);
+ src_r2 = _mm_cvtepu8_epi16(src_r2);
+ src_r3 = _mm_cvtepu8_epi16(src_r3);
+
+ /* p00 p01 p02 p03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+
+ /* p10 p11 p12 p13 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+
+ /* p20 p21 p22 p23 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+
+ /* p30 p31 p32 p33 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+
+ src_r0 = _mm_sub_epi16(src_r0, pred_r0);
+ src_r1 = _mm_sub_epi16(src_r1, pred_r1);
+ src_r2 = _mm_sub_epi16(src_r2, pred_r2);
+ src_r3 = _mm_sub_epi16(src_r3, pred_r3);
+
+ /* load upsampled residual values and subtract from
+ the previous residue */
+ upsampled_res0 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[0]));
+
+ upsampled_res1 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[i4_upsampled_res_stride]));
+
+ upsampled_res2 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[2 * i4_upsampled_res_stride]));
+
+ upsampled_res3 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[3 * i4_upsampled_res_stride]));
+
+ src_r0 = _mm_sub_epi16(src_r0, upsampled_res0);
+ src_r1 = _mm_sub_epi16(src_r1, upsampled_res1);
+ src_r2 = _mm_sub_epi16(src_r2, upsampled_res2);
+ src_r3 = _mm_sub_epi16(src_r3, upsampled_res3);
+
+ src_r1 = _mm_unpacklo_epi16(src_r0, src_r1);
+ src_r3 = _mm_unpacklo_epi16(src_r2, src_r3);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ src_r1 = _mm_max_epi16(src_r1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(src_r1, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ src_r3 = _mm_max_epi16(src_r3, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp2 = _mm_min_epi16(src_r3, pos_255_8x16b);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 c0 d0 a1 b1 c1 d1 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* a2 b2 c2 d2 a3 b3 c3 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 b0 c0 d0 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* a1 b1 c1 d1 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* a2 b2 c2 d2 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* a3 b3 c3 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 c0 c1 d0 d1 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* a2 a3 b2 b3 c2 c3 d2 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 a1 a2 a3 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* b0 b1 b2 b3 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* c0 c1 c2 c3 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* d0 d1 d2 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ /* get the first 16 bits from the register */
+ tmp_dc = _mm_extract_epi16(src_r0, 0);
+ *pi2_dc_out = tmp_dc;
+
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ src_r0 = _mm_unpacklo_epi64(src_r0, src_r1);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ src_r2 = _mm_unpacklo_epi64(src_r2, src_r3);
+ sign_reg0 = _mm_cmpgt_epi16(zero_8x16b, src_r0);
+ sign_reg2 = _mm_cmpgt_epi16(zero_8x16b, src_r2);
+
+ sign_reg0 = _mm_mullo_epi16(temp_2, sign_reg0);
+ sign_reg2 = _mm_mullo_epi16(temp_2, sign_reg2);
+
+ sign_reg0 = _mm_add_epi16(temp_1, sign_reg0);
+ sign_reg2 = _mm_add_epi16(temp_1, sign_reg2);
+
+ src_r0 = _mm_abs_epi16(src_r0);
+ src_r2 = _mm_abs_epi16(src_r2);
+
+ threshold_mask_r0_r1 = _mm_cmpgt_epi16(threshold_r0_r1, src_r0);
+ threshold_mask_r2_r3 = _mm_cmpgt_epi16(threshold_r2_r3, src_r2);
+
+ src_r1 = _mm_srli_si128(src_r0, 8);
+ src_r0 = _mm_cvtepu16_epi32(src_r0);
+ src_r1 = _mm_cvtepu16_epi32(src_r1);
+ src_r3 = _mm_srli_si128(src_r2, 8);
+ src_r2 = _mm_cvtepu16_epi32(src_r2);
+ src_r3 = _mm_cvtepu16_epi32(src_r3);
+
+ temp0 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ scalemat_r0_r1 = _mm_srli_si128(scalemat_r0_r1, 8);
+ temp2 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+ scalemat_r2_r3 = _mm_srli_si128(scalemat_r2_r3, 8);
+ temp1 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ temp3 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+
+ temp0 = _mm_mullo_epi32(temp0, src_r0);
+ temp1 = _mm_mullo_epi32(temp1, src_r1);
+ temp2 = _mm_mullo_epi32(temp2, src_r2);
+ temp3 = _mm_mullo_epi32(temp3, src_r3);
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact);
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+ temp2 = _mm_add_epi32(temp2, rnd_fact);
+ temp3 = _mm_add_epi32(temp3, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0, u4_qbits);
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+ temp2 = _mm_srli_epi32(temp2, u4_qbits);
+ temp3 = _mm_srli_epi32(temp3, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1);
+ temp2 = _mm_packs_epi32(temp2, temp3);
+
+ temp0 = _mm_sign_epi16(temp0, sign_reg0);
+ temp2 = _mm_sign_epi16(temp2, sign_reg2);
+
+ temp0 = _mm_andnot_si128(threshold_mask_r0_r1, temp0);
+ temp2 = _mm_andnot_si128(threshold_mask_r2_r3, temp2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[8]), temp2);
+
+ cmp0 = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ cmp1 = _mm_cmpeq_epi16(temp2, zero_8x16b);
+
+ mask0 = _mm_movemask_epi8(cmp0);
+ mask1 = _mm_movemask_epi8(cmp1);
+ u4_zero_coeff = 0;
+ if(mask0)
+ {
+ if(mask0 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp0);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ u4_nonzero_coeff = 16 - u4_zero_coeff;
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+/**
+
+ * *******************************************************************************
+
+ * *
+ * @brief
+ * This function performs forward transform and quantization on
+ * a 4*4 chroma
+ *block
+ *
+ * @par Description:
+ * The function accepts source
+ * buffer and estimation buffer. From these, it
+ * computes the residue. This
+ * is residue is then transformed and quantized.
+ * The transform and
+ * quantization are in placed computed. They use the residue
+ * buffer for
+ * this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+ *
+ *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ * @param[in]
+ * pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in] i4_src_stride
+ *
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ * Prediction stride
+ *
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ *
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ *
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+
+ * * Pointer to Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ *
+ * Quantization Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero
+ * coefficients in the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ *
+ * None
+ *
+
+ * *******************************************************************************
+
+ */
+void isvc_resi_trans_quant_chroma_4x4_sse42(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out,
+ UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 tmp_dc, u4_zero_coeff, u4_nonzero_coeff = 0;
+ WORD32 mask0, mask1;
+ __m128i cmp0, cmp1, sum0, sum1, sum2;
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+ __m128i temp_2 = _mm_set1_epi16(2);
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i temp0, temp1, temp2, temp3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i sign_reg0, sign_reg2;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i threshold_r0_r1, threshold_r2_r3;
+ __m128i threshold_mask_r0_r1, threshold_mask_r2_r3;
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+
+ ASSERT(0 == u1_use_upsampled_res);
+ ASSERT(4 == i4_out_stride);
+ UNUSED(u1_use_upsampled_res);
+ UNUSED(i4_out_stride);
+ UNUSED(ps_upsampled_res);
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the treshold matrix 0th,1st row */
+ threshold_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the threshold matrix 2nd,3rd row */
+ threshold_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix + 8));
+
+ /* a00 a01 a02 a03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ src_r0 = _mm_loadl_epi64((__m128i *) (&pu1_src[0]));
+ /* a10 a11 a12 a13 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r1 = _mm_loadl_epi64((__m128i *) (&pu1_src[i4_src_stride]));
+ /* a20 a21 a22 a23 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r2 = _mm_loadl_epi64((__m128i *) (&pu1_src[2 * i4_src_stride]));
+ /* a30 a31 a32 a33 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r3 = _mm_loadl_epi64((__m128i *) (&pu1_src[3 * i4_src_stride]));
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask);
+ src_r1 = _mm_and_si128(src_r1, chroma_mask);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask);
+
+ /* p00 p01 p02 p03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ /* p10 p11 p12 p13 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ /* p20 p21 p22 p23 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ /* p30 p31 p32 p33 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ src_r0 = _mm_sub_epi16(src_r0, pred_r0);
+ src_r1 = _mm_sub_epi16(src_r1, pred_r1);
+ src_r2 = _mm_sub_epi16(src_r2, pred_r2);
+ src_r3 = _mm_sub_epi16(src_r3, pred_r3);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ /* a0 b0 a1 b1 a2 b2 a3 b3 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* c0 d0 c1 d1 c2 d2 c3 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 b0 c0 d0 a1 b1 c1 d1 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* a2 b2 c2 d2 a3 b3 c3 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 b0 c0 d0 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* a1 b1 c1 d1 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* a2 b2 c2 d2 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* a3 b3 c3 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 c0 c1 d0 d1 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* a2 a3 b2 b3 c2 c3 d2 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 a1 a2 a3 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* b0 b1 b2 b3 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* c0 c1 c2 c3 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* d0 d1 d2 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ /* get the first 16 bits from the register */
+ tmp_dc = _mm_extract_epi16(src_r0, 0);
+ *pi2_dc_out = tmp_dc;
+
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ src_r0 = _mm_unpacklo_epi64(src_r0, src_r1);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ src_r2 = _mm_unpacklo_epi64(src_r2, src_r3);
+ sign_reg0 = _mm_cmpgt_epi16(zero_8x16b, src_r0);
+ sign_reg2 = _mm_cmpgt_epi16(zero_8x16b, src_r2);
+
+ sign_reg0 = _mm_mullo_epi16(temp_2, sign_reg0);
+ sign_reg2 = _mm_mullo_epi16(temp_2, sign_reg2);
+
+ sign_reg0 = _mm_add_epi16(temp_1, sign_reg0);
+ sign_reg2 = _mm_add_epi16(temp_1, sign_reg2);
+
+ src_r0 = _mm_abs_epi16(src_r0);
+ src_r2 = _mm_abs_epi16(src_r2);
+
+ threshold_mask_r0_r1 = _mm_cmpgt_epi16(threshold_r0_r1, src_r0);
+ threshold_mask_r2_r3 = _mm_cmpgt_epi16(threshold_r2_r3, src_r2);
+
+ src_r1 = _mm_srli_si128(src_r0, 8);
+ src_r0 = _mm_cvtepu16_epi32(src_r0);
+ src_r1 = _mm_cvtepu16_epi32(src_r1);
+ src_r3 = _mm_srli_si128(src_r2, 8);
+ src_r2 = _mm_cvtepu16_epi32(src_r2);
+ src_r3 = _mm_cvtepu16_epi32(src_r3);
+
+ temp0 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ scalemat_r0_r1 = _mm_srli_si128(scalemat_r0_r1, 8);
+ temp2 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+ scalemat_r2_r3 = _mm_srli_si128(scalemat_r2_r3, 8);
+ temp1 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ temp3 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+
+ temp0 = _mm_mullo_epi32(temp0, src_r0);
+ temp1 = _mm_mullo_epi32(temp1, src_r1);
+ temp2 = _mm_mullo_epi32(temp2, src_r2);
+ temp3 = _mm_mullo_epi32(temp3, src_r3);
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact);
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+ temp2 = _mm_add_epi32(temp2, rnd_fact);
+ temp3 = _mm_add_epi32(temp3, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0, u4_qbits);
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+ temp2 = _mm_srli_epi32(temp2, u4_qbits);
+ temp3 = _mm_srli_epi32(temp3, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1);
+ temp2 = _mm_packs_epi32(temp2, temp3);
+
+ temp0 = _mm_sign_epi16(temp0, sign_reg0);
+ temp2 = _mm_sign_epi16(temp2, sign_reg2);
+
+ temp0 = _mm_andnot_si128(threshold_mask_r0_r1, temp0);
+ temp2 = _mm_andnot_si128(threshold_mask_r2_r3, temp2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[8]), temp2);
+
+ cmp0 = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ cmp1 = _mm_cmpeq_epi16(temp2, zero_8x16b);
+
+ mask0 = _mm_movemask_epi8(cmp0);
+ mask1 = _mm_movemask_epi8(cmp1);
+ u4_zero_coeff = 0;
+ if(mask0)
+ {
+ if(mask0 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp0);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ u4_nonzero_coeff = 16 - u4_zero_coeff;
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+void isvc_resi_trans_quant_chroma_4x4_with_res_pred_sse42(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_out,
+ buffer_container_t *ps_upsampled_res, resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz, WORD16 *pi2_dc_out, UWORD8 u1_use_upsampled_res)
+{
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_out = (WORD16 *) ps_out->pv_data;
+ WORD16 *pi2_upsampled_res = ps_upsampled_res ? (WORD16 *) ps_upsampled_res->pv_data : NULL;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_out_stride = ps_out->i4_data_stride;
+ WORD32 i4_upsampled_res_stride = ps_upsampled_res ? ps_upsampled_res->i4_data_stride : 0;
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 tmp_dc, u4_zero_coeff, u4_nonzero_coeff = 0;
+ WORD32 mask0, mask1;
+ __m128i cmp0, cmp1, sum0, sum1, sum2;
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+ __m128i temp_2 = _mm_set1_epi16(2);
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i temp0, temp1, temp2, temp3;
+ /* all bits reset to zero */
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i neg_255_8x16b = _mm_set1_epi16(-((WORD16) UINT8_MAX));
+ __m128i pos_255_8x16b = _mm_set1_epi16(((WORD16) UINT8_MAX));
+ __m128i sign_reg0, sign_reg2;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i upsampled_res0, upsampled_res1, upsampled_res2, upsampled_res3;
+ __m128i threshold_r0_r1, threshold_r2_r3;
+ __m128i threshold_mask_r0_r1, threshold_mask_r2_r3;
+ __m128i chroma_mask = _mm_set1_epi16(0xFF);
+
+ ASSERT(1 == u1_use_upsampled_res);
+ ASSERT(4 == i4_out_stride);
+ UNUSED(u1_use_upsampled_res);
+ UNUSED(i4_out_stride);
+ UNUSED(ps_upsampled_res);
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the scaling matrix 0th,1st row */
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the scaling matrix 2nd,3rd row */
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_scale_matrix + 8));
+
+ /* b00 b01 b02 b03 b10 b11 b12 b13
+ -- the treshold matrix 0th,1st row */
+ threshold_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix));
+
+ /* b20 b21 b22 b23 b30 b31 b32 b33
+ -- the threshold matrix 2nd,3rd row */
+ threshold_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_threshold_matrix + 8));
+
+ /* a00 a01 a02 a03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ src_r0 = _mm_loadl_epi64((__m128i *) (&pu1_src[0]));
+ /* a10 a11 a12 a13 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r1 = _mm_loadl_epi64((__m128i *) (&pu1_src[i4_src_stride]));
+ /* a20 a21 a22 a23 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r2 = _mm_loadl_epi64((__m128i *) (&pu1_src[2 * i4_src_stride]));
+ /* a30 a31 a32 a33 0 0 0 0 0 0 0
+ 0 -- all 8 bits */
+ src_r3 = _mm_loadl_epi64((__m128i *) (&pu1_src[3 * i4_src_stride]));
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask);
+ src_r1 = _mm_and_si128(src_r1, chroma_mask);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask);
+
+ /* p00 p01 p02 p03 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ /* p10 p11 p12 p13 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[i4_pred_stride]));
+ /* p20 p21 p22 p23 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * i4_pred_stride]));
+ /* p30 p31 p32 p33 0 0 0 0 0
+ 0 0 0 -- all 8 bits */
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * i4_pred_stride]));
+
+ pred_r0 = _mm_and_si128(pred_r0, chroma_mask);
+ pred_r1 = _mm_and_si128(pred_r1, chroma_mask);
+ pred_r2 = _mm_and_si128(pred_r2, chroma_mask);
+ pred_r3 = _mm_and_si128(pred_r3, chroma_mask);
+
+ src_r0 = _mm_sub_epi16(src_r0, pred_r0);
+ src_r1 = _mm_sub_epi16(src_r1, pred_r1);
+ src_r2 = _mm_sub_epi16(src_r2, pred_r2);
+ src_r3 = _mm_sub_epi16(src_r3, pred_r3);
+
+ /* load upsampled residual values and subtract from
+ the previous residue */
+ upsampled_res0 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[0]));
+
+ upsampled_res1 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[i4_upsampled_res_stride]));
+
+ upsampled_res2 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[2 * i4_upsampled_res_stride]));
+
+ upsampled_res3 = _mm_loadu_si128((__m128i *) (&pi2_upsampled_res[3 * i4_upsampled_res_stride]));
+
+ src_r0 = _mm_sub_epi16(src_r0, upsampled_res0);
+ src_r1 = _mm_sub_epi16(src_r1, upsampled_res1);
+ src_r2 = _mm_sub_epi16(src_r2, upsampled_res2);
+ src_r3 = _mm_sub_epi16(src_r3, upsampled_res3);
+
+ src_r1 = _mm_unpacklo_epi16(src_r0, src_r1);
+ src_r3 = _mm_unpacklo_epi16(src_r2, src_r3);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ src_r1 = _mm_max_epi16(src_r1, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp0 = _mm_min_epi16(src_r1, pos_255_8x16b);
+
+ /* Saturate all values < -255 to -255 and retain the rest as it is */
+ src_r3 = _mm_max_epi16(src_r3, neg_255_8x16b);
+ /* Saturate all values > 255 to 255 and retain the rest as it is */
+ temp2 = _mm_min_epi16(src_r3, pos_255_8x16b);
+
+ /* Perform Forward transform */
+ /*-------------------------------------------------------------*/
+ /* DCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* a2 b2 c2 d2 a3 b3 c3 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 b0 c0 d0 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* a1 b1 c1 d1 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* a2 b2 c2 d2 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* a3 b3 c3 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ /* a0 a1 b0 b1 c0 c1 d0 d1 */
+ temp0 = _mm_unpacklo_epi16(src_r0, src_r1);
+ /* a2 a3 b2 b3 c2 c3 d2 d3 */
+ temp2 = _mm_unpacklo_epi16(src_r2, src_r3);
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ temp1 = _mm_unpacklo_epi32(temp0, temp2);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ temp3 = _mm_unpackhi_epi32(temp0, temp2);
+
+ /* a0 a1 a2 a3 */
+ src_r0 = _mm_unpacklo_epi64(temp1, zero_8x16b);
+ /* b0 b1 b2 b3 */
+ src_r1 = _mm_unpackhi_epi64(temp1, zero_8x16b);
+ /* c0 c1 c2 c3 */
+ src_r2 = _mm_unpacklo_epi64(temp3, zero_8x16b);
+ /* d0 d1 d2 d3 */
+ src_r3 = _mm_unpackhi_epi64(temp3, zero_8x16b);
+
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ temp0 = _mm_add_epi16(src_r0, src_r3);
+ /* x1 = z1 + z2 */
+ temp1 = _mm_add_epi16(src_r1, src_r2);
+ /* x2 = z1 - z2 */
+ temp2 = _mm_sub_epi16(src_r1, src_r2);
+ /* x3 = z0 - z3 */
+ temp3 = _mm_sub_epi16(src_r0, src_r3);
+
+ /* z0 = x0 + x1 */
+ src_r0 = _mm_add_epi16(temp0, temp1);
+ /* z1 = (x3 << 1) + x2 */
+ src_r1 = _mm_slli_epi16(temp3, 1);
+ src_r1 = _mm_add_epi16(src_r1, temp2);
+ /* z2 = x0 - x1 */
+ src_r2 = _mm_sub_epi16(temp0, temp1);
+ /* z3 = x3 - (x2 << 1) */
+ src_r3 = _mm_slli_epi16(temp2, 1);
+ src_r3 = _mm_sub_epi16(temp3, src_r3);
+
+ /* get the first 16 bits from the register */
+ tmp_dc = _mm_extract_epi16(src_r0, 0);
+ *pi2_dc_out = tmp_dc;
+
+ /* a0 a1 a2 a3 b0 b1 b2 b3 */
+ src_r0 = _mm_unpacklo_epi64(src_r0, src_r1);
+ /* c0 c1 c2 c3 d0 d1 d2 d3 */
+ src_r2 = _mm_unpacklo_epi64(src_r2, src_r3);
+ sign_reg0 = _mm_cmpgt_epi16(zero_8x16b, src_r0);
+ sign_reg2 = _mm_cmpgt_epi16(zero_8x16b, src_r2);
+
+ sign_reg0 = _mm_mullo_epi16(temp_2, sign_reg0);
+ sign_reg2 = _mm_mullo_epi16(temp_2, sign_reg2);
+
+ sign_reg0 = _mm_add_epi16(temp_1, sign_reg0);
+ sign_reg2 = _mm_add_epi16(temp_1, sign_reg2);
+
+ src_r0 = _mm_abs_epi16(src_r0);
+ src_r2 = _mm_abs_epi16(src_r2);
+
+ threshold_mask_r0_r1 = _mm_cmpgt_epi16(threshold_r0_r1, src_r0);
+ threshold_mask_r2_r3 = _mm_cmpgt_epi16(threshold_r2_r3, src_r2);
+
+ src_r1 = _mm_srli_si128(src_r0, 8);
+ src_r0 = _mm_cvtepu16_epi32(src_r0);
+ src_r1 = _mm_cvtepu16_epi32(src_r1);
+ src_r3 = _mm_srli_si128(src_r2, 8);
+ src_r2 = _mm_cvtepu16_epi32(src_r2);
+ src_r3 = _mm_cvtepu16_epi32(src_r3);
+
+ temp0 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ scalemat_r0_r1 = _mm_srli_si128(scalemat_r0_r1, 8);
+ temp2 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+ scalemat_r2_r3 = _mm_srli_si128(scalemat_r2_r3, 8);
+ temp1 = _mm_cvtepu16_epi32(scalemat_r0_r1);
+ temp3 = _mm_cvtepu16_epi32(scalemat_r2_r3);
+
+ temp0 = _mm_mullo_epi32(temp0, src_r0);
+ temp1 = _mm_mullo_epi32(temp1, src_r1);
+ temp2 = _mm_mullo_epi32(temp2, src_r2);
+ temp3 = _mm_mullo_epi32(temp3, src_r3);
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact);
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+ temp2 = _mm_add_epi32(temp2, rnd_fact);
+ temp3 = _mm_add_epi32(temp3, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0, u4_qbits);
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+ temp2 = _mm_srli_epi32(temp2, u4_qbits);
+ temp3 = _mm_srli_epi32(temp3, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1);
+ temp2 = _mm_packs_epi32(temp2, temp3);
+
+ temp0 = _mm_sign_epi16(temp0, sign_reg0);
+ temp2 = _mm_sign_epi16(temp2, sign_reg2);
+
+ temp0 = _mm_andnot_si128(threshold_mask_r0_r1, temp0);
+ temp2 = _mm_andnot_si128(threshold_mask_r2_r3, temp2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[8]), temp2);
+
+ cmp0 = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ cmp1 = _mm_cmpeq_epi16(temp2, zero_8x16b);
+
+ mask0 = _mm_movemask_epi8(cmp0);
+ mask1 = _mm_movemask_epi8(cmp1);
+ u4_zero_coeff = 0;
+ if(mask0)
+ {
+ if(mask0 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp0);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ u4_nonzero_coeff = 16 - u4_zero_coeff;
+ *pu1_nnz = u4_nonzero_coeff;
+}
+
+/**
+
+ * *******************************************************************************
+
+ * *
+ * @brief
+ * This function performs forward hadamard transform and
+ * quantization on a 4*4
+ *block
+ *
+ * @par Description:
+ * The function
+ * accepts source buffer and estimation buffer. From these, it
+ * computes the
+ * residue. This is residue is then transformed and quantized.
+ * The
+ * transform and quantization are in placed computed. They use the residue
+ *
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ * Pointer to source sub-block
+
+ * *
+ * @param[in] pu1_pred
+ * Pointer to prediction sub-block
+ *
+ *
+ * @param[in] pi2_out
+ * Pointer to residual sub-block
+ *
+ * @param[in]
+ * i4_src_stride
+ * Source stride
+ *
+ * @param[in] i4_pred_stride
+ *
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ * Destination stride
+ *
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 + floor(QP/6)
+ *
+ * @param[in]
+ * pu2_threshold_matrix
+ * Pointer to Forward Quant Threshold Matrix
+ *
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to Forward Quant Scale Matrix
+ *
+ *
+ * @param[in] u4_round_factor
+ * Quantization Round factor
+ *
+ * @param[out]
+ * pu1_nnz
+ * Total non-zero coefficients in the current sub-block
+ *
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ */
+
+void isvc_hadamard_quant_4x4_sse42(WORD16 *pi2_src, WORD16 *pi2_dst,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz)
+{
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 u4_zero_coeff, u4_nonzero_coeff = 0;
+ __m128i cmp0, cmp1, sum0, sum1, sum2;
+ WORD32 mask0, mask1;
+ __m128i src_r0_r1, src_r2_r3, sign_reg;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i temp0, temp1, temp2, temp3;
+ __m128i sign_reg0, sign_reg1, sign_reg2, sign_reg3;
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+ __m128i scale_val = _mm_set1_epi32(pu2_scale_matrix[0]);
+
+ UNUSED(pu2_threshold_matrix);
+
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src)); // a00 a01 a02 a03 a10 a11 a12 a13 -- the
+ // source matrix 0th,1st row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8)); // a20 a21 a22 a23 a30 a31 a32 a33 --
+ // the source matrix 2nd,3rd row
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, src_r0_r1);
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, sign_reg); // a0 a1 a2 a3
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, sign_reg); // b0 b1 b2 b3
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, src_r2_r3);
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, sign_reg); // c0 c1 c2 c3
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, sign_reg); // d0 d1 d2 d3
+
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* Forward DC transform [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp0 = _mm_unpacklo_epi32(src_r0, src_r1); // a0 b0 a1 b1
+ temp2 = _mm_unpacklo_epi32(src_r2, src_r3); // c0 d0 c1 d1
+ temp1 = _mm_unpackhi_epi32(src_r0, src_r1); // a2 b2 a3 b3
+ temp3 = _mm_unpackhi_epi32(src_r2, src_r3); // c2 d2 c3 d3
+ src_r0 = _mm_unpacklo_epi64(temp0, temp2); // a0 b0 c0 d0
+ src_r1 = _mm_unpackhi_epi64(temp0, temp2); // a1 b1 c1 d1
+ src_r2 = _mm_unpacklo_epi64(temp1, temp3); // a2 b2 c2 d2
+ src_r3 = _mm_unpackhi_epi64(temp1, temp3); // a3 b3 c3 d3
+
+ temp0 = _mm_add_epi32(src_r0, src_r3);
+ temp1 = _mm_add_epi32(src_r1, src_r2);
+ temp2 = _mm_sub_epi32(src_r1, src_r2);
+ temp3 = _mm_sub_epi32(src_r0, src_r3);
+
+ src_r0 = _mm_add_epi32(temp0, temp1);
+ src_r1 = _mm_add_epi32(temp2, temp3);
+ src_r2 = _mm_sub_epi32(temp0, temp1);
+ src_r3 = _mm_sub_epi32(temp3, temp2);
+
+ /*-------------------------------------------------------------*/
+ /* Forward DC transform [ Vertical transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp0 = _mm_unpacklo_epi32(src_r0, src_r1); // a0 a1 b0 b1
+ temp2 = _mm_unpacklo_epi32(src_r2, src_r3); // a2 a3 b2 b3
+ temp1 = _mm_unpackhi_epi32(src_r0, src_r1); // c0 c1 d0 d1
+ temp3 = _mm_unpackhi_epi32(src_r2, src_r3); // c2 c3 d2 d3
+ src_r0 = _mm_unpacklo_epi64(temp0, temp2); // a0 a1 a2 a3
+ src_r1 = _mm_unpackhi_epi64(temp0, temp2); // b0 b1 b2 b3
+ src_r2 = _mm_unpacklo_epi64(temp1, temp3); // c0 c1 c2 c3
+ src_r3 = _mm_unpackhi_epi64(temp1, temp3); // d0 d1 d2 d3
+
+ temp0 = _mm_add_epi32(src_r0, src_r3);
+ temp1 = _mm_add_epi32(src_r1, src_r2);
+ temp2 = _mm_sub_epi32(src_r1, src_r2);
+ temp3 = _mm_sub_epi32(src_r0, src_r3);
+
+ src_r0 = _mm_add_epi32(temp0, temp1);
+ src_r1 = _mm_add_epi32(temp2, temp3);
+ src_r2 = _mm_sub_epi32(temp0, temp1);
+ src_r3 = _mm_sub_epi32(temp3, temp2);
+
+ src_r0 = _mm_srai_epi32(src_r0, 1);
+ src_r1 = _mm_srai_epi32(src_r1, 1);
+ src_r2 = _mm_srai_epi32(src_r2, 1);
+ src_r3 = _mm_srai_epi32(src_r3, 1);
+
+ // Quantization
+ sign_reg0 =
+ _mm_cmpgt_epi32(zero_8x16b, src_r0); // Find sign of each value for later restoration
+ sign_reg1 = _mm_cmpgt_epi32(zero_8x16b, src_r1);
+ sign_reg2 = _mm_cmpgt_epi32(zero_8x16b, src_r2);
+ sign_reg3 = _mm_cmpgt_epi32(zero_8x16b, src_r3);
+
+ sign_reg0 = _mm_packs_epi32(sign_reg0,
+ sign_reg1); // Sign = -1 or 0 depending on <0 or >0 respectively
+ sign_reg2 = _mm_packs_epi32(sign_reg2, sign_reg3);
+
+ sign_reg0 = _mm_slli_epi16(sign_reg0, 1); // Sign = -2 or 0 depending on <0 or >0 respectively
+ sign_reg2 = _mm_slli_epi16(sign_reg2, 1);
+
+ sign_reg0 =
+ _mm_add_epi16(temp_1, sign_reg0); // Sign = -1 or 1 depending on <0 or >0 respectively
+ sign_reg2 = _mm_add_epi16(temp_1, sign_reg2);
+
+ src_r0 = _mm_abs_epi32(src_r0); // Absolute values
+ src_r1 = _mm_abs_epi32(src_r1);
+ src_r2 = _mm_abs_epi32(src_r2);
+ src_r3 = _mm_abs_epi32(src_r3);
+
+ temp0 = _mm_mullo_epi32(scale_val, src_r0); // multiply by
+ // pu2_scale_matrix[0]
+ temp1 = _mm_mullo_epi32(scale_val, src_r1);
+ temp2 = _mm_mullo_epi32(scale_val, src_r2);
+ temp3 = _mm_mullo_epi32(scale_val, src_r3);
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact); // Add round factor
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+ temp2 = _mm_add_epi32(temp2, rnd_fact);
+ temp3 = _mm_add_epi32(temp3, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0,
+ u4_qbits); // RIght shift by qbits, unsigned variable,
+ // so shift right immediate works
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+ temp2 = _mm_srli_epi32(temp2, u4_qbits);
+ temp3 = _mm_srli_epi32(temp3, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1); // Final values are 16-bits only.
+ temp2 = _mm_packs_epi32(temp2, temp3);
+
+ temp0 = _mm_sign_epi16(temp0, sign_reg0); // Sign restoration
+ temp2 = _mm_sign_epi16(temp2, sign_reg2);
+
+ _mm_storeu_si128((__m128i *) (&pi2_dst[0]), temp0);
+ _mm_storeu_si128((__m128i *) (&pi2_dst[8]), temp2);
+
+ cmp0 = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ cmp1 = _mm_cmpeq_epi16(temp2, zero_8x16b);
+
+ mask0 = _mm_movemask_epi8(cmp0);
+ mask1 = _mm_movemask_epi8(cmp1);
+ u4_zero_coeff = 0;
+ if(mask0)
+ {
+ if(mask0 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp0);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xffff)
+ u4_zero_coeff += 8;
+ else
+ {
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ sum2 = _mm_hadd_epi16(sum1, zero_8x16b);
+ u4_zero_coeff += _mm_cvtsi128_si32(sum2);
+ }
+ }
+
+ /* Return total nonzero coefficients in the current sub block */
+ u4_nonzero_coeff = 16 - u4_zero_coeff;
+ pu1_nnz[0] = u4_nonzero_coeff;
+}
+
+/**
+
+ * *******************************************************************************
+
+ * *
+ * @brief
+ * This function performs forward hadamard transform and
+ * quantization on a 2*2
+ *block for both U and V planes
+ *
+ * @par
+ * Description:
+ * The function accepts source buffer and estimation buffer.
+ * From these, it
+ * computes the residue. This is residue is then transformed
+ * and quantized.
+ * The transform and quantization are in placed computed.
+ * They use the residue
+ * buffer for this.
+ *
+ * @param[in] pu1_src
+ *
+ * Pointer to source sub-block
+ *
+ * @param[in] pu1_pred
+ * Pointer to
+ * prediction sub-block
+ *
+ * @param[in] pi2_out
+ * Pointer to residual
+ * sub-block
+ *
+ * @param[in] i4_src_stride
+ * Source stride
+ *
+ * @param[in]
+ * i4_pred_stride
+ * Prediction stride
+ *
+ * @param[in] dst_strd
+ *
+ * Destination stride
+ *
+ * @param[in] u4_qbits
+ * QP_BITS_h264_4x4 +
+ * floor(QP/6)
+ *
+ * @param[in] pu2_threshold_matrix
+ * Pointer to Forward
+ * Quant Threshold Matrix
+ *
+ * @param[in] pu2_scale_matrix
+ * Pointer to
+ * Forward Quant Scale Matrix
+ *
+ * @param[in] u4_round_factor
+ * Quantization
+ * Round factor
+ *
+ * @param[out] pu1_nnz
+ * Total non-zero coefficients in
+ * the current sub-block
+ *
+ * @returns
+ *
+ * @remarks
+ * NNZ for dc is
+ * populated at 0 and 5th position of pu1_nnz
+ *
+ */
+
+void isvc_hadamard_quant_2x2_uv_sse42(WORD16 *pi2_src, WORD16 *pi2_dst,
+ resi_trans_quant_constants_t *ps_quant_constants,
+ UWORD8 *pu1_nnz)
+{
+ const UWORD16 *pu2_scale_matrix = ps_quant_constants->pu2_scale_matrix;
+ const UWORD16 *pu2_threshold_matrix = ps_quant_constants->pu2_threshold_matrix;
+ UWORD32 u4_qbits = ps_quant_constants->u4_qbits;
+ UWORD32 u4_round_factor = ps_quant_constants->u4_round_factor;
+ WORD32 val, nonzero_coeff_0 = 0, nonzero_coeff_1 = 0;
+ __m128i cmp, cmp0, cmp1;
+ __m128i sum0, sum1;
+ WORD32 mask, mask0, mask1;
+ __m128i src, plane_0, plane_1, temp0, temp1, sign_reg;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i scale_val = _mm_set1_epi32(pu2_scale_matrix[0]);
+ __m128i sign_reg0, sign_reg1;
+ __m128i temp_1 = _mm_set1_epi16(1);
+ __m128i rnd_fact = _mm_set1_epi32(u4_round_factor);
+
+ UNUSED(pu2_threshold_matrix);
+
+ src = _mm_loadu_si128((__m128i *) pi2_src); // a0 a1 a2 a3 b0 b1 b2 b3
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, src);
+ plane_0 = _mm_unpacklo_epi16(src, sign_reg); // a0 a1 a2 a3 -- 32 bits
+ plane_1 = _mm_unpackhi_epi16(src, sign_reg); // b0 b1 b2 b3 -- 32 bits
+
+ temp0 = _mm_hadd_epi32(plane_0, plane_1); // a0+a1 a2+a3 b0+b1 b2+b3
+ temp1 = _mm_hsub_epi32(plane_0, plane_1); // a0-a1 a2-a3 b0-b1 b2-b3
+
+ plane_0 = _mm_hadd_epi32(temp0, temp1); // a0+a1+a2+a3 b0+b1+b2+b3 a0-a1+a2-a3 b0-b1+b2-b3
+ plane_1 = _mm_hsub_epi32(temp0, temp1); // a0+a1-a2-a3 b0+b1-b2-b3 a0-a1-a2+a3 b0-b1-b2+b3
+
+ temp0 =
+ _mm_unpacklo_epi32(plane_0, plane_1); // a0+a1+a2+a3 a0+a1-a2-a3 b0+b1+b2+b3 b0+b1-b2-b3
+ temp1 =
+ _mm_unpackhi_epi32(plane_0, plane_1); // a0-a1+a2-a3 a0-a1-a2+a3 b0-b1+b2-b3 b0-b1-b2+b3
+
+ plane_0 = _mm_unpacklo_epi64(temp0, temp1); // a0+a1+a2+a3 a0+a1-a2-a3 a0-a1+a2-a3 a0-a1-a2+a3
+ plane_1 = _mm_unpackhi_epi64(temp0, temp1); // b0+b1+b2+b3 b0+b1-b2-b3 b0-b1+b2-b3 b0-b1-b2+b3
+
+ plane_0 = _mm_shuffle_epi32(plane_0, 0xd8); // a0+a1+a2+a3 a0-a1+a2-a3 a0+a1-a2-a3 a0-a1-a2+a3
+ plane_1 = _mm_shuffle_epi32(plane_1, 0xd8); // b0+b1+b2+b3 b0-b1+b2-b3 b0+b1-b2-b3 b0-b1-b2+b3
+ // Quantization
+ sign_reg0 =
+ _mm_cmpgt_epi32(zero_8x16b, plane_0); // Find sign of each value for later restoration
+ sign_reg1 = _mm_cmpgt_epi32(zero_8x16b, plane_1);
+
+ sign_reg0 = _mm_packs_epi32(sign_reg0,
+ sign_reg1); // Sign = -1 or 0 depending on <0 or >0 respectively
+ sign_reg0 = _mm_slli_epi16(sign_reg0, 1); // Sign = -2 or 0 depending on <0 or >0 respectively
+ sign_reg0 =
+ _mm_add_epi16(temp_1, sign_reg0); // Sign = -1 or 1 depending on <0 or >0 respectively
+
+ plane_0 = _mm_abs_epi32(plane_0); // Absolute values
+ plane_1 = _mm_abs_epi32(plane_1);
+
+ temp0 = _mm_mullo_epi32(scale_val, plane_0); // multiply by pu2_scale_matrix[0]
+ temp1 = _mm_mullo_epi32(scale_val, plane_1); // multiply by pu2_scale_matrix[0]
+
+ temp0 = _mm_add_epi32(temp0, rnd_fact); // Add round factor
+ temp1 = _mm_add_epi32(temp1, rnd_fact);
+
+ temp0 = _mm_srli_epi32(temp0,
+ u4_qbits); // RIght shift by qbits, unsigned variable,
+ // so shift right immediate works
+ temp1 = _mm_srli_epi32(temp1, u4_qbits);
+
+ temp0 = _mm_packs_epi32(temp0, temp1); // Final values are 16-bits only.
+ temp0 = _mm_sign_epi16(temp0, sign_reg0); // Sign restoration
+
+ _mm_storeu_si128((__m128i *) (&pi2_dst[0]), temp0);
+
+ cmp = _mm_cmpeq_epi16(temp0, zero_8x16b);
+ mask = _mm_movemask_epi8(cmp);
+ mask0 = mask & 0xff;
+ mask1 = mask >> 8;
+ if(mask0)
+ {
+ if(mask0 == 0xff)
+ nonzero_coeff_0 += 4;
+ else
+ {
+ cmp0 = _mm_and_si128(temp_1, cmp);
+ sum0 = _mm_hadd_epi16(cmp0, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ val = _mm_cvtsi128_si32(sum1);
+ val = val & 0xffff;
+ nonzero_coeff_0 += val;
+ }
+ }
+ if(mask1)
+ {
+ if(mask1 == 0xff)
+ nonzero_coeff_1 += 4;
+ else
+ {
+ cmp1 = _mm_srli_si128(cmp, 8);
+ cmp1 = _mm_and_si128(temp_1, cmp1);
+ sum0 = _mm_hadd_epi16(cmp1, zero_8x16b);
+ sum1 = _mm_hadd_epi16(sum0, zero_8x16b);
+ nonzero_coeff_1 += _mm_cvtsi128_si32(sum1);
+ }
+ }
+
+ pu1_nnz[0] = 4 - nonzero_coeff_0;
+ pu1_nnz[1] = 4 - nonzero_coeff_1;
+}
diff --git a/decoder/arm/svc/isvcd_function_selector.c b/decoder/arm/svc/isvcd_function_selector.c
new file mode 100644
index 0000000..3883663
--- /dev/null
+++ b/decoder/arm/svc/isvcd_function_selector.c
@@ -0,0 +1,107 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in hevc
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_init_function_ptr()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264_defs.h"
+#include "ih264_size_defs.h"
+#include "ih264_error.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264d_structs.h"
+#include "ih264d_function_selector.h"
+#include "isvcd_structs.h"
+#include "isvcd_function_selector.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing arm v8/x86/a9q architecture
+*
+* @param[in] ps_codec
+* ps_codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvcd_init_function_ptr(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_codec = &ps_svc_lyr_dec->s_dec;
+ IVD_ARCH_T e_proc_arch = ps_codec->e_processor_arch;
+ isvcd_init_function_ptr_generic(ps_svc_lyr_dec);
+ switch(e_proc_arch)
+ {
+#if defined(ARMV8)
+ case ARCH_ARMV8_GENERIC:
+ default:
+ ih264d_init_function_ptr_av8(ps_codec);
+ isvcd_init_function_ptr_neonintr(ps_svc_lyr_dec);
+ break;
+#elif !defined(DISABLE_NEON)
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A15:
+ case ARCH_ARM_A9Q:
+ default:
+ ih264d_init_function_ptr_a9q(ps_codec);
+ isvcd_init_function_ptr_neonintr(ps_svc_lyr_dec);
+ break;
+#else
+ default:
+#endif
+ case ARCH_ARM_NONEON:
+ break;
+ }
+}
diff --git a/decoder/arm/svc/isvcd_function_selector_neon.c b/decoder/arm/svc/isvcd_function_selector_neon.c
new file mode 100644
index 0000000..9ae7e7c
--- /dev/null
+++ b/decoder/arm/svc/isvcd_function_selector_neon.c
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_function_selector_neonintr.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_init_function_ptr_neonintr()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include "isvcd_structs.h"
+#include "isvcd_function_selector.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing arm v8 architecture
+*
+* @param[in] ps_svc_lyr_dec
+* svc layer dec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvcd_init_function_ptr_neonintr(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ residual_sampling_ctxt_t *ps_resd_samp_ctx;
+ intra_sampling_ctxt_t *ps_intra_samp_ctxt;
+ ps_resd_samp_ctx = (residual_sampling_ctxt_t *) ps_svc_lyr_dec->pv_residual_sample_ctxt;
+ ps_intra_samp_ctxt = (intra_sampling_ctxt_t *) ps_svc_lyr_dec->pv_intra_sample_ctxt;
+
+ ps_intra_samp_ctxt->pf_interpolate_base_luma_dyadic =
+ isvcd_interpolate_base_luma_dyadic_neonintr;
+ ps_intra_samp_ctxt->pf_interpolate_intra_base = isvcd_interpolate_intra_base_neonintr;
+
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[0] = isvcd_vert_interpol_chroma_dyadic_1_neonintr;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[1] = isvcd_vert_interpol_chroma_dyadic_2_neonintr;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[2] = isvcd_vert_interpol_chroma_dyadic_3_neonintr;
+
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[0] = isvcd_horz_interpol_chroma_dyadic_1_neonintr;
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[1] = isvcd_horz_interpol_chroma_dyadic_2_neonintr;
+
+ ps_resd_samp_ctx->pf_residual_luma_dyadic = isvcd_residual_luma_dyadic_neonintr;
+ ps_resd_samp_ctx->pf_interpolate_residual = isvcd_interpolate_residual_neonintr;
+
+ ps_resd_samp_ctx->pf_residual_reflayer_const_non_boundary_mb =
+ isvcd_residual_reflayer_const_non_boundary_mb_neonintr;
+
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_4x4 = isvcd_pred_residual_recon_4x4_neonintr;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_8x8 = isvcd_pred_residual_recon_8x8_neonintr;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_16x16 = isvcd_pred_residual_recon_16x16_neonintr;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_4x4 =
+ isvcd_pred_residual_recon_chroma_4x4_neonintr;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_8x8 =
+ isvcd_pred_residual_recon_chroma_8x8_neonintr;
+
+ ps_svc_lyr_dec->pf_residual_luma_4x4 = isvcd_residual_luma_4x4_neonintr;
+ ps_svc_lyr_dec->pf_residual_luma_8x8 = isvcd_residual_luma_8x8_neonintr;
+ ps_svc_lyr_dec->pf_residual_luma_16x16 = isvcd_residual_luma_16x16_neonintr;
+ ps_svc_lyr_dec->pf_residual_chroma_cb_cr_8x8 = isvcd_residual_chroma_cb_cr_8x8_neonintr;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4 = isvcd_iquant_itrans_residual_4x4_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4_dc =
+ isvcd_iquant_itrans_residual_4x4_dc_neonintr;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8 = isvcd_iquant_itrans_residual_8x8_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8_dc =
+ isvcd_iquant_itrans_residual_8x8_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4 =
+ isvcd_iquant_itrans_residual_chroma_4x4_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_chroma_4x4_dc_neonintr;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_4x4_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8_dc =
+ isvcd_iquant_itrans_residual_recon_8x8_dc_neonintr;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4 =
+ isvcd_iquant_itrans_residual_recon_4x4_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8 =
+ isvcd_iquant_itrans_residual_recon_8x8_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4 =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_neonintr;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4_dc = isvcd_iquant_itrans_4x4_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8_dc = isvcd_iquant_itrans_8x8_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4 = isvcd_iquant_itrans_4x4_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8 = isvcd_iquant_itrans_8x8_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4_dc = isvcd_iquant_itrans_chroma_4x4_dc_neonintr;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4 = isvcd_iquant_itrans_chroma_4x4_neonintr;
+
+ return;
+}
diff --git a/decoder/arm/svc/isvcd_intra_resamp_neon.c b/decoder/arm/svc/isvcd_intra_resamp_neon.c
new file mode 100644
index 0000000..24059ed
--- /dev/null
+++ b/decoder/arm/svc/isvcd_intra_resamp_neon.c
@@ -0,0 +1,1548 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_intra_resamp_neonintr.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_interpolate_base_luma_dyadic_neonintr()
+ * - isvcd_interpolate_intra_base_neonintr()
+ * - isvcd_horz_interpol_chroma_dyadic_1_neonintr()
+ * - isvcd_horz_interpol_chroma_dyadic_2_neonintr()
+ * - isvcd_vert_interpol_chroma_dyadic_1_neonintr()
+ * - isvcd_vert_interpol_chroma_dyadic_2_neonintr()
+ * - isvcd_vert_interpol_chroma_dyadic_3_neonintr()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <assert.h>
+#include <string.h>
+#include <arm_neon.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264_debug.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_base_luma_dyadic_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* intra resampling for dyadic scaling ratios */
+/* Inputs : pu1_inp_buf : ptr to the 12x12 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 12x16 buffer to hold the */
+/* vertically interpolated data */
+/* pu1_out_buf : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 05 21 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_base_luma_dyadic_neonintr(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_y;
+ WORD16 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ int16x4_t i4_rslt_vert_16x4_1, i4_rslt_vert_16x4_2;
+ uint8x8_t i4_samp_vert_8x8_0, i4_samp_vert_8x8_1, i4_samp_vert_8x8_2, i4_samp_vert_8x8_3;
+ int16x8_t i4_rslt_vert_16x8_0, i4_rslt_vert_16x8_2;
+ /* Horizontal interpolation */
+ int32x4_t const_512_32x4 = vdupq_n_s32(512);
+ int32x4_t i4_rslt_horz_r0_1, i4_rslt_horz_r1_1, i4_rslt_horz_r0_2, i4_rslt_horz_r1_2;
+ uint16x4_t i4_rslt_horz_r0_1_tmp, i4_rslt_horz_r1_1_tmp, i4_rslt_horz_r0_2_tmp,
+ i4_rslt_horz_r1_2_tmp;
+ uint16x8_t rslt_16x8_t_1, rslt_16x8_t_2;
+ int32x4x2_t i4_rslt_horz_32x4x2_t;
+ int16x4_t i4_samp_horz_16x4_0, i4_samp_horz_16x4_1, i4_samp_horz_16x4_2, i4_samp_horz_16x4_3,
+ i4_samp_horz_16x4_4;
+ int16x4_t i4_samp_horz_16x4_5, i4_samp_horz_16x4_6, i4_samp_horz_16x4_7, i4_samp_horz_16x4_8;
+ int16_t i4_coeff_c0 = -3;
+ int16_t i4_coeff_c1 = 28;
+ int16_t i4_coeff_c2 = 8;
+ int16_t i4_coeff_c3 = -1;
+ int32x4_t i4_rslt_horz_r0_1_tmp32, i4_rslt_horz_r1_1_tmp32, i4_rslt_horz_r0_2_tmp32,
+ i4_rslt_horz_r1_2_tmp32;
+
+ /* Filter coefficient values for phase 4 */
+ i4_coeff_0 = -3;
+ i4_coeff_1 = 28;
+ i4_coeff_2 = 8;
+ i4_coeff_3 = -1;
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ // First 64 bits
+ i4_samp_vert_8x8_0 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_1 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_2 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_3);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_0);
+
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_0);
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_0);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_3);
+
+ i4_rslt_vert_16x8_2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_3);
+ i4_rslt_vert_16x8_2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_2);
+ i4_rslt_vert_16x8_2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_1);
+ i4_rslt_vert_16x8_2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_0);
+
+ /* Storing the results */
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_0));
+ pi2_tmp += i4_filt_stride;
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_2));
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ } /*End of Loop over y*/
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+
+ i4_rslt_vert_16x8_0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_0)), i4_coeff_0);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_1)), i4_coeff_1);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_2)), i4_coeff_2);
+ i4_rslt_vert_16x8_0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_3)), i4_coeff_3);
+
+ vst1q_s16(pi2_tmp, (i4_rslt_vert_16x8_0));
+ /* End of loop over x */
+
+ // Remaining 32 bits
+ pu1_inp = pu1_inp_buf + 8;
+ pi2_tmp = pi2_tmp_filt_buf + 8;
+
+ i4_samp_vert_8x8_0 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_1 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_2 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x4_1 =
+ vmul_n_s16(vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_3);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))), i4_coeff_2);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))), i4_coeff_1);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))), i4_coeff_0);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+
+ i4_rslt_vert_16x4_1 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_0);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))),
+ i4_coeff_1);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))),
+ i4_coeff_2);
+ i4_rslt_vert_16x4_1 = vmla_n_s16(
+ i4_rslt_vert_16x4_1, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))),
+ i4_coeff_3);
+
+ i4_rslt_vert_16x4_2 = vmul_n_s16(
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_3);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))),
+ i4_coeff_2);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))),
+ i4_coeff_1);
+ i4_rslt_vert_16x4_2 = vmla_n_s16(
+ i4_rslt_vert_16x4_2, vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))),
+ i4_coeff_0);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ pi2_tmp += i4_filt_stride;
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_2));
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ }
+
+ i4_samp_vert_8x8_0 = i4_samp_vert_8x8_1;
+ i4_samp_vert_8x8_1 = i4_samp_vert_8x8_2;
+ i4_samp_vert_8x8_2 = i4_samp_vert_8x8_3;
+ i4_samp_vert_8x8_3 = vld1_u8((const uint8_t *) pu1_inp);
+
+ i4_rslt_vert_16x4_1 =
+ vmul_n_s16(vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_0))), i4_coeff_0);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_1))), i4_coeff_1);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_2))), i4_coeff_2);
+ i4_rslt_vert_16x4_1 =
+ vmla_n_s16(i4_rslt_vert_16x4_1,
+ vreinterpret_s16_u16(vget_low_u16(vmovl_u8(i4_samp_vert_8x8_3))), i4_coeff_3);
+
+ vst1_s16(pi2_tmp, (i4_rslt_vert_16x4_1));
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ i4_samp_horz_16x4_0 = vld1_s16(pi2_tmp);
+ i4_samp_horz_16x4_1 = vld1_s16(pi2_tmp + 1);
+ i4_samp_horz_16x4_2 = vld1_s16(pi2_tmp + 2);
+ i4_samp_horz_16x4_3 = vld1_s16(pi2_tmp + 3);
+ i4_samp_horz_16x4_4 = vld1_s16(pi2_tmp + 4);
+ i4_samp_horz_16x4_5 = vld1_s16(pi2_tmp + 5);
+ i4_samp_horz_16x4_6 = vld1_s16(pi2_tmp + 6);
+ i4_samp_horz_16x4_7 = vld1_s16(pi2_tmp + 7);
+ i4_samp_horz_16x4_8 = vld1_s16(pi2_tmp + 8);
+
+ i4_rslt_horz_r0_1 = vmull_n_s16(i4_samp_horz_16x4_0, i4_coeff_c3); // a0c3 a1c3 a2c3 a3c3
+ i4_rslt_horz_r0_1 = vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_1,
+ i4_coeff_c2); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_rslt_horz_r0_1 = vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_2, i4_coeff_c1);
+ i4_rslt_horz_r0_1 = vmlal_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x4_3, i4_coeff_c0);
+
+ i4_rslt_horz_r1_1 = vmull_n_s16(i4_samp_horz_16x4_1, i4_coeff_c0); // a0c0 a1c0 a2c0 a3c0
+ i4_rslt_horz_r1_1 = vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_2,
+ i4_coeff_c1); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_rslt_horz_r1_1 = vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_3, i4_coeff_c2);
+ i4_rslt_horz_r1_1 = vmlal_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x4_4, i4_coeff_c3);
+
+ i4_rslt_horz_r0_2 = vmull_n_s16(i4_samp_horz_16x4_4, i4_coeff_c3); // a0c3 a1c3 a2c3 a3c3
+ i4_rslt_horz_r0_2 = vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_5,
+ i4_coeff_c2); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_rslt_horz_r0_2 = vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_6, i4_coeff_c1);
+ i4_rslt_horz_r0_2 = vmlal_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x4_7, i4_coeff_c0);
+
+ i4_rslt_horz_r1_2 = vmull_n_s16(i4_samp_horz_16x4_5, i4_coeff_c0); // a0c0 a1c0 a2c0 a3c0
+ i4_rslt_horz_r1_2 = vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_6,
+ i4_coeff_c1); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_rslt_horz_r1_2 = vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_7, i4_coeff_c2);
+ i4_rslt_horz_r1_2 = vmlal_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x4_8, i4_coeff_c3);
+
+ i4_rslt_horz_32x4x2_t = vzipq_s32(i4_rslt_horz_r0_1, i4_rslt_horz_r1_1);
+ i4_rslt_horz_r0_1_tmp32 = i4_rslt_horz_32x4x2_t.val[0]; // 0 to 3
+ i4_rslt_horz_r1_1_tmp32 = i4_rslt_horz_32x4x2_t.val[1]; // 4 to 7
+
+ i4_rslt_horz_32x4x2_t = vzipq_s32(i4_rslt_horz_r0_2, i4_rslt_horz_r1_2);
+ i4_rslt_horz_r0_2_tmp32 = i4_rslt_horz_32x4x2_t.val[0]; // 8 to 11
+ i4_rslt_horz_r1_2_tmp32 = i4_rslt_horz_32x4x2_t.val[1]; // 12 to 15
+
+ i4_rslt_horz_r0_1 = vaddq_s32(i4_rslt_horz_r0_1_tmp32, const_512_32x4);
+ i4_rslt_horz_r1_1 = vaddq_s32(i4_rslt_horz_r1_1_tmp32, const_512_32x4);
+ i4_rslt_horz_r0_2 = vaddq_s32(i4_rslt_horz_r0_2_tmp32, const_512_32x4);
+ i4_rslt_horz_r1_2 = vaddq_s32(i4_rslt_horz_r1_2_tmp32, const_512_32x4);
+
+ i4_rslt_horz_r0_1_tmp = vqshrun_n_s32(i4_rslt_horz_r0_1, 10);
+ i4_rslt_horz_r1_1_tmp = vqshrun_n_s32(i4_rslt_horz_r1_1, 10);
+
+ i4_rslt_horz_r0_2_tmp = vqshrun_n_s32(i4_rslt_horz_r0_2, 10);
+ i4_rslt_horz_r1_2_tmp = vqshrun_n_s32(i4_rslt_horz_r1_2, 10);
+
+ rslt_16x8_t_1 = vcombine_u16(i4_rslt_horz_r0_1_tmp, i4_rslt_horz_r1_1_tmp); // 0 to 7
+ rslt_16x8_t_2 = vcombine_u16(i4_rslt_horz_r0_2_tmp, i4_rslt_horz_r1_2_tmp); // 8 to 15
+
+ vst1_u8(pu1_out, vqmovn_u16(rslt_16x8_t_1));
+ vst1_u8(pu1_out + 8, vqmovn_u16(rslt_16x8_t_2));
+
+ pu1_out += i4_out_stride;
+ pi2_tmp += i4_filt_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_intra_base_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* interpolation of a component to find the intra */
+/* resampled value */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* pu1_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_intra_base_neonintr(void *pv_intra_samp_ctxt, UWORD8 *pu1_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd,
+ WORD32 i4_mb_x, WORD32 i4_mb_y, WORD32 i4_chroma_flag,
+ WORD32 i4_refarray_flag)
+{
+ /* --------------------------------------------------------------------- */
+ /* Index Parameters */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_map_ctxt_t *ps_map_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ UWORD8 *pu1_refarray = NULL;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+ WORD32 i4_temp_array_ht;
+ WORD32 *pi4_interp_buff;
+
+ UWORD8 arr_y_ref_pos_luma[16] = {0};
+ UWORD8 arr_x_ref_pos_luma[16] = {0};
+ UWORD8 arr_x_ref_pos_luma_low[16] = {0};
+ UWORD8 arr_x_ref_pos_luma_high[16] = {0};
+ UWORD8 arr_phase_luma[16] = {0};
+ UWORD8 *pi4_y_ref_pos_luma;
+ UWORD8 *pi4_x_ref_pos_luma_low;
+ UWORD8 *pi4_x_ref_pos_luma_high;
+ UWORD8 *pi4_phase_luma;
+ WORD16 *pi2_interp_buff_temp;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD32 i4_x_min;
+ ref_min_max_map_t *ps_x_min_max;
+ UWORD8 *pu1_refarray_temp;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ if(0 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_buffer;
+ }
+ else if(1 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_cb;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA or CHROMA */
+ /* --------------------------------------------------------------------- */
+
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &(ps_lyr_ctxt->s_chroma_map_ctxt);
+ else
+ ps_map_ctxt = &(ps_lyr_ctxt->s_luma_map_ctxt);
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+
+ i4_frm_mb_y = i4_mb_y * i4_mb_ht;
+ i4_frm_mb_x = i4_mb_x * i4_mb_wd;
+ /* get the min and max positions */
+ i4_x_min = ps_x_min_max[i4_mb_x].i2_min_pos;
+
+ /* --------------------------------------------------------------------- */
+ /* Projected frame level pointers */
+ /* --------------------------------------------------------------------- */
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointers and Dimenstion of the temporary buffer */
+ /* --------------------------------------------------------------------- */
+ i4_temp_array_ht = i4_mb_ht;
+ pi4_interp_buff = ps_ctxt->pi4_temp_interpolation_buffer;
+ pi2_interp_buff_temp = (WORD16 *) pi4_interp_buff;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation in vertical direction */
+ /* --------------------------------------------------------------------- */
+ if(i4_chroma_flag == 0)
+ {
+ {
+ uint8x8_t inp_8x8_r0, inp_8x8_r0_1;
+ uint8x8_t inp_8x8_r1, inp_8x8_r1_1;
+ uint8x8_t inp_8x8_r2, inp_8x8_r2_1;
+ uint8x8_t inp_8x8_r3, inp_8x8_r3_1;
+ int16x8_t out_res_16x8_r0_0, out_res_16x8_r0_1;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_phase_luma[i4_y] = (UWORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos_luma[i4_y] = (UWORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi4_y_ref_pos_luma = arr_y_ref_pos_luma;
+ pi4_phase_luma = arr_phase_luma;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ pu1_refarray_temp =
+ pu1_refarray + (pi4_y_ref_pos_luma[i4_y] * i4_refarray_wd) + (i4_x_min - 1);
+ inp_8x8_r0 = vld1_u8((pu1_refarray_temp - i4_refarray_wd));
+ inp_8x8_r1 = vld1_u8((pu1_refarray_temp));
+ inp_8x8_r2 = vld1_u8((pu1_refarray_temp + i4_refarray_wd));
+ inp_8x8_r3 = vld1_u8((pu1_refarray_temp + 2 * i4_refarray_wd));
+
+ inp_8x8_r0_1 = vld1_u8((pu1_refarray_temp + 8 - i4_refarray_wd));
+ inp_8x8_r1_1 = vld1_u8((pu1_refarray_temp + 8));
+ inp_8x8_r2_1 = vld1_u8((pu1_refarray_temp + 8 + i4_refarray_wd));
+ inp_8x8_r3_1 = vld1_u8((pu1_refarray_temp + 8 + 2 * i4_refarray_wd));
+
+ out_res_16x8_r0_0 = vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r0)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y]]);
+ out_res_16x8_r0_0 =
+ vmlaq_n_s16(out_res_16x8_r0_0, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r1)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 16]);
+ out_res_16x8_r0_0 =
+ vmlaq_n_s16(out_res_16x8_r0_0, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r2)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 32]);
+ out_res_16x8_r0_0 =
+ vmlaq_n_s16(out_res_16x8_r0_0, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r3)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 48]);
+
+ out_res_16x8_r0_1 = vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r0_1)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y]]);
+ out_res_16x8_r0_1 =
+ vmlaq_n_s16(out_res_16x8_r0_1, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r1_1)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 16]);
+ out_res_16x8_r0_1 =
+ vmlaq_n_s16(out_res_16x8_r0_1, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r2_1)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 32]);
+ out_res_16x8_r0_1 =
+ vmlaq_n_s16(out_res_16x8_r0_1, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r3_1)),
+ g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 48]);
+
+ vst1q_s16((pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1)),
+ out_res_16x8_r0_0);
+ vst1q_s16((pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1) + 8),
+ out_res_16x8_r0_1);
+ }
+ }
+ /*Horizontal Interpolation*/
+ {
+ WORD32 strt_indx = 10;
+
+ uint8x16_t phs_mask_8x8_0;
+ uint8x16_t x_ref_pos_luma_mask_r0_0;
+ uint8x16_t x_ref_pos_luma_mask_r0_1;
+ uint8x16_t x_ref_pos_luma_mask_r1_0;
+ uint8x16_t x_ref_pos_luma_mask_r1_1;
+ uint8x16_t x_ref_pos_luma_mask_r2_0;
+ uint8x16_t x_ref_pos_luma_mask_r2_1;
+ uint8x16_t x_ref_pos_luma_mask_r3_0;
+ uint8x16_t x_ref_pos_luma_mask_r3_1;
+
+ WORD32 strt_indx_h = 0, i4_x2 = 0;
+ WORD32 i4_mb_wd_hlf = (i4_mb_wd >> 1);
+ uint8x16_t twos = vdupq_n_u8(2);
+ strt_indx = ps_x_pos_phase[0 + i4_frm_mb_x].i2_ref_pos - 1;
+ strt_indx_h = (ps_x_pos_phase[8 + i4_frm_mb_x].i2_ref_pos - strt_indx - 1);
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos_luma[i4_x] = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_phase_luma[i4_x] = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ arr_x_ref_pos_luma[i4_x] = arr_x_ref_pos_luma[i4_x] - strt_indx - 1;
+ }
+
+ for(i4_x = 0; i4_x < i4_mb_wd_hlf; i4_x++)
+ {
+ i4_x2 = i4_x << 1;
+ arr_x_ref_pos_luma_low[i4_x2] = (arr_x_ref_pos_luma[i4_x]) << 1;
+ arr_x_ref_pos_luma_low[i4_x2 + 1] = arr_x_ref_pos_luma_low[i4_x2] + 1;
+ }
+ for(i4_x = i4_mb_wd_hlf; i4_x < i4_mb_wd; i4_x++)
+ {
+ i4_x2 = (i4_x - i4_mb_wd_hlf) << 1;
+ arr_x_ref_pos_luma_high[i4_x2] = ((arr_x_ref_pos_luma[i4_x] - strt_indx_h) << 1);
+ arr_x_ref_pos_luma_high[i4_x2 + 1] = arr_x_ref_pos_luma_high[i4_x2] + 1;
+ }
+ pi4_x_ref_pos_luma_low = arr_x_ref_pos_luma_low;
+ pi4_x_ref_pos_luma_high = arr_x_ref_pos_luma_high;
+ pi4_phase_luma = arr_phase_luma;
+
+ phs_mask_8x8_0 = vld1q_u8((const uint8_t *) pi4_phase_luma);
+
+ x_ref_pos_luma_mask_r0_0 = vld1q_u8(pi4_x_ref_pos_luma_low);
+ x_ref_pos_luma_mask_r0_1 = vld1q_u8(pi4_x_ref_pos_luma_high);
+ x_ref_pos_luma_mask_r1_0 = vaddq_u8(x_ref_pos_luma_mask_r0_0, twos);
+ x_ref_pos_luma_mask_r1_1 = vaddq_u8(x_ref_pos_luma_mask_r0_1, twos);
+ x_ref_pos_luma_mask_r2_0 = vaddq_u8(x_ref_pos_luma_mask_r1_0, twos);
+ x_ref_pos_luma_mask_r2_1 = vaddq_u8(x_ref_pos_luma_mask_r1_1, twos);
+ x_ref_pos_luma_mask_r3_0 = x_ref_pos_luma_mask_r0_0;
+ x_ref_pos_luma_mask_r3_1 = x_ref_pos_luma_mask_r0_1;
+
+ {
+ int8x16_t ip_filt_8x16_r0;
+ int8x16_t ip_filt_8x16_r1;
+ int8x16_t ip_filt_8x16_r2;
+ int8x16_t ip_filt_8x16_r3;
+
+ int16x8_t ip_filt_16x8_r0_0, ip_filt_16x8_r0_1;
+ int16x8_t ip_filt_16x8_r1_0, ip_filt_16x8_r1_1;
+ int16x8_t ip_filt_16x8_r2_0, ip_filt_16x8_r2_1;
+ int16x8_t ip_filt_16x8_r3_0, ip_filt_16x8_r3_1;
+
+ int16x8_t inp_16x8_0;
+ int16x8_t inp_16x8_1;
+ int16x8_t inp_16x8_2;
+ int16x8_t inp_16x8_3;
+
+ int16x8_t inp_16x8_r0_0, inp_16x8_r2_0;
+ int16x8_t inp_16x8_r0_1, inp_16x8_r2_1;
+ int16x8_t inp_16x8_r1_0, inp_16x8_r3_0;
+ int16x8_t inp_16x8_r1_1, inp_16x8_r3_1;
+
+ int16x4_t inp_16x4_r0_0, inp_16x4_r2_0;
+ int16x4_t inp_16x4_r0_1, inp_16x4_r2_1;
+ int16x4_t inp_16x4_r1_0, inp_16x4_r3_0;
+ int16x4_t inp_16x4_r1_1, inp_16x4_r3_1;
+
+ int32x4_t out_res_32x4_r0_l_0;
+ int32x4_t out_res_32x4_r0_l_1;
+ int32x4_t out_res_32x4_r0_h_0;
+ int32x4_t out_res_32x4_r0_h_1;
+
+ uint16x4_t out_res_16x4_r0_l_0;
+ uint16x4_t out_res_16x4_r0_l_1;
+ uint16x4_t out_res_16x4_r0_h_0;
+ uint16x4_t out_res_16x4_r0_h_1;
+
+ uint8x8_t out_res_8x8_r0_l, out_res_8x8_r0_h;
+ uint8x8x2_t u1_temp_8x8x2_t;
+ uint8x8_t u1_temp_8x8_t0, u1_temp_8x8_t1;
+
+ ip_filt_8x16_r0 = vld1q_s8((g_ai1_interp_filter_luma));
+ ip_filt_8x16_r1 = vld1q_s8((g_ai1_interp_filter_luma + 16));
+ ip_filt_8x16_r2 = vld1q_s8((g_ai1_interp_filter_luma + 32));
+ ip_filt_8x16_r3 = vld1q_s8((g_ai1_interp_filter_luma + 48));
+
+ u1_temp_8x8x2_t.val[0] = vreinterpret_u8_s8(vget_low_s8(ip_filt_8x16_r0));
+ u1_temp_8x8x2_t.val[1] = vreinterpret_u8_s8(vget_high_s8(ip_filt_8x16_r0));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r0 = vcombine_s8(vreinterpret_s8_u8(u1_temp_8x8_t0),
+ vreinterpret_s8_u8(u1_temp_8x8_t1));
+
+ u1_temp_8x8x2_t.val[0] = vreinterpret_u8_s8(vget_low_s8(ip_filt_8x16_r1));
+ u1_temp_8x8x2_t.val[1] = vreinterpret_u8_s8(vget_high_s8(ip_filt_8x16_r1));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r1 = vcombine_s8(vreinterpret_s8_u8(u1_temp_8x8_t0),
+ vreinterpret_s8_u8(u1_temp_8x8_t1));
+ u1_temp_8x8x2_t.val[0] = vreinterpret_u8_s8(vget_low_s8(ip_filt_8x16_r2));
+ u1_temp_8x8x2_t.val[1] = vreinterpret_u8_s8(vget_high_s8(ip_filt_8x16_r2));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r2 = vcombine_s8(vreinterpret_s8_u8(u1_temp_8x8_t0),
+ vreinterpret_s8_u8(u1_temp_8x8_t1));
+ u1_temp_8x8x2_t.val[0] = vreinterpret_u8_s8(vget_low_s8(ip_filt_8x16_r3));
+ u1_temp_8x8x2_t.val[1] = vreinterpret_u8_s8(vget_high_s8(ip_filt_8x16_r3));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r3 = vcombine_s8(vreinterpret_s8_u8(u1_temp_8x8_t0),
+ vreinterpret_s8_u8(u1_temp_8x8_t1));
+ ip_filt_16x8_r0_0 = vmovl_s8(vget_low_s8(ip_filt_8x16_r0));
+ ip_filt_16x8_r1_0 = vmovl_s8(vget_low_s8(ip_filt_8x16_r1));
+ ip_filt_16x8_r2_0 = vmovl_s8(vget_low_s8(ip_filt_8x16_r2));
+ ip_filt_16x8_r3_0 = vmovl_s8(vget_low_s8(ip_filt_8x16_r3));
+ ip_filt_16x8_r0_1 = vmovl_s8(vget_high_s8(ip_filt_8x16_r0));
+ ip_filt_16x8_r1_1 = vmovl_s8(vget_high_s8(ip_filt_8x16_r1));
+ ip_filt_16x8_r2_1 = vmovl_s8(vget_high_s8(ip_filt_8x16_r2));
+ ip_filt_16x8_r3_1 = vmovl_s8(vget_high_s8(ip_filt_8x16_r3));
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ inp_16x8_0 = vld1q_s16((pi2_interp_buff_temp + strt_indx));
+ inp_16x8_1 = vld1q_s16((pi2_interp_buff_temp + strt_indx + strt_indx_h));
+ inp_16x8_2 = vld1q_s16((pi2_interp_buff_temp + strt_indx + 3));
+ inp_16x8_3 = vld1q_s16((pi2_interp_buff_temp + strt_indx + strt_indx_h + 3));
+ pi2_interp_buff_temp += i4_refarray_wd;
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r0_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r0_0));
+ inp_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r0_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r0_1));
+ inp_16x8_r0_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r1_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r1_0));
+ inp_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r1_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r1_1));
+ inp_16x8_r1_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r2_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r2_0));
+ inp_16x8_r2_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_1)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r2_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r2_1));
+ inp_16x8_r2_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_2)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_2)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r3_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r3_0));
+ inp_16x8_r3_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_3)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_3)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r3_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r3_1));
+ inp_16x8_r3_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ inp_16x4_r0_0 = vget_low_s16(inp_16x8_r0_0);
+ inp_16x4_r0_1 = vget_low_s16(inp_16x8_r0_1);
+ inp_16x4_r1_0 = vget_low_s16(inp_16x8_r1_0);
+ inp_16x4_r1_1 = vget_low_s16(inp_16x8_r1_1);
+
+ inp_16x4_r2_0 = vget_low_s16(inp_16x8_r2_0);
+ inp_16x4_r2_1 = vget_low_s16(inp_16x8_r2_1);
+ inp_16x4_r3_0 = vget_low_s16(inp_16x8_r3_0);
+ inp_16x4_r3_1 = vget_low_s16(inp_16x8_r3_1);
+
+ out_res_32x4_r0_l_0 = vmull_s16(inp_16x4_r0_0, vget_low_s16(ip_filt_16x8_r0_0));
+ out_res_32x4_r0_l_0 = vmlal_s16(out_res_32x4_r0_l_0, inp_16x4_r1_0,
+ vget_low_s16(ip_filt_16x8_r1_0));
+ out_res_32x4_r0_l_0 = vmlal_s16(out_res_32x4_r0_l_0, inp_16x4_r2_0,
+ vget_low_s16(ip_filt_16x8_r2_0));
+ out_res_32x4_r0_l_0 = vmlal_s16(out_res_32x4_r0_l_0, inp_16x4_r3_0,
+ vget_low_s16(ip_filt_16x8_r3_0));
+ out_res_32x4_r0_l_1 =
+ vmull_s16(vget_high_s16(inp_16x8_r0_0), vget_high_s16(ip_filt_16x8_r0_0));
+ out_res_32x4_r0_l_1 =
+ vmlal_s16(out_res_32x4_r0_l_1, vget_high_s16(inp_16x8_r1_0),
+ vget_high_s16(ip_filt_16x8_r1_0));
+ out_res_32x4_r0_l_1 =
+ vmlal_s16(out_res_32x4_r0_l_1, vget_high_s16(inp_16x8_r2_0),
+ vget_high_s16(ip_filt_16x8_r2_0));
+ out_res_32x4_r0_l_1 =
+ vmlal_s16(out_res_32x4_r0_l_1, vget_high_s16(inp_16x8_r3_0),
+ vget_high_s16(ip_filt_16x8_r3_0));
+
+ out_res_32x4_r0_h_0 = vmull_s16(inp_16x4_r0_1, vget_low_s16(ip_filt_16x8_r0_1));
+ out_res_32x4_r0_h_0 = vmlal_s16(out_res_32x4_r0_h_0, inp_16x4_r1_1,
+ vget_low_s16(ip_filt_16x8_r1_1));
+ out_res_32x4_r0_h_0 = vmlal_s16(out_res_32x4_r0_h_0, inp_16x4_r2_1,
+ vget_low_s16(ip_filt_16x8_r2_1));
+ out_res_32x4_r0_h_0 = vmlal_s16(out_res_32x4_r0_h_0, inp_16x4_r3_1,
+ vget_low_s16(ip_filt_16x8_r3_1));
+
+ out_res_32x4_r0_h_1 =
+ vmull_s16(vget_high_s16(inp_16x8_r0_1), vget_high_s16(ip_filt_16x8_r0_1));
+ out_res_32x4_r0_h_1 =
+ vmlal_s16(out_res_32x4_r0_h_1, vget_high_s16(inp_16x8_r1_1),
+ vget_high_s16(ip_filt_16x8_r1_1));
+ out_res_32x4_r0_h_1 =
+ vmlal_s16(out_res_32x4_r0_h_1, vget_high_s16(inp_16x8_r2_1),
+ vget_high_s16(ip_filt_16x8_r2_1));
+ out_res_32x4_r0_h_1 =
+ vmlal_s16(out_res_32x4_r0_h_1, vget_high_s16(inp_16x8_r3_1),
+ vget_high_s16(ip_filt_16x8_r3_1));
+
+ out_res_16x4_r0_l_0 = vqrshrun_n_s32(out_res_32x4_r0_l_0, 10);
+ out_res_16x4_r0_l_1 = vqrshrun_n_s32(out_res_32x4_r0_l_1, 10);
+ out_res_16x4_r0_h_0 = vqrshrun_n_s32(out_res_32x4_r0_h_0, 10);
+ out_res_16x4_r0_h_1 = vqrshrun_n_s32(out_res_32x4_r0_h_1, 10);
+
+ out_res_8x8_r0_l =
+ vqmovn_u16(vcombine_u16(out_res_16x4_r0_l_0, out_res_16x4_r0_l_1));
+ out_res_8x8_r0_h =
+ vqmovn_u16(vcombine_u16(out_res_16x4_r0_h_0, out_res_16x4_r0_h_1));
+ vst1q_u8((pu1_out + (i4_y * i4_out_stride)),
+ vcombine_u8(out_res_8x8_r0_l, out_res_8x8_r0_h));
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_ref_pos_luma[i4_y] = (UWORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos;
+ arr_phase_luma[i4_y] = (UWORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ }
+ pi4_y_ref_pos_luma = arr_y_ref_pos_luma;
+ pi4_phase_luma = arr_phase_luma;
+
+ {
+ uint8x8_t inp_8x8_r0, inp_8x8_r0_1;
+ uint8x8_t inp_8x8_r1, inp_8x8_r1_1;
+ int16x8_t out_res_16x8_r0_0, out_res_16x8_r0_1;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ pu1_refarray_temp =
+ pu1_refarray + (pi4_y_ref_pos_luma[i4_y] * i4_refarray_wd) + (i4_x_min - 1);
+ inp_8x8_r0 = vld1_u8((pu1_refarray_temp));
+ inp_8x8_r1 = vld1_u8((pu1_refarray_temp + i4_refarray_wd));
+
+ inp_8x8_r0_1 = vld1_u8((pu1_refarray_temp + 8));
+ inp_8x8_r1_1 = vld1_u8((pu1_refarray_temp + 8 + i4_refarray_wd));
+
+ out_res_16x8_r0_0 = vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r0)),
+ g_au1_interp_filter_chroma[pi4_phase_luma[i4_y]]);
+ out_res_16x8_r0_0 =
+ vmlaq_n_s16(out_res_16x8_r0_0, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r1)),
+ g_au1_interp_filter_chroma[pi4_phase_luma[i4_y] + 16]);
+
+ out_res_16x8_r0_1 = vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r0_1)),
+ g_au1_interp_filter_chroma[pi4_phase_luma[i4_y]]);
+ out_res_16x8_r0_1 =
+ vmlaq_n_s16(out_res_16x8_r0_1, vreinterpretq_s16_u16(vmovl_u8(inp_8x8_r1_1)),
+ g_au1_interp_filter_chroma[pi4_phase_luma[i4_y] + 16]);
+
+ vst1q_s16((pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1)),
+ out_res_16x8_r0_0);
+ vst1q_s16((pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1) + 8),
+ out_res_16x8_r0_1);
+ }
+ }
+
+ {
+ WORD32 strt_indx = 10;
+
+ uint8x16_t phs_mask_8x8_0;
+ uint8x16_t x_ref_pos_luma_mask_r0_0;
+ uint8x16_t x_ref_pos_luma_mask_r1_0;
+
+ WORD32 i4_x2 = 0;
+ uint8x16_t twos = vdupq_n_u8(2);
+ strt_indx = ps_x_pos_phase[0 + i4_frm_mb_x].i2_ref_pos;
+
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos_luma[i4_x] = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_phase_luma[i4_x] = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ arr_x_ref_pos_luma[i4_x] = arr_x_ref_pos_luma[i4_x] - strt_indx;
+ i4_x2 = i4_x << 1;
+ arr_x_ref_pos_luma_low[i4_x2] = (arr_x_ref_pos_luma[i4_x]) << 1;
+ arr_x_ref_pos_luma_low[i4_x2 + 1] = arr_x_ref_pos_luma_low[i4_x2] + 1;
+ }
+
+ pi4_x_ref_pos_luma_low = arr_x_ref_pos_luma_low;
+ pi4_phase_luma = arr_phase_luma;
+
+ phs_mask_8x8_0 = vld1q_u8(pi4_phase_luma);
+ x_ref_pos_luma_mask_r0_0 = vld1q_u8(pi4_x_ref_pos_luma_low);
+ x_ref_pos_luma_mask_r1_0 = vaddq_u8(x_ref_pos_luma_mask_r0_0, twos);
+
+ {
+ uint8x16_t ip_filt_8x16_r0;
+ uint8x16_t ip_filt_8x16_r1;
+ int16x8_t ip_filt_16x8_r0_0;
+ int16x8_t ip_filt_16x8_r1_0;
+ int16x8_t inp_16x8_0;
+ int16x8_t inp_16x8_r0_0;
+ int16x8_t inp_16x8_r1_0;
+ int16x4_t inp_16x4_r0_0;
+ int16x4_t inp_16x4_r1_0;
+ int32x4_t out_res_32x4_r0_l_0;
+ int32x4_t out_res_32x4_r0_l_1;
+ uint16x4_t out_res_16x4_r0_l_0;
+ uint16x4_t out_res_16x4_r0_l_1;
+ uint16x8_t out_res_16x8_r0_l;
+ uint8x16_t out_8x16_r0;
+ uint8x8x2_t u1_incr_8x8x2_t;
+ uint8x8_t u1_incr_8x8_t0, u1_incr_8x8_t1;
+ uint8x8x2_t u1_temp_8x8x2_t;
+ uint8x8_t u1_temp_8x8_t0, u1_temp_8x8_t1;
+ uint8x16_t chroma_mask_8x16 = vreinterpretq_u8_u16(vdupq_n_u16(0x00ff));
+
+ ip_filt_8x16_r0 = vld1q_u8((g_au1_interp_filter_chroma));
+ ip_filt_8x16_r1 = vld1q_u8((g_au1_interp_filter_chroma + 16));
+
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(ip_filt_8x16_r0);
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(ip_filt_8x16_r0);
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(ip_filt_8x16_r1);
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(ip_filt_8x16_r1);
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(phs_mask_8x8_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(phs_mask_8x8_0));
+ ip_filt_8x16_r1 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ ip_filt_16x8_r0_0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(ip_filt_8x16_r0)));
+ ip_filt_16x8_r1_0 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(ip_filt_8x16_r1)));
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ inp_16x8_0 = vld1q_s16((pi2_interp_buff_temp + strt_indx));
+ pi2_interp_buff_temp += i4_refarray_wd;
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r0_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r0_0));
+ inp_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(inp_16x8_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_luma_mask_r1_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_luma_mask_r1_0));
+ inp_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+ inp_16x4_r0_0 = vget_low_s16(inp_16x8_r0_0);
+ inp_16x4_r1_0 = vget_low_s16(inp_16x8_r1_0);
+
+ out_res_32x4_r0_l_0 = vmull_s16(inp_16x4_r0_0, vget_low_s16(ip_filt_16x8_r0_0));
+ out_res_32x4_r0_l_0 = vmlal_s16(out_res_32x4_r0_l_0, inp_16x4_r1_0,
+ vget_low_s16(ip_filt_16x8_r1_0));
+ out_res_32x4_r0_l_1 =
+ vmull_s16(vget_high_s16(inp_16x8_r0_0), vget_high_s16(ip_filt_16x8_r0_0));
+ out_res_32x4_r0_l_1 =
+ vmlal_s16(out_res_32x4_r0_l_1, vget_high_s16(inp_16x8_r1_0),
+ vget_high_s16(ip_filt_16x8_r1_0));
+
+ out_res_16x4_r0_l_0 = vqrshrun_n_s32(out_res_32x4_r0_l_0, 10);
+ out_res_16x4_r0_l_1 = vqrshrun_n_s32(out_res_32x4_r0_l_1, 10);
+ out_res_16x8_r0_l = vcombine_u16(out_res_16x4_r0_l_0, out_res_16x4_r0_l_1);
+ out_8x16_r0 = vld1q_u8(pu1_out + (i4_y * i4_out_stride));
+ out_8x16_r0 = vbslq_u8(chroma_mask_8x16,
+ vreinterpretq_u8_u16(out_res_16x8_r0_l), out_8x16_r0);
+ vst1q_u8((pu1_out + (i4_y * i4_out_stride)), out_8x16_r0);
+ }
+ }
+ }
+ }
+ return;
+} /* End of Interpolation Function */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_1_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* interpolation of a component to find the intra */
+/* resampled value */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* pu1_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation on horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_horz_interpol_chroma_dyadic_1_neonintr(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ int16x8_t i4_samp_horz_16x8_r0_0, i4_samp_horz_16x8_r0_1, i4_samp_horz_16x8_r0_2;
+ int16x8_t i4_samp_horz_16x8_r1_0, i4_samp_horz_16x8_r1_1, i4_samp_horz_16x8_r1_2;
+ int16x8_t i4_rslt_horz_r0_1, i4_rslt_horz_r0_2;
+ int16x8_t i4_rslt_horz_r1_1, i4_rslt_horz_r1_2;
+
+ int16x8_t final_horz_16x8_r0_1;
+ int16x8_t final_horz_16x8_r1_1;
+
+ uint8x16_t i4_out_horz_8x16_r0, i4_out_horz_8x16_r1;
+ uint8x16_t chroma_mask_8x16 = vreinterpretq_u8_u16(vdupq_n_u16(0x00ff));
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_horz_16x8_r0_0 = vld1q_s16(pi2_tmp); // a0 a1 a2 a3 a4 a5 a6 a7
+ i4_samp_horz_16x8_r0_1 = vld1q_s16(pi2_tmp + 1); // a1 a2 a3 a4
+ i4_samp_horz_16x8_r0_2 = vld1q_s16(pi2_tmp + 2); // a2 a3 a4 a5
+
+ i4_samp_horz_16x8_r1_0 = vld1q_s16(pi2_tmp + i4_filt_stride);
+ i4_samp_horz_16x8_r1_1 = vld1q_s16(pi2_tmp + i4_filt_stride + 1);
+ i4_samp_horz_16x8_r1_2 = vld1q_s16(pi2_tmp + (i4_filt_stride + 2));
+
+ i4_rslt_horz_r0_1 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_0, i4_coeff_0); // a0c0 a1c0 a2c0 a3c0
+
+ i4_rslt_horz_r0_2 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_1, i4_coeff_2); // a1c2 a2c2 a3c2 a4c2
+ i4_rslt_horz_r0_1 = vmlaq_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x8_r0_1,
+ i4_coeff_1); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+
+ i4_rslt_horz_r0_2 = vmlaq_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x8_r0_2,
+ i4_coeff_3); // a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3
+
+ i4_rslt_horz_r1_1 = vmulq_n_s16(i4_samp_horz_16x8_r1_0, i4_coeff_0);
+ i4_rslt_horz_r1_2 = vmulq_n_s16(i4_samp_horz_16x8_r1_1, i4_coeff_2);
+
+ i4_rslt_horz_r1_1 = vmlaq_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x8_r1_1, i4_coeff_1);
+ i4_rslt_horz_r1_2 = vmlaq_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x8_r1_2, i4_coeff_3);
+
+ final_horz_16x8_r0_1 = vzipq_s16(i4_rslt_horz_r0_1, i4_rslt_horz_r0_2).val[0];
+ final_horz_16x8_r1_1 = vzipq_s16(i4_rslt_horz_r1_1, i4_rslt_horz_r1_2).val[0];
+
+ final_horz_16x8_r0_1 = vrshrq_n_s16(final_horz_16x8_r0_1, 6);
+
+ final_horz_16x8_r1_1 = vrshrq_n_s16(final_horz_16x8_r1_1, 6);
+
+ i4_out_horz_8x16_r0 = vld1q_u8(pu1_out);
+ i4_out_horz_8x16_r1 = vld1q_u8(pu1_out + i4_dst_stride);
+
+ i4_out_horz_8x16_r0 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r0_1),
+ i4_out_horz_8x16_r0);
+ i4_out_horz_8x16_r1 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r1_1),
+ i4_out_horz_8x16_r1);
+
+ vst1q_u8(pu1_out, i4_out_horz_8x16_r0);
+ vst1q_u8(pu1_out + i4_dst_stride, i4_out_horz_8x16_r1);
+
+ /* Incrementing ptr */
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_out += (i4_dst_stride << 1);
+
+ } /* End of loop over y */
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_2_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* 0 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_horz_interpol_chroma_dyadic_2_neonintr(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ int16x8_t i4_samp_horz_16x8_r0_0, i4_samp_horz_16x8_r0_1;
+ int16x8_t i4_samp_horz_16x8_r1_0, i4_samp_horz_16x8_r1_1;
+ int16x8_t i4_rslt_horz_r0_1, i4_rslt_horz_r0_2;
+ int16x8_t i4_rslt_horz_r1_1, i4_rslt_horz_r1_2;
+
+ int16x8_t final_horz_16x8_r0_1;
+ int16x8_t final_horz_16x8_r1_1;
+
+ uint8x16_t i4_out_horz_8x16_r0, i4_out_horz_8x16_r1;
+ uint8x16_t chroma_mask_8x16 = vreinterpretq_u8_u16(vdupq_n_u16(0x00ff));
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf + 1;
+ i4_filt_stride = 6;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_horz_16x8_r0_0 = vld1q_s16(pi2_tmp); // a0 a1 a2 a3 a4 a5 a6 a7
+ i4_samp_horz_16x8_r0_1 = vld1q_s16(pi2_tmp + 1); // a1 a2 a3 a4
+
+ i4_samp_horz_16x8_r1_0 = vld1q_s16(pi2_tmp + i4_filt_stride);
+ i4_samp_horz_16x8_r1_1 = vld1q_s16(pi2_tmp + i4_filt_stride + 1);
+
+ i4_rslt_horz_r0_1 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_0, i4_coeff_0); // a0c0 a1c0 a2c0 a3c0
+
+ i4_rslt_horz_r0_2 =
+ vmulq_n_s16(i4_samp_horz_16x8_r0_0, i4_coeff_2); // a1c2 a2c2 a3c2 a4c2
+ i4_rslt_horz_r0_1 = vmlaq_n_s16(i4_rslt_horz_r0_1, i4_samp_horz_16x8_r0_1,
+ i4_coeff_1); // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+
+ i4_rslt_horz_r0_2 = vmlaq_n_s16(i4_rslt_horz_r0_2, i4_samp_horz_16x8_r0_1,
+ i4_coeff_3); // a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3
+
+ i4_rslt_horz_r1_1 = vmulq_n_s16(i4_samp_horz_16x8_r1_0, i4_coeff_0);
+ i4_rslt_horz_r1_2 = vmulq_n_s16(i4_samp_horz_16x8_r1_0, i4_coeff_2);
+
+ i4_rslt_horz_r1_1 = vmlaq_n_s16(i4_rslt_horz_r1_1, i4_samp_horz_16x8_r1_1, i4_coeff_1);
+ i4_rslt_horz_r1_2 = vmlaq_n_s16(i4_rslt_horz_r1_2, i4_samp_horz_16x8_r1_1, i4_coeff_3);
+
+ final_horz_16x8_r0_1 = vzipq_s16(i4_rslt_horz_r0_1, i4_rslt_horz_r0_2).val[0];
+ final_horz_16x8_r1_1 = vzipq_s16(i4_rslt_horz_r1_1, i4_rslt_horz_r1_2).val[0];
+
+ final_horz_16x8_r0_1 = vrshrq_n_s16(final_horz_16x8_r0_1, 6);
+
+ final_horz_16x8_r1_1 = vrshrq_n_s16(final_horz_16x8_r1_1, 6);
+
+ i4_out_horz_8x16_r0 = vld1q_u8(pu1_out);
+ i4_out_horz_8x16_r1 = vld1q_u8(pu1_out + i4_dst_stride);
+
+ i4_out_horz_8x16_r0 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r0_1),
+ i4_out_horz_8x16_r0);
+ i4_out_horz_8x16_r1 = vbslq_u8(chroma_mask_8x16, vreinterpretq_u8_s16(final_horz_16x8_r1_1),
+ i4_out_horz_8x16_r1);
+
+ vst1q_u8(pu1_out, i4_out_horz_8x16_r0);
+ vst1q_u8(pu1_out + i4_dst_stride, i4_out_horz_8x16_r1);
+
+ /* Incrementing ptr */
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_out += (i4_dst_stride << 1);
+
+ } /* End of loop over y */
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_1_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_1_neonintr(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ uint8x8_t i4_samp_vert_8x8_r0, i4_samp_vert_8x8_r1, i4_samp_vert_8x8_r2;
+ uint8x8_t i4_samp_vert_8x8_r3, i4_samp_vert_8x8_r4, i4_samp_vert_8x8_r5;
+ int16x8_t i4_rslt_vert_16x8_r0, i4_rslt_vert_16x8_r1, i4_rslt_vert_16x8_r2,
+ i4_rslt_vert_16x8_r3;
+ int16x8_t i4_rslt_vert_16x8_r4, i4_rslt_vert_16x8_r5, i4_rslt_vert_16x8_r6,
+ i4_rslt_vert_16x8_r7;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ /* Vertical interpolation */
+ i4_samp_vert_8x8_r0 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r1 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r2 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r3 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r4 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r5 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ i4_rslt_vert_16x8_r0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_0);
+ i4_rslt_vert_16x8_r0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_1);
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_r0);
+
+ i4_rslt_vert_16x8_r1 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_2);
+ i4_rslt_vert_16x8_r1 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r1, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 6, i4_rslt_vert_16x8_r1);
+
+ i4_rslt_vert_16x8_r2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_0);
+ i4_rslt_vert_16x8_r2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 12, i4_rslt_vert_16x8_r2);
+
+ i4_rslt_vert_16x8_r3 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_2);
+ i4_rslt_vert_16x8_r3 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r3, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 18, i4_rslt_vert_16x8_r3);
+
+ i4_rslt_vert_16x8_r4 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_0);
+ i4_rslt_vert_16x8_r4 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r4, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 24, i4_rslt_vert_16x8_r4);
+
+ i4_rslt_vert_16x8_r5 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_2);
+ i4_rslt_vert_16x8_r5 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r5, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 30, i4_rslt_vert_16x8_r5);
+
+ i4_rslt_vert_16x8_r6 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_0);
+ i4_rslt_vert_16x8_r6 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r6, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 36, i4_rslt_vert_16x8_r6);
+
+ i4_rslt_vert_16x8_r7 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_2);
+ i4_rslt_vert_16x8_r7 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r7, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r5)), i4_coeff_3);
+ vst1_s16(pi2_tmp + 42, vget_low_s16(i4_rslt_vert_16x8_r7));
+ vst1q_lane_s16(pi2_tmp + 46, i4_rslt_vert_16x8_r7, 4);
+ vst1q_lane_s16(pi2_tmp + 47, i4_rslt_vert_16x8_r7, 5);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_2_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_2_neonintr(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ uint8x8_t i4_samp_vert_8x8_r0, i4_samp_vert_8x8_r1, i4_samp_vert_8x8_r2, i4_samp_vert_8x8_r3;
+ uint8x8_t i4_samp_vert_8x8_r4;
+ int16x8_t i4_rslt_vert_16x8_r0, i4_rslt_vert_16x8_r1, i4_rslt_vert_16x8_r2,
+ i4_rslt_vert_16x8_r3;
+ int16x8_t i4_rslt_vert_16x8_r4, i4_rslt_vert_16x8_r5, i4_rslt_vert_16x8_r6,
+ i4_rslt_vert_16x8_r7;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+
+ /* Vertical interpolation */
+ i4_samp_vert_8x8_r0 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r1 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r2 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r3 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r4 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase = phase_0 for y = 0 */
+ i4_rslt_vert_16x8_r0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_0);
+ i4_rslt_vert_16x8_r0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_1);
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_r0);
+
+ i4_rslt_vert_16x8_r1 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_2);
+ i4_rslt_vert_16x8_r1 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r1, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 6, i4_rslt_vert_16x8_r1);
+
+ i4_rslt_vert_16x8_r2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_0);
+ i4_rslt_vert_16x8_r2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 12, i4_rslt_vert_16x8_r2);
+
+ i4_rslt_vert_16x8_r3 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_2);
+ i4_rslt_vert_16x8_r3 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r3, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 18, i4_rslt_vert_16x8_r3);
+
+ i4_rslt_vert_16x8_r4 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_0);
+ i4_rslt_vert_16x8_r4 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r4, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 24, i4_rslt_vert_16x8_r4);
+
+ i4_rslt_vert_16x8_r5 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_2);
+ i4_rslt_vert_16x8_r5 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r5, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 30, i4_rslt_vert_16x8_r5);
+
+ i4_rslt_vert_16x8_r6 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_0);
+ i4_rslt_vert_16x8_r6 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r6, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 36, i4_rslt_vert_16x8_r6);
+
+ i4_rslt_vert_16x8_r7 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_2);
+ i4_rslt_vert_16x8_r7 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r7, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_3);
+ vst1_s16(pi2_tmp + 42, vget_low_s16(i4_rslt_vert_16x8_r7));
+
+ vst1q_lane_s16(pi2_tmp + 46, i4_rslt_vert_16x8_r7, 4);
+ vst1q_lane_s16(pi2_tmp + 47, i4_rslt_vert_16x8_r7, 5);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_3_neonintr */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_3_neonintr(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ uint8x8_t i4_samp_vert_8x8_r0, i4_samp_vert_8x8_r1, i4_samp_vert_8x8_r2;
+ uint8x8_t i4_samp_vert_8x8_r3, i4_samp_vert_8x8_r4;
+ int16x8_t i4_rslt_vert_16x8_r0, i4_rslt_vert_16x8_r1, i4_rslt_vert_16x8_r2,
+ i4_rslt_vert_16x8_r3;
+ int16x8_t i4_rslt_vert_16x8_r4, i4_rslt_vert_16x8_r5, i4_rslt_vert_16x8_r6,
+ i4_rslt_vert_16x8_r7;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf;
+
+ /* Vertical interpolation */
+ /* y = 0, y_phase = phase_0 */
+ i4_samp_vert_8x8_r0 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r1 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r2 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r3 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+ i4_samp_vert_8x8_r4 = vld1_u8(pu1_inp);
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase = phase_0 for y = 0 */
+ i4_rslt_vert_16x8_r0 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_0);
+ i4_rslt_vert_16x8_r0 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r0, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_1);
+ vst1q_s16(pi2_tmp, i4_rslt_vert_16x8_r0);
+
+ i4_rslt_vert_16x8_r1 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r0)), i4_coeff_2);
+ i4_rslt_vert_16x8_r1 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r1, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 6, i4_rslt_vert_16x8_r1);
+
+ i4_rslt_vert_16x8_r2 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_0);
+ i4_rslt_vert_16x8_r2 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r2, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 12, i4_rslt_vert_16x8_r2);
+
+ i4_rslt_vert_16x8_r3 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r1)), i4_coeff_2);
+ i4_rslt_vert_16x8_r3 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r3, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 18, i4_rslt_vert_16x8_r3);
+
+ i4_rslt_vert_16x8_r4 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_0);
+ i4_rslt_vert_16x8_r4 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r4, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 24, i4_rslt_vert_16x8_r4);
+
+ i4_rslt_vert_16x8_r5 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r2)), i4_coeff_2);
+ i4_rslt_vert_16x8_r5 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r5, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_3);
+ vst1q_s16(pi2_tmp + 30, i4_rslt_vert_16x8_r5);
+
+ i4_rslt_vert_16x8_r6 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_0);
+ i4_rslt_vert_16x8_r6 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r6, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_1);
+ vst1q_s16(pi2_tmp + 36, i4_rslt_vert_16x8_r6);
+
+ i4_rslt_vert_16x8_r7 =
+ vmulq_n_s16(vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r3)), i4_coeff_2);
+ i4_rslt_vert_16x8_r7 = vmlaq_n_s16(
+ i4_rslt_vert_16x8_r7, vreinterpretq_s16_u16(vmovl_u8(i4_samp_vert_8x8_r4)), i4_coeff_3);
+ vst1_s16(pi2_tmp + 42, vget_low_s16(i4_rslt_vert_16x8_r7));
+
+ vst1q_lane_s16(pi2_tmp + 46, i4_rslt_vert_16x8_r7, 4);
+ vst1q_lane_s16(pi2_tmp + 47, i4_rslt_vert_16x8_r7, 5);
+}
diff --git a/decoder/arm/svc/isvcd_iquant_itrans_neon.c b/decoder/arm/svc/isvcd_iquant_itrans_neon.c
new file mode 100644
index 0000000..4be5e74
--- /dev/null
+++ b/decoder/arm/svc/isvcd_iquant_itrans_neon.c
@@ -0,0 +1,960 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_neonintr.c
+ *
+ * @brief
+ * Contains definition of functions for svc inverse quantization inverse
+ * transformation and resd comp
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_4x4_neonintr()
+ * - isvcd_iquant_itrans_8x8_neonintr()
+ * - isvcd_iquant_itrans_4x4_dc_neonintr()
+ * - isvcd_iquant_itrans_8x8_dc_neonintr()
+ * - isvcd_iquant_itrans_chroma_4x4_neonintr()
+ * - isvcd_iquant_itrans_chroma_4x4_dc_neonintr()
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <string.h>
+#include <arm_neon.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_4x4_dc_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0, dup_min, dup_max;
+
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_ld_addr[0];
+ }
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ temp_0 = vminq_s16(temp_0, dup_max);
+ temp_0 = vmaxq_s16(temp_0, dup_min);
+
+ vst1_s16((int16_t *) (pi2_out), vget_low_s16(temp_0));
+ vst1_s16((int16_t *) (pi2_out + out_strd), vget_high_s16(temp_0));
+ vst1_s16((int16_t *) (pi2_out + (out_strd * 2)), vget_low_s16(temp_0));
+ vst1_s16((int16_t *) (pi2_out + (out_strd * 3)), vget_high_s16(temp_0));
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_chroma_4x4_dc_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ int16x8_t temp_0, dup_max, dup_min;
+ WORD32 i4_iq_out_temp;
+
+ int16x8_t i4_out_horz_16x8_r0, i4_out_horz_16x8_r1, i4_out_horz_16x8_r2, i4_out_horz_16x8_r3;
+ uint16x8_t chroma_mask_16x8 = vreinterpretq_u16_u32(vdupq_n_u32(0x0000ffff));
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ i4_iq_out_temp = pi2_dc_src[0];
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+ temp_0 = vminq_s16(temp_0, dup_max);
+ temp_0 = vmaxq_s16(temp_0, dup_min);
+
+ i4_out_horz_16x8_r0 = vld1q_s16(pi2_out);
+ i4_out_horz_16x8_r1 = vld1q_s16(pi2_out + out_strd);
+ i4_out_horz_16x8_r2 = vld1q_s16(pi2_out + out_strd * 2);
+ i4_out_horz_16x8_r3 = vld1q_s16(pi2_out + out_strd * 3);
+
+ i4_out_horz_16x8_r0 = vbslq_s16(chroma_mask_16x8, temp_0, i4_out_horz_16x8_r0);
+ i4_out_horz_16x8_r1 = vbslq_s16(chroma_mask_16x8, temp_0, i4_out_horz_16x8_r1);
+ i4_out_horz_16x8_r2 = vbslq_s16(chroma_mask_16x8, temp_0, i4_out_horz_16x8_r2);
+ i4_out_horz_16x8_r3 = vbslq_s16(chroma_mask_16x8, temp_0, i4_out_horz_16x8_r3);
+
+ vst1q_s16((int16_t *) (pi2_out), i4_out_horz_16x8_r0);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), i4_out_horz_16x8_r1);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 2), i4_out_horz_16x8_r2);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 3), i4_out_horz_16x8_r3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_8x8_dc_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_8x8_dc_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ int16x8_t dup_max, dup_min;
+
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ i4_iq_out_temp = pi2_src[0];
+
+ INV_QUANT(i4_iq_out_temp, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+ temp_0 = vminq_s16(temp_0, dup_max);
+ temp_0 = vmaxq_s16(temp_0, dup_min);
+
+ vst1q_s16((int16_t *) (pi2_out), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 2)), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 3)), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 4)), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 5)), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 6)), temp_0);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 7)), temp_0);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_chroma_4x4_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+ int16x4_t zero_16x4 = vdup_n_s16(0);
+ int16x4_t x_16x4_low, x_16x4_high;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x4_t dup_max, dup_min;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2, x_16x4x2_t;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+ int16x8_t i4_out_horz_16x8_r0, i4_out_horz_16x8_r1, i4_out_horz_16x8_r2, i4_out_horz_16x8_r3;
+ uint16x8_t chroma_mask_16x8 = vreinterpretq_u16_u32(vdupq_n_u32(0x0000ffff));
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ dup_min = vdup_n_s16(RSD_MIN);
+ dup_max = vdup_n_s16(RSD_MAX);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ x0_16x4 = vmin_s16(x0_16x4, dup_max);
+ x0_16x4 = vmax_s16(x0_16x4, dup_min);
+ x1_16x4 = vmin_s16(x1_16x4, dup_max);
+ x1_16x4 = vmax_s16(x1_16x4, dup_min);
+ x2_16x4 = vmin_s16(x2_16x4, dup_max);
+ x2_16x4 = vmax_s16(x2_16x4, dup_min);
+ x3_16x4 = vmin_s16(x3_16x4, dup_max);
+ x3_16x4 = vmax_s16(x3_16x4, dup_min);
+
+ x_16x4x2_t = vzip_s16(x0_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x0_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x1_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x1_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x2_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x2_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x3_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x3_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ i4_out_horz_16x8_r0 = vld1q_s16(pi2_out);
+ i4_out_horz_16x8_r1 = vld1q_s16(pi2_out + out_strd);
+ i4_out_horz_16x8_r2 = vld1q_s16(pi2_out + out_strd * 2);
+ i4_out_horz_16x8_r3 = vld1q_s16(pi2_out + out_strd * 3);
+
+ i4_out_horz_16x8_r0 = vbslq_s16(chroma_mask_16x8, x0_16x8, i4_out_horz_16x8_r0);
+ i4_out_horz_16x8_r1 = vbslq_s16(chroma_mask_16x8, x1_16x8, i4_out_horz_16x8_r1);
+ i4_out_horz_16x8_r2 = vbslq_s16(chroma_mask_16x8, x2_16x8, i4_out_horz_16x8_r2);
+ i4_out_horz_16x8_r3 = vbslq_s16(chroma_mask_16x8, x3_16x8, i4_out_horz_16x8_r3);
+
+ vst1q_s16((int16_t *) (pi2_out), i4_out_horz_16x8_r0);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), i4_out_horz_16x8_r1);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 2), i4_out_horz_16x8_r2);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 3), i4_out_horz_16x8_r3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_8x8_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_8x8_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ int16x8_t iscal_16x8_0, iscal_16x8_1, iscal_16x8_2, iscal_16x8_3, iscal_16x8_4, iscal_16x8_5,
+ iscal_16x8_6, iscal_16x8_7;
+
+ int16x8_t weigh_16x8_0, weigh_16x8_1, weigh_16x8_2, weigh_16x8_3, weigh_16x8_4, weigh_16x8_5,
+ weigh_16x8_6, weigh_16x8_7;
+
+ int16x8_t src_16x8_0, src_16x8_1, src_16x8_2, src_16x8_3, src_16x8_4, src_16x8_5, src_16x8_6,
+ src_16x8_7;
+ int16x8_t coeff_mul_16x8_0, coeff_mul_16x8_1, coeff_mul_16x8_2, coeff_mul_16x8_3,
+ coeff_mul_16x8_4, coeff_mul_16x8_5, coeff_mul_16x8_6, coeff_mul_16x8_7;
+
+ int32x4_t quant_res_32x4_l_0, quant_res_32x4_l_1, quant_res_32x4_l_2, quant_res_32x4_l_3,
+ quant_res_32x4_l_4, quant_res_32x4_l_5, quant_res_32x4_l_6, quant_res_32x4_l_7;
+ int32x4_t quant_res_32x4_h_0, quant_res_32x4_h_1, quant_res_32x4_h_2, quant_res_32x4_h_3,
+ quant_res_32x4_h_4, quant_res_32x4_h_5, quant_res_32x4_h_6, quant_res_32x4_h_7;
+ int16x4_t quant_res_16x4_l_0, quant_res_16x4_l_1, quant_res_16x4_l_2, quant_res_16x4_l_3,
+ quant_res_16x4_l_4, quant_res_16x4_l_5, quant_res_16x4_l_6, quant_res_16x4_l_7;
+ int16x4_t quant_res_16x4_h_0, quant_res_16x4_h_1, quant_res_16x4_h_2, quant_res_16x4_h_3,
+ quant_res_16x4_h_4, quant_res_16x4_h_5, quant_res_16x4_h_6, quant_res_16x4_h_7;
+
+ int16x8_t quant_res_16x8_0, quant_res_16x8_1, quant_res_16x8_2, quant_res_16x8_3,
+ quant_res_16x8_4, quant_res_16x8_5, quant_res_16x8_6, quant_res_16x8_7;
+
+ int16x8_t trans_16x8_0, trans_16x8_1, trans_16x8_2, trans_16x8_3, trans_16x8_4, trans_16x8_5,
+ trans_16x8_6, trans_16x8_7;
+ int32x4_t trans_32x4_0, trans_32x4_1, trans_32x4_2, trans_32x4_3, trans_32x4_4, trans_32x4_5,
+ trans_32x4_6, trans_32x4_7;
+ int64x2_t trans_64x2_0, trans_64x2_1, trans_64x2_2, trans_64x2_3, trans_64x2_4, trans_64x2_5,
+ trans_64x2_6, trans_64x2_7;
+ int16x4_t trans_16x4_1_l, trans_16x4_3_l, trans_16x4_5_l, trans_16x4_7_l;
+ int16x8_t rs_trans_16x8_1, rs_trans_16x8_2, rs_trans_16x8_3, rs_trans_16x8_5, rs_trans_16x8_6,
+ rs_trans_16x8_7;
+ int32x4_t sub_3_5_l, sub_3_5_h;
+ int32x4_t add_3_5_l, add_3_5_h;
+ int32x4_t sub_1_7_l, sub_1_7_h;
+ int32x4_t add_1_7_l, add_1_7_h;
+ int32x4_t sub_357_l, sub_357_h;
+ int32x4_t add_351_l, add_351_h;
+ int32x4_t add_175_l, add_175_h;
+ int32x4_t sub_173_l, sub_173_h;
+ int32x4_t y1_32x4_l, y1_32x4_h;
+ int32x4_t y3_32x4_l, y3_32x4_h;
+ int32x4_t y5_32x4_l, y5_32x4_h;
+ int32x4_t y7_32x4_l, y7_32x4_h;
+ int16x4_t y1_16x4_l, y3_16x4_l, y5_16x4_l, y7_16x4_l;
+ int16x4_t y1_16x4_h, y3_16x4_h, y5_16x4_h, y7_16x4_h;
+
+ int16x8_t y0_16x8, y1_16x8, y2_16x8, y3_16x8, y4_16x8, y5_16x8, y6_16x8, y7_16x8;
+ int16x8_t rs_y1_16x8, rs_y3_16x8, rs_y5_16x8, rs_y7_16x8;
+ int16x8_t z0_16x8, z1_16x8, z2_16x8, z3_16x8, z4_16x8, z5_16x8, z6_16x8, z7_16x8;
+ int16x8_t dup_max, dup_min;
+ int32x4_t qp_div_32x4 = vdupq_n_s32(qp_div);
+ int16x8x2_t trans_16x8_0_1, trans_16x8_2_3, trans_16x8_4_5, trans_16x8_6_7;
+ int32x4x2_t trans_32x4_0_2, trans_32x4_1_3, trans_32x4_4_6, trans_32x4_5_7;
+ WORD32 i;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ iscal_16x8_0 = vld1q_s16((const int16_t *) pu2_iscale_mat);
+ iscal_16x8_1 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 8));
+ iscal_16x8_2 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 16));
+ iscal_16x8_3 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 24));
+ iscal_16x8_4 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 32));
+ iscal_16x8_5 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 40));
+ iscal_16x8_6 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 48));
+ iscal_16x8_7 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 56));
+
+ weigh_16x8_0 = vld1q_s16((const int16_t *) pu2_weigh_mat);
+ weigh_16x8_1 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 8));
+ weigh_16x8_2 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 16));
+ weigh_16x8_3 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 24));
+ weigh_16x8_4 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 32));
+ weigh_16x8_5 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 40));
+ weigh_16x8_6 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 48));
+ weigh_16x8_7 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 56));
+
+ src_16x8_0 = vld1q_s16((const int16_t *) pi2_src); // a0 a1 a2 a3 a4 a5 a6 a7
+ src_16x8_1 = vld1q_s16((const int16_t *) (pi2_src + 8)); // b0 b1 b2 b3 b4 b5 b6 b7
+ src_16x8_2 = vld1q_s16((const int16_t *) (pi2_src + 16));
+ src_16x8_3 = vld1q_s16((const int16_t *) (pi2_src + 24));
+ src_16x8_4 = vld1q_s16((const int16_t *) (pi2_src + 32));
+ src_16x8_5 = vld1q_s16((const int16_t *) (pi2_src + 40));
+ src_16x8_6 = vld1q_s16((const int16_t *) (pi2_src + 48));
+ src_16x8_7 = vld1q_s16((const int16_t *) (pi2_src + 56));
+
+ coeff_mul_16x8_0 = vmulq_s16(iscal_16x8_0, weigh_16x8_0);
+ coeff_mul_16x8_1 = vmulq_s16(iscal_16x8_1, weigh_16x8_1);
+ coeff_mul_16x8_2 = vmulq_s16(iscal_16x8_2, weigh_16x8_2);
+ coeff_mul_16x8_3 = vmulq_s16(iscal_16x8_3, weigh_16x8_3);
+ coeff_mul_16x8_4 = vmulq_s16(iscal_16x8_4, weigh_16x8_4);
+ coeff_mul_16x8_5 = vmulq_s16(iscal_16x8_5, weigh_16x8_5);
+ coeff_mul_16x8_6 = vmulq_s16(iscal_16x8_6, weigh_16x8_6);
+ coeff_mul_16x8_7 = vmulq_s16(iscal_16x8_7, weigh_16x8_7);
+
+ quant_res_32x4_l_0 = vmull_s16(vget_low_s16(coeff_mul_16x8_0), vget_low_s16(src_16x8_0));
+ quant_res_32x4_l_1 = vmull_s16(vget_low_s16(coeff_mul_16x8_1), vget_low_s16(src_16x8_1));
+ quant_res_32x4_l_2 = vmull_s16(vget_low_s16(coeff_mul_16x8_2), vget_low_s16(src_16x8_2));
+ quant_res_32x4_l_3 = vmull_s16(vget_low_s16(coeff_mul_16x8_3), vget_low_s16(src_16x8_3));
+ quant_res_32x4_l_4 = vmull_s16(vget_low_s16(coeff_mul_16x8_4), vget_low_s16(src_16x8_4));
+ quant_res_32x4_l_5 = vmull_s16(vget_low_s16(coeff_mul_16x8_5), vget_low_s16(src_16x8_5));
+ quant_res_32x4_l_6 = vmull_s16(vget_low_s16(coeff_mul_16x8_6), vget_low_s16(src_16x8_6));
+ quant_res_32x4_l_7 = vmull_s16(vget_low_s16(coeff_mul_16x8_7), vget_low_s16(src_16x8_7));
+
+ quant_res_32x4_h_0 = vmull_s16(vget_high_s16(coeff_mul_16x8_0), vget_high_s16(src_16x8_0));
+ quant_res_32x4_h_1 = vmull_s16(vget_high_s16(coeff_mul_16x8_1), vget_high_s16(src_16x8_1));
+ quant_res_32x4_h_2 = vmull_s16(vget_high_s16(coeff_mul_16x8_2), vget_high_s16(src_16x8_2));
+ quant_res_32x4_h_3 = vmull_s16(vget_high_s16(coeff_mul_16x8_3), vget_high_s16(src_16x8_3));
+ quant_res_32x4_h_4 = vmull_s16(vget_high_s16(coeff_mul_16x8_4), vget_high_s16(src_16x8_4));
+ quant_res_32x4_h_5 = vmull_s16(vget_high_s16(coeff_mul_16x8_5), vget_high_s16(src_16x8_5));
+ quant_res_32x4_h_6 = vmull_s16(vget_high_s16(coeff_mul_16x8_6), vget_high_s16(src_16x8_6));
+ quant_res_32x4_h_7 = vmull_s16(vget_high_s16(coeff_mul_16x8_7), vget_high_s16(src_16x8_7));
+
+ quant_res_32x4_l_0 = vshlq_s32(quant_res_32x4_l_0, qp_div_32x4);
+ quant_res_32x4_l_1 = vshlq_s32(quant_res_32x4_l_1, qp_div_32x4);
+ quant_res_32x4_l_2 = vshlq_s32(quant_res_32x4_l_2, qp_div_32x4);
+ quant_res_32x4_l_3 = vshlq_s32(quant_res_32x4_l_3, qp_div_32x4);
+ quant_res_32x4_l_4 = vshlq_s32(quant_res_32x4_l_4, qp_div_32x4);
+ quant_res_32x4_l_5 = vshlq_s32(quant_res_32x4_l_5, qp_div_32x4);
+ quant_res_32x4_l_6 = vshlq_s32(quant_res_32x4_l_6, qp_div_32x4);
+ quant_res_32x4_l_7 = vshlq_s32(quant_res_32x4_l_7, qp_div_32x4);
+
+ quant_res_32x4_h_0 = vshlq_s32(quant_res_32x4_h_0, qp_div_32x4);
+ quant_res_32x4_h_1 = vshlq_s32(quant_res_32x4_h_1, qp_div_32x4);
+ quant_res_32x4_h_2 = vshlq_s32(quant_res_32x4_h_2, qp_div_32x4);
+ quant_res_32x4_h_3 = vshlq_s32(quant_res_32x4_h_3, qp_div_32x4);
+ quant_res_32x4_h_4 = vshlq_s32(quant_res_32x4_h_4, qp_div_32x4);
+ quant_res_32x4_h_5 = vshlq_s32(quant_res_32x4_h_5, qp_div_32x4);
+ quant_res_32x4_h_6 = vshlq_s32(quant_res_32x4_h_6, qp_div_32x4);
+ quant_res_32x4_h_7 = vshlq_s32(quant_res_32x4_h_7, qp_div_32x4);
+
+ quant_res_16x4_l_0 = vqrshrn_n_s32(quant_res_32x4_l_0, 6);
+ quant_res_16x4_l_1 = vqrshrn_n_s32(quant_res_32x4_l_1, 6);
+ quant_res_16x4_l_2 = vqrshrn_n_s32(quant_res_32x4_l_2, 6);
+ quant_res_16x4_l_3 = vqrshrn_n_s32(quant_res_32x4_l_3, 6);
+ quant_res_16x4_l_4 = vqrshrn_n_s32(quant_res_32x4_l_4, 6);
+ quant_res_16x4_l_5 = vqrshrn_n_s32(quant_res_32x4_l_5, 6);
+ quant_res_16x4_l_6 = vqrshrn_n_s32(quant_res_32x4_l_6, 6);
+ quant_res_16x4_l_7 = vqrshrn_n_s32(quant_res_32x4_l_7, 6);
+
+ quant_res_16x4_h_0 = vqrshrn_n_s32(quant_res_32x4_h_0, 6);
+ quant_res_16x4_h_1 = vqrshrn_n_s32(quant_res_32x4_h_1, 6);
+ quant_res_16x4_h_2 = vqrshrn_n_s32(quant_res_32x4_h_2, 6);
+ quant_res_16x4_h_3 = vqrshrn_n_s32(quant_res_32x4_h_3, 6);
+ quant_res_16x4_h_4 = vqrshrn_n_s32(quant_res_32x4_h_4, 6);
+ quant_res_16x4_h_5 = vqrshrn_n_s32(quant_res_32x4_h_5, 6);
+ quant_res_16x4_h_6 = vqrshrn_n_s32(quant_res_32x4_h_6, 6);
+ quant_res_16x4_h_7 = vqrshrn_n_s32(quant_res_32x4_h_7, 6);
+
+ quant_res_16x8_0 = vcombine_s16(quant_res_16x4_l_0, quant_res_16x4_h_0);
+ quant_res_16x8_1 = vcombine_s16(quant_res_16x4_l_1, quant_res_16x4_h_1);
+ quant_res_16x8_2 = vcombine_s16(quant_res_16x4_l_2, quant_res_16x4_h_2);
+ quant_res_16x8_3 = vcombine_s16(quant_res_16x4_l_3, quant_res_16x4_h_3);
+ quant_res_16x8_4 = vcombine_s16(quant_res_16x4_l_4, quant_res_16x4_h_4);
+ quant_res_16x8_5 = vcombine_s16(quant_res_16x4_l_5, quant_res_16x4_h_5);
+ quant_res_16x8_6 = vcombine_s16(quant_res_16x4_l_6, quant_res_16x4_h_6);
+ quant_res_16x8_7 = vcombine_s16(quant_res_16x4_l_7, quant_res_16x4_h_7);
+
+ for(i = 0; i < 2; i++)
+ {
+ trans_16x8_0_1 = vtrnq_s16(quant_res_16x8_0, quant_res_16x8_1);
+ trans_16x8_0 = trans_16x8_0_1.val[0];
+ trans_16x8_1 = trans_16x8_0_1.val[1];
+
+ trans_16x8_2_3 = vtrnq_s16(quant_res_16x8_2, quant_res_16x8_3);
+ trans_16x8_2 = trans_16x8_2_3.val[0];
+ trans_16x8_3 = trans_16x8_2_3.val[1];
+
+ trans_16x8_4_5 = vtrnq_s16(quant_res_16x8_4, quant_res_16x8_5);
+ trans_16x8_4 = trans_16x8_4_5.val[0];
+ trans_16x8_5 = trans_16x8_4_5.val[1];
+
+ trans_16x8_6_7 = vtrnq_s16(quant_res_16x8_6, quant_res_16x8_7);
+ trans_16x8_6 = trans_16x8_6_7.val[0];
+ trans_16x8_7 = trans_16x8_6_7.val[1];
+
+ trans_32x4_0_2 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_0), vreinterpretq_s32_s16(trans_16x8_2));
+ trans_32x4_0 = trans_32x4_0_2.val[0];
+ trans_32x4_2 = trans_32x4_0_2.val[1];
+
+ trans_32x4_1_3 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_1), vreinterpretq_s32_s16(trans_16x8_3));
+ trans_32x4_1 = trans_32x4_1_3.val[0];
+ trans_32x4_3 = trans_32x4_1_3.val[1];
+
+ trans_32x4_4_6 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_4), vreinterpretq_s32_s16(trans_16x8_6));
+ trans_32x4_4 = trans_32x4_4_6.val[0];
+ trans_32x4_6 = trans_32x4_4_6.val[1];
+
+ trans_32x4_5_7 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_5), vreinterpretq_s32_s16(trans_16x8_7));
+ trans_32x4_5 = trans_32x4_5_7.val[0];
+ trans_32x4_7 = trans_32x4_5_7.val[1];
+
+ trans_64x2_0 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_4)));
+ trans_64x2_4 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_4)));
+
+ trans_64x2_1 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_5)));
+ trans_64x2_5 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_5)));
+
+ trans_64x2_2 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_6)));
+ trans_64x2_6 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_6)));
+
+ trans_64x2_3 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_7)));
+ trans_64x2_7 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_7)));
+
+ trans_16x8_0 = vreinterpretq_s16_s64(trans_64x2_0);
+ trans_16x8_1 = vreinterpretq_s16_s64(trans_64x2_1);
+ trans_16x8_2 = vreinterpretq_s16_s64(trans_64x2_2);
+ trans_16x8_3 = vreinterpretq_s16_s64(trans_64x2_3);
+ trans_16x8_4 = vreinterpretq_s16_s64(trans_64x2_4);
+ trans_16x8_5 = vreinterpretq_s16_s64(trans_64x2_5);
+ trans_16x8_6 = vreinterpretq_s16_s64(trans_64x2_6);
+ trans_16x8_7 = vreinterpretq_s16_s64(trans_64x2_7);
+
+ rs_trans_16x8_1 = vshrq_n_s16(trans_16x8_1, 1);
+ rs_trans_16x8_2 = vshrq_n_s16(trans_16x8_2, 1);
+ rs_trans_16x8_3 = vshrq_n_s16(trans_16x8_3, 1);
+ rs_trans_16x8_5 = vshrq_n_s16(trans_16x8_5, 1);
+ rs_trans_16x8_6 = vshrq_n_s16(trans_16x8_6, 1);
+ rs_trans_16x8_7 = vshrq_n_s16(trans_16x8_7, 1);
+
+ y0_16x8 = vaddq_s16(trans_16x8_0, trans_16x8_4);
+ y2_16x8 = vsubq_s16(trans_16x8_0, trans_16x8_4);
+ y4_16x8 = vsubq_s16(rs_trans_16x8_2, trans_16x8_6);
+ y6_16x8 = vaddq_s16(trans_16x8_2, rs_trans_16x8_6);
+
+ trans_16x4_3_l = vget_low_s16(trans_16x8_3);
+ trans_16x4_5_l = vget_low_s16(trans_16x8_5);
+
+ //-w3 + w5
+ sub_3_5_l = vsubl_s16(vget_low_s16(trans_16x8_5), vget_low_s16(trans_16x8_3));
+ sub_3_5_h = vsubl_s16(vget_high_s16(trans_16x8_5), vget_high_s16(trans_16x8_3));
+
+ // w3 + w5
+ add_3_5_l = vaddl_s16(trans_16x4_3_l, trans_16x4_5_l);
+ add_3_5_h = vaddl_s16(vget_high_s16(trans_16x8_3), vget_high_s16(trans_16x8_5));
+
+ trans_16x4_1_l = vget_low_s16(trans_16x8_1);
+ trans_16x4_7_l = vget_low_s16(trans_16x8_7);
+
+ //-w1 + w7
+ sub_1_7_l = vsubl_s16(trans_16x4_7_l, trans_16x4_1_l);
+ sub_1_7_h = vsubl_s16(vget_high_s16(trans_16x8_7), vget_high_s16(trans_16x8_1));
+
+ // w1 + w7
+ add_1_7_l = vaddl_s16(trans_16x4_1_l, trans_16x4_7_l);
+ add_1_7_h = vaddl_s16(vget_high_s16(trans_16x8_1), vget_high_s16(trans_16x8_7));
+
+ //-w3 + w5 - w7
+ sub_357_l = vsubw_s16(sub_3_5_l, trans_16x4_7_l);
+ sub_357_h = vsubw_s16(sub_3_5_h, vget_high_s16(trans_16x8_7));
+
+ // w3 + w5 + w1
+ add_351_l = vaddw_s16(add_3_5_l, trans_16x4_1_l);
+ add_351_h = vaddw_s16(add_3_5_h, vget_high_s16(trans_16x8_1));
+
+ //-w1 + w7 + w5
+ add_175_l = vaddw_s16(sub_1_7_l, trans_16x4_5_l);
+ add_175_h = vaddw_s16(sub_1_7_h, vget_high_s16(trans_16x8_5));
+
+ // w1 + w7 - w3
+ sub_173_l = vsubw_s16(add_1_7_l, trans_16x4_3_l);
+ sub_173_h = vsubw_s16(add_1_7_h, vget_high_s16(trans_16x8_3));
+
+ //-w3 + w5 - w7 - (w7 >> 1)
+ y1_32x4_l = vsubw_s16(sub_357_l, vget_low_s16(rs_trans_16x8_7));
+ y1_32x4_h = vsubw_s16(sub_357_h, vget_high_s16(rs_trans_16x8_7));
+
+ // w1 + w7 - w3 - (w3 >> 1)
+ y3_32x4_l = vsubw_s16(sub_173_l, vget_low_s16(rs_trans_16x8_3));
+ y3_32x4_h = vsubw_s16(sub_173_h, vget_high_s16(rs_trans_16x8_3));
+
+ //-w1 + w7 + w5 + (w5 >> 1)
+ y5_32x4_l = vaddw_s16(add_175_l, vget_low_s16(rs_trans_16x8_5));
+ y5_32x4_h = vaddw_s16(add_175_h, vget_high_s16(rs_trans_16x8_5));
+
+ // w3 + w5 + w1 + (w1 >> 1)
+ y7_32x4_l = vaddw_s16(add_351_l, vget_low_s16(rs_trans_16x8_1));
+ y7_32x4_h = vaddw_s16(add_351_h, vget_high_s16(rs_trans_16x8_1));
+
+ y1_16x4_l = vmovn_s32(y1_32x4_l);
+ y1_16x4_h = vmovn_s32(y1_32x4_h);
+ y1_16x8 = vcombine_s16(y1_16x4_l, y1_16x4_h);
+ y3_16x4_l = vmovn_s32(y3_32x4_l);
+ y3_16x4_h = vmovn_s32(y3_32x4_h);
+ y3_16x8 = vcombine_s16(y3_16x4_l, y3_16x4_h);
+ y5_16x4_l = vmovn_s32(y5_32x4_l);
+ y5_16x4_h = vmovn_s32(y5_32x4_h);
+ y5_16x8 = vcombine_s16(y5_16x4_l, y5_16x4_h);
+ y7_16x4_l = vmovn_s32(y7_32x4_l);
+ y7_16x4_h = vmovn_s32(y7_32x4_h);
+ y7_16x8 = vcombine_s16(y7_16x4_l, y7_16x4_h);
+
+ rs_y1_16x8 = vshrq_n_s16(y1_16x8, 2);
+ rs_y3_16x8 = vshrq_n_s16(y3_16x8, 2);
+ rs_y5_16x8 = vshrq_n_s16(y5_16x8, 2);
+ rs_y7_16x8 = vshrq_n_s16(y7_16x8, 2);
+
+ z0_16x8 = vaddq_s16(y0_16x8, y6_16x8); // z0 = y0 + y6
+ z1_16x8 = vaddq_s16(y1_16x8, rs_y7_16x8); // z1 = y1 + (y7 >> 2)
+ z2_16x8 = vaddq_s16(y2_16x8, y4_16x8); // z2 = y2 + y4
+ z3_16x8 = vaddq_s16(y3_16x8, rs_y5_16x8); // z3 = y3 + (y5 >> 2)
+ z4_16x8 = vsubq_s16(y2_16x8, y4_16x8); // z4 = y2 - y4
+ z5_16x8 = vsubq_s16(rs_y3_16x8, y5_16x8); // z5 = (y3 >> 2) - y5
+ z6_16x8 = vsubq_s16(y0_16x8, y6_16x8); // z6 = y0 - y6
+ z7_16x8 = vsubq_s16(y7_16x8, rs_y1_16x8); // z7 = y7 - (y1 >> 2)
+
+ quant_res_16x8_0 = vaddq_s16(z0_16x8, z7_16x8); // x0 = z0 + z7
+ quant_res_16x8_1 = vaddq_s16(z2_16x8, z5_16x8); // x1 = z2 + z5
+ quant_res_16x8_2 = vaddq_s16(z4_16x8, z3_16x8); // x2 = z4 + z3
+ quant_res_16x8_3 = vaddq_s16(z6_16x8, z1_16x8); // x3 = z6 + z1
+ quant_res_16x8_4 = vsubq_s16(z6_16x8, z1_16x8); // x4 = z6 - z1
+ quant_res_16x8_5 = vsubq_s16(z4_16x8, z3_16x8); // x5 = z4 - z3
+ quant_res_16x8_6 = vsubq_s16(z2_16x8, z5_16x8); // x6 = z2 - z5
+ quant_res_16x8_7 = vsubq_s16(z0_16x8, z7_16x8); // x7 = z0 - z7
+ }
+
+ quant_res_16x8_0 = vrshrq_n_s16(quant_res_16x8_0, 6);
+ quant_res_16x8_1 = vrshrq_n_s16(quant_res_16x8_1, 6);
+ quant_res_16x8_2 = vrshrq_n_s16(quant_res_16x8_2, 6);
+ quant_res_16x8_3 = vrshrq_n_s16(quant_res_16x8_3, 6);
+ quant_res_16x8_4 = vrshrq_n_s16(quant_res_16x8_4, 6);
+ quant_res_16x8_5 = vrshrq_n_s16(quant_res_16x8_5, 6);
+ quant_res_16x8_6 = vrshrq_n_s16(quant_res_16x8_6, 6);
+ quant_res_16x8_7 = vrshrq_n_s16(quant_res_16x8_7, 6);
+
+ quant_res_16x8_0 = vminq_s16(quant_res_16x8_0, dup_max);
+ quant_res_16x8_0 = vmaxq_s16(quant_res_16x8_0, dup_min);
+ quant_res_16x8_1 = vminq_s16(quant_res_16x8_1, dup_max);
+ quant_res_16x8_1 = vmaxq_s16(quant_res_16x8_1, dup_min);
+ quant_res_16x8_2 = vminq_s16(quant_res_16x8_2, dup_max);
+ quant_res_16x8_2 = vmaxq_s16(quant_res_16x8_2, dup_min);
+ quant_res_16x8_3 = vminq_s16(quant_res_16x8_3, dup_max);
+ quant_res_16x8_3 = vmaxq_s16(quant_res_16x8_3, dup_min);
+ quant_res_16x8_4 = vminq_s16(quant_res_16x8_4, dup_max);
+ quant_res_16x8_4 = vmaxq_s16(quant_res_16x8_4, dup_min);
+
+ vst1q_s16(pi2_out, quant_res_16x8_0);
+ vst1q_s16(pi2_out + out_strd, quant_res_16x8_1);
+ vst1q_s16(pi2_out + out_strd * 2, quant_res_16x8_2);
+ vst1q_s16(pi2_out + out_strd * 3, quant_res_16x8_3);
+ vst1q_s16(pi2_out + out_strd * 4, quant_res_16x8_4);
+ vst1q_s16(pi2_out + out_strd * 5, quant_res_16x8_5);
+ vst1q_s16(pi2_out + out_strd * 6, quant_res_16x8_6);
+ vst1q_s16(pi2_out + out_strd * 7, quant_res_16x8_7);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4_neonintr */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_4x4_neonintr(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ int16x4_t dup_min, dup_max;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ UNUSED(pi2_tmp);
+
+ dup_min = vdup_n_s16(RSD_MIN);
+ dup_max = vdup_n_s16(RSD_MAX);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_ld_addr[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ x0_16x4 = vmin_s16(x0_16x4, dup_max);
+ x0_16x4 = vmax_s16(x0_16x4, dup_min);
+ x1_16x4 = vmin_s16(x1_16x4, dup_max);
+ x1_16x4 = vmax_s16(x1_16x4, dup_min);
+ x2_16x4 = vmin_s16(x2_16x4, dup_max);
+ x2_16x4 = vmax_s16(x2_16x4, dup_min);
+ x3_16x4 = vmin_s16(x3_16x4, dup_max);
+ x3_16x4 = vmax_s16(x3_16x4, dup_min);
+
+ vst1_s16(pi2_out, x0_16x4);
+ vst1_s16(pi2_out + out_strd, x1_16x4);
+ vst1_s16(pi2_out + (out_strd << 1), x2_16x4);
+ vst1_s16(pi2_out + ((out_strd << 1) + out_strd), x3_16x4);
+}
diff --git a/decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c b/decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c
new file mode 100644
index 0000000..4e4b86b
--- /dev/null
+++ b/decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c
@@ -0,0 +1,1308 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_neonintr.c
+ *
+ * @brief
+ * Contains definition of functions for h264 inverse quantization inverse
+ * transformation and resd comp
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_residual_4x4_neonintr()
+ * - isvcd_iquant_itrans_residual_8x8_neonintr()
+ * - isvcd_iquant_itrans_residual_4x4_dc_neonintr()
+ * - isvcd_iquant_itrans_residual_8x8_dc_neonintr()
+ * - isvcd_iquant_itrans_residual_chroma_4x4_neonintr()
+ * - isvcd_iquant_itrans_residual_chroma_4x4_dc_neonintr()
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include <string.h>
+#include <arm_neon.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans_residual.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4_neonintr */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_4x4_neonintr(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+
+ int16x4_t pred0, pred1, pred2, pred3;
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4, dup_min, dup_max;
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+
+ int16x8_t pred01_in, pred23_in;
+ WORD32 i4_nnz;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ UNUSED(pi2_tmp);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ dup_min = vdup_n_s16(RSD_MIN);
+ dup_max = vdup_n_s16(RSD_MAX);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_ld_addr[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ pred0 = vld1_s16((int16_t *) pi2_pred);
+ pred1 = vld1_s16((int16_t *) pi2_pred + pred_strd);
+ pred2 = vld1_s16((int16_t *) pi2_pred + (pred_strd * 2));
+ pred3 = vld1_s16((int16_t *) pi2_pred + (pred_strd * 3));
+
+ x0_16x4 = vadd_s16(pred0, x0_16x4);
+ x1_16x4 = vadd_s16(pred1, x1_16x4);
+ x2_16x4 = vadd_s16(pred2, x2_16x4);
+ x3_16x4 = vadd_s16(pred3, x3_16x4);
+
+ x0_16x4 = vmin_s16(x0_16x4, dup_max);
+ x0_16x4 = vmax_s16(x0_16x4, dup_min);
+ x1_16x4 = vmin_s16(x1_16x4, dup_max);
+ x1_16x4 = vmax_s16(x1_16x4, dup_min);
+ x2_16x4 = vmin_s16(x2_16x4, dup_max);
+ x2_16x4 = vmax_s16(x2_16x4, dup_min);
+ x3_16x4 = vmin_s16(x3_16x4, dup_max);
+ x3_16x4 = vmax_s16(x3_16x4, dup_min);
+
+ pred01_in = vcombine_s16(x0_16x4, x1_16x4);
+ pred23_in = vcombine_s16(x2_16x4, x3_16x4);
+
+ dup_val_1 = vabsq_s16(pred01_in);
+ dup_val_2 = vabsq_s16(pred23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ vst1_s16(pi2_out, x0_16x4);
+ vst1_s16(pi2_out + out_strd, x1_16x4);
+ vst1_s16(pi2_out + (out_strd << 1), x2_16x4);
+ vst1_s16(pi2_out + ((out_strd << 1) + out_strd), x3_16x4);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_iquant_itrans_residual_4x4_dc_neonintr(WORD16 *pi2_src, WORD16 *pi2_pred,
+ WORD16 *pi2_out, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp,
+ WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x4_t temp_0;
+ int16x4_t pred0_in, pred1_in, pred2_in, pred3_in, dup_min, dup_max;
+ int16x8_t pred01_in, pred23_in;
+ WORD32 i4_nnz;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_ld_addr[0];
+ }
+
+ /* inv transform and residual comp */
+ pred0_in = vld1_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred1_in = vld1_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred2_in = vld1_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred3_in = vld1_s16((int16_t *) pi2_pred);
+
+ temp_0 = vdup_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdup_n_s16(RSD_MIN);
+ dup_max = vdup_n_s16(RSD_MAX);
+
+ pred0_in = vadd_s16(pred0_in, temp_0);
+ pred1_in = vadd_s16(pred1_in, temp_0);
+ pred2_in = vadd_s16(pred2_in, temp_0);
+ pred3_in = vadd_s16(pred3_in, temp_0);
+
+ pred0_in = vmin_s16(pred0_in, dup_max);
+ pred0_in = vmax_s16(pred0_in, dup_min);
+ pred1_in = vmin_s16(pred1_in, dup_max);
+ pred1_in = vmax_s16(pred1_in, dup_min);
+ pred2_in = vmin_s16(pred2_in, dup_max);
+ pred2_in = vmax_s16(pred2_in, dup_min);
+ pred3_in = vmin_s16(pred3_in, dup_max);
+ pred3_in = vmax_s16(pred3_in, dup_min);
+
+ pred01_in = vcombine_s16(pred0_in, pred1_in);
+ pred23_in = vcombine_s16(pred2_in, pred3_in);
+
+ dup_val_1 = vabsq_s16(pred01_in);
+ dup_val_2 = vabsq_s16(pred23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ vst1_s16((int16_t *) (pi2_out), pred0_in);
+ vst1_s16((int16_t *) (pi2_out + out_strd), pred1_in);
+ vst1_s16((int16_t *) (pi2_out + (out_strd * 2)), pred2_in);
+ vst1_s16((int16_t *) (pi2_out + (out_strd * 3)), pred3_in);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4_neonintr */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4_neonintr(
+ WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out, WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ int16x4_t zero_16x4 = vdup_n_s16(0);
+ int16x4_t x_16x4_low, x_16x4_high;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x8_t dup_min, dup_max;
+ WORD32 i4_nnz;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2, x_16x4x2_t;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+ int16x8_t dup_val_1, dup_val_2, dup_val_3, dup_val_4, dup_val_5, dup_abs;
+ int16x8_t i4_out_horz_16x8_r0, i4_out_horz_16x8_r1, i4_out_horz_16x8_r2, i4_out_horz_16x8_r3;
+ uint16x8_t chroma_mask_16x8 = vreinterpretq_u16_u32(vdupq_n_u32(0x0000ffff));
+ int16x8_t chroma_mask_16x8_2 = vreinterpretq_s16_s32(vdupq_n_s32(0x0000ffff));
+
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ UNUSED(pi2_tmp);
+
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ x_16x4x2_t = vzip_s16(x0_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x0_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x1_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x1_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x2_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x2_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ x_16x4x2_t = vzip_s16(x3_16x4, zero_16x4);
+ x_16x4_low = x_16x4x2_t.val[0];
+ x_16x4_high = x_16x4x2_t.val[1];
+ x3_16x8 = vcombine_s16(x_16x4_low, x_16x4_high);
+
+ pred0 = vld1q_s16((int16_t *) pi2_pred);
+ pred1 = vld1q_s16((int16_t *) pi2_pred + pred_strd);
+ pred2 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 2));
+ pred3 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 3));
+
+ x0_16x8 = vaddq_s16(pred0, x0_16x8);
+ x1_16x8 = vaddq_s16(pred1, x1_16x8);
+ x2_16x8 = vaddq_s16(pred2, x2_16x8);
+ x3_16x8 = vaddq_s16(pred3, x3_16x8);
+
+ x0_16x8 = vminq_s16(x0_16x8, dup_max);
+ x0_16x8 = vmaxq_s16(x0_16x8, dup_min);
+ x1_16x8 = vminq_s16(x1_16x8, dup_max);
+ x1_16x8 = vmaxq_s16(x1_16x8, dup_min);
+ x2_16x8 = vminq_s16(x2_16x8, dup_max);
+ x2_16x8 = vmaxq_s16(x2_16x8, dup_min);
+ x3_16x8 = vminq_s16(x3_16x8, dup_max);
+ x3_16x8 = vmaxq_s16(x3_16x8, dup_min);
+
+ x0_16x8 = vandq_s16(x0_16x8, chroma_mask_16x8_2);
+ x1_16x8 = vandq_s16(x1_16x8, chroma_mask_16x8_2);
+ x2_16x8 = vandq_s16(x2_16x8, chroma_mask_16x8_2);
+ x3_16x8 = vandq_s16(x3_16x8, chroma_mask_16x8_2);
+
+ dup_val_1 = vabsq_s16(x0_16x8);
+ dup_val_2 = vabsq_s16(x1_16x8);
+ dup_val_3 = vabsq_s16(x2_16x8);
+ dup_val_4 = vabsq_s16(x3_16x8);
+ dup_val_5 = vqaddq_s16(dup_val_1, dup_val_2);
+ dup_val_1 = vqaddq_s16(dup_val_3, dup_val_4);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_5);
+
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ i4_out_horz_16x8_r0 = vld1q_s16(pi2_out);
+ i4_out_horz_16x8_r1 = vld1q_s16(pi2_out + out_strd);
+ i4_out_horz_16x8_r2 = vld1q_s16(pi2_out + out_strd * 2);
+ i4_out_horz_16x8_r3 = vld1q_s16(pi2_out + out_strd * 3);
+
+ i4_out_horz_16x8_r0 = vbslq_s16(chroma_mask_16x8, x0_16x8, i4_out_horz_16x8_r0);
+ i4_out_horz_16x8_r1 = vbslq_s16(chroma_mask_16x8, x1_16x8, i4_out_horz_16x8_r1);
+ i4_out_horz_16x8_r2 = vbslq_s16(chroma_mask_16x8, x2_16x8, i4_out_horz_16x8_r2);
+ i4_out_horz_16x8_r3 = vbslq_s16(chroma_mask_16x8, x3_16x8, i4_out_horz_16x8_r3);
+
+ vst1q_s16((int16_t *) (pi2_out), i4_out_horz_16x8_r0);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), i4_out_horz_16x8_r1);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 2), i4_out_horz_16x8_r2);
+ vst1q_s16((int16_t *) (pi2_out + out_strd * 3), i4_out_horz_16x8_r3);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4_dc_neonintr(
+ WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out, WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t temp_0, dup_min, dup_max;
+ WORD32 i4_iq_out_temp;
+ int16x8_t dup_val_1, dup_val_2, dup_val_3, dup_val_4, dup_val_5, dup_abs;
+ int16x8_t i4_out_horz_16x8_r0, i4_out_horz_16x8_r1, i4_out_horz_16x8_r2, i4_out_horz_16x8_r3;
+ uint16x8_t chroma_mask_16x8 = vreinterpretq_u16_u32(vdupq_n_u32(0x0000ffff));
+ int16x8_t chroma_mask_16x8_2 = vreinterpretq_s16_s32(vdupq_n_s32(0x0000ffff));
+
+ WORD32 i4_nnz;
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+ UNUSED(pi2_dc_src);
+
+ i4_iq_out_temp = pi2_dc_src[0];
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ pred0 = vld1q_s16((int16_t *) pi2_pred);
+ pred1 = vld1q_s16((int16_t *) pi2_pred + pred_strd);
+ pred2 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 2));
+ pred3 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 3));
+
+ pred0 = vaddq_s16(pred0, temp_0);
+ pred1 = vaddq_s16(pred1, temp_0);
+ pred2 = vaddq_s16(pred2, temp_0);
+ pred3 = vaddq_s16(pred3, temp_0);
+
+ pred0 = vminq_s16(pred0, dup_max);
+ pred0 = vmaxq_s16(pred0, dup_min);
+ pred1 = vminq_s16(pred1, dup_max);
+ pred1 = vmaxq_s16(pred1, dup_min);
+ pred2 = vminq_s16(pred2, dup_max);
+ pred2 = vmaxq_s16(pred2, dup_min);
+ pred3 = vminq_s16(pred3, dup_max);
+ pred3 = vmaxq_s16(pred3, dup_min);
+
+ pred0 = vandq_s16(pred0, chroma_mask_16x8_2);
+ pred1 = vandq_s16(pred1, chroma_mask_16x8_2);
+ pred2 = vandq_s16(pred2, chroma_mask_16x8_2);
+ pred3 = vandq_s16(pred3, chroma_mask_16x8_2);
+
+ dup_val_1 = vabsq_s16(pred0);
+ dup_val_2 = vabsq_s16(pred1);
+ dup_val_3 = vabsq_s16(pred2);
+ dup_val_4 = vabsq_s16(pred2);
+ dup_val_5 = vqaddq_s16(dup_val_1, dup_val_2);
+ dup_val_1 = vqaddq_s16(dup_val_3, dup_val_4);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_5);
+
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ i4_out_horz_16x8_r0 = vld1q_s16(pi2_out);
+ i4_out_horz_16x8_r1 = vld1q_s16(pi2_out + out_strd);
+ i4_out_horz_16x8_r2 = vld1q_s16(pi2_out + (out_strd * 2));
+ i4_out_horz_16x8_r3 = vld1q_s16(pi2_out + (out_strd * 3));
+
+ i4_out_horz_16x8_r0 = vbslq_s16(chroma_mask_16x8, pred0, i4_out_horz_16x8_r0);
+ i4_out_horz_16x8_r1 = vbslq_s16(chroma_mask_16x8, pred1, i4_out_horz_16x8_r1);
+ i4_out_horz_16x8_r2 = vbslq_s16(chroma_mask_16x8, pred2, i4_out_horz_16x8_r2);
+ i4_out_horz_16x8_r3 = vbslq_s16(chroma_mask_16x8, pred3, i4_out_horz_16x8_r3);
+
+ vst1q_s16((int16_t *) (pi2_out), i4_out_horz_16x8_r0);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), i4_out_horz_16x8_r1);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 2)), i4_out_horz_16x8_r2);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 3)), i4_out_horz_16x8_r3);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8_neonintr */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8_neonintr(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ int16x8_t iscal_16x8_0, iscal_16x8_1, iscal_16x8_2, iscal_16x8_3, iscal_16x8_4, iscal_16x8_5,
+ iscal_16x8_6, iscal_16x8_7;
+
+ int16x8_t weigh_16x8_0, weigh_16x8_1, weigh_16x8_2, weigh_16x8_3, weigh_16x8_4, weigh_16x8_5,
+ weigh_16x8_6, weigh_16x8_7;
+
+ int16x8_t src_16x8_0, src_16x8_1, src_16x8_2, src_16x8_3, src_16x8_4, src_16x8_5, src_16x8_6,
+ src_16x8_7;
+ int16x8_t coeff_mul_16x8_0, coeff_mul_16x8_1, coeff_mul_16x8_2, coeff_mul_16x8_3,
+ coeff_mul_16x8_4, coeff_mul_16x8_5, coeff_mul_16x8_6, coeff_mul_16x8_7;
+
+ int32x4_t quant_res_32x4_l_0, quant_res_32x4_l_1, quant_res_32x4_l_2, quant_res_32x4_l_3,
+ quant_res_32x4_l_4, quant_res_32x4_l_5, quant_res_32x4_l_6, quant_res_32x4_l_7;
+ int32x4_t quant_res_32x4_h_0, quant_res_32x4_h_1, quant_res_32x4_h_2, quant_res_32x4_h_3,
+ quant_res_32x4_h_4, quant_res_32x4_h_5, quant_res_32x4_h_6, quant_res_32x4_h_7;
+ int16x4_t quant_res_16x4_l_0, quant_res_16x4_l_1, quant_res_16x4_l_2, quant_res_16x4_l_3,
+ quant_res_16x4_l_4, quant_res_16x4_l_5, quant_res_16x4_l_6, quant_res_16x4_l_7;
+ int16x4_t quant_res_16x4_h_0, quant_res_16x4_h_1, quant_res_16x4_h_2, quant_res_16x4_h_3,
+ quant_res_16x4_h_4, quant_res_16x4_h_5, quant_res_16x4_h_6, quant_res_16x4_h_7;
+
+ int16x8_t quant_res_16x8_0, quant_res_16x8_1, quant_res_16x8_2, quant_res_16x8_3,
+ quant_res_16x8_4, quant_res_16x8_5, quant_res_16x8_6, quant_res_16x8_7;
+
+ int16x8_t trans_16x8_0, trans_16x8_1, trans_16x8_2, trans_16x8_3, trans_16x8_4, trans_16x8_5,
+ trans_16x8_6, trans_16x8_7;
+ int32x4_t trans_32x4_0, trans_32x4_1, trans_32x4_2, trans_32x4_3, trans_32x4_4, trans_32x4_5,
+ trans_32x4_6, trans_32x4_7;
+ int64x2_t trans_64x2_0, trans_64x2_1, trans_64x2_2, trans_64x2_3, trans_64x2_4, trans_64x2_5,
+ trans_64x2_6, trans_64x2_7;
+ int16x4_t trans_16x4_1_l, trans_16x4_3_l, trans_16x4_5_l, trans_16x4_7_l;
+ int16x8_t rs_trans_16x8_1, rs_trans_16x8_2, rs_trans_16x8_3, rs_trans_16x8_5, rs_trans_16x8_6,
+ rs_trans_16x8_7;
+ int32x4_t sub_3_5_l, sub_3_5_h;
+ int32x4_t add_3_5_l, add_3_5_h;
+ int32x4_t sub_1_7_l, sub_1_7_h;
+ int32x4_t add_1_7_l, add_1_7_h;
+ int32x4_t sub_357_l, sub_357_h;
+ int32x4_t add_351_l, add_351_h;
+ int32x4_t add_175_l, add_175_h;
+ int32x4_t sub_173_l, sub_173_h;
+ int32x4_t y1_32x4_l, y1_32x4_h;
+ int32x4_t y3_32x4_l, y3_32x4_h;
+ int32x4_t y5_32x4_l, y5_32x4_h;
+ int32x4_t y7_32x4_l, y7_32x4_h;
+ int16x4_t y1_16x4_l, y3_16x4_l, y5_16x4_l, y7_16x4_l;
+
+ int16x8_t y0_16x8, y1_16x8, y2_16x8, y3_16x8, y4_16x8, y5_16x8, y6_16x8, y7_16x8;
+ int16x8_t rs_y1_16x8, rs_y3_16x8, rs_y5_16x8, rs_y7_16x8;
+ int16x8_t z0_16x8, z1_16x8, z2_16x8, z3_16x8, z4_16x8, z5_16x8, z6_16x8, z7_16x8;
+ int16x8_t pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7;
+
+ int64x2_t pred0_in_64x2, pred1_in_64x2, pred2_in_64x2, pred3_in_64x2, pred4_in_64x2,
+ pred5_in_64x2, pred6_in_64x2, pred7_in_64x2;
+
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(qp_div);
+
+ int16x8_t pred_b0_r01_in;
+ int16x8_t pred_b0_r23_in;
+ int16x8_t pred_b1_r01_in;
+ int16x8_t pred_b1_r23_in;
+ int16x8_t pred_b2_r45_in;
+ int16x8_t pred_b2_r67_in;
+ int16x8_t pred_b3_r45_in;
+ int16x8_t pred_b3_r67_in;
+ int16x8_t dup_min, dup_max;
+
+ int16x8x2_t trans_16x8_0_1, trans_16x8_2_3, trans_16x8_4_5, trans_16x8_6_7;
+ int32x4x2_t trans_32x4_0_2, trans_32x4_1_3, trans_32x4_4_6, trans_32x4_5_7;
+ int16x4_t y1_16x4_h, y3_16x4_h, y5_16x4_h, y7_16x4_h;
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3, i;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ iscal_16x8_0 = vld1q_s16((const int16_t *) pu2_iscale_mat);
+ iscal_16x8_1 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 8));
+ iscal_16x8_2 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 16));
+ iscal_16x8_3 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 24));
+ iscal_16x8_4 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 32));
+ iscal_16x8_5 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 40));
+ iscal_16x8_6 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 48));
+ iscal_16x8_7 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 56));
+
+ weigh_16x8_0 = vld1q_s16((const int16_t *) pu2_weigh_mat);
+ weigh_16x8_1 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 8));
+ weigh_16x8_2 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 16));
+ weigh_16x8_3 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 24));
+ weigh_16x8_4 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 32));
+ weigh_16x8_5 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 40));
+ weigh_16x8_6 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 48));
+ weigh_16x8_7 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 56));
+
+ src_16x8_0 = vld1q_s16((const int16_t *) pi2_src); // a0 a1 a2 a3 a4 a5 a6 a7
+ src_16x8_1 = vld1q_s16((const int16_t *) (pi2_src + 8)); // b0 b1 b2 b3 b4 b5 b6 b7
+ src_16x8_2 = vld1q_s16((const int16_t *) (pi2_src + 16));
+ src_16x8_3 = vld1q_s16((const int16_t *) (pi2_src + 24));
+ src_16x8_4 = vld1q_s16((const int16_t *) (pi2_src + 32));
+ src_16x8_5 = vld1q_s16((const int16_t *) (pi2_src + 40));
+ src_16x8_6 = vld1q_s16((const int16_t *) (pi2_src + 48));
+ src_16x8_7 = vld1q_s16((const int16_t *) (pi2_src + 56));
+
+ coeff_mul_16x8_0 = vmulq_s16(iscal_16x8_0, weigh_16x8_0);
+ coeff_mul_16x8_1 = vmulq_s16(iscal_16x8_1, weigh_16x8_1);
+ coeff_mul_16x8_2 = vmulq_s16(iscal_16x8_2, weigh_16x8_2);
+ coeff_mul_16x8_3 = vmulq_s16(iscal_16x8_3, weigh_16x8_3);
+ coeff_mul_16x8_4 = vmulq_s16(iscal_16x8_4, weigh_16x8_4);
+ coeff_mul_16x8_5 = vmulq_s16(iscal_16x8_5, weigh_16x8_5);
+ coeff_mul_16x8_6 = vmulq_s16(iscal_16x8_6, weigh_16x8_6);
+ coeff_mul_16x8_7 = vmulq_s16(iscal_16x8_7, weigh_16x8_7);
+
+ quant_res_32x4_l_0 = vmull_s16(vget_low_s16(coeff_mul_16x8_0), vget_low_s16(src_16x8_0));
+ quant_res_32x4_l_1 = vmull_s16(vget_low_s16(coeff_mul_16x8_1), vget_low_s16(src_16x8_1));
+ quant_res_32x4_l_2 = vmull_s16(vget_low_s16(coeff_mul_16x8_2), vget_low_s16(src_16x8_2));
+ quant_res_32x4_l_3 = vmull_s16(vget_low_s16(coeff_mul_16x8_3), vget_low_s16(src_16x8_3));
+ quant_res_32x4_l_4 = vmull_s16(vget_low_s16(coeff_mul_16x8_4), vget_low_s16(src_16x8_4));
+ quant_res_32x4_l_5 = vmull_s16(vget_low_s16(coeff_mul_16x8_5), vget_low_s16(src_16x8_5));
+ quant_res_32x4_l_6 = vmull_s16(vget_low_s16(coeff_mul_16x8_6), vget_low_s16(src_16x8_6));
+ quant_res_32x4_l_7 = vmull_s16(vget_low_s16(coeff_mul_16x8_7), vget_low_s16(src_16x8_7));
+
+ quant_res_32x4_h_0 = vmull_s16(vget_high_s16(coeff_mul_16x8_0), vget_high_s16(src_16x8_0));
+ quant_res_32x4_h_1 = vmull_s16(vget_high_s16(coeff_mul_16x8_1), vget_high_s16(src_16x8_1));
+ quant_res_32x4_h_2 = vmull_s16(vget_high_s16(coeff_mul_16x8_2), vget_high_s16(src_16x8_2));
+ quant_res_32x4_h_3 = vmull_s16(vget_high_s16(coeff_mul_16x8_3), vget_high_s16(src_16x8_3));
+ quant_res_32x4_h_4 = vmull_s16(vget_high_s16(coeff_mul_16x8_4), vget_high_s16(src_16x8_4));
+ quant_res_32x4_h_5 = vmull_s16(vget_high_s16(coeff_mul_16x8_5), vget_high_s16(src_16x8_5));
+ quant_res_32x4_h_6 = vmull_s16(vget_high_s16(coeff_mul_16x8_6), vget_high_s16(src_16x8_6));
+ quant_res_32x4_h_7 = vmull_s16(vget_high_s16(coeff_mul_16x8_7), vget_high_s16(src_16x8_7));
+
+ quant_res_32x4_l_0 = vshlq_s32(quant_res_32x4_l_0, qp_div_6_32x4);
+ quant_res_32x4_l_1 = vshlq_s32(quant_res_32x4_l_1, qp_div_6_32x4);
+ quant_res_32x4_l_2 = vshlq_s32(quant_res_32x4_l_2, qp_div_6_32x4);
+ quant_res_32x4_l_3 = vshlq_s32(quant_res_32x4_l_3, qp_div_6_32x4);
+ quant_res_32x4_l_4 = vshlq_s32(quant_res_32x4_l_4, qp_div_6_32x4);
+ quant_res_32x4_l_5 = vshlq_s32(quant_res_32x4_l_5, qp_div_6_32x4);
+ quant_res_32x4_l_6 = vshlq_s32(quant_res_32x4_l_6, qp_div_6_32x4);
+ quant_res_32x4_l_7 = vshlq_s32(quant_res_32x4_l_7, qp_div_6_32x4);
+
+ quant_res_32x4_h_0 = vshlq_s32(quant_res_32x4_h_0, qp_div_6_32x4);
+ quant_res_32x4_h_1 = vshlq_s32(quant_res_32x4_h_1, qp_div_6_32x4);
+ quant_res_32x4_h_2 = vshlq_s32(quant_res_32x4_h_2, qp_div_6_32x4);
+ quant_res_32x4_h_3 = vshlq_s32(quant_res_32x4_h_3, qp_div_6_32x4);
+ quant_res_32x4_h_4 = vshlq_s32(quant_res_32x4_h_4, qp_div_6_32x4);
+ quant_res_32x4_h_5 = vshlq_s32(quant_res_32x4_h_5, qp_div_6_32x4);
+ quant_res_32x4_h_6 = vshlq_s32(quant_res_32x4_h_6, qp_div_6_32x4);
+ quant_res_32x4_h_7 = vshlq_s32(quant_res_32x4_h_7, qp_div_6_32x4);
+
+ quant_res_16x4_l_0 = vqrshrn_n_s32(quant_res_32x4_l_0, 6);
+ quant_res_16x4_l_1 = vqrshrn_n_s32(quant_res_32x4_l_1, 6);
+ quant_res_16x4_l_2 = vqrshrn_n_s32(quant_res_32x4_l_2, 6);
+ quant_res_16x4_l_3 = vqrshrn_n_s32(quant_res_32x4_l_3, 6);
+ quant_res_16x4_l_4 = vqrshrn_n_s32(quant_res_32x4_l_4, 6);
+ quant_res_16x4_l_5 = vqrshrn_n_s32(quant_res_32x4_l_5, 6);
+ quant_res_16x4_l_6 = vqrshrn_n_s32(quant_res_32x4_l_6, 6);
+ quant_res_16x4_l_7 = vqrshrn_n_s32(quant_res_32x4_l_7, 6);
+
+ quant_res_16x4_h_0 = vqrshrn_n_s32(quant_res_32x4_h_0, 6);
+ quant_res_16x4_h_1 = vqrshrn_n_s32(quant_res_32x4_h_1, 6);
+ quant_res_16x4_h_2 = vqrshrn_n_s32(quant_res_32x4_h_2, 6);
+ quant_res_16x4_h_3 = vqrshrn_n_s32(quant_res_32x4_h_3, 6);
+ quant_res_16x4_h_4 = vqrshrn_n_s32(quant_res_32x4_h_4, 6);
+ quant_res_16x4_h_5 = vqrshrn_n_s32(quant_res_32x4_h_5, 6);
+ quant_res_16x4_h_6 = vqrshrn_n_s32(quant_res_32x4_h_6, 6);
+ quant_res_16x4_h_7 = vqrshrn_n_s32(quant_res_32x4_h_7, 6);
+
+ quant_res_16x8_0 = vcombine_s16(quant_res_16x4_l_0, quant_res_16x4_h_0);
+ quant_res_16x8_1 = vcombine_s16(quant_res_16x4_l_1, quant_res_16x4_h_1);
+ quant_res_16x8_2 = vcombine_s16(quant_res_16x4_l_2, quant_res_16x4_h_2);
+ quant_res_16x8_3 = vcombine_s16(quant_res_16x4_l_3, quant_res_16x4_h_3);
+ quant_res_16x8_4 = vcombine_s16(quant_res_16x4_l_4, quant_res_16x4_h_4);
+ quant_res_16x8_5 = vcombine_s16(quant_res_16x4_l_5, quant_res_16x4_h_5);
+ quant_res_16x8_6 = vcombine_s16(quant_res_16x4_l_6, quant_res_16x4_h_6);
+ quant_res_16x8_7 = vcombine_s16(quant_res_16x4_l_7, quant_res_16x4_h_7);
+
+ for(i = 0; i < 2; i++)
+ {
+ trans_16x8_0_1 = vtrnq_s16(quant_res_16x8_0, quant_res_16x8_1);
+ trans_16x8_0 = trans_16x8_0_1.val[0];
+ trans_16x8_1 = trans_16x8_0_1.val[1];
+
+ trans_16x8_2_3 = vtrnq_s16(quant_res_16x8_2, quant_res_16x8_3);
+ trans_16x8_2 = trans_16x8_2_3.val[0];
+ trans_16x8_3 = trans_16x8_2_3.val[1];
+
+ trans_16x8_4_5 = vtrnq_s16(quant_res_16x8_4, quant_res_16x8_5);
+ trans_16x8_4 = trans_16x8_4_5.val[0];
+ trans_16x8_5 = trans_16x8_4_5.val[1];
+
+ trans_16x8_6_7 = vtrnq_s16(quant_res_16x8_6, quant_res_16x8_7);
+ trans_16x8_6 = trans_16x8_6_7.val[0];
+ trans_16x8_7 = trans_16x8_6_7.val[1];
+
+ trans_32x4_0_2 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_0), vreinterpretq_s32_s16(trans_16x8_2));
+ trans_32x4_0 = trans_32x4_0_2.val[0];
+ trans_32x4_2 = trans_32x4_0_2.val[1];
+
+ trans_32x4_1_3 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_1), vreinterpretq_s32_s16(trans_16x8_3));
+ trans_32x4_1 = trans_32x4_1_3.val[0];
+ trans_32x4_3 = trans_32x4_1_3.val[1];
+
+ trans_32x4_4_6 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_4), vreinterpretq_s32_s16(trans_16x8_6));
+ trans_32x4_4 = trans_32x4_4_6.val[0];
+ trans_32x4_6 = trans_32x4_4_6.val[1];
+
+ trans_32x4_5_7 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_5), vreinterpretq_s32_s16(trans_16x8_7));
+ trans_32x4_5 = trans_32x4_5_7.val[0];
+ trans_32x4_7 = trans_32x4_5_7.val[1];
+
+ trans_64x2_0 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_4)));
+ trans_64x2_4 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_4)));
+
+ trans_64x2_1 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_5)));
+ trans_64x2_5 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_5)));
+
+ trans_64x2_2 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_6)));
+ trans_64x2_6 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_6)));
+
+ trans_64x2_3 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_7)));
+ trans_64x2_7 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_7)));
+
+ trans_16x8_0 = vreinterpretq_s16_s64(trans_64x2_0);
+ trans_16x8_1 = vreinterpretq_s16_s64(trans_64x2_1);
+ trans_16x8_2 = vreinterpretq_s16_s64(trans_64x2_2);
+ trans_16x8_3 = vreinterpretq_s16_s64(trans_64x2_3);
+ trans_16x8_4 = vreinterpretq_s16_s64(trans_64x2_4);
+ trans_16x8_5 = vreinterpretq_s16_s64(trans_64x2_5);
+ trans_16x8_6 = vreinterpretq_s16_s64(trans_64x2_6);
+ trans_16x8_7 = vreinterpretq_s16_s64(trans_64x2_7);
+
+ rs_trans_16x8_1 = vshrq_n_s16(trans_16x8_1, 1); //(pi2_tmp_ptr[1] >> 1)
+ rs_trans_16x8_2 = vshrq_n_s16(trans_16x8_2, 1); //(pi2_tmp_ptr[2] >> 1)
+ rs_trans_16x8_3 = vshrq_n_s16(trans_16x8_3, 1); //(pi2_tmp_ptr[3] >> 1)
+ rs_trans_16x8_5 = vshrq_n_s16(trans_16x8_5, 1); //(pi2_tmp_ptr[5] >> 1)
+ rs_trans_16x8_6 = vshrq_n_s16(trans_16x8_6, 1); //(pi2_tmp_ptr[6] >> 1)
+ rs_trans_16x8_7 = vshrq_n_s16(trans_16x8_7, 1); //(pi2_tmp_ptr[7] >> 1)
+
+ y0_16x8 = vaddq_s16(trans_16x8_0,
+ trans_16x8_4); // i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4] );
+ y2_16x8 = vsubq_s16(trans_16x8_0,
+ trans_16x8_4); // i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4] );
+ y4_16x8 = vsubq_s16(rs_trans_16x8_2,
+ trans_16x8_6); // i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6] );
+ y6_16x8 = vaddq_s16(trans_16x8_2,
+ rs_trans_16x8_6); // i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+
+ trans_16x4_3_l = vget_low_s16(trans_16x8_3);
+ trans_16x4_5_l = vget_low_s16(trans_16x8_5);
+
+ //-w3 + w5
+ sub_3_5_l = vsubl_s16(vget_low_s16(trans_16x8_5), vget_low_s16(trans_16x8_3));
+ sub_3_5_h = vsubl_s16(vget_high_s16(trans_16x8_5), vget_high_s16(trans_16x8_3));
+
+ // w3 + w5
+ add_3_5_l = vaddl_s16(trans_16x4_3_l, trans_16x4_5_l);
+ add_3_5_h = vaddl_s16(vget_high_s16(trans_16x8_3), vget_high_s16(trans_16x8_5));
+
+ trans_16x4_1_l = vget_low_s16(trans_16x8_1);
+ trans_16x4_7_l = vget_low_s16(trans_16x8_7);
+
+ //-w1 + w7
+ sub_1_7_l = vsubl_s16(trans_16x4_7_l, trans_16x4_1_l);
+ sub_1_7_h = vsubl_s16(vget_high_s16(trans_16x8_7), vget_high_s16(trans_16x8_1));
+
+ // w1 + w7
+ add_1_7_l = vaddl_s16(trans_16x4_1_l, trans_16x4_7_l);
+ add_1_7_h = vaddl_s16(vget_high_s16(trans_16x8_1), vget_high_s16(trans_16x8_7));
+
+ //-w3 + w5 - w7
+ sub_357_l = vsubw_s16(sub_3_5_l, trans_16x4_7_l);
+ sub_357_h = vsubw_s16(sub_3_5_h, vget_high_s16(trans_16x8_7));
+
+ // w3 + w5 + w1
+ add_351_l = vaddw_s16(add_3_5_l, trans_16x4_1_l);
+ add_351_h = vaddw_s16(add_3_5_h, vget_high_s16(trans_16x8_1));
+
+ //-w1 + w7 + w5
+ add_175_l = vaddw_s16(sub_1_7_l, trans_16x4_5_l);
+ add_175_h = vaddw_s16(sub_1_7_h, vget_high_s16(trans_16x8_5));
+
+ // w1 + w7 - w3
+ sub_173_l = vsubw_s16(add_1_7_l, trans_16x4_3_l);
+ sub_173_h = vsubw_s16(add_1_7_h, vget_high_s16(trans_16x8_3));
+
+ //-w3 + w5 - w7 - (w7 >> 1)
+ y1_32x4_l = vsubw_s16(sub_357_l, vget_low_s16(rs_trans_16x8_7));
+ y1_32x4_h = vsubw_s16(sub_357_h, vget_high_s16(rs_trans_16x8_7));
+
+ // w1 + w7 - w3 - (w3 >> 1)
+ y3_32x4_l = vsubw_s16(sub_173_l, vget_low_s16(rs_trans_16x8_3));
+ y3_32x4_h = vsubw_s16(sub_173_h, vget_high_s16(rs_trans_16x8_3));
+
+ //-w1 + w7 + w5 + (w5 >> 1)
+ y5_32x4_l = vaddw_s16(add_175_l, vget_low_s16(rs_trans_16x8_5));
+ y5_32x4_h = vaddw_s16(add_175_h, vget_high_s16(rs_trans_16x8_5));
+
+ // w3 + w5 + w1 + (w1 >> 1)
+ y7_32x4_l = vaddw_s16(add_351_l, vget_low_s16(rs_trans_16x8_1));
+ y7_32x4_h = vaddw_s16(add_351_h, vget_high_s16(rs_trans_16x8_1));
+
+ y1_16x4_l = vmovn_s32(y1_32x4_l);
+ y1_16x4_h = vmovn_s32(y1_32x4_h);
+ y1_16x8 = vcombine_s16(y1_16x4_l, y1_16x4_h);
+ y3_16x4_l = vmovn_s32(y3_32x4_l);
+ y3_16x4_h = vmovn_s32(y3_32x4_h);
+ y3_16x8 = vcombine_s16(y3_16x4_l, y3_16x4_h);
+ y5_16x4_l = vmovn_s32(y5_32x4_l);
+ y5_16x4_h = vmovn_s32(y5_32x4_h);
+ y5_16x8 = vcombine_s16(y5_16x4_l, y5_16x4_h);
+ y7_16x4_l = vmovn_s32(y7_32x4_l);
+ y7_16x4_h = vmovn_s32(y7_32x4_h);
+ y7_16x8 = vcombine_s16(y7_16x4_l, y7_16x4_h);
+
+ rs_y1_16x8 = vshrq_n_s16(y1_16x8, 2);
+ rs_y3_16x8 = vshrq_n_s16(y3_16x8, 2);
+ rs_y5_16x8 = vshrq_n_s16(y5_16x8, 2);
+ rs_y7_16x8 = vshrq_n_s16(y7_16x8, 2);
+
+ z0_16x8 = vaddq_s16(y0_16x8, y6_16x8); // z0 = y0 + y6
+ z1_16x8 = vaddq_s16(y1_16x8, rs_y7_16x8); // z1 = y1 + (y7 >> 2)
+ z2_16x8 = vaddq_s16(y2_16x8, y4_16x8); // z2 = y2 + y4
+ z3_16x8 = vaddq_s16(y3_16x8, rs_y5_16x8); // z3 = y3 + (y5 >> 2)
+ z4_16x8 = vsubq_s16(y2_16x8, y4_16x8); // z4 = y2 - y4
+ z5_16x8 = vsubq_s16(rs_y3_16x8, y5_16x8); // z5 = (y3 >> 2) - y5
+ z6_16x8 = vsubq_s16(y0_16x8, y6_16x8); // z6 = y0 - y6
+ z7_16x8 = vsubq_s16(y7_16x8, rs_y1_16x8); // z7 = y7 - (y1 >> 2)
+
+ quant_res_16x8_0 = vaddq_s16(z0_16x8, z7_16x8); // x0 = z0 + z7
+ quant_res_16x8_1 = vaddq_s16(z2_16x8, z5_16x8); // x1 = z2 + z5
+ quant_res_16x8_2 = vaddq_s16(z4_16x8, z3_16x8); // x2 = z4 + z3
+ quant_res_16x8_3 = vaddq_s16(z6_16x8, z1_16x8); // x3 = z6 + z1
+ quant_res_16x8_4 = vsubq_s16(z6_16x8, z1_16x8); // x4 = z6 - z1
+ quant_res_16x8_5 = vsubq_s16(z4_16x8, z3_16x8); // x5 = z4 - z3
+ quant_res_16x8_6 = vsubq_s16(z2_16x8, z5_16x8); // x6 = z2 - z5
+ quant_res_16x8_7 = vsubq_s16(z0_16x8, z7_16x8); // x7 = z0 - z7
+ }
+
+ quant_res_16x8_0 = vrshrq_n_s16(quant_res_16x8_0, 6);
+ quant_res_16x8_1 = vrshrq_n_s16(quant_res_16x8_1, 6);
+ quant_res_16x8_2 = vrshrq_n_s16(quant_res_16x8_2, 6);
+ quant_res_16x8_3 = vrshrq_n_s16(quant_res_16x8_3, 6);
+ quant_res_16x8_4 = vrshrq_n_s16(quant_res_16x8_4, 6);
+ quant_res_16x8_5 = vrshrq_n_s16(quant_res_16x8_5, 6);
+ quant_res_16x8_6 = vrshrq_n_s16(quant_res_16x8_6, 6);
+ quant_res_16x8_7 = vrshrq_n_s16(quant_res_16x8_7, 6);
+
+ pred0 = vld1q_s16((int16_t *) pi2_pred);
+ pred1 = vld1q_s16((int16_t *) pi2_pred + pred_strd);
+ pred2 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 2));
+ pred3 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 3));
+ pred4 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 4));
+ pred5 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 5));
+ pred6 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 6));
+ pred7 = vld1q_s16((int16_t *) pi2_pred + (pred_strd * 7));
+
+ quant_res_16x8_0 = vaddq_s16(pred0, quant_res_16x8_0);
+ quant_res_16x8_1 = vaddq_s16(pred1, quant_res_16x8_1);
+ quant_res_16x8_2 = vaddq_s16(pred2, quant_res_16x8_2);
+ quant_res_16x8_3 = vaddq_s16(pred3, quant_res_16x8_3);
+ quant_res_16x8_4 = vaddq_s16(pred4, quant_res_16x8_4);
+ quant_res_16x8_5 = vaddq_s16(pred5, quant_res_16x8_5);
+ quant_res_16x8_6 = vaddq_s16(pred6, quant_res_16x8_6);
+ quant_res_16x8_7 = vaddq_s16(pred7, quant_res_16x8_7);
+
+ quant_res_16x8_0 = vminq_s16(quant_res_16x8_0, dup_max);
+ quant_res_16x8_0 = vmaxq_s16(quant_res_16x8_0, dup_min);
+ quant_res_16x8_1 = vminq_s16(quant_res_16x8_1, dup_max);
+ quant_res_16x8_1 = vmaxq_s16(quant_res_16x8_1, dup_min);
+ quant_res_16x8_2 = vminq_s16(quant_res_16x8_2, dup_max);
+ quant_res_16x8_2 = vmaxq_s16(quant_res_16x8_2, dup_min);
+ quant_res_16x8_3 = vminq_s16(quant_res_16x8_3, dup_max);
+ quant_res_16x8_3 = vmaxq_s16(quant_res_16x8_3, dup_min);
+ quant_res_16x8_4 = vminq_s16(quant_res_16x8_4, dup_max);
+ quant_res_16x8_4 = vmaxq_s16(quant_res_16x8_4, dup_min);
+ quant_res_16x8_5 = vminq_s16(quant_res_16x8_5, dup_max);
+ quant_res_16x8_5 = vmaxq_s16(quant_res_16x8_5, dup_min);
+ quant_res_16x8_6 = vminq_s16(quant_res_16x8_6, dup_max);
+ quant_res_16x8_6 = vmaxq_s16(quant_res_16x8_6, dup_min);
+ quant_res_16x8_7 = vminq_s16(quant_res_16x8_7, dup_max);
+ quant_res_16x8_7 = vmaxq_s16(quant_res_16x8_7, dup_min);
+
+ pred0_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_0);
+ pred1_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_1);
+ pred2_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_2);
+ pred3_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_3);
+ pred4_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_4);
+ pred5_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_5);
+ pred6_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_6);
+ pred7_in_64x2 = vreinterpretq_s64_s16(quant_res_16x8_7);
+
+ pred_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred0_in_64x2), vget_low_s64(pred1_in_64x2)));
+ pred_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred2_in_64x2), vget_low_s64(pred3_in_64x2)));
+ pred_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred0_in_64x2), vget_high_s64(pred1_in_64x2)));
+ pred_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred2_in_64x2), vget_high_s64(pred3_in_64x2)));
+ pred_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred4_in_64x2), vget_low_s64(pred5_in_64x2)));
+ pred_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred6_in_64x2), vget_low_s64(pred7_in_64x2)));
+ pred_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred4_in_64x2), vget_high_s64(pred5_in_64x2)));
+ pred_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred6_in_64x2), vget_high_s64(pred7_in_64x2)));
+
+ dup_val_1 = vabsq_s16(pred_b0_r01_in);
+ dup_val_2 = vabsq_s16(pred_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b1_r01_in);
+ dup_val_2 = vabsq_s16(pred_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b2_r45_in);
+ dup_val_2 = vabsq_s16(pred_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b3_r45_in);
+ dup_val_2 = vabsq_s16(pred_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ vst1q_s16(pi2_out, quant_res_16x8_0);
+ vst1q_s16(pi2_out + out_strd, quant_res_16x8_1);
+ vst1q_s16(pi2_out + out_strd * 2, quant_res_16x8_2);
+ vst1q_s16(pi2_out + out_strd * 3, quant_res_16x8_3);
+ vst1q_s16(pi2_out + out_strd * 4, quant_res_16x8_4);
+ vst1q_s16(pi2_out + out_strd * 5, quant_res_16x8_5);
+ vst1q_s16(pi2_out + out_strd * 6, quant_res_16x8_6);
+ vst1q_s16(pi2_out + out_strd * 7, quant_res_16x8_7);
+
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8_dc_neonintr */
+/* */
+/* Description : this function computes the resd dc output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8_dc_neonintr(WORD16 *pi2_src, WORD16 *pi2_pred,
+ WORD16 *pi2_out, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0, dup_min, dup_max;
+ int16x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred4_in, pred5_in, pred6_in, pred7_in;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+
+ int64x2_t pred0_in_64x2, pred1_in_64x2, pred2_in_64x2, pred3_in_64x2, pred4_in_64x2,
+ pred5_in_64x2, pred6_in_64x2, pred7_in_64x2;
+
+ int16x8_t pred_b0_r01_in;
+ int16x8_t pred_b0_r23_in;
+ int16x8_t pred_b1_r01_in;
+ int16x8_t pred_b1_r23_in;
+ int16x8_t pred_b2_r45_in;
+ int16x8_t pred_b2_r67_in;
+ int16x8_t pred_b3_r45_in;
+ int16x8_t pred_b3_r67_in;
+
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ i4_iq_out_temp = pi2_src[0];
+ INV_QUANT(i4_iq_out_temp, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+
+ /* inv transform and residual comp */
+ pred0_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred1_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred2_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred3_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred4_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred5_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred6_in = vld1q_s16((int16_t *) pi2_pred);
+ pi2_pred = pi2_pred + pred_strd;
+ pred7_in = vld1q_s16((int16_t *) pi2_pred);
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ pred0_in = vaddq_s16(pred0_in, temp_0);
+ pred1_in = vaddq_s16(pred1_in, temp_0);
+ pred2_in = vaddq_s16(pred2_in, temp_0);
+ pred3_in = vaddq_s16(pred3_in, temp_0);
+ pred4_in = vaddq_s16(pred4_in, temp_0);
+ pred5_in = vaddq_s16(pred5_in, temp_0);
+ pred6_in = vaddq_s16(pred6_in, temp_0);
+ pred7_in = vaddq_s16(pred7_in, temp_0);
+
+ pred0_in = vminq_s16(pred0_in, dup_max);
+ pred0_in = vmaxq_s16(pred0_in, dup_min);
+ pred1_in = vminq_s16(pred1_in, dup_max);
+ pred1_in = vmaxq_s16(pred1_in, dup_min);
+ pred2_in = vminq_s16(pred2_in, dup_max);
+ pred2_in = vmaxq_s16(pred2_in, dup_min);
+ pred3_in = vminq_s16(pred3_in, dup_max);
+ pred3_in = vmaxq_s16(pred3_in, dup_min);
+ pred4_in = vminq_s16(pred4_in, dup_max);
+ pred4_in = vmaxq_s16(pred4_in, dup_min);
+ pred5_in = vminq_s16(pred5_in, dup_max);
+ pred5_in = vmaxq_s16(pred5_in, dup_min);
+ pred6_in = vminq_s16(pred6_in, dup_max);
+ pred6_in = vmaxq_s16(pred6_in, dup_min);
+ pred7_in = vminq_s16(pred7_in, dup_max);
+ pred7_in = vmaxq_s16(pred7_in, dup_min);
+
+ pred0_in_64x2 = vreinterpretq_s64_s16(pred0_in);
+ pred1_in_64x2 = vreinterpretq_s64_s16(pred1_in);
+ pred2_in_64x2 = vreinterpretq_s64_s16(pred2_in);
+ pred3_in_64x2 = vreinterpretq_s64_s16(pred3_in);
+ pred4_in_64x2 = vreinterpretq_s64_s16(pred4_in);
+ pred5_in_64x2 = vreinterpretq_s64_s16(pred5_in);
+ pred6_in_64x2 = vreinterpretq_s64_s16(pred6_in);
+ pred7_in_64x2 = vreinterpretq_s64_s16(pred7_in);
+
+ pred_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred0_in_64x2), vget_low_s64(pred1_in_64x2)));
+ pred_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred2_in_64x2), vget_low_s64(pred3_in_64x2)));
+ pred_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred0_in_64x2), vget_high_s64(pred1_in_64x2)));
+ pred_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred2_in_64x2), vget_high_s64(pred3_in_64x2)));
+ pred_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred4_in_64x2), vget_low_s64(pred5_in_64x2)));
+ pred_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(pred6_in_64x2), vget_low_s64(pred7_in_64x2)));
+ pred_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred4_in_64x2), vget_high_s64(pred5_in_64x2)));
+ pred_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(pred6_in_64x2), vget_high_s64(pred7_in_64x2)));
+
+ dup_val_1 = vabsq_s16(pred_b0_r01_in);
+ dup_val_2 = vabsq_s16(pred_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b1_r01_in);
+ dup_val_2 = vabsq_s16(pred_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b2_r45_in);
+ dup_val_2 = vabsq_s16(pred_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b3_r45_in);
+ dup_val_2 = vabsq_s16(pred_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ vst1q_s16((int16_t *) (pi2_out), pred0_in);
+ vst1q_s16((int16_t *) (pi2_out + out_strd), pred1_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 2)), pred2_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 3)), pred3_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 4)), pred4_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 5)), pred5_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 6)), pred6_in);
+ vst1q_s16((int16_t *) (pi2_out + (out_strd * 7)), pred7_in);
+
+ return nnz;
+}
diff --git a/decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c b/decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c
new file mode 100644
index 0000000..dc445eb
--- /dev/null
+++ b/decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c
@@ -0,0 +1,1422 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_recon_neonintr.c
+ *
+ * @brief
+ * Contains definition of functions for h264 inverse quantization inverse
+ * transformation and recon
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - ih264_iquant_itrans_residual_recon_4x4()
+ * - ih264_iquant_itrans_residual_recon_8x8()
+ * - isvcd_iquant_itrans_residual_recon_4x4_dc_neonintr()
+ * - isvcd_iquant_itrans_residual_recon_8x8_dc_neonintr()
+ * - ih264_iquant_itrans_residual_recon_chroma_4x4()
+ * - isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_neonintr()
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include <string.h>
+#include <arm_neon.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans_residual_recon.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4_dc_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ int16x8_t resd01, resd23, dup_max, dup_min;
+ WORD32 i4_nnz;
+
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+ if(iq_start_idx == 0)
+ {
+ i4_iq_out_temp = pi2_src[0];
+
+ INV_QUANT(i4_iq_out_temp, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ i4_iq_out_temp = pi2_dc_ld_addr[0];
+ }
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred1_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred2_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred3_in = vld1_u8((uint8_t *) pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ resd0_in = vaddq_s16(resd0_in, temp_0);
+ resd1_in = vaddq_s16(resd1_in, temp_0);
+ resd2_in = vaddq_s16(resd2_in, temp_0);
+ resd3_in = vaddq_s16(resd3_in, temp_0);
+
+ resd0_in = vminq_s16(resd0_in, dup_max);
+ resd0_in = vmaxq_s16(resd0_in, dup_min);
+ resd1_in = vminq_s16(resd1_in, dup_max);
+ resd1_in = vmaxq_s16(resd1_in, dup_min);
+ resd2_in = vminq_s16(resd2_in, dup_max);
+ resd2_in = vmaxq_s16(resd2_in, dup_min);
+ resd3_in = vminq_s16(resd3_in, dup_max);
+ resd3_in = vmaxq_s16(resd3_in, dup_min);
+
+ resd01 = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd0_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd1_in))));
+
+ resd23 = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd2_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd3_in))));
+
+ dup_val_1 = vabsq_s16(resd01);
+ dup_val_2 = vabsq_s16(resd23);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred0_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd), vreinterpret_u32_u8(pred1_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd * 2), vreinterpret_u32_u8(pred2_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd * 3), vreinterpret_u32_u8(pred3_in), 0);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_neonintr */
+/* */
+/* Description : this function computes the recon output for the chroma */
+/* from IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in, dup_min, dup_max;
+
+ uint8x8_t i4_out_horz_8x8_r0, i4_out_horz_8x8_r1, i4_out_horz_8x8_r2, i4_out_horz_8x8_r3;
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ i4_iq_out_temp = pi2_dc_src[0];
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred1_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred2_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred3_in = vld1_u8((uint8_t *) pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ resd0_in = vaddq_s16(resd0_in, temp_0);
+ resd1_in = vaddq_s16(resd1_in, temp_0);
+ resd2_in = vaddq_s16(resd2_in, temp_0);
+ resd3_in = vaddq_s16(resd3_in, temp_0);
+
+ resd0_in = vminq_s16(resd0_in, dup_max);
+ resd0_in = vmaxq_s16(resd0_in, dup_min);
+ resd1_in = vminq_s16(resd1_in, dup_max);
+ resd1_in = vmaxq_s16(resd1_in, dup_min);
+ resd2_in = vminq_s16(resd2_in, dup_max);
+ resd2_in = vmaxq_s16(resd2_in, dup_min);
+ resd3_in = vminq_s16(resd3_in, dup_max);
+ resd3_in = vmaxq_s16(resd3_in, dup_min);
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + out_strd);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + out_strd * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + out_strd * 3);
+
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), i4_out_horz_8x8_r3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4_neonintr */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x4_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd01_in, resd23_in, dup_min, dup_max;
+ int16x8_t pred01_in, pred23_in;
+ uint8x8_t pred01_un, pred23_un;
+ WORD32 i4_nnz;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ UNUSED(pi2_tmp);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ if(iq_start_idx == 1)
+ {
+ q0_16x4 = vset_lane_s16(pi2_dc_ld_addr[0], q0_16x4, 0);
+ }
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ resd0_in = vld1_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ resd0_in = vadd_s16(resd0_in, x0_16x4);
+ resd1_in = vadd_s16(resd1_in, x1_16x4);
+ resd2_in = vadd_s16(resd2_in, x2_16x4);
+ resd3_in = vadd_s16(resd3_in, x3_16x4);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ resd01_in = vcombine_s16(resd0_in, resd1_in);
+ resd23_in = vcombine_s16(resd2_in, resd3_in);
+
+ resd01_in = vminq_s16(resd01_in, dup_max);
+ resd01_in = vmaxq_s16(resd01_in, dup_min);
+ resd23_in = vminq_s16(resd23_in, dup_max);
+ resd23_in = vmaxq_s16(resd23_in, dup_min);
+
+ dup_val_1 = vabsq_s16(resd01_in);
+ dup_val_2 = vabsq_s16(resd23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ pred01_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(pred0)),
+ vget_low_s64(vreinterpretq_s64_s16(pred1))));
+
+ pred23_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(pred2)),
+ vget_low_s64(vreinterpretq_s64_s16(pred3))));
+
+ pred01_in = vaddq_s16(pred01_in, resd01_in);
+ pred23_in = vaddq_s16(pred23_in, resd23_in);
+
+ pred01_un = vqmovun_s16(pred01_in);
+ pred23_un = vqmovun_s16(pred23_in);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred01_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd), vreinterpret_u32_u8(pred01_un), 1);
+ vst1_lane_u32((uint32_t *) (pu1_out + (out_strd << 1)), vreinterpret_u32_u8(pred23_un), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + ((out_strd << 1) + out_strd)),
+ vreinterpret_u32_u8(pred23_un), 1);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4_neonintr */
+/* */
+/* Description : this function computes the recon output for the chroma */
+/* from IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ int16x4x4_t src_16x4x2;
+ int16x4x4_t iscal_16x4x2;
+ int16x4x4_t weigh_16x4x2;
+
+ int16x4_t q0_16x4, q1_16x4, q2_16x4, q3_16x4;
+ int32x4_t q0_32x4, q1_32x4, q2_32x4, q3_32x4;
+ int16x4_t rq1_16x4, rq3_16x4;
+ int16x4_t x0_16x4, x1_16x4, x2_16x4, x3_16x4;
+ int16x8_t x0_16x8, x1_16x8, x2_16x8, x3_16x8;
+ int16x4_t xx0_16x4, xx1_16x4, xx2_16x4, xx3_16x4;
+ int16x4_t xx0_0_16x4, xx0_1_16x4, xx2_0_16x4, xx2_1_16x4;
+ int32x2_t x0_32x2, x1_32x2, x2_32x2, x3_32x2;
+ int16x4_t weigh0_16x4, weigh1_16x4, weigh2_16x4, weigh3_16x4;
+
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t rec0, rec1, rec2, rec3;
+ uint8x8_t rec0_un, rec1_un, rec2_un, rec3_un;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in, dup_min, dup_max;
+ uint8x8_t out0, out1, out2, out3;
+ int16x4x2_t xx0_16x4_2, xx2_16x4_2;
+ int32x2x2_t x0_32x2_2, x1_32x2_2;
+
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+ int32x4_t qp_div_6_32x4 = vdupq_n_s32(u4_qp_div_6);
+ WORD16 rnd_factor = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ int32x4_t rnd_fact = vdupq_n_s32(rnd_factor);
+ UNUSED(pi2_tmp);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ src_16x4x2 = vld4_s16(pi2_src);
+ iscal_16x4x2 = vld4_s16((const int16_t *) pu2_iscal_mat);
+ weigh_16x4x2 = vld4_s16((const int16_t *) pu2_weigh_mat);
+
+ weigh0_16x4 = vmul_s16(weigh_16x4x2.val[0], iscal_16x4x2.val[0]);
+ weigh1_16x4 = vmul_s16(weigh_16x4x2.val[1], iscal_16x4x2.val[1]);
+ weigh2_16x4 = vmul_s16(weigh_16x4x2.val[2], iscal_16x4x2.val[2]);
+ weigh3_16x4 = vmul_s16(weigh_16x4x2.val[3], iscal_16x4x2.val[3]);
+
+ q0_32x4 = vmull_s16(weigh0_16x4, src_16x4x2.val[0]);
+ q1_32x4 = vmull_s16(weigh1_16x4, src_16x4x2.val[1]);
+ q2_32x4 = vmull_s16(weigh2_16x4, src_16x4x2.val[2]);
+ q3_32x4 = vmull_s16(weigh3_16x4, src_16x4x2.val[3]);
+
+ q0_32x4 = vaddq_s32(q0_32x4, rnd_fact);
+ q1_32x4 = vaddq_s32(q1_32x4, rnd_fact);
+ q2_32x4 = vaddq_s32(q2_32x4, rnd_fact);
+ q3_32x4 = vaddq_s32(q3_32x4, rnd_fact);
+
+ q0_32x4 = vshlq_s32(q0_32x4, qp_div_6_32x4);
+ q1_32x4 = vshlq_s32(q1_32x4, qp_div_6_32x4);
+ q2_32x4 = vshlq_s32(q2_32x4, qp_div_6_32x4);
+ q3_32x4 = vshlq_s32(q3_32x4, qp_div_6_32x4);
+
+ q0_16x4 = vqshrn_n_s32(q0_32x4, 4);
+ q1_16x4 = vqshrn_n_s32(q1_32x4, 4);
+ q2_16x4 = vqshrn_n_s32(q2_32x4, 4);
+ q3_16x4 = vqshrn_n_s32(q3_32x4, 4);
+
+ q0_16x4 = vset_lane_s16(pi2_dc_src[0], q0_16x4, 0);
+
+ rq1_16x4 = vshr_n_s16(q1_16x4, 1); // q1 >>1
+ rq3_16x4 = vshr_n_s16(q3_16x4, 1); // q3 >>1
+
+ x0_16x4 = vadd_s16(q0_16x4, q2_16x4); // x0 = q0 + q2
+ x1_16x4 = vsub_s16(q0_16x4, q2_16x4); // x1 = q0 - q2
+ x2_16x4 = vsub_s16(rq1_16x4, q3_16x4); // x2 = q1>>1 - q3
+ x3_16x4 = vadd_s16(q1_16x4, rq3_16x4); // x2 = q1 + q3>>1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x3_16x4); // x0+x3
+ xx1_16x4 = vadd_s16(x1_16x4, x2_16x4); // x1+x2
+ xx2_16x4 = vsub_s16(x1_16x4, x2_16x4); // x1-x2
+ xx3_16x4 = vsub_s16(x0_16x4, x3_16x4); // x0-x3
+
+ xx0_16x4_2 = vtrn_s16(xx0_16x4, xx1_16x4);
+ xx0_0_16x4 = xx0_16x4_2.val[0];
+ xx0_1_16x4 = xx0_16x4_2.val[1];
+ xx2_16x4_2 = vtrn_s16(xx2_16x4, xx3_16x4);
+ xx2_0_16x4 = xx2_16x4_2.val[0];
+ xx2_1_16x4 = xx2_16x4_2.val[1];
+ x0_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_0_16x4), vreinterpret_s32_s16(xx2_0_16x4));
+ x1_32x2_2 = vtrn_s32(vreinterpret_s32_s16(xx0_1_16x4), vreinterpret_s32_s16(xx2_1_16x4));
+ x0_32x2 = x0_32x2_2.val[0];
+ x1_32x2 = x1_32x2_2.val[0];
+ x2_32x2 = x0_32x2_2.val[1];
+ x3_32x2 = x1_32x2_2.val[1];
+
+ x0_16x4 = vreinterpret_s16_s32(x0_32x2);
+ x1_16x4 = vreinterpret_s16_s32(x1_32x2);
+ x2_16x4 = vreinterpret_s16_s32(x2_32x2);
+ x3_16x4 = vreinterpret_s16_s32(x3_32x2);
+
+ /* vertical inverse transform */
+ rq1_16x4 = vshr_n_s16(x1_16x4, 1); // q1 >> 1
+ rq3_16x4 = vshr_n_s16(x3_16x4, 1); // q3 >> 1
+
+ xx0_16x4 = vadd_s16(x0_16x4, x2_16x4); // x0 = q0 + q2
+ xx1_16x4 = vsub_s16(x0_16x4, x2_16x4); // x1 = q0 - q2
+ xx2_16x4 = vsub_s16(rq1_16x4, x3_16x4); // x2 = q1>>1 - q3
+ xx3_16x4 = vadd_s16(x1_16x4, rq3_16x4); // x3 = q1 + q3>>1
+
+ x0_16x4 = vadd_s16(xx0_16x4, xx3_16x4); // imacro = x0 + x3
+ x1_16x4 = vadd_s16(xx1_16x4, xx2_16x4); // imacro = x1 + x2
+ x2_16x4 = vsub_s16(xx1_16x4, xx2_16x4); // imacro = x1 - x2
+ x3_16x4 = vsub_s16(xx0_16x4, xx3_16x4); // imacro = x0 - x3
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ x0_16x4 = vrshr_n_s16(x0_16x4, 6);
+ x1_16x4 = vrshr_n_s16(x1_16x4, 6);
+ x2_16x4 = vrshr_n_s16(x2_16x4, 6);
+ x3_16x4 = vrshr_n_s16(x3_16x4, 6);
+
+ x0_16x8 = vreinterpretq_s16_s32(vmovl_s16(x0_16x4));
+ x1_16x8 = vreinterpretq_s16_s32(vmovl_s16(x1_16x4));
+ x2_16x8 = vreinterpretq_s16_s32(vmovl_s16(x2_16x4));
+ x3_16x8 = vreinterpretq_s16_s32(vmovl_s16(x3_16x4));
+
+ resd0_in = vaddq_s16(resd0_in, x0_16x8);
+ resd1_in = vaddq_s16(resd1_in, x1_16x8);
+ resd2_in = vaddq_s16(resd2_in, x2_16x8);
+ resd3_in = vaddq_s16(resd3_in, x3_16x8);
+
+ resd0_in = vminq_s16(resd0_in, dup_max);
+ resd0_in = vmaxq_s16(resd0_in, dup_min);
+ resd1_in = vminq_s16(resd1_in, dup_max);
+ resd1_in = vmaxq_s16(resd1_in, dup_min);
+ resd2_in = vminq_s16(resd2_in, dup_max);
+ resd2_in = vmaxq_s16(resd2_in, dup_min);
+ resd3_in = vminq_s16(resd3_in, dup_max);
+ resd3_in = vmaxq_s16(resd3_in, dup_min);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd << 1));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ rec0 = vaddq_s16(pred0, resd0_in);
+ rec1 = vaddq_s16(pred1, resd1_in);
+ rec2 = vaddq_s16(pred2, resd2_in);
+ rec3 = vaddq_s16(pred3, resd3_in);
+
+ out0 = vld1_u8(pu1_out);
+ out1 = vld1_u8(pu1_out + out_strd);
+ out2 = vld1_u8(pu1_out + out_strd * 2);
+ out3 = vld1_u8(pu1_out + out_strd * 3);
+
+ rec0_un = vqmovun_s16(rec0);
+ rec1_un = vqmovun_s16(rec1);
+ rec2_un = vqmovun_s16(rec2);
+ rec3_un = vqmovun_s16(rec3);
+
+ out0 = vbsl_u8(chroma_mask_8x8, rec0_un, out0);
+ out1 = vbsl_u8(chroma_mask_8x8, rec1_un, out1);
+ out2 = vbsl_u8(chroma_mask_8x8, rec2_un, out2);
+ out3 = vbsl_u8(chroma_mask_8x8, rec3_un, out3);
+
+ vst1_u8((pu1_out), out0);
+ vst1_u8((pu1_out + out_strd), out1);
+ vst1_u8((pu1_out + (out_strd << 1)), out2);
+ vst1_u8((pu1_out + ((out_strd << 1) + out_strd)), out3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8_neonintr */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd_ptr, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ int32x4_t qp_div_32x4 = vdupq_n_s32(qp_div);
+ int16x8_t iscal_16x8_0, iscal_16x8_1, iscal_16x8_2, iscal_16x8_3, iscal_16x8_4, iscal_16x8_5,
+ iscal_16x8_6, iscal_16x8_7;
+ int16x8_t weigh_16x8_0, weigh_16x8_1, weigh_16x8_2, weigh_16x8_3, weigh_16x8_4, weigh_16x8_5,
+ weigh_16x8_6, weigh_16x8_7;
+
+ int16x8_t src_16x8_0, src_16x8_1, src_16x8_2, src_16x8_3, src_16x8_4, src_16x8_5, src_16x8_6,
+ src_16x8_7;
+ int16x8_t coeff_mul_16x8_0, coeff_mul_16x8_1, coeff_mul_16x8_2, coeff_mul_16x8_3,
+ coeff_mul_16x8_4, coeff_mul_16x8_5, coeff_mul_16x8_6, coeff_mul_16x8_7;
+
+ int32x4_t quant_res_32x4_l_0, quant_res_32x4_l_1, quant_res_32x4_l_2, quant_res_32x4_l_3,
+ quant_res_32x4_l_4, quant_res_32x4_l_5, quant_res_32x4_l_6, quant_res_32x4_l_7;
+ int32x4_t quant_res_32x4_h_0, quant_res_32x4_h_1, quant_res_32x4_h_2, quant_res_32x4_h_3,
+ quant_res_32x4_h_4, quant_res_32x4_h_5, quant_res_32x4_h_6, quant_res_32x4_h_7;
+ int16x4_t quant_res_16x4_l_0, quant_res_16x4_l_1, quant_res_16x4_l_2, quant_res_16x4_l_3,
+ quant_res_16x4_l_4, quant_res_16x4_l_5, quant_res_16x4_l_6, quant_res_16x4_l_7;
+ int16x4_t quant_res_16x4_h_0, quant_res_16x4_h_1, quant_res_16x4_h_2, quant_res_16x4_h_3,
+ quant_res_16x4_h_4, quant_res_16x4_h_5, quant_res_16x4_h_6, quant_res_16x4_h_7;
+
+ int16x8_t quant_res_16x8_0, quant_res_16x8_1, quant_res_16x8_2, quant_res_16x8_3,
+ quant_res_16x8_4, quant_res_16x8_5, quant_res_16x8_6, quant_res_16x8_7;
+
+ int16x8_t trans_16x8_0, trans_16x8_1, trans_16x8_2, trans_16x8_3, trans_16x8_4, trans_16x8_5,
+ trans_16x8_6, trans_16x8_7;
+ int32x4_t trans_32x4_0, trans_32x4_1, trans_32x4_2, trans_32x4_3, trans_32x4_4, trans_32x4_5,
+ trans_32x4_6, trans_32x4_7;
+ int64x2_t trans_64x2_0, trans_64x2_1, trans_64x2_2, trans_64x2_3, trans_64x2_4, trans_64x2_5,
+ trans_64x2_6, trans_64x2_7;
+ int16x4_t trans_16x4_1_l, trans_16x4_3_l, trans_16x4_5_l, trans_16x4_7_l;
+ int16x8_t rs_trans_16x8_1, rs_trans_16x8_2, rs_trans_16x8_3, rs_trans_16x8_5, rs_trans_16x8_6,
+ rs_trans_16x8_7;
+ int32x4_t sub_3_5_l, sub_3_5_h;
+ int32x4_t add_3_5_l, add_3_5_h;
+ int32x4_t sub_1_7_l, sub_1_7_h;
+ int32x4_t add_1_7_l, add_1_7_h;
+ int32x4_t sub_357_l, sub_357_h;
+ int32x4_t add_351_l, add_351_h;
+ int32x4_t add_175_l, add_175_h;
+ int32x4_t sub_173_l, sub_173_h;
+ int32x4_t y1_32x4_l, y1_32x4_h;
+ int32x4_t y3_32x4_l, y3_32x4_h;
+ int32x4_t y5_32x4_l, y5_32x4_h;
+ int32x4_t y7_32x4_l, y7_32x4_h;
+ int16x4_t y1_16x4_l, y3_16x4_l, y5_16x4_l, y7_16x4_l;
+ int16x4_t y1_16x4_h, y3_16x4_h, y5_16x4_h, y7_16x4_h;
+
+ int16x8_t y0_16x8, y1_16x8, y2_16x8, y3_16x8, y4_16x8, y5_16x8, y6_16x8, y7_16x8;
+ int16x8_t rs_y1_16x8, rs_y3_16x8, rs_y5_16x8, rs_y7_16x8;
+ int16x8_t z0_16x8, z1_16x8, z2_16x8, z3_16x8, z4_16x8, z5_16x8, z6_16x8, z7_16x8;
+
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in, resd4_in, resd5_in, resd6_in, resd7_in;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in, pred4_in, pred5_in, pred6_in, pred7_in;
+ int16x8_t pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7;
+ int16x8_t rec0, rec1, rec2, rec3, rec4, rec5, rec6, rec7;
+ uint8x8_t rec0_un, rec1_un, rec2_un, rec3_un, rec4_un, rec5_un, rec6_un, rec7_un;
+
+ int64x2_t resd0_64x2, resd1_64x2, resd2_64x2, resd3_64x2, resd4_64x2, resd5_64x2, resd6_64x2,
+ resd7_64x2;
+ int16x8x2_t trans_16x8_0_1, trans_16x8_2_3, trans_16x8_4_5, trans_16x8_6_7;
+ int32x4x2_t trans_32x4_0_2, trans_32x4_1_3, trans_32x4_4_6, trans_32x4_5_7;
+
+ int16x8_t resd_b0_r01;
+ int16x8_t resd_b0_r23;
+ int16x8_t resd_b1_r01;
+ int16x8_t resd_b1_r23;
+ int16x8_t resd_b2_r45;
+ int16x8_t resd_b2_r67;
+ int16x8_t resd_b3_r45;
+ int16x8_t resd_b3_r67;
+
+ int16x8_t dup_min, dup_max;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+ WORD32 i;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ iscal_16x8_0 = vld1q_s16((const int16_t *) pu2_iscale_mat);
+ iscal_16x8_1 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 8));
+ iscal_16x8_2 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 16));
+ iscal_16x8_3 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 24));
+ iscal_16x8_4 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 32));
+ iscal_16x8_5 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 40));
+ iscal_16x8_6 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 48));
+ iscal_16x8_7 = vld1q_s16((const int16_t *) (pu2_iscale_mat + 56));
+
+ weigh_16x8_0 = vld1q_s16((const int16_t *) pu2_weigh_mat);
+ weigh_16x8_1 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 8));
+ weigh_16x8_2 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 16));
+ weigh_16x8_3 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 24));
+ weigh_16x8_4 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 32));
+ weigh_16x8_5 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 40));
+ weigh_16x8_6 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 48));
+ weigh_16x8_7 = vld1q_s16((const int16_t *) (pu2_weigh_mat + 56));
+
+ src_16x8_0 = vld1q_s16((const int16_t *) pi2_src); // a0 a1 a2 a3 a4 a5 a6 a7
+ src_16x8_1 = vld1q_s16((const int16_t *) (pi2_src + 8)); // b0 b1 b2 b3 b4 b5 b6 b7
+ src_16x8_2 = vld1q_s16((const int16_t *) (pi2_src + 16));
+ src_16x8_3 = vld1q_s16((const int16_t *) (pi2_src + 24));
+ src_16x8_4 = vld1q_s16((const int16_t *) (pi2_src + 32));
+ src_16x8_5 = vld1q_s16((const int16_t *) (pi2_src + 40));
+ src_16x8_6 = vld1q_s16((const int16_t *) (pi2_src + 48));
+ src_16x8_7 = vld1q_s16((const int16_t *) (pi2_src + 56));
+
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ coeff_mul_16x8_0 = vmulq_s16(iscal_16x8_0, weigh_16x8_0);
+ coeff_mul_16x8_1 = vmulq_s16(iscal_16x8_1, weigh_16x8_1);
+ coeff_mul_16x8_2 = vmulq_s16(iscal_16x8_2, weigh_16x8_2);
+ coeff_mul_16x8_3 = vmulq_s16(iscal_16x8_3, weigh_16x8_3);
+ coeff_mul_16x8_4 = vmulq_s16(iscal_16x8_4, weigh_16x8_4);
+ coeff_mul_16x8_5 = vmulq_s16(iscal_16x8_5, weigh_16x8_5);
+ coeff_mul_16x8_6 = vmulq_s16(iscal_16x8_6, weigh_16x8_6);
+ coeff_mul_16x8_7 = vmulq_s16(iscal_16x8_7, weigh_16x8_7);
+
+ quant_res_32x4_l_0 = vmull_s16(vget_low_s16(coeff_mul_16x8_0), vget_low_s16(src_16x8_0));
+ quant_res_32x4_l_1 = vmull_s16(vget_low_s16(coeff_mul_16x8_1), vget_low_s16(src_16x8_1));
+ quant_res_32x4_l_2 = vmull_s16(vget_low_s16(coeff_mul_16x8_2), vget_low_s16(src_16x8_2));
+ quant_res_32x4_l_3 = vmull_s16(vget_low_s16(coeff_mul_16x8_3), vget_low_s16(src_16x8_3));
+ quant_res_32x4_l_4 = vmull_s16(vget_low_s16(coeff_mul_16x8_4), vget_low_s16(src_16x8_4));
+ quant_res_32x4_l_5 = vmull_s16(vget_low_s16(coeff_mul_16x8_5), vget_low_s16(src_16x8_5));
+ quant_res_32x4_l_6 = vmull_s16(vget_low_s16(coeff_mul_16x8_6), vget_low_s16(src_16x8_6));
+ quant_res_32x4_l_7 = vmull_s16(vget_low_s16(coeff_mul_16x8_7), vget_low_s16(src_16x8_7));
+
+ quant_res_32x4_h_0 = vmull_s16(vget_high_s16(coeff_mul_16x8_0), vget_high_s16(src_16x8_0));
+ quant_res_32x4_h_1 = vmull_s16(vget_high_s16(coeff_mul_16x8_1), vget_high_s16(src_16x8_1));
+ quant_res_32x4_h_2 = vmull_s16(vget_high_s16(coeff_mul_16x8_2), vget_high_s16(src_16x8_2));
+ quant_res_32x4_h_3 = vmull_s16(vget_high_s16(coeff_mul_16x8_3), vget_high_s16(src_16x8_3));
+ quant_res_32x4_h_4 = vmull_s16(vget_high_s16(coeff_mul_16x8_4), vget_high_s16(src_16x8_4));
+ quant_res_32x4_h_5 = vmull_s16(vget_high_s16(coeff_mul_16x8_5), vget_high_s16(src_16x8_5));
+ quant_res_32x4_h_6 = vmull_s16(vget_high_s16(coeff_mul_16x8_6), vget_high_s16(src_16x8_6));
+ quant_res_32x4_h_7 = vmull_s16(vget_high_s16(coeff_mul_16x8_7), vget_high_s16(src_16x8_7));
+
+ quant_res_32x4_l_0 = vshlq_s32(quant_res_32x4_l_0, qp_div_32x4);
+ quant_res_32x4_l_1 = vshlq_s32(quant_res_32x4_l_1, qp_div_32x4);
+ quant_res_32x4_l_2 = vshlq_s32(quant_res_32x4_l_2, qp_div_32x4);
+ quant_res_32x4_l_3 = vshlq_s32(quant_res_32x4_l_3, qp_div_32x4);
+ quant_res_32x4_l_4 = vshlq_s32(quant_res_32x4_l_4, qp_div_32x4);
+ quant_res_32x4_l_5 = vshlq_s32(quant_res_32x4_l_5, qp_div_32x4);
+ quant_res_32x4_l_6 = vshlq_s32(quant_res_32x4_l_6, qp_div_32x4);
+ quant_res_32x4_l_7 = vshlq_s32(quant_res_32x4_l_7, qp_div_32x4);
+
+ quant_res_32x4_h_0 = vshlq_s32(quant_res_32x4_h_0, qp_div_32x4);
+ quant_res_32x4_h_1 = vshlq_s32(quant_res_32x4_h_1, qp_div_32x4);
+ quant_res_32x4_h_2 = vshlq_s32(quant_res_32x4_h_2, qp_div_32x4);
+ quant_res_32x4_h_3 = vshlq_s32(quant_res_32x4_h_3, qp_div_32x4);
+ quant_res_32x4_h_4 = vshlq_s32(quant_res_32x4_h_4, qp_div_32x4);
+ quant_res_32x4_h_5 = vshlq_s32(quant_res_32x4_h_5, qp_div_32x4);
+ quant_res_32x4_h_6 = vshlq_s32(quant_res_32x4_h_6, qp_div_32x4);
+ quant_res_32x4_h_7 = vshlq_s32(quant_res_32x4_h_7, qp_div_32x4);
+
+ quant_res_16x4_l_0 = vqrshrn_n_s32(quant_res_32x4_l_0, 6);
+ quant_res_16x4_l_1 = vqrshrn_n_s32(quant_res_32x4_l_1, 6);
+ quant_res_16x4_l_2 = vqrshrn_n_s32(quant_res_32x4_l_2, 6);
+ quant_res_16x4_l_3 = vqrshrn_n_s32(quant_res_32x4_l_3, 6);
+ quant_res_16x4_l_4 = vqrshrn_n_s32(quant_res_32x4_l_4, 6);
+ quant_res_16x4_l_5 = vqrshrn_n_s32(quant_res_32x4_l_5, 6);
+ quant_res_16x4_l_6 = vqrshrn_n_s32(quant_res_32x4_l_6, 6);
+ quant_res_16x4_l_7 = vqrshrn_n_s32(quant_res_32x4_l_7, 6);
+
+ quant_res_16x4_h_0 = vqrshrn_n_s32(quant_res_32x4_h_0, 6);
+ quant_res_16x4_h_1 = vqrshrn_n_s32(quant_res_32x4_h_1, 6);
+ quant_res_16x4_h_2 = vqrshrn_n_s32(quant_res_32x4_h_2, 6);
+ quant_res_16x4_h_3 = vqrshrn_n_s32(quant_res_32x4_h_3, 6);
+ quant_res_16x4_h_4 = vqrshrn_n_s32(quant_res_32x4_h_4, 6);
+ quant_res_16x4_h_5 = vqrshrn_n_s32(quant_res_32x4_h_5, 6);
+ quant_res_16x4_h_6 = vqrshrn_n_s32(quant_res_32x4_h_6, 6);
+ quant_res_16x4_h_7 = vqrshrn_n_s32(quant_res_32x4_h_7, 6);
+
+ quant_res_16x8_0 = vcombine_s16(quant_res_16x4_l_0, quant_res_16x4_h_0);
+ quant_res_16x8_1 = vcombine_s16(quant_res_16x4_l_1, quant_res_16x4_h_1);
+ quant_res_16x8_2 = vcombine_s16(quant_res_16x4_l_2, quant_res_16x4_h_2);
+ quant_res_16x8_3 = vcombine_s16(quant_res_16x4_l_3, quant_res_16x4_h_3);
+ quant_res_16x8_4 = vcombine_s16(quant_res_16x4_l_4, quant_res_16x4_h_4);
+ quant_res_16x8_5 = vcombine_s16(quant_res_16x4_l_5, quant_res_16x4_h_5);
+ quant_res_16x8_6 = vcombine_s16(quant_res_16x4_l_6, quant_res_16x4_h_6);
+ quant_res_16x8_7 = vcombine_s16(quant_res_16x4_l_7, quant_res_16x4_h_7);
+
+ for(i = 0; i < 2; i++)
+ {
+ trans_16x8_0_1 = vtrnq_s16(quant_res_16x8_0, quant_res_16x8_1);
+ trans_16x8_0 = trans_16x8_0_1.val[0];
+ trans_16x8_1 = trans_16x8_0_1.val[1];
+
+ trans_16x8_2_3 = vtrnq_s16(quant_res_16x8_2, quant_res_16x8_3);
+ trans_16x8_2 = trans_16x8_2_3.val[0];
+ trans_16x8_3 = trans_16x8_2_3.val[1];
+
+ trans_16x8_4_5 = vtrnq_s16(quant_res_16x8_4, quant_res_16x8_5);
+ trans_16x8_4 = trans_16x8_4_5.val[0];
+ trans_16x8_5 = trans_16x8_4_5.val[1];
+
+ trans_16x8_6_7 = vtrnq_s16(quant_res_16x8_6, quant_res_16x8_7);
+ trans_16x8_6 = trans_16x8_6_7.val[0];
+ trans_16x8_7 = trans_16x8_6_7.val[1];
+
+ trans_32x4_0_2 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_0), vreinterpretq_s32_s16(trans_16x8_2));
+ trans_32x4_0 = trans_32x4_0_2.val[0];
+ trans_32x4_2 = trans_32x4_0_2.val[1];
+
+ trans_32x4_1_3 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_1), vreinterpretq_s32_s16(trans_16x8_3));
+ trans_32x4_1 = trans_32x4_1_3.val[0];
+ trans_32x4_3 = trans_32x4_1_3.val[1];
+
+ trans_32x4_4_6 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_4), vreinterpretq_s32_s16(trans_16x8_6));
+ trans_32x4_4 = trans_32x4_4_6.val[0];
+ trans_32x4_6 = trans_32x4_4_6.val[1];
+
+ trans_32x4_5_7 =
+ vtrnq_s32(vreinterpretq_s32_s16(trans_16x8_5), vreinterpretq_s32_s16(trans_16x8_7));
+ trans_32x4_5 = trans_32x4_5_7.val[0];
+ trans_32x4_7 = trans_32x4_5_7.val[1];
+
+ trans_64x2_0 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_4)));
+ trans_64x2_4 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_0)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_4)));
+
+ trans_64x2_1 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_5)));
+ trans_64x2_5 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_1)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_5)));
+
+ trans_64x2_2 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_6)));
+ trans_64x2_6 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_2)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_6)));
+
+ trans_64x2_3 = vcombine_s64(vreinterpret_s64_s32(vget_low_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_low_s32(trans_32x4_7)));
+ trans_64x2_7 = vcombine_s64(vreinterpret_s64_s32(vget_high_s32(trans_32x4_3)),
+ vreinterpret_s64_s32(vget_high_s32(trans_32x4_7)));
+
+ trans_16x8_0 = vreinterpretq_s16_s64(trans_64x2_0);
+ trans_16x8_1 = vreinterpretq_s16_s64(trans_64x2_1);
+ trans_16x8_2 = vreinterpretq_s16_s64(trans_64x2_2);
+ trans_16x8_3 = vreinterpretq_s16_s64(trans_64x2_3);
+ trans_16x8_4 = vreinterpretq_s16_s64(trans_64x2_4);
+ trans_16x8_5 = vreinterpretq_s16_s64(trans_64x2_5);
+ trans_16x8_6 = vreinterpretq_s16_s64(trans_64x2_6);
+ trans_16x8_7 = vreinterpretq_s16_s64(trans_64x2_7);
+
+ rs_trans_16x8_1 = vshrq_n_s16(trans_16x8_1, 1);
+ rs_trans_16x8_2 = vshrq_n_s16(trans_16x8_2, 1);
+ rs_trans_16x8_3 = vshrq_n_s16(trans_16x8_3, 1);
+ rs_trans_16x8_5 = vshrq_n_s16(trans_16x8_5, 1);
+ rs_trans_16x8_6 = vshrq_n_s16(trans_16x8_6, 1);
+ rs_trans_16x8_7 = vshrq_n_s16(trans_16x8_7, 1);
+
+ y0_16x8 = vaddq_s16(trans_16x8_0,
+ trans_16x8_4); // i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4] );
+ y2_16x8 = vsubq_s16(trans_16x8_0,
+ trans_16x8_4); // i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4] );
+ y4_16x8 = vsubq_s16(rs_trans_16x8_2,
+ trans_16x8_6); // i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6] );
+ y6_16x8 = vaddq_s16(trans_16x8_2,
+ rs_trans_16x8_6); // i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+
+ trans_16x4_3_l = vget_low_s16(trans_16x8_3);
+ trans_16x4_5_l = vget_low_s16(trans_16x8_5);
+
+ //-w3 + w5
+ sub_3_5_l = vsubl_s16(vget_low_s16(trans_16x8_5), vget_low_s16(trans_16x8_3));
+ sub_3_5_h = vsubl_s16(vget_high_s16(trans_16x8_5), vget_high_s16(trans_16x8_3));
+
+ // w3 + w5
+ add_3_5_l = vaddl_s16(trans_16x4_3_l, trans_16x4_5_l);
+ add_3_5_h = vaddl_s16(vget_high_s16(trans_16x8_3), vget_high_s16(trans_16x8_5));
+
+ trans_16x4_1_l = vget_low_s16(trans_16x8_1);
+ trans_16x4_7_l = vget_low_s16(trans_16x8_7);
+
+ //-w1 + w7
+ sub_1_7_l = vsubl_s16(trans_16x4_7_l, trans_16x4_1_l);
+ sub_1_7_h = vsubl_s16(vget_high_s16(trans_16x8_7), vget_high_s16(trans_16x8_1));
+
+ // w1 + w7
+ add_1_7_l = vaddl_s16(trans_16x4_1_l, trans_16x4_7_l);
+ add_1_7_h = vaddl_s16(vget_high_s16(trans_16x8_1), vget_high_s16(trans_16x8_7));
+
+ //-w3 + w5 - w7
+ sub_357_l = vsubw_s16(sub_3_5_l, trans_16x4_7_l);
+ sub_357_h = vsubw_s16(sub_3_5_h, vget_high_s16(trans_16x8_7));
+
+ // w3 + w5 + w1
+ add_351_l = vaddw_s16(add_3_5_l, trans_16x4_1_l);
+ add_351_h = vaddw_s16(add_3_5_h, vget_high_s16(trans_16x8_1));
+
+ //-w1 + w7 + w5
+ add_175_l = vaddw_s16(sub_1_7_l, trans_16x4_5_l);
+ add_175_h = vaddw_s16(sub_1_7_h, vget_high_s16(trans_16x8_5));
+
+ // w1 + w7 - w3
+ sub_173_l = vsubw_s16(add_1_7_l, trans_16x4_3_l);
+ sub_173_h = vsubw_s16(add_1_7_h, vget_high_s16(trans_16x8_3));
+
+ //-w3 + w5 - w7 - (w7 >> 1)
+ y1_32x4_l = vsubw_s16(sub_357_l, vget_low_s16(rs_trans_16x8_7));
+ y1_32x4_h = vsubw_s16(sub_357_h, vget_high_s16(rs_trans_16x8_7));
+
+ // w1 + w7 - w3 - (w3 >> 1)
+ y3_32x4_l = vsubw_s16(sub_173_l, vget_low_s16(rs_trans_16x8_3));
+ y3_32x4_h = vsubw_s16(sub_173_h, vget_high_s16(rs_trans_16x8_3));
+
+ //-w1 + w7 + w5 + (w5 >> 1)
+ y5_32x4_l = vaddw_s16(add_175_l, vget_low_s16(rs_trans_16x8_5));
+ y5_32x4_h = vaddw_s16(add_175_h, vget_high_s16(rs_trans_16x8_5));
+
+ // w3 + w5 + w1 + (w1 >> 1)
+ y7_32x4_l = vaddw_s16(add_351_l, vget_low_s16(rs_trans_16x8_1));
+ y7_32x4_h = vaddw_s16(add_351_h, vget_high_s16(rs_trans_16x8_1));
+
+ y1_16x4_l = vmovn_s32(y1_32x4_l);
+ y1_16x4_h = vmovn_s32(y1_32x4_h);
+ y1_16x8 = vcombine_s16(y1_16x4_l, y1_16x4_h);
+ y3_16x4_l = vmovn_s32(y3_32x4_l);
+ y3_16x4_h = vmovn_s32(y3_32x4_h);
+ y3_16x8 = vcombine_s16(y3_16x4_l, y3_16x4_h);
+ y5_16x4_l = vmovn_s32(y5_32x4_l);
+ y5_16x4_h = vmovn_s32(y5_32x4_h);
+ y5_16x8 = vcombine_s16(y5_16x4_l, y5_16x4_h);
+ y7_16x4_l = vmovn_s32(y7_32x4_l);
+ y7_16x4_h = vmovn_s32(y7_32x4_h);
+ y7_16x8 = vcombine_s16(y7_16x4_l, y7_16x4_h);
+
+ rs_y1_16x8 = vshrq_n_s16(y1_16x8, 2);
+ rs_y3_16x8 = vshrq_n_s16(y3_16x8, 2);
+ rs_y5_16x8 = vshrq_n_s16(y5_16x8, 2);
+ rs_y7_16x8 = vshrq_n_s16(y7_16x8, 2);
+
+ z0_16x8 = vaddq_s16(y0_16x8, y6_16x8); // z0 = y0 + y6
+ z1_16x8 = vaddq_s16(y1_16x8, rs_y7_16x8); // z1 = y1 + (y7 >> 2)
+ z2_16x8 = vaddq_s16(y2_16x8, y4_16x8); // z2 = y2 + y4
+ z3_16x8 = vaddq_s16(y3_16x8, rs_y5_16x8); // z3 = y3 + (y5 >> 2)
+ z4_16x8 = vsubq_s16(y2_16x8, y4_16x8); // z4 = y2 - y4
+ z5_16x8 = vsubq_s16(rs_y3_16x8, y5_16x8); // z5 = (y3 >> 2) - y5
+ z6_16x8 = vsubq_s16(y0_16x8, y6_16x8); // z6 = y0 - y6
+ z7_16x8 = vsubq_s16(y7_16x8, rs_y1_16x8); // z7 = y7 - (y1 >> 2)
+
+ quant_res_16x8_0 = vaddq_s16(z0_16x8, z7_16x8); // x0 = z0 + z7
+ quant_res_16x8_1 = vaddq_s16(z2_16x8, z5_16x8); // x1 = z2 + z5
+ quant_res_16x8_2 = vaddq_s16(z4_16x8, z3_16x8); // x2 = z4 + z3
+ quant_res_16x8_3 = vaddq_s16(z6_16x8, z1_16x8); // x3 = z6 + z1
+ quant_res_16x8_4 = vsubq_s16(z6_16x8, z1_16x8); // x4 = z6 - z1
+ quant_res_16x8_5 = vsubq_s16(z4_16x8, z3_16x8); // x5 = z4 - z3
+ quant_res_16x8_6 = vsubq_s16(z2_16x8, z5_16x8); // x6 = z2 - z5
+ quant_res_16x8_7 = vsubq_s16(z0_16x8, z7_16x8); // x7 = z0 - z7
+ }
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ quant_res_16x8_0 = vrshrq_n_s16(quant_res_16x8_0, 6);
+ quant_res_16x8_1 = vrshrq_n_s16(quant_res_16x8_1, 6);
+ quant_res_16x8_2 = vrshrq_n_s16(quant_res_16x8_2, 6);
+ quant_res_16x8_3 = vrshrq_n_s16(quant_res_16x8_3, 6);
+ quant_res_16x8_4 = vrshrq_n_s16(quant_res_16x8_4, 6);
+ quant_res_16x8_5 = vrshrq_n_s16(quant_res_16x8_5, 6);
+ quant_res_16x8_6 = vrshrq_n_s16(quant_res_16x8_6, 6);
+ quant_res_16x8_7 = vrshrq_n_s16(quant_res_16x8_7, 6);
+
+ resd0_in = vaddq_s16(quant_res_16x8_0, resd0_in);
+ resd1_in = vaddq_s16(quant_res_16x8_1, resd1_in);
+ resd2_in = vaddq_s16(quant_res_16x8_2, resd2_in);
+ resd3_in = vaddq_s16(quant_res_16x8_3, resd3_in);
+ resd4_in = vaddq_s16(quant_res_16x8_4, resd4_in);
+ resd5_in = vaddq_s16(quant_res_16x8_5, resd5_in);
+ resd6_in = vaddq_s16(quant_res_16x8_6, resd6_in);
+ resd7_in = vaddq_s16(quant_res_16x8_7, resd7_in);
+
+ resd0_in = vminq_s16(resd0_in, dup_max);
+ resd0_in = vmaxq_s16(resd0_in, dup_min);
+ resd1_in = vminq_s16(resd1_in, dup_max);
+ resd1_in = vmaxq_s16(resd1_in, dup_min);
+ resd2_in = vminq_s16(resd2_in, dup_max);
+ resd2_in = vmaxq_s16(resd2_in, dup_min);
+ resd3_in = vminq_s16(resd3_in, dup_max);
+ resd3_in = vmaxq_s16(resd3_in, dup_min);
+ resd4_in = vminq_s16(resd4_in, dup_max);
+ resd4_in = vmaxq_s16(resd4_in, dup_min);
+ resd5_in = vminq_s16(resd5_in, dup_max);
+ resd5_in = vmaxq_s16(resd5_in, dup_min);
+ resd6_in = vminq_s16(resd6_in, dup_max);
+ resd6_in = vmaxq_s16(resd6_in, dup_min);
+ resd7_in = vminq_s16(resd7_in, dup_max);
+ resd7_in = vmaxq_s16(resd7_in, dup_min);
+
+ resd0_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(resd0_64x2), vget_low_s64(resd1_64x2)));
+ resd_b0_r23 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(resd2_64x2), vget_low_s64(resd3_64x2)));
+ resd_b1_r01 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(resd0_64x2), vget_high_s64(resd1_64x2)));
+ resd_b1_r23 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(resd2_64x2), vget_high_s64(resd3_64x2)));
+ resd_b2_r45 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(resd4_64x2), vget_low_s64(resd5_64x2)));
+ resd_b2_r67 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(resd6_64x2), vget_low_s64(resd7_64x2)));
+ resd_b3_r45 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(resd4_64x2), vget_high_s64(resd5_64x2)));
+ resd_b3_r67 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(resd6_64x2), vget_high_s64(resd7_64x2)));
+
+ dup_val_1 = vabsq_s16(resd_b0_r01);
+ dup_val_2 = vabsq_s16(resd_b0_r23);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01);
+ dup_val_2 = vabsq_s16(resd_b1_r23);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45);
+ dup_val_2 = vabsq_s16(resd_b2_r67);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45);
+ dup_val_2 = vabsq_s16(resd_b3_r67);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred1_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred2_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred3_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred4_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred5_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred6_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred7_in = vld1_u8((uint8_t *) pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ rec0 = vaddq_s16(pred0, resd0_in);
+ rec1 = vaddq_s16(pred1, resd1_in);
+ rec2 = vaddq_s16(pred2, resd2_in);
+ rec3 = vaddq_s16(pred3, resd3_in);
+ rec4 = vaddq_s16(pred4, resd4_in);
+ rec5 = vaddq_s16(pred5, resd5_in);
+ rec6 = vaddq_s16(pred6, resd6_in);
+ rec7 = vaddq_s16(pred7, resd7_in);
+
+ rec0_un = vqmovun_s16(rec0);
+ rec1_un = vqmovun_s16(rec1);
+ rec2_un = vqmovun_s16(rec2);
+ rec3_un = vqmovun_s16(rec3);
+ rec4_un = vqmovun_s16(rec4);
+ rec5_un = vqmovun_s16(rec5);
+ rec6_un = vqmovun_s16(rec6);
+ rec7_un = vqmovun_s16(rec7);
+
+ vst1_u8(pu1_out, rec0_un);
+ vst1_u8(pu1_out + out_strd, rec1_un);
+ vst1_u8(pu1_out + out_strd * 2, rec2_un);
+ vst1_u8(pu1_out + out_strd * 3, rec3_un);
+ vst1_u8(pu1_out + out_strd * 4, rec4_un);
+ vst1_u8(pu1_out + out_strd * 5, rec5_un);
+ vst1_u8(pu1_out + out_strd * 6, rec6_un);
+ vst1_u8(pu1_out + out_strd * 7, rec7_un);
+
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8_dc_neonintr */
+/* */
+/* Description : this function computes the recon dc output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8_dc_neonintr(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_iq_out_temp;
+ int16x8_t temp_0;
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ uint8x8_t pred4_in, pred5_in, pred6_in, pred7_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t pred4, pred5, pred6, pred7, dup_min, dup_max;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+
+ int64x2_t pred0_64x2, pred1_64x2, pred2_64x2, pred3_64x2, pred4_64x2, pred5_64x2, pred6_64x2,
+ pred7_64x2;
+
+ int16x8_t pred_b0_r01;
+ int16x8_t pred_b0_r23;
+ int16x8_t pred_b1_r01;
+ int16x8_t pred_b1_r23;
+ int16x8_t pred_b2_r45;
+ int16x8_t pred_b2_r67;
+ int16x8_t pred_b3_r45;
+ int16x8_t pred_b3_r67;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ i4_iq_out_temp = pi2_src[0];
+
+ INV_QUANT(i4_iq_out_temp, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+
+ temp_0 = vdupq_n_s16((i4_iq_out_temp + 32) >> 6);
+ dup_min = vdupq_n_s16(RSD_MIN);
+ dup_max = vdupq_n_s16(RSD_MAX);
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred1_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred2_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred3_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred4_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred5_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred6_in = vld1_u8((uint8_t *) pu1_pred);
+ pu1_pred = pu1_pred + pred_strd;
+ pred7_in = vld1_u8((uint8_t *) pu1_pred);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ resd0_in = vaddq_s16(resd0_in, temp_0);
+ resd1_in = vaddq_s16(resd1_in, temp_0);
+ resd2_in = vaddq_s16(resd2_in, temp_0);
+ resd3_in = vaddq_s16(resd3_in, temp_0);
+ resd4_in = vaddq_s16(resd4_in, temp_0);
+ resd5_in = vaddq_s16(resd5_in, temp_0);
+ resd6_in = vaddq_s16(resd6_in, temp_0);
+ resd7_in = vaddq_s16(resd7_in, temp_0);
+
+ resd0_in = vminq_s16(resd0_in, dup_max);
+ resd0_in = vmaxq_s16(resd0_in, dup_min);
+ resd1_in = vminq_s16(resd1_in, dup_max);
+ resd1_in = vmaxq_s16(resd1_in, dup_min);
+ resd2_in = vminq_s16(resd2_in, dup_max);
+ resd2_in = vmaxq_s16(resd2_in, dup_min);
+ resd3_in = vminq_s16(resd3_in, dup_max);
+ resd3_in = vmaxq_s16(resd3_in, dup_min);
+ resd4_in = vminq_s16(resd4_in, dup_max);
+ resd4_in = vmaxq_s16(resd4_in, dup_min);
+ resd5_in = vminq_s16(resd5_in, dup_max);
+ resd5_in = vmaxq_s16(resd5_in, dup_min);
+ resd6_in = vminq_s16(resd6_in, dup_max);
+ resd6_in = vmaxq_s16(resd6_in, dup_min);
+ resd7_in = vminq_s16(resd7_in, dup_max);
+ resd7_in = vmaxq_s16(resd7_in, dup_min);
+
+ pred0_64x2 = vreinterpretq_s64_s16(resd0_in);
+ pred1_64x2 = vreinterpretq_s64_s16(resd1_in);
+ pred2_64x2 = vreinterpretq_s64_s16(resd2_in);
+ pred3_64x2 = vreinterpretq_s64_s16(resd3_in);
+ pred4_64x2 = vreinterpretq_s64_s16(resd4_in);
+ pred5_64x2 = vreinterpretq_s64_s16(resd5_in);
+ pred6_64x2 = vreinterpretq_s64_s16(resd6_in);
+ pred7_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ pred_b0_r01 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(pred0_64x2), vget_low_s64(pred1_64x2)));
+ pred_b0_r23 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(pred2_64x2), vget_low_s64(pred3_64x2)));
+ pred_b1_r01 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(pred0_64x2), vget_high_s64(pred1_64x2)));
+ pred_b1_r23 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(pred2_64x2), vget_high_s64(pred3_64x2)));
+ pred_b2_r45 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(pred4_64x2), vget_low_s64(pred5_64x2)));
+ pred_b2_r67 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(pred6_64x2), vget_low_s64(pred7_64x2)));
+ pred_b3_r45 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(pred4_64x2), vget_high_s64(pred5_64x2)));
+ pred_b3_r67 =
+ vreinterpretq_s16_s64(vcombine_s64(vget_high_s64(pred6_64x2), vget_high_s64(pred7_64x2)));
+
+ dup_val_1 = vabsq_s16(pred_b0_r01);
+ dup_val_2 = vabsq_s16(pred_b0_r23);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b1_r01);
+ dup_val_2 = vabsq_s16(pred_b1_r23);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b2_r45);
+ dup_val_2 = vabsq_s16(pred_b2_r67);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(pred_b3_r45);
+ dup_val_2 = vabsq_s16(pred_b3_r67);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 7), pred7_in);
+
+ return nnz;
+}
diff --git a/decoder/arm/svc/isvcd_pred_residual_recon_neon.c b/decoder/arm/svc/isvcd_pred_residual_recon_neon.c
new file mode 100644
index 0000000..24932b5
--- /dev/null
+++ b/decoder/arm/svc/isvcd_pred_residual_recon_neon.c
@@ -0,0 +1,1694 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_pred_residual_recon_neonintr.c
+*
+* @brief
+* Contains definition of functions for h264 inverse quantization inverse
+* transformation and resd comp
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_pred_residual_recon_16x16_neonintr()
+* - isvcd_pred_residual_recon_8x8_neonintr()
+* - isvcd_pred_residual_recon_4x4_neonintr()
+* - isvcd_pred_residual_recon_chroma_4x4_neonintr()
+* - isvcd_pred_residual_recon_chroma_8x8_neonintr()
+* - isvcd_residual_luma_4x4_neonintr()
+* - isvcd_residual_luma_8x8_neonintr()
+* - isvcd_residual_luma_16x16_neonintr()
+* - isvcd_residual_chroma_cb_cr_8x8_neonintr()
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <string.h>
+#include <arm_neon.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_pred_residual_recon.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_4x4_neonintr */
+/* */
+/* Description : this function computes the recon data from the */
+/* pred and residual buffer */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_4x4_neonintr(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd01_in, resd23_in;
+ WORD32 i4_nnz;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 1));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ resd01_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd0_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd1_in))));
+
+ resd23_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd2_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd3_in))));
+
+ dup_val_1 = vabsq_s16(resd01_in);
+ dup_val_2 = vabsq_s16(resd23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ vst1_lane_u32((uint32_t *) (pu1_out), vreinterpret_u32_u8(pred0_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd), vreinterpret_u32_u8(pred1_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd * 2), vreinterpret_u32_u8(pred2_in), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out + out_strd * 3), vreinterpret_u32_u8(pred3_in), 0);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_8x8_neonintr */
+/* */
+/* Description : this function computes the recon data from the */
+/* pred and residual buffer */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_8x8_neonintr(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ uint8x8_t pred4_in, pred5_in, pred6_in, pred7_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t pred4, pred5, pred6, pred7;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ int64x2_t resd0_in_64x2, resd1_in_64x2, resd2_in_64x2, resd3_in_64x2, resd4_in_64x2,
+ resd5_in_64x2, resd6_in_64x2, resd7_in_64x2;
+
+ int16x8_t resd_b0_r01_in;
+ int16x8_t resd_b0_r23_in;
+ int16x8_t resd_b1_r01_in;
+ int16x8_t resd_b1_r23_in;
+ int16x8_t resd_b2_r45_in;
+ int16x8_t resd_b2_r67_in;
+ int16x8_t resd_b3_r45_in;
+ int16x8_t resd_b3_r67_in;
+
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+ pred4_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 4));
+ pred5_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 5));
+ pred6_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 6));
+ pred7_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 7));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 7), pred7_in);
+
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_16x16_neonintr */
+/* */
+/* Description : this function computes the recon data from the */
+/* pred and residual buffer */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_16x16_neonintr(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ uint8x8_t pred4_in, pred5_in, pred6_in, pred7_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t pred4, pred5, pred6, pred7;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+
+ int64x2_t resd0_in_64x2, resd1_in_64x2, resd2_in_64x2, resd3_in_64x2, resd4_in_64x2,
+ resd5_in_64x2, resd6_in_64x2, resd7_in_64x2;
+
+ int16x8_t resd_b0_r01_in;
+ int16x8_t resd_b0_r23_in;
+ int16x8_t resd_b1_r01_in;
+ int16x8_t resd_b1_r23_in;
+ int16x8_t resd_b2_r45_in;
+ int16x8_t resd_b2_r67_in;
+ int16x8_t resd_b3_r45_in;
+ int16x8_t resd_b3_r67_in;
+
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+
+ /* First row of 8, first 8x8 elements */
+ pred0_in = vld1_u8((uint8_t *) pu1_pred_ptr);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 3));
+ pred4_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 4));
+ pred5_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 5));
+ pred6_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 6));
+ pred7_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 7));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out_ptr), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 7), pred7_in);
+
+ /* first row of 8, sec 8x8 elements */
+ pu1_out_ptr = pu1_out_ptr + 8;
+ pi2_rsd_ptr = pi2_rsd_ptr + 8;
+ pu1_pred_ptr = pu1_pred_ptr + 8;
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred_ptr);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 3));
+ pred4_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 4));
+ pred5_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 5));
+ pred6_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 6));
+ pred7_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 7));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 2 | (nnz_b1 << 3) | (nnz_b2 << 6) | (nnz_b3 << 7));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out_ptr), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 7), pred7_in);
+
+ pu1_out_ptr = pu1_out + (8 * out_strd);
+ pi2_rsd_ptr = pi2_rsd + (8 * rsd_strd);
+ pu1_pred_ptr = pu1_pred + (8 * pred_strd);
+
+ /*Sec row of 8, first 8x8*/
+ pred0_in = vld1_u8((uint8_t *) pu1_pred_ptr);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 3));
+ pred4_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 4));
+ pred5_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 5));
+ pred6_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 6));
+ pred7_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 7));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 8 | (nnz_b1 << 9) | (nnz_b2 << 12) | (nnz_b3 << 13));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out_ptr), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 7), pred7_in);
+
+ /*Sec row of 8, Sec 8x8*/
+ pu1_out_ptr = pu1_out_ptr + 8;
+ pi2_rsd_ptr = pi2_rsd_ptr + 8;
+ pu1_pred_ptr = pu1_pred_ptr + 8;
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred_ptr);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 3));
+ pred4_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 4));
+ pred5_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 5));
+ pred6_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 6));
+ pred7_in = vld1_u8((uint8_t *) pu1_pred_ptr + (pred_strd * 7));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 10 | (nnz_b1 << 11) | (nnz_b2 << 14) | (nnz_b3 << 15));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ vst1_u8((uint8_t *) (pu1_out_ptr), pred0_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd), pred1_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 2), pred2_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 3), pred3_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 4), pred4_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 5), pred5_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 6), pred6_in);
+ vst1_u8((uint8_t *) (pu1_out_ptr + out_strd * 7), pred7_in);
+
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_8x8_neonintr */
+/* */
+/* Description : this function computes the recon data from the */
+/* pred and residual buffer */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_pred_residual_recon_chroma_8x8_neonintr(UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd)
+{
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ uint8x8_t pred4_in, pred5_in, pred6_in, pred7_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t pred4, pred5, pred6, pred7;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ uint8x16_t pred0_inp_full, pred1_inp_full, pred2_inp_full, pred3_inp_full;
+ uint8x16_t pred4_inp_full, pred5_inp_full, pred6_inp_full, pred7_inp_full;
+ uint8x8_t i4_out_horz_8x8_r0, i4_out_horz_8x8_r1, i4_out_horz_8x8_r2, i4_out_horz_8x8_r3;
+ uint8x8_t i4_out_horz_8x8_r4, i4_out_horz_8x8_r5, i4_out_horz_8x8_r6, i4_out_horz_8x8_r7;
+ uint8x8_t chroma_mask_8x8;
+
+ pred0_inp_full = vld1q_u8((uint8_t *) pu1_pred);
+ pred1_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd));
+ pred2_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 2));
+ pred3_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+ pred4_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 4));
+ pred5_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 5));
+ pred6_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 6));
+ pred7_inp_full = vld1q_u8((uint8_t *) pu1_pred + (pred_strd * 7));
+
+ pred0_in = vget_low_u8(pred0_inp_full);
+ pred1_in = vget_low_u8(pred1_inp_full);
+ pred2_in = vget_low_u8(pred2_inp_full);
+ pred3_in = vget_low_u8(pred3_inp_full);
+ pred4_in = vget_low_u8(pred4_inp_full);
+ pred5_in = vget_low_u8(pred5_inp_full);
+ pred6_in = vget_low_u8(pred6_inp_full);
+ pred7_in = vget_low_u8(pred7_inp_full);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + out_strd);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + out_strd * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + out_strd * 3);
+ i4_out_horz_8x8_r4 = vld1_u8(pu1_out + out_strd * 4);
+ i4_out_horz_8x8_r5 = vld1_u8(pu1_out + out_strd * 5);
+ i4_out_horz_8x8_r6 = vld1_u8(pu1_out + out_strd * 6);
+ i4_out_horz_8x8_r7 = vld1_u8(pu1_out + out_strd * 7);
+
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+ i4_out_horz_8x8_r4 = vbsl_u8(chroma_mask_8x8, pred4_in, i4_out_horz_8x8_r4);
+ i4_out_horz_8x8_r5 = vbsl_u8(chroma_mask_8x8, pred5_in, i4_out_horz_8x8_r5);
+ i4_out_horz_8x8_r6 = vbsl_u8(chroma_mask_8x8, pred6_in, i4_out_horz_8x8_r6);
+ i4_out_horz_8x8_r7 = vbsl_u8(chroma_mask_8x8, pred7_in, i4_out_horz_8x8_r7);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), i4_out_horz_8x8_r3);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 4), i4_out_horz_8x8_r4);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 5), i4_out_horz_8x8_r5);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 6), i4_out_horz_8x8_r6);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 7), i4_out_horz_8x8_r7);
+
+ /* for the next 4 elements interleaved format */
+ pred0_in = vget_high_u8(pred0_inp_full);
+ pred1_in = vget_high_u8(pred1_inp_full);
+ pred2_in = vget_high_u8(pred2_inp_full);
+ pred3_in = vget_high_u8(pred3_inp_full);
+ pred4_in = vget_high_u8(pred4_inp_full);
+ pred5_in = vget_high_u8(pred5_inp_full);
+ pred6_in = vget_high_u8(pred6_inp_full);
+ pred7_in = vget_high_u8(pred7_inp_full);
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+ pred4 = vreinterpretq_s16_u16(vmovl_u8(pred4_in));
+ pred5 = vreinterpretq_s16_u16(vmovl_u8(pred5_in));
+ pred6 = vreinterpretq_s16_u16(vmovl_u8(pred6_in));
+ pred7 = vreinterpretq_s16_u16(vmovl_u8(pred7_in));
+
+ pi2_rsd = pi2_rsd + 8;
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+ pred4 = vaddq_s16(pred4, resd4_in);
+ pred5 = vaddq_s16(pred5, resd5_in);
+ pred6 = vaddq_s16(pred6, resd6_in);
+ pred7 = vaddq_s16(pred7, resd7_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+ pred4_in = vqmovun_s16(pred4);
+ pred5_in = vqmovun_s16(pred5);
+ pred6_in = vqmovun_s16(pred6);
+ pred7_in = vqmovun_s16(pred7);
+
+ pu1_out = pu1_out + 8;
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + out_strd);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + out_strd * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + out_strd * 3);
+ i4_out_horz_8x8_r4 = vld1_u8(pu1_out + out_strd * 4);
+ i4_out_horz_8x8_r5 = vld1_u8(pu1_out + out_strd * 5);
+ i4_out_horz_8x8_r6 = vld1_u8(pu1_out + out_strd * 6);
+ i4_out_horz_8x8_r7 = vld1_u8(pu1_out + out_strd * 7);
+
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+ i4_out_horz_8x8_r4 = vbsl_u8(chroma_mask_8x8, pred4_in, i4_out_horz_8x8_r4);
+ i4_out_horz_8x8_r5 = vbsl_u8(chroma_mask_8x8, pred5_in, i4_out_horz_8x8_r5);
+ i4_out_horz_8x8_r6 = vbsl_u8(chroma_mask_8x8, pred6_in, i4_out_horz_8x8_r6);
+ i4_out_horz_8x8_r7 = vbsl_u8(chroma_mask_8x8, pred7_in, i4_out_horz_8x8_r7);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), i4_out_horz_8x8_r3);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 4), i4_out_horz_8x8_r4);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 5), i4_out_horz_8x8_r5);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 6), i4_out_horz_8x8_r6);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 7), i4_out_horz_8x8_r7);
+
+ pu1_out = pu1_out_ptr;
+ pu1_pred = pu1_pred_ptr;
+ pi2_rsd = pi2_rsd_ptr;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_4x4_neonintr */
+/* */
+/* Description : this function computes the recon data from the */
+/* pred and residual buffer */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_pred_residual_recon_chroma_4x4_neonintr(UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd)
+{
+ uint8x8_t pred0_in, pred1_in, pred2_in, pred3_in;
+ int16x8_t pred0, pred1, pred2, pred3;
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+
+ uint8x8_t i4_out_horz_8x8_r0, i4_out_horz_8x8_r1, i4_out_horz_8x8_r2, i4_out_horz_8x8_r3;
+ uint8x8_t chroma_mask_8x8 = vreinterpret_u8_u16(vdup_n_u16(0x00ff));
+
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+
+ pred0_in = vld1_u8((uint8_t *) pu1_pred);
+ pred1_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd));
+ pred2_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 2));
+ pred3_in = vld1_u8((uint8_t *) pu1_pred + (pred_strd * 3));
+
+ pred0 = vreinterpretq_s16_u16(vmovl_u8(pred0_in));
+ pred1 = vreinterpretq_s16_u16(vmovl_u8(pred1_in));
+ pred2 = vreinterpretq_s16_u16(vmovl_u8(pred2_in));
+ pred3 = vreinterpretq_s16_u16(vmovl_u8(pred3_in));
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ pred0 = vaddq_s16(pred0, resd0_in);
+ pred1 = vaddq_s16(pred1, resd1_in);
+ pred2 = vaddq_s16(pred2, resd2_in);
+ pred3 = vaddq_s16(pred3, resd3_in);
+
+ pred0_in = vqmovun_s16(pred0);
+ pred1_in = vqmovun_s16(pred1);
+ pred2_in = vqmovun_s16(pred2);
+ pred3_in = vqmovun_s16(pred3);
+
+ i4_out_horz_8x8_r0 = vld1_u8(pu1_out);
+ i4_out_horz_8x8_r1 = vld1_u8(pu1_out + out_strd);
+ i4_out_horz_8x8_r2 = vld1_u8(pu1_out + out_strd * 2);
+ i4_out_horz_8x8_r3 = vld1_u8(pu1_out + out_strd * 3);
+
+ i4_out_horz_8x8_r0 = vbsl_u8(chroma_mask_8x8, pred0_in, i4_out_horz_8x8_r0);
+ i4_out_horz_8x8_r1 = vbsl_u8(chroma_mask_8x8, pred1_in, i4_out_horz_8x8_r1);
+ i4_out_horz_8x8_r2 = vbsl_u8(chroma_mask_8x8, pred2_in, i4_out_horz_8x8_r2);
+ i4_out_horz_8x8_r3 = vbsl_u8(chroma_mask_8x8, pred3_in, i4_out_horz_8x8_r3);
+
+ vst1_u8((uint8_t *) (pu1_out), i4_out_horz_8x8_r0);
+ vst1_u8((uint8_t *) (pu1_out + out_strd), i4_out_horz_8x8_r1);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 2), i4_out_horz_8x8_r2);
+ vst1_u8((uint8_t *) (pu1_out + out_strd * 3), i4_out_horz_8x8_r3);
+
+ pu1_out = pu1_out_ptr;
+ pu1_pred = pu1_pred_ptr;
+ pi2_rsd = pi2_rsd_ptr;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_4x4_neonintr */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_4x4_neonintr(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd01_in, resd23_in;
+ WORD32 i4_nnz;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+
+ resd01_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd0_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd1_in))));
+
+ resd23_in = vreinterpretq_s16_s64(vcombine_s64(vget_low_s64(vreinterpretq_s64_s16(resd2_in)),
+ vget_low_s64(vreinterpretq_s64_s16(resd3_in))));
+
+ dup_val_1 = vabsq_s16(resd01_in);
+ dup_val_2 = vabsq_s16(resd23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ i4_nnz = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_8x8_neonintr */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_8x8_neonintr(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+
+ int64x2_t resd0_in_64x2, resd1_in_64x2, resd2_in_64x2, resd3_in_64x2, resd4_in_64x2,
+ resd5_in_64x2, resd6_in_64x2, resd7_in_64x2;
+
+ int16x8_t resd_b0_r01_in;
+ int16x8_t resd_b0_r23_in;
+ int16x8_t resd_b1_r01_in;
+ int16x8_t resd_b1_r23_in;
+ int16x8_t resd_b2_r45_in;
+ int16x8_t resd_b2_r67_in;
+ int16x8_t resd_b3_r45_in;
+ int16x8_t resd_b3_r67_in;
+
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_16x16_neonintr */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_16x16_neonintr(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ int16x8_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8_t resd4_in, resd5_in, resd6_in, resd7_in;
+
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ int64x2_t resd0_in_64x2, resd1_in_64x2, resd2_in_64x2, resd3_in_64x2, resd4_in_64x2,
+ resd5_in_64x2, resd6_in_64x2, resd7_in_64x2;
+
+ int16x8_t resd_b0_r01_in;
+ int16x8_t resd_b0_r23_in;
+ int16x8_t resd_b1_r01_in;
+ int16x8_t resd_b1_r23_in;
+ int16x8_t resd_b2_r45_in;
+ int16x8_t resd_b2_r67_in;
+ int16x8_t resd_b3_r45_in;
+ int16x8_t resd_b3_r67_in;
+
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+
+ /* First row of 8, first 8x8 elements */
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = (nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 4) | (nnz_b3 << 5));
+
+ /* first row of 8, sec 8x8 elements */
+ pi2_rsd_ptr = pi2_rsd_ptr + 8;
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 2 | (nnz_b1 << 3) | (nnz_b2 << 6) | (nnz_b3 << 7));
+
+ pi2_rsd_ptr = pi2_rsd + (8 * rsd_strd);
+ /*Sec row of 8, first 8x8*/
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 8 | (nnz_b1 << 9) | (nnz_b2 << 12) | (nnz_b3 << 13));
+
+ /*Sec row of 8, Sec 8x8*/
+ pi2_rsd_ptr = pi2_rsd_ptr + 8;
+
+ resd0_in = vld1q_s16((int16_t *) pi2_rsd_ptr);
+ resd1_in = vld1q_s16((int16_t *) pi2_rsd_ptr + rsd_strd);
+ resd2_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 2));
+ resd3_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 3));
+ resd4_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 4));
+ resd5_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 5));
+ resd6_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 6));
+ resd7_in = vld1q_s16((int16_t *) pi2_rsd_ptr + (rsd_strd * 7));
+
+ resd0_in_64x2 = vreinterpretq_s64_s16(resd0_in);
+ resd1_in_64x2 = vreinterpretq_s64_s16(resd1_in);
+ resd2_in_64x2 = vreinterpretq_s64_s16(resd2_in);
+ resd3_in_64x2 = vreinterpretq_s64_s16(resd3_in);
+ resd4_in_64x2 = vreinterpretq_s64_s16(resd4_in);
+ resd5_in_64x2 = vreinterpretq_s64_s16(resd5_in);
+ resd6_in_64x2 = vreinterpretq_s64_s16(resd6_in);
+ resd7_in_64x2 = vreinterpretq_s64_s16(resd7_in);
+
+ resd_b0_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_in_64x2), vget_low_s64(resd1_in_64x2)));
+ resd_b0_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_in_64x2), vget_low_s64(resd3_in_64x2)));
+ resd_b1_r01_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_in_64x2), vget_high_s64(resd1_in_64x2)));
+ resd_b1_r23_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_in_64x2), vget_high_s64(resd3_in_64x2)));
+ resd_b2_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_in_64x2), vget_low_s64(resd5_in_64x2)));
+ resd_b2_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_in_64x2), vget_low_s64(resd7_in_64x2)));
+ resd_b3_r45_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_in_64x2), vget_high_s64(resd5_in_64x2)));
+ resd_b3_r67_in = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_in_64x2), vget_high_s64(resd7_in_64x2)));
+ dup_val_1 = vabsq_s16(resd_b0_r01_in);
+ dup_val_2 = vabsq_s16(resd_b0_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_in);
+ dup_val_2 = vabsq_s16(resd_b1_r23_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_in);
+ dup_val_2 = vabsq_s16(resd_b2_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_in);
+ dup_val_2 = vabsq_s16(resd_b3_r67_in);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= (nnz_b0 << 10 | (nnz_b1 << 11) | (nnz_b2 << 14) | (nnz_b3 << 15));
+ return nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_chroma_cb_cr_8x8_neonintr */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_chroma_cb_cr_8x8_neonintr(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ int16x8x2_t resd0_in, resd1_in, resd2_in, resd3_in;
+ int16x8x2_t resd4_in, resd5_in, resd6_in, resd7_in;
+
+ int64x2_t resd0_cr_64x2, resd1_cr_64x2, resd2_cr_64x2, resd3_cr_64x2, resd4_cr_64x2,
+ resd5_cr_64x2, resd6_cr_64x2, resd7_cr_64x2;
+
+ int16x8_t resd_b0_r01_cr;
+ int16x8_t resd_b0_r23_cr;
+ int16x8_t resd_b1_r01_cr;
+ int16x8_t resd_b1_r23_cr;
+ int16x8_t resd_b2_r45_cr;
+ int16x8_t resd_b2_r67_cr;
+ int16x8_t resd_b3_r45_cr;
+ int16x8_t resd_b3_r67_cr;
+
+ int64x2_t resd0_cb_64x2, resd1_cb_64x2, resd2_cb_64x2, resd3_cb_64x2, resd4_cb_64x2,
+ resd5_cb_64x2, resd6_cb_64x2, resd7_cb_64x2;
+
+ int16x8_t resd_b0_r01_cb;
+ int16x8_t resd_b0_r23_cb;
+ int16x8_t resd_b1_r01_cb;
+ int16x8_t resd_b1_r23_cb;
+ int16x8_t resd_b2_r45_cb;
+ int16x8_t resd_b2_r67_cb;
+ int16x8_t resd_b3_r45_cb;
+ int16x8_t resd_b3_r67_cb;
+
+ WORD32 nnz, nnz_b0, nnz_b1, nnz_b2, nnz_b3;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+
+ resd0_in = vld2q_s16((int16_t *) pi2_rsd);
+ resd1_in = vld2q_s16((int16_t *) pi2_rsd + rsd_strd);
+ resd2_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 2));
+ resd3_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 3));
+ resd4_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 4));
+ resd5_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 5));
+ resd6_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 6));
+ resd7_in = vld2q_s16((int16_t *) pi2_rsd + (rsd_strd * 7));
+
+ resd0_cb_64x2 = vreinterpretq_s64_s16(resd0_in.val[0]);
+ resd1_cb_64x2 = vreinterpretq_s64_s16(resd1_in.val[0]);
+ resd2_cb_64x2 = vreinterpretq_s64_s16(resd2_in.val[0]);
+ resd3_cb_64x2 = vreinterpretq_s64_s16(resd3_in.val[0]);
+ resd4_cb_64x2 = vreinterpretq_s64_s16(resd4_in.val[0]);
+ resd5_cb_64x2 = vreinterpretq_s64_s16(resd5_in.val[0]);
+ resd6_cb_64x2 = vreinterpretq_s64_s16(resd6_in.val[0]);
+ resd7_cb_64x2 = vreinterpretq_s64_s16(resd7_in.val[0]);
+
+ resd_b0_r01_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_cb_64x2), vget_low_s64(resd1_cb_64x2)));
+ resd_b0_r23_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_cb_64x2), vget_low_s64(resd3_cb_64x2)));
+ resd_b1_r01_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_cb_64x2), vget_high_s64(resd1_cb_64x2)));
+ resd_b1_r23_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_cb_64x2), vget_high_s64(resd3_cb_64x2)));
+ resd_b2_r45_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_cb_64x2), vget_low_s64(resd5_cb_64x2)));
+ resd_b2_r67_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_cb_64x2), vget_low_s64(resd7_cb_64x2)));
+ resd_b3_r45_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_cb_64x2), vget_high_s64(resd5_cb_64x2)));
+ resd_b3_r67_cb = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_cb_64x2), vget_high_s64(resd7_cb_64x2)));
+
+ resd0_cr_64x2 = vreinterpretq_s64_s16(resd0_in.val[1]);
+ resd1_cr_64x2 = vreinterpretq_s64_s16(resd1_in.val[1]);
+ resd2_cr_64x2 = vreinterpretq_s64_s16(resd2_in.val[1]);
+ resd3_cr_64x2 = vreinterpretq_s64_s16(resd3_in.val[1]);
+ resd4_cr_64x2 = vreinterpretq_s64_s16(resd4_in.val[1]);
+ resd5_cr_64x2 = vreinterpretq_s64_s16(resd5_in.val[1]);
+ resd6_cr_64x2 = vreinterpretq_s64_s16(resd6_in.val[1]);
+ resd7_cr_64x2 = vreinterpretq_s64_s16(resd7_in.val[1]);
+
+ resd_b0_r01_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd0_cr_64x2), vget_low_s64(resd1_cr_64x2)));
+ resd_b0_r23_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd2_cr_64x2), vget_low_s64(resd3_cr_64x2)));
+ resd_b1_r01_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd0_cr_64x2), vget_high_s64(resd1_cr_64x2)));
+ resd_b1_r23_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd2_cr_64x2), vget_high_s64(resd3_cr_64x2)));
+ resd_b2_r45_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd4_cr_64x2), vget_low_s64(resd5_cr_64x2)));
+ resd_b2_r67_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_low_s64(resd6_cr_64x2), vget_low_s64(resd7_cr_64x2)));
+ resd_b3_r45_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd4_cr_64x2), vget_high_s64(resd5_cr_64x2)));
+ resd_b3_r67_cr = vreinterpretq_s16_s64(
+ vcombine_s64(vget_high_s64(resd6_cr_64x2), vget_high_s64(resd7_cr_64x2)));
+
+ dup_val_1 = vabsq_s16(resd_b0_r01_cr);
+ dup_val_2 = vabsq_s16(resd_b0_r23_cr);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_cr);
+ dup_val_2 = vabsq_s16(resd_b1_r23_cr);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_cr);
+ dup_val_2 = vabsq_s16(resd_b2_r67_cr);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_cr);
+ dup_val_2 = vabsq_s16(resd_b3_r67_cr);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz = ((nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 2) | (nnz_b3 << 3)) << 4);
+
+ dup_val_1 = vabsq_s16(resd_b0_r01_cb);
+ dup_val_2 = vabsq_s16(resd_b0_r23_cb);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b0 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b1_r01_cb);
+ dup_val_2 = vabsq_s16(resd_b1_r23_cb);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b2_r45_cb);
+ dup_val_2 = vabsq_s16(resd_b2_r67_cb);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b2 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ dup_val_1 = vabsq_s16(resd_b3_r45_cb);
+ dup_val_2 = vabsq_s16(resd_b3_r67_cb);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ nnz_b3 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] || dup_abs[5] ||
+ dup_abs[6] || dup_abs[7];
+
+ nnz |= ((nnz_b0 | (nnz_b1 << 1) | (nnz_b2 << 2) | (nnz_b3 << 3)));
+ return nnz;
+}
diff --git a/decoder/arm/svc/isvcd_residual_resamp_neon.c b/decoder/arm/svc/isvcd_residual_resamp_neon.c
new file mode 100644
index 0000000..28c41c5
--- /dev/null
+++ b/decoder/arm/svc/isvcd_residual_resamp_neon.c
@@ -0,0 +1,1599 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_residual_resamp_neonintr.c
+*
+* @brief
+* Contains routines that resample for SVC resampling
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_pred_residual_recon_4x4_neonintr()
+* - isvcd_pred_residual_recon_8x8_neonintr()
+* - isvcd_pred_residual_recon_16x16_neonintr()
+* - isvcd_pred_residual_recon_chroma_4x4_neonintr()
+* - isvcd_pred_residual_recon_chroma_8x8_neonintr()
+* - isvcd_residual_luma_4x4_neonintr()
+* - isvcd_residual_luma_8x8_neonintr()
+* - isvcd_residual_luma_16x16_neonintr()
+* - isvcd_residual_chroma_cb_cr_8x8_neonintr()
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+/*!
+ **************************************************************************
+ * \file isvcd_residual_resamp_neonintr.c
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : kishore
+ **************************************************************************
+ */
+#include <assert.h>
+#include <string.h>
+#include <arm_neon.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264_debug.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_dyadic_neonintr */
+/* */
+/* Description : this fucntion does the upsampling of luma residuals for */
+/* Dyadic cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* ps_ref_mb_mode : reference mb mode pointer of base layer */
+/* ps_coord : mb co-ordinate pointer */
+/* Globals : none */
+/* Processing : it does the upsampling with fixed phase values and */
+/* reference layer transform size */
+/* Outputs : Upsampled residuals for luma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_residual_luma_dyadic_neonintr(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, mem_element_t *ps_ref_mb_mode,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
+ WORD32 i4_ref_tx_size)
+{
+ WORD16 *pi2_refarray_buffer;
+ WORD32 i4_blk_ctr;
+ residual_sampling_ctxt_t *ps_ctxt;
+ UNUSED(ps_ref_mb_mode);
+ UNUSED(u2_mb_x);
+ UNUSED(u2_mb_y);
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ pi2_refarray_buffer = ps_ctxt->pi2_refarray_buffer;
+
+ /* based on transform size the counter and interpolation width and */
+ /* height are intialised as follows */
+ if((i4_ref_tx_size) && (0 != i4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i, i4_j;
+ /* ----------- Horizontal Interpolation ---------------- */
+ int16x8_t i2_coeff_add_16x8_r0;
+ int16x8_t i2_coeff_16x8_r0_0, i2_coeff_16x8_r0_1;
+ int16x8_t i2_coeff_16x8_sl_r0_0, i2_coeff_16x8_sl_r0_1;
+ int16x8_t result_16x8_r0_0, result_16x8_r0_1;
+ int16x8_t final_result_16x8_r0_0, final_result_16x8_r0_1;
+
+ int16x8_t i2_coeff_add_16x8_r1;
+ int16x8_t i2_coeff_16x8_r1_0, i2_coeff_16x8_r1_1;
+ int16x8_t i2_coeff_16x8_sl_r1_0, i2_coeff_16x8_sl_r1_1;
+ int16x8_t result_16x8_r1_0, result_16x8_r1_1;
+ int16x8_t final_result_16x8_r1_0, final_result_16x8_r1_1;
+ int16x8x2_t result_16x8x2_t_0;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLOCK_HEIGHT; i4_i += 2)
+ {
+ i2_coeff_16x8_r0_0 = vld1q_s16(pi2_ref_data_byte);
+ i2_coeff_16x8_r0_1 = vld1q_s16((pi2_ref_data_byte + 1));
+
+ i2_coeff_16x8_r1_0 = vld1q_s16(pi2_ref_data_byte + i4_inp_data_stride);
+ i2_coeff_16x8_r1_1 = vld1q_s16((pi2_ref_data_byte + i4_inp_data_stride + 1));
+
+ i2_coeff_add_16x8_r0 = vaddq_s16(i2_coeff_16x8_r0_0, i2_coeff_16x8_r0_1);
+ i2_coeff_16x8_sl_r0_0 = vshlq_n_s16(i2_coeff_16x8_r0_0, 1);
+ i2_coeff_16x8_sl_r0_1 = vshlq_n_s16(i2_coeff_16x8_r0_1, 1);
+
+ i2_coeff_add_16x8_r1 = vaddq_s16(i2_coeff_16x8_r1_0, i2_coeff_16x8_r1_1);
+ i2_coeff_16x8_sl_r1_0 = vshlq_n_s16(i2_coeff_16x8_r1_0, 1);
+ i2_coeff_16x8_sl_r1_1 = vshlq_n_s16(i2_coeff_16x8_r1_1, 1);
+
+ result_16x8_r0_0 = vaddq_s16(i2_coeff_16x8_sl_r0_0, i2_coeff_add_16x8_r0);
+ result_16x8_r0_1 = vaddq_s16(i2_coeff_16x8_sl_r0_1, i2_coeff_add_16x8_r0);
+
+ result_16x8_r1_0 = vaddq_s16(i2_coeff_16x8_sl_r1_0, i2_coeff_add_16x8_r1);
+ result_16x8_r1_1 = vaddq_s16(i2_coeff_16x8_sl_r1_1, i2_coeff_add_16x8_r1);
+
+ result_16x8x2_t_0 = vzipq_s16(result_16x8_r0_0, result_16x8_r0_1);
+ final_result_16x8_r0_0 = result_16x8x2_t_0.val[0];
+ final_result_16x8_r0_1 = result_16x8x2_t_0.val[1];
+
+ result_16x8x2_t_0 = vzipq_s16(result_16x8_r1_0, result_16x8_r1_1);
+ final_result_16x8_r1_0 = result_16x8x2_t_0.val[0];
+ final_result_16x8_r1_1 = result_16x8x2_t_0.val[1];
+
+ vst1q_s32(pi4_ref_array + 1, vmovl_s16(vget_low_s16(final_result_16x8_r0_0)));
+ vst1q_s32(pi4_ref_array + 5, vmovl_s16(vget_high_s16(final_result_16x8_r0_0)));
+ vst1q_s32(pi4_ref_array + 9, vmovl_s16(vget_low_s16(final_result_16x8_r0_1)));
+ vst1q_s32(pi4_ref_array + 13, vmovl_s16(vget_high_s16(final_result_16x8_r0_1)));
+ pi4_ref_array[0] = pi2_ref_data_byte[0] << 2;
+ pi4_ref_array[15] = pi2_ref_data_byte[7] << 2;
+ pi4_ref_array += 16;
+ pi2_ref_data_byte += i4_inp_data_stride;
+
+ vst1q_s32(pi4_ref_array + 1, vmovl_s16(vget_low_s16(final_result_16x8_r1_0)));
+ vst1q_s32(pi4_ref_array + 5, vmovl_s16(vget_high_s16(final_result_16x8_r1_0)));
+ vst1q_s32(pi4_ref_array + 9, vmovl_s16(vget_low_s16(final_result_16x8_r1_1)));
+ vst1q_s32(pi4_ref_array + 13, vmovl_s16(vget_high_s16(final_result_16x8_r1_1)));
+
+ pi4_ref_array[0] = pi2_ref_data_byte[0] << 2;
+ pi4_ref_array[15] = pi2_ref_data_byte[7] << 2;
+ pi4_ref_array += 16;
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 2) * i4_inp_data_stride);
+ }
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ int32x4_t i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r1_2, i4_horz_samp_32x4_r1_3,
+ i4_horz_samp_32x4_r1_4;
+ int32x4_t i4_horz_samp_32x4_r2_1, i4_horz_samp_32x4_r2_2, i4_horz_samp_32x4_r2_3,
+ i4_horz_samp_32x4_r2_4;
+
+ int32x4_t i4_horz_res_32x4_r1_1, i4_horz_res_32x4_r1_2, i4_horz_res_32x4_r1_3,
+ i4_horz_res_32x4_r1_4;
+ int32x4_t i4_horz_res_32x4_r2_1, i4_horz_res_32x4_r2_2, i4_horz_res_32x4_r2_3,
+ i4_horz_res_32x4_r2_4;
+ int32x4_t i4_horz_res_32x4_r3_1, i4_horz_res_32x4_r3_2, i4_horz_res_32x4_r3_3,
+ i4_horz_res_32x4_r3_4;
+ int32x4_t horz_add_32x4_r2_1, horz_add_32x4_r2_2, horz_add_32x4_r2_3,
+ horz_add_32x4_r2_4;
+
+ int16x8_t comb_horz_16x8_1, comb_horz_16x8_2, comb_horz_16x8_3, comb_horz_16x8_4;
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+
+ i4_horz_samp_32x4_r1_1 = vld1q_s32(pi4_ref_array_temp);
+ i4_horz_samp_32x4_r1_2 = vld1q_s32(pi4_ref_array_temp + 4);
+ i4_horz_samp_32x4_r1_3 = vld1q_s32(pi4_ref_array_temp + 8);
+ i4_horz_samp_32x4_r1_4 = vld1q_s32(pi4_ref_array_temp + 12);
+
+ /* populate the first inter sample */
+ i4_horz_res_32x4_r1_1 = vrshrq_n_s32(i4_horz_samp_32x4_r1_1, 2);
+ i4_horz_res_32x4_r1_2 = vrshrq_n_s32(i4_horz_samp_32x4_r1_2, 2);
+ i4_horz_res_32x4_r1_3 = vrshrq_n_s32(i4_horz_samp_32x4_r1_3, 2);
+ i4_horz_res_32x4_r1_4 = vrshrq_n_s32(i4_horz_samp_32x4_r1_4, 2);
+
+ comb_horz_16x8_1 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_1), vmovn_s32(i4_horz_res_32x4_r1_2));
+ comb_horz_16x8_2 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_3), vmovn_s32(i4_horz_res_32x4_r1_4));
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi4_ref_array_temp += MB_WIDTH;
+ i4_horz_samp_32x4_r2_1 = vld1q_s32(pi4_ref_array_temp);
+ i4_horz_samp_32x4_r2_2 = vld1q_s32(pi4_ref_array_temp + 4);
+ i4_horz_samp_32x4_r2_3 = vld1q_s32(pi4_ref_array_temp + 8);
+ i4_horz_samp_32x4_r2_4 = vld1q_s32(pi4_ref_array_temp + 12);
+
+ horz_add_32x4_r2_1 = vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r2_1);
+ horz_add_32x4_r2_2 = vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_samp_32x4_r2_2);
+ horz_add_32x4_r2_3 = vaddq_s32(i4_horz_samp_32x4_r1_3, i4_horz_samp_32x4_r2_3);
+ horz_add_32x4_r2_4 = vaddq_s32(i4_horz_samp_32x4_r1_4, i4_horz_samp_32x4_r2_4);
+
+ i4_horz_res_32x4_r2_1 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_1, 1), horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r2_2 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_2, 1), horz_add_32x4_r2_2);
+ i4_horz_res_32x4_r2_3 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_3, 1), horz_add_32x4_r2_3);
+ i4_horz_res_32x4_r2_4 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_4, 1), horz_add_32x4_r2_4);
+
+ i4_horz_res_32x4_r3_1 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_1, 1), horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r3_2 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_2, 1), horz_add_32x4_r2_2);
+ i4_horz_res_32x4_r3_3 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_3, 1), horz_add_32x4_r2_3);
+ i4_horz_res_32x4_r3_4 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_4, 1), horz_add_32x4_r2_4);
+
+ i4_horz_res_32x4_r2_1 = vrshrq_n_s32(i4_horz_res_32x4_r2_1, 4);
+ i4_horz_res_32x4_r2_2 = vrshrq_n_s32(i4_horz_res_32x4_r2_2, 4);
+ i4_horz_res_32x4_r2_3 = vrshrq_n_s32(i4_horz_res_32x4_r2_3, 4);
+ i4_horz_res_32x4_r2_4 = vrshrq_n_s32(i4_horz_res_32x4_r2_4, 4);
+
+ i4_horz_res_32x4_r3_1 = vrshrq_n_s32(i4_horz_res_32x4_r3_1, 4);
+ i4_horz_res_32x4_r3_2 = vrshrq_n_s32(i4_horz_res_32x4_r3_2, 4);
+ i4_horz_res_32x4_r3_3 = vrshrq_n_s32(i4_horz_res_32x4_r3_3, 4);
+ i4_horz_res_32x4_r3_4 = vrshrq_n_s32(i4_horz_res_32x4_r3_4, 4);
+
+ comb_horz_16x8_1 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r2_1),
+ vmovn_s32(i4_horz_res_32x4_r2_2));
+ comb_horz_16x8_2 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r2_3),
+ vmovn_s32(i4_horz_res_32x4_r2_4));
+
+ comb_horz_16x8_3 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r3_1),
+ vmovn_s32(i4_horz_res_32x4_r3_2));
+ comb_horz_16x8_4 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r3_3),
+ vmovn_s32(i4_horz_res_32x4_r3_4));
+
+ /* populate 2 samples based on current coeffs */
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+ pi2_out += i4_out_res_stride;
+
+ vst1q_s16(pi2_out, comb_horz_16x8_3);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_4);
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_32x4_r1_1 = i4_horz_samp_32x4_r2_1;
+ i4_horz_samp_32x4_r1_2 = i4_horz_samp_32x4_r2_2;
+ i4_horz_samp_32x4_r1_3 = i4_horz_samp_32x4_r2_3;
+ i4_horz_samp_32x4_r1_4 = i4_horz_samp_32x4_r2_4;
+ }
+
+ /* populate the first inter sample */
+ i4_horz_res_32x4_r1_1 = vrshrq_n_s32(i4_horz_samp_32x4_r1_1, 2);
+ i4_horz_res_32x4_r1_2 = vrshrq_n_s32(i4_horz_samp_32x4_r1_2, 2);
+ i4_horz_res_32x4_r1_3 = vrshrq_n_s32(i4_horz_samp_32x4_r1_3, 2);
+ i4_horz_res_32x4_r1_4 = vrshrq_n_s32(i4_horz_samp_32x4_r1_4, 2);
+
+ comb_horz_16x8_1 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_1), vmovn_s32(i4_horz_res_32x4_r1_2));
+ comb_horz_16x8_2 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_3), vmovn_s32(i4_horz_res_32x4_r1_4));
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ /* if reference layer is not coded then no processing */
+ if(0 != (i4_ref_nnz & 0x1))
+ {
+ int16x8_t i2_coeff1_16x8_r0_0, i2_coeff1_16x8_r0_1;
+ int16x8_t i2_coeff1_16x8_r1_0, i2_coeff1_16x8_r1_1;
+ int16x8_t i2_coeff1_16x8_r2_0, i2_coeff1_16x8_r2_1;
+ int16x8_t i2_coeff1_16x8_r3_0, i2_coeff1_16x8_r3_1;
+ int16x8_t i2_add_16x8_r0_0;
+ int16x8_t i2_add_16x8_r1_0;
+ int16x8_t i2_add_16x8_r2_0;
+ int16x8_t i2_add_16x8_r3_0;
+ int16x8_t i2_res_16x8_r0_0, i2_res_16x8_r0_1;
+ int16x8_t i2_res_16x8_r1_0, i2_res_16x8_r1_1;
+ int16x8_t i2_res_16x8_r2_0, i2_res_16x8_r2_1;
+ int16x8_t i2_res_16x8_r3_0, i2_res_16x8_r3_1;
+
+ i2_coeff1_16x8_r0_0 = vld1q_s16(pi2_inp_data);
+ i2_coeff1_16x8_r1_0 = vld1q_s16(pi2_inp_data + i4_inp_data_stride);
+ i2_coeff1_16x8_r2_0 = vld1q_s16(pi2_inp_data + (i4_inp_data_stride << 1));
+ i2_coeff1_16x8_r3_0 =
+ vld1q_s16(pi2_inp_data + (i4_inp_data_stride << 1) + i4_inp_data_stride);
+
+ i2_coeff1_16x8_r0_1 = vextq_s16(i2_coeff1_16x8_r0_0, i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_1 = vextq_s16(i2_coeff1_16x8_r1_0, i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_1 = vextq_s16(i2_coeff1_16x8_r2_0, i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_1 = vextq_s16(i2_coeff1_16x8_r3_0, i2_coeff1_16x8_r3_0, 1);
+
+ i2_add_16x8_r0_0 = vaddq_s16(i2_coeff1_16x8_r0_1, i2_coeff1_16x8_r0_0);
+ i2_add_16x8_r1_0 = vaddq_s16(i2_coeff1_16x8_r1_1, i2_coeff1_16x8_r1_0);
+ i2_add_16x8_r2_0 = vaddq_s16(i2_coeff1_16x8_r2_1, i2_coeff1_16x8_r2_0);
+ i2_add_16x8_r3_0 = vaddq_s16(i2_coeff1_16x8_r3_1, i2_coeff1_16x8_r3_0);
+
+ i2_coeff1_16x8_r0_0 = vshlq_n_s16(i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_0 = vshlq_n_s16(i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_0 = vshlq_n_s16(i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_0 = vshlq_n_s16(i2_coeff1_16x8_r3_0, 1);
+
+ i2_coeff1_16x8_r0_1 = vshlq_n_s16(i2_coeff1_16x8_r0_1, 1);
+ i2_coeff1_16x8_r1_1 = vshlq_n_s16(i2_coeff1_16x8_r1_1, 1);
+ i2_coeff1_16x8_r2_1 = vshlq_n_s16(i2_coeff1_16x8_r2_1, 1);
+ i2_coeff1_16x8_r3_1 = vshlq_n_s16(i2_coeff1_16x8_r3_1, 1);
+
+ i2_res_16x8_r0_0 = vaddq_s16(i2_coeff1_16x8_r0_0, i2_add_16x8_r0_0);
+ i2_res_16x8_r1_0 = vaddq_s16(i2_coeff1_16x8_r1_0, i2_add_16x8_r1_0);
+ i2_res_16x8_r2_0 = vaddq_s16(i2_coeff1_16x8_r2_0, i2_add_16x8_r2_0);
+ i2_res_16x8_r3_0 = vaddq_s16(i2_coeff1_16x8_r3_0, i2_add_16x8_r3_0);
+
+ i2_res_16x8_r0_1 = vaddq_s16(i2_coeff1_16x8_r0_1, i2_add_16x8_r0_0);
+ i2_res_16x8_r1_1 = vaddq_s16(i2_coeff1_16x8_r1_1, i2_add_16x8_r1_0);
+ i2_res_16x8_r2_1 = vaddq_s16(i2_coeff1_16x8_r2_1, i2_add_16x8_r2_0);
+ i2_res_16x8_r3_1 = vaddq_s16(i2_coeff1_16x8_r3_1, i2_add_16x8_r3_0);
+
+ i2_res_16x8_r0_0 = vzipq_s16(i2_res_16x8_r0_0, i2_res_16x8_r0_1).val[0];
+ i2_res_16x8_r1_0 = vzipq_s16(i2_res_16x8_r1_0, i2_res_16x8_r1_1).val[0];
+ i2_res_16x8_r2_0 = vzipq_s16(i2_res_16x8_r2_0, i2_res_16x8_r2_1).val[0];
+ i2_res_16x8_r3_0 = vzipq_s16(i2_res_16x8_r3_0, i2_res_16x8_r3_1).val[0];
+
+ i2_coeff1_16x8_r0_0 = vshlq_n_s16(i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_0 = vshlq_n_s16(i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_0 = vshlq_n_s16(i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_0 = vshlq_n_s16(i2_coeff1_16x8_r3_0, 1);
+
+ vst1q_s16(pi2_refarray_buffer + 1, i2_res_16x8_r0_0);
+ vst1q_lane_s16(pi2_refarray_buffer, i2_coeff1_16x8_r0_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 7, i2_coeff1_16x8_r0_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 9, i2_res_16x8_r1_0);
+ vst1q_lane_s16(pi2_refarray_buffer + 8, i2_coeff1_16x8_r1_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 15, i2_coeff1_16x8_r1_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 17, i2_res_16x8_r2_0);
+ vst1q_lane_s16(pi2_refarray_buffer + 16, i2_coeff1_16x8_r2_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 23, i2_coeff1_16x8_r2_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 25, i2_res_16x8_r3_0);
+ vst1q_lane_s16(pi2_refarray_buffer + 24, i2_coeff1_16x8_r3_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 31, i2_coeff1_16x8_r3_0, 3);
+
+ {
+ int16x4_t i4_horz_samp_16x4_r0_1, i4_horz_samp_16x4_r0_2;
+ int16x4_t i4_horz_samp_16x4_r1_1, i4_horz_samp_16x4_r1_2;
+ int16x4_t i4_horz_samp_16x4_r2_1, i4_horz_samp_16x4_r2_2;
+ int16x4_t i4_horz_samp_16x4_r3_1, i4_horz_samp_16x4_r3_2;
+
+ int32x4_t i4_horz_samp_32x4_r0_1, i4_horz_samp_32x4_r0_2;
+ int32x4_t i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r1_2;
+ int32x4_t i4_horz_samp_32x4_r2_1, i4_horz_samp_32x4_r2_2;
+ int32x4_t i4_horz_samp_32x4_r3_1, i4_horz_samp_32x4_r3_2;
+
+ int32x4_t i4_horz_add_32x4_r1_1, i4_horz_add_32x4_r1_2;
+ int32x4_t i4_horz_add_32x4_r2_1, i4_horz_add_32x4_r2_2;
+ int32x4_t i4_horz_add_32x4_r3_1, i4_horz_add_32x4_r3_2;
+
+ int16x4_t i4_horz_res_16x4_r0_1, i4_horz_res_16x4_r0_2;
+ int16x4_t i4_horz_res_16x4_r1_1, i4_horz_res_16x4_r1_2;
+ int16x4_t i4_horz_res_16x4_r2_1, i4_horz_res_16x4_r2_2;
+ int16x4_t i4_horz_res_16x4_r3_1, i4_horz_res_16x4_r3_2;
+ int16x4_t i4_horz_res_16x4_r4_1, i4_horz_res_16x4_r4_2;
+ int16x4_t i4_horz_res_16x4_r5_1, i4_horz_res_16x4_r5_2;
+ int16x4_t i4_horz_res_16x4_r6_1, i4_horz_res_16x4_r6_2;
+ int16x4_t i4_horz_res_16x4_r7_1, i4_horz_res_16x4_r7_2;
+
+ int32x4_t i4_horz_res_32x4_r1_1, i4_horz_res_32x4_r1_2;
+ int32x4_t i4_horz_res_32x4_r2_1, i4_horz_res_32x4_r2_2;
+ int32x4_t i4_horz_res_32x4_r3_1, i4_horz_res_32x4_r3_2;
+ int32x4_t i4_horz_res_32x4_r4_1, i4_horz_res_32x4_r4_2;
+ int32x4_t i4_horz_res_32x4_r5_1, i4_horz_res_32x4_r5_2;
+ int32x4_t i4_horz_res_32x4_r6_1, i4_horz_res_32x4_r6_2;
+
+ i4_horz_samp_16x4_r0_1 = vld1_s16(pi2_refarray_buffer);
+ i4_horz_samp_16x4_r0_2 = vld1_s16(pi2_refarray_buffer + 4);
+
+ i4_horz_samp_16x4_r1_1 = vld1_s16(pi2_refarray_buffer + 8);
+ i4_horz_samp_16x4_r1_2 = vld1_s16(pi2_refarray_buffer + 12);
+
+ i4_horz_samp_16x4_r2_1 = vld1_s16(pi2_refarray_buffer + 16);
+ i4_horz_samp_16x4_r2_2 = vld1_s16(pi2_refarray_buffer + 20);
+
+ i4_horz_samp_16x4_r3_1 = vld1_s16(pi2_refarray_buffer + 24);
+ i4_horz_samp_16x4_r3_2 = vld1_s16(pi2_refarray_buffer + 28);
+
+ i4_horz_res_16x4_r0_1 = vrshr_n_s16(i4_horz_samp_16x4_r0_1, 2);
+ i4_horz_res_16x4_r0_2 = vrshr_n_s16(i4_horz_samp_16x4_r0_2, 2);
+
+ i4_horz_add_32x4_r1_1 =
+ vaddl_s16(i4_horz_samp_16x4_r0_1, i4_horz_samp_16x4_r1_1);
+ i4_horz_add_32x4_r1_2 =
+ vaddl_s16(i4_horz_samp_16x4_r0_2, i4_horz_samp_16x4_r1_2);
+
+ i4_horz_add_32x4_r2_1 =
+ vaddl_s16(i4_horz_samp_16x4_r1_1, i4_horz_samp_16x4_r2_1);
+ i4_horz_add_32x4_r2_2 =
+ vaddl_s16(i4_horz_samp_16x4_r1_2, i4_horz_samp_16x4_r2_2);
+
+ i4_horz_add_32x4_r3_1 =
+ vaddl_s16(i4_horz_samp_16x4_r2_1, i4_horz_samp_16x4_r3_1);
+ i4_horz_add_32x4_r3_2 =
+ vaddl_s16(i4_horz_samp_16x4_r2_2, i4_horz_samp_16x4_r3_2);
+
+ i4_horz_samp_32x4_r0_1 = vshll_n_s16(i4_horz_samp_16x4_r0_1, 1);
+ i4_horz_samp_32x4_r0_2 = vshll_n_s16(i4_horz_samp_16x4_r0_2, 1);
+
+ i4_horz_samp_32x4_r1_1 = vshll_n_s16(i4_horz_samp_16x4_r1_1, 1);
+ i4_horz_samp_32x4_r1_2 = vshll_n_s16(i4_horz_samp_16x4_r1_2, 1);
+
+ i4_horz_samp_32x4_r2_1 = vshll_n_s16(i4_horz_samp_16x4_r2_1, 1);
+ i4_horz_samp_32x4_r2_2 = vshll_n_s16(i4_horz_samp_16x4_r2_2, 1);
+
+ i4_horz_samp_32x4_r3_1 = vshll_n_s16(i4_horz_samp_16x4_r3_1, 1);
+ i4_horz_samp_32x4_r3_2 = vshll_n_s16(i4_horz_samp_16x4_r3_2, 1);
+
+ i4_horz_res_32x4_r1_1 =
+ vaddq_s32(i4_horz_samp_32x4_r0_1, i4_horz_add_32x4_r1_1);
+ i4_horz_res_32x4_r1_2 =
+ vaddq_s32(i4_horz_samp_32x4_r0_2, i4_horz_add_32x4_r1_2);
+
+ i4_horz_res_32x4_r2_1 =
+ vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_add_32x4_r1_1);
+ i4_horz_res_32x4_r2_2 =
+ vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_add_32x4_r1_2);
+
+ i4_horz_res_32x4_r3_1 =
+ vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r3_2 =
+ vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_add_32x4_r2_2);
+
+ i4_horz_res_32x4_r4_1 =
+ vaddq_s32(i4_horz_samp_32x4_r2_1, i4_horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r4_2 =
+ vaddq_s32(i4_horz_samp_32x4_r2_2, i4_horz_add_32x4_r2_2);
+
+ i4_horz_res_32x4_r5_1 =
+ vaddq_s32(i4_horz_samp_32x4_r2_1, i4_horz_add_32x4_r3_1);
+ i4_horz_res_32x4_r5_2 =
+ vaddq_s32(i4_horz_samp_32x4_r2_2, i4_horz_add_32x4_r3_2);
+
+ i4_horz_res_32x4_r6_1 =
+ vaddq_s32(i4_horz_samp_32x4_r3_1, i4_horz_add_32x4_r3_1);
+ i4_horz_res_32x4_r6_2 =
+ vaddq_s32(i4_horz_samp_32x4_r3_2, i4_horz_add_32x4_r3_2);
+
+ i4_horz_res_16x4_r1_1 = vqrshrn_n_s32(i4_horz_res_32x4_r1_1, 4);
+ i4_horz_res_16x4_r1_2 = vqrshrn_n_s32(i4_horz_res_32x4_r1_2, 4);
+
+ i4_horz_res_16x4_r2_1 = vqrshrn_n_s32(i4_horz_res_32x4_r2_1, 4);
+ i4_horz_res_16x4_r2_2 = vqrshrn_n_s32(i4_horz_res_32x4_r2_2, 4);
+
+ i4_horz_res_16x4_r3_1 = vqrshrn_n_s32(i4_horz_res_32x4_r3_1, 4);
+ i4_horz_res_16x4_r3_2 = vqrshrn_n_s32(i4_horz_res_32x4_r3_2, 4);
+
+ i4_horz_res_16x4_r4_1 = vqrshrn_n_s32(i4_horz_res_32x4_r4_1, 4);
+ i4_horz_res_16x4_r4_2 = vqrshrn_n_s32(i4_horz_res_32x4_r4_2, 4);
+
+ i4_horz_res_16x4_r5_1 = vqrshrn_n_s32(i4_horz_res_32x4_r5_1, 4);
+ i4_horz_res_16x4_r5_2 = vqrshrn_n_s32(i4_horz_res_32x4_r5_2, 4);
+
+ i4_horz_res_16x4_r6_1 = vqrshrn_n_s32(i4_horz_res_32x4_r6_1, 4);
+ i4_horz_res_16x4_r6_2 = vqrshrn_n_s32(i4_horz_res_32x4_r6_2, 4);
+
+ i4_horz_res_16x4_r7_1 = vrshr_n_s16(i4_horz_samp_16x4_r3_1, 2);
+ i4_horz_res_16x4_r7_2 = vrshr_n_s16(i4_horz_samp_16x4_r3_2, 2);
+
+ vst1_s16(pi2_out_res, i4_horz_res_16x4_r0_1);
+ vst1_s16(pi2_out_res + 4, i4_horz_res_16x4_r0_2);
+
+ vst1_s16(pi2_out_res + i4_out_res_stride, i4_horz_res_16x4_r1_1);
+ vst1_s16(pi2_out_res + i4_out_res_stride + 4, i4_horz_res_16x4_r1_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 1), i4_horz_res_16x4_r2_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 1) + 4, i4_horz_res_16x4_r2_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 3), i4_horz_res_16x4_r3_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 3) + 4, i4_horz_res_16x4_r3_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 2), i4_horz_res_16x4_r4_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 2) + 4, i4_horz_res_16x4_r4_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 5), i4_horz_res_16x4_r5_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 5) + 4, i4_horz_res_16x4_r5_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 6), i4_horz_res_16x4_r6_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 6) + 4, i4_horz_res_16x4_r6_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 7), i4_horz_res_16x4_r7_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 7) + 4, i4_horz_res_16x4_r7_2);
+
+ pi2_out_res += BLOCK_WIDTH;
+ }
+ }
+ else
+ {
+ pi2_out_res += BLOCK_WIDTH;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= SUB_BLOCK_WIDTH;
+ pi2_inp_data += (i4_inp_data_stride * SUB_BLOCK_HEIGHT);
+ pi2_out_res -= MB_WIDTH;
+ pi2_out_res += (i4_out_res_stride * BLOCK_HEIGHT);
+ i4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += SUB_BLOCK_WIDTH;
+ }
+
+ i4_ref_nnz >>= 1;
+ } /* end of loop over all the blocks */
+ }
+
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_residual_neonintr */
+/* */
+/* Description : this fucntion does the upsampling of residuals. */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* ps_ref_mb_mode : reference mb mode pointer of base layer */
+/* ps_coord : mb co-ordinate pointer */
+/* Globals : none */
+/* Processing : it does the upsampling with fixed phase values and */
+/* reference layer transform size */
+/* Outputs : Upsampled residuals. */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_interpolate_residual_neonintr(void *pv_residual_samp_ctxt, WORD16 *pi2_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_chroma_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ residual_samp_map_ctxt_t *ps_map_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ WORD32 i4_temp_array_ht;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD16 *pi2_ref_array;
+ UWORD8 *pu1_ref_x_ptr_incr, *pu1_ref_y_ptr_incr;
+
+ UWORD8 arr_y_ref_pos[16] = {0};
+ UWORD8 arr_x_ref_pos[16] = {0};
+ UWORD8 arr_x_ref_pos_low[16] = {0};
+ UWORD8 arr_x_phase[16] = {0};
+ UWORD8 arr_y_phase[16] = {0};
+ UWORD8 *pi1_y_ref_pos;
+ UWORD8 *pi1_x_ref_pos;
+ UWORD8 *pi1_x_ref_pos_low;
+ UWORD8 *pi1_y_phase;
+ UWORD8 *pi1_x_phase;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
+ pu1_ref_x_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr;
+ pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_y_ptr_incr;
+
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ else
+ ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ i4_temp_array_ht = i4_mb_ht;
+ i4_frm_mb_y = u2_mb_y * i4_mb_ht;
+ i4_frm_mb_x = u2_mb_x * i4_mb_wd;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation */
+ /* --------------------------------------------------------------------- */
+ if(i4_chroma_flag == 0)
+ {
+ int16x8_t ref_arr_16x8_r0_0, ref_arr_16x8_r0_1;
+ int16x8_t ref_arr_16x8_r1_0, ref_arr_16x8_r1_1;
+ uint8x16_t x_ref_pos_mask_r0_0, x_ref_rnd_mask_r0_0;
+ uint8x16_t u1_incr_8x16_r0_0, x_ref_pos_mask_temp_r0_0, u1_incr_not_8x16_r0_0,
+ u1_y_incr_8x16_r0_0, phs_mask_8x16_0;
+ uint8x16_t u1_incr_8x16_r1_0, x_ref_pos_mask_temp_r1_0, u1_incr_not_8x16_r1_0;
+ int16x8_t ref_arr_temp0_16x8_r0_0, res_16x8_r0_0, vert_res_16x8_r0_0;
+ int16x8_t ref_arr_temp0_16x8_r1_0, res_16x8_r1_0, vert_res_16x8_r1_0;
+ int16x8_t ref_arr_temp1_16x8_r0_0;
+ int16x8_t ref_arr_temp1_16x8_r1_0;
+
+ uint8x16_t x_ref_pos_mask_temp_r0_1, u1_incr_not_8x16_r0_1;
+ uint8x16_t x_ref_pos_mask_temp_r1_1, u1_incr_not_8x16_r1_1;
+ int16x8_t ref_arr_temp0_16x8_r0_1, res_16x8_r0_1, vert_res_16x8_r0_1;
+ int16x8_t ref_arr_temp0_16x8_r1_1, res_16x8_r1_1, vert_res_16x8_r1_1;
+ int16x8_t ref_arr_temp1_16x8_r0_1;
+ int16x8_t ref_arr_temp1_16x8_r1_1;
+
+ uint16x8_t u1_y_incr_16x8_r0_0, u1_y_incr_16x8_r0_1;
+
+ uint8x16_t u1_incr_not_8x16_r0_0_even, u1_incr_not_8x16_r1_0_even,
+ x_ref_pos_mask_temp_r0_0_even, x_ref_pos_mask_temp_r1_0_even;
+ uint8x16_t u1_incr_not_8x16_r0_0_odd, u1_incr_not_8x16_r1_0_odd,
+ x_ref_pos_mask_temp_r0_0_odd, x_ref_pos_mask_temp_r1_0_odd;
+ uint8x16x2_t u1_incr_not_8x16_2, x_ref_pos_mask_temp;
+ int16x8_t prev_res_16x8_r0_0;
+ int16x8_t prev_res_16x8_r1_0;
+ int16x8_t prev_res_16x8_r0_1;
+ int16x8_t prev_res_16x8_r1_1;
+ uint8x8x2_t u1_incr_8x8x2_t;
+ uint8x8_t u1_incr_8x8_t0, u1_incr_8x8_t1;
+ uint16x8_t u1_prev_y_incr_16x8_r0_0;
+ uint16x8_t u1_prev_y_incr_16x8_r0_1;
+
+ WORD32 zero_r0_r1 = 0;
+
+ int32x4_t res_32x4_l_0, res_32x4_h_0;
+ int32x4_t res_32x4_l_1, res_32x4_h_1;
+ int16x8_t res_16x8_l, res_16x8_h;
+ uint16x8_t phs_mask_16x8_0, phs_mask_16x8_1;
+ int16x8_t const_16_16x8, phs_mask_16min_16x8_0;
+ int16x8_t dup_val_1, dup_val_2, dup_val_3, dup_val_4, dup_val_5, dup_abs;
+ uint8x16_t phs_mask_div8_8x16_0, mid_indx_8x16;
+ int16x8_t phs_mask_16min_16x8_1;
+ uint16x8_t ones = vdupq_n_u16(0xFFFF);
+ uint8x16_t const_ones = vdupq_n_u8(1);
+ uint8x8x2_t u1_temp_8x8x2_t;
+ uint8x8_t u1_temp_8x8_t0, u1_temp_8x8_t1;
+
+ WORD16 *pi2_ref_array_temp;
+ UWORD8 *pu1_ref_x_ptr_incr_temp, *pu1_ref_y_ptr_incr_temp;
+ WORD32 i4_y_phase;
+ WORD32 out_stride_temp;
+ WORD32 strt_indx_h = 0;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_phase[i4_y] = (UWORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos[i4_y] = (UWORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi1_y_ref_pos = arr_y_ref_pos;
+ pi1_y_phase = arr_y_phase;
+
+ strt_indx_h = (ps_x_pos_phase[8 + i4_frm_mb_x].i2_ref_pos);
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_x_phase[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ }
+
+ pi1_x_ref_pos = arr_x_ref_pos;
+ pi1_x_phase = arr_x_phase;
+
+ phs_mask_8x16_0 = vld1q_u8((pi1_x_phase));
+ phs_mask_16x8_0 = vmovl_u8(vget_low_u8(phs_mask_8x16_0));
+ phs_mask_16x8_1 = vmovl_u8(vld1_u8((pi1_x_phase + 8)));
+ x_ref_pos_mask_r0_0 = vld1q_u8((pi1_x_ref_pos));
+ const_16_16x8 = vdupq_n_s16(16);
+ phs_mask_div8_8x16_0 = vshrq_n_u8(phs_mask_8x16_0, 3);
+
+ phs_mask_16min_16x8_0 = vsubq_s16(const_16_16x8, vreinterpretq_s16_u16(phs_mask_16x8_0));
+ phs_mask_16min_16x8_1 = vsubq_s16(const_16_16x8, vreinterpretq_s16_u16(phs_mask_16x8_1));
+
+ x_ref_rnd_mask_r0_0 = vaddq_u8(x_ref_pos_mask_r0_0, phs_mask_div8_8x16_0);
+ mid_indx_8x16 = vdupq_n_u8((strt_indx_h << 1));
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ if((i4_y > 0) && (pi1_y_ref_pos[i4_y] == pi1_y_ref_pos[i4_y - 1]))
+ {
+ if(!zero_r0_r1)
+ {
+ res_16x8_l = vdupq_n_s16(0);
+ res_16x8_h = vdupq_n_s16(0);
+
+ out_stride_temp = (i4_y * i4_out_stride);
+ vst1q_s16((pi2_out + out_stride_temp), res_16x8_l);
+ vst1q_s16((pi2_out + out_stride_temp + 8), res_16x8_h);
+ continue;
+ }
+
+ res_16x8_r0_0 = prev_res_16x8_r0_0;
+ res_16x8_r1_0 = prev_res_16x8_r1_0;
+ res_16x8_r0_1 = prev_res_16x8_r0_1;
+ res_16x8_r1_1 = prev_res_16x8_r1_1;
+
+ u1_y_incr_16x8_r0_0 = u1_prev_y_incr_16x8_r0_0;
+ u1_y_incr_16x8_r0_1 = u1_prev_y_incr_16x8_r0_1;
+ }
+ else
+ {
+ pi2_ref_array_temp = pi2_ref_array + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ pu1_ref_x_ptr_incr_temp =
+ pu1_ref_x_ptr_incr + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ ref_arr_16x8_r0_0 = vld1q_s16((pi2_ref_array_temp));
+ ref_arr_16x8_r1_0 = vld1q_s16((pi2_ref_array_temp + i4_refarray_wd));
+ ref_arr_16x8_r0_1 = vld1q_s16((pi2_ref_array_temp + strt_indx_h));
+ ref_arr_16x8_r1_1 = vld1q_s16((pi2_ref_array_temp + i4_refarray_wd + strt_indx_h));
+
+ dup_val_1 = vabsq_s16(ref_arr_16x8_r0_0);
+ dup_val_2 = vabsq_s16(ref_arr_16x8_r1_0);
+ dup_val_3 = vabsq_s16(ref_arr_16x8_r0_1);
+ dup_val_4 = vabsq_s16(ref_arr_16x8_r1_1);
+ dup_val_5 = vqaddq_s16(dup_val_1, dup_val_2);
+ dup_val_1 = vqaddq_s16(dup_val_3, dup_val_4);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_5);
+ zero_r0_r1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] ||
+ dup_abs[5] || dup_abs[6] || dup_abs[7];
+ if(zero_r0_r1)
+ {
+ u1_incr_8x16_r0_0 = vld1q_u8((pu1_ref_x_ptr_incr_temp));
+ u1_incr_8x16_r1_0 = vld1q_u8((pu1_ref_x_ptr_incr_temp + i4_refarray_wd));
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(u1_incr_8x16_r0_0);
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(u1_incr_8x16_r0_0);
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x16_r0_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(u1_incr_8x16_r1_0);
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(u1_incr_8x16_r1_0);
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x16_r1_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+ u1_incr_not_8x16_r0_0 = vbicq_u8(phs_mask_div8_8x16_0, u1_incr_8x16_r0_0);
+ u1_incr_not_8x16_r1_0 = vbicq_u8(phs_mask_div8_8x16_0, u1_incr_8x16_r1_0);
+
+ u1_incr_not_8x16_r0_0 = vaddq_u8(u1_incr_not_8x16_r0_0, x_ref_pos_mask_r0_0);
+ u1_incr_not_8x16_r1_0 = vaddq_u8(u1_incr_not_8x16_r1_0, x_ref_pos_mask_r0_0);
+
+ x_ref_pos_mask_temp_r0_0 = vaddq_u8(u1_incr_not_8x16_r0_0, u1_incr_8x16_r0_0);
+ x_ref_pos_mask_temp_r1_0 = vaddq_u8(u1_incr_not_8x16_r1_0, u1_incr_8x16_r1_0);
+
+ u1_incr_not_8x16_r0_0_even = vshlq_n_u8(u1_incr_not_8x16_r0_0, 1);
+ u1_incr_not_8x16_r1_0_even = vshlq_n_u8(u1_incr_not_8x16_r1_0, 1);
+ x_ref_pos_mask_temp_r0_0_even = vshlq_n_u8(x_ref_pos_mask_temp_r0_0, 1);
+ x_ref_pos_mask_temp_r1_0_even = vshlq_n_u8(x_ref_pos_mask_temp_r1_0, 1);
+
+ u1_incr_not_8x16_r0_0_odd = vaddq_u8(u1_incr_not_8x16_r0_0_even, const_ones);
+ u1_incr_not_8x16_r1_0_odd = vaddq_u8(u1_incr_not_8x16_r1_0_even, const_ones);
+ x_ref_pos_mask_temp_r0_0_odd =
+ vaddq_u8(x_ref_pos_mask_temp_r0_0_even, const_ones);
+ x_ref_pos_mask_temp_r1_0_odd =
+ vaddq_u8(x_ref_pos_mask_temp_r1_0_even, const_ones);
+
+ u1_incr_not_8x16_2 =
+ vzipq_u8(u1_incr_not_8x16_r0_0_even, u1_incr_not_8x16_r0_0_odd);
+
+ u1_incr_not_8x16_r0_0 = u1_incr_not_8x16_2.val[0];
+ u1_incr_not_8x16_r0_1 = u1_incr_not_8x16_2.val[1];
+
+ u1_incr_not_8x16_2 =
+ vzipq_u8(u1_incr_not_8x16_r1_0_even, u1_incr_not_8x16_r1_0_odd);
+ u1_incr_not_8x16_r1_0 = u1_incr_not_8x16_2.val[0];
+ u1_incr_not_8x16_r1_1 = u1_incr_not_8x16_2.val[1];
+
+ x_ref_pos_mask_temp =
+ vzipq_u8(x_ref_pos_mask_temp_r0_0_even, x_ref_pos_mask_temp_r0_0_odd);
+ x_ref_pos_mask_temp_r0_0 = x_ref_pos_mask_temp.val[0];
+ x_ref_pos_mask_temp_r0_1 = x_ref_pos_mask_temp.val[1];
+
+ x_ref_pos_mask_temp =
+ vzipq_u8(x_ref_pos_mask_temp_r1_0_even, x_ref_pos_mask_temp_r1_0_odd);
+ x_ref_pos_mask_temp_r1_0 = x_ref_pos_mask_temp.val[0];
+ x_ref_pos_mask_temp_r1_1 = x_ref_pos_mask_temp.val[1];
+ u1_incr_not_8x16_r0_1 = vsubq_u8(u1_incr_not_8x16_r0_1, mid_indx_8x16);
+ u1_incr_not_8x16_r1_1 = vsubq_u8(u1_incr_not_8x16_r1_1, mid_indx_8x16);
+ x_ref_pos_mask_temp_r0_1 = vsubq_u8(x_ref_pos_mask_temp_r0_1, mid_indx_8x16);
+ x_ref_pos_mask_temp_r1_1 = vsubq_u8(x_ref_pos_mask_temp_r1_1, mid_indx_8x16);
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r0_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r0_0));
+ ref_arr_temp0_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r1_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r1_0));
+ ref_arr_temp0_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r0_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r0_0));
+ ref_arr_temp1_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r1_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r1_0));
+ ref_arr_temp1_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_1)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r0_1));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r0_1));
+ ref_arr_temp0_16x8_r0_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_1)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r1_1));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r1_1));
+ ref_arr_temp0_16x8_r1_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_1)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r0_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r0_1));
+ ref_arr_temp1_16x8_r0_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_1)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_1)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r1_1));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r1_1));
+ ref_arr_temp1_16x8_r1_1 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ res_16x8_r0_0 = vmulq_s16(ref_arr_temp0_16x8_r0_0, phs_mask_16min_16x8_0);
+ res_16x8_r1_0 = vmulq_s16(ref_arr_temp0_16x8_r1_0, phs_mask_16min_16x8_0);
+ res_16x8_r0_0 = vmlaq_s16(res_16x8_r0_0, ref_arr_temp1_16x8_r0_0,
+ vreinterpretq_s16_u16(phs_mask_16x8_0));
+ res_16x8_r1_0 = vmlaq_s16(res_16x8_r1_0, ref_arr_temp1_16x8_r1_0,
+ vreinterpretq_s16_u16(phs_mask_16x8_0));
+ res_16x8_r0_1 = vmulq_s16(ref_arr_temp0_16x8_r0_1, phs_mask_16min_16x8_1);
+ res_16x8_r1_1 = vmulq_s16(ref_arr_temp0_16x8_r1_1, phs_mask_16min_16x8_1);
+ res_16x8_r0_1 = vmlaq_s16(res_16x8_r0_1, ref_arr_temp1_16x8_r0_1,
+ vreinterpretq_s16_u16(phs_mask_16x8_1));
+ res_16x8_r1_1 = vmlaq_s16(res_16x8_r1_1, ref_arr_temp1_16x8_r1_1,
+ vreinterpretq_s16_u16(phs_mask_16x8_1));
+
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + (pi1_y_ref_pos[i4_y] * i4_refarray_wd);
+ u1_y_incr_8x16_r0_0 = vld1q_u8((pu1_ref_y_ptr_incr_temp));
+
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(u1_y_incr_8x16_r0_0);
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(u1_y_incr_8x16_r0_0);
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_rnd_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_rnd_mask_r0_0));
+ u1_y_incr_8x16_r0_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+ u1_y_incr_16x8_r0_0 = vmovl_u8(vget_low_u8(u1_y_incr_8x16_r0_0));
+ u1_y_incr_16x8_r0_1 = vmovl_u8(vget_high_u8(u1_y_incr_8x16_r0_0));
+ u1_y_incr_16x8_r0_0 = vtstq_u16(u1_y_incr_16x8_r0_0, ones);
+ u1_y_incr_16x8_r0_1 = vtstq_u16(u1_y_incr_16x8_r0_1, ones);
+
+ prev_res_16x8_r0_0 = res_16x8_r0_0;
+ prev_res_16x8_r1_0 = res_16x8_r1_0;
+ prev_res_16x8_r0_1 = res_16x8_r0_1;
+ prev_res_16x8_r1_1 = res_16x8_r1_1;
+
+ u1_prev_y_incr_16x8_r0_0 = u1_y_incr_16x8_r0_0;
+ u1_prev_y_incr_16x8_r0_1 = u1_y_incr_16x8_r0_1;
+ }
+ }
+
+ if(!zero_r0_r1)
+ {
+ res_16x8_l = vdupq_n_s16(0);
+ res_16x8_h = vdupq_n_s16(0);
+ }
+ else
+ {
+ i4_y_phase = pi1_y_phase[i4_y];
+
+ if((i4_y_phase) >> 3)
+ {
+ vert_res_16x8_r0_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r0_0, res_16x8_r1_0);
+ vert_res_16x8_r1_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r1_0, res_16x8_r1_0);
+ vert_res_16x8_r0_1 =
+ vbslq_s16(u1_y_incr_16x8_r0_1, res_16x8_r0_1, res_16x8_r1_1);
+ vert_res_16x8_r1_1 =
+ vbslq_s16(u1_y_incr_16x8_r0_1, res_16x8_r1_1, res_16x8_r1_1);
+ }
+ else
+ {
+ vert_res_16x8_r0_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r0_0, res_16x8_r0_0);
+ vert_res_16x8_r1_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r1_0, res_16x8_r0_0);
+ vert_res_16x8_r0_1 =
+ vbslq_s16(u1_y_incr_16x8_r0_1, res_16x8_r0_1, res_16x8_r0_1);
+ vert_res_16x8_r1_1 =
+ vbslq_s16(u1_y_incr_16x8_r0_1, res_16x8_r1_1, res_16x8_r0_1);
+ }
+
+ res_32x4_l_0 = vmull_n_s16(vget_low_s16(vert_res_16x8_r0_0), 16 - i4_y_phase);
+ res_32x4_l_0 =
+ vmlal_n_s16(res_32x4_l_0, vget_low_s16(vert_res_16x8_r1_0), i4_y_phase);
+
+ res_32x4_l_1 = vmull_n_s16(vget_high_s16(vert_res_16x8_r0_0), 16 - i4_y_phase);
+ res_32x4_l_1 =
+ vmlal_n_s16(res_32x4_l_1, vget_high_s16(vert_res_16x8_r1_0), i4_y_phase);
+ res_32x4_h_0 = vmull_n_s16(vget_low_s16(vert_res_16x8_r0_1), 16 - i4_y_phase);
+ res_32x4_h_0 =
+ vmlal_n_s16(res_32x4_h_0, vget_low_s16(vert_res_16x8_r1_1), i4_y_phase);
+ res_32x4_h_1 = vmull_n_s16(vget_high_s16(vert_res_16x8_r0_1), 16 - i4_y_phase);
+ res_32x4_h_1 =
+ vmlal_n_s16(res_32x4_h_1, vget_high_s16(vert_res_16x8_r1_1), i4_y_phase);
+
+ res_32x4_l_0 = vrshrq_n_s32(res_32x4_l_0, 8);
+ res_32x4_l_1 = vrshrq_n_s32(res_32x4_l_1, 8);
+ res_32x4_h_0 = vrshrq_n_s32(res_32x4_h_0, 8);
+ res_32x4_h_1 = vrshrq_n_s32(res_32x4_h_1, 8);
+
+ res_16x8_l = vcombine_s16(vmovn_s32(res_32x4_l_0), vmovn_s32(res_32x4_l_1));
+ res_16x8_h = vcombine_s16(vmovn_s32(res_32x4_h_0), vmovn_s32(res_32x4_h_1));
+ }
+
+ out_stride_temp = (i4_y * i4_out_stride);
+ vst1q_s16((pi2_out + out_stride_temp), res_16x8_l);
+ vst1q_s16((pi2_out + out_stride_temp + 8), res_16x8_h);
+ }
+ }
+ else
+ {
+ int16x8_t ref_arr_16x8_r0_0;
+ int16x8_t ref_arr_16x8_r1_0;
+ uint8x16_t x_ref_pos_mask_r0_0, x_ref_rnd_mask_r0_0;
+ uint16x8_t u1_incr_16x8_r0_0, u1_incr_mask_16x8_r0_0, phs_mask_16x8_0,
+ u1_incr_not_16x8_r0_0, u1_y_incr_16x8_r0_0;
+ uint16x8_t u1_incr_16x8_r1_0, u1_incr_mask_16x8_r1_0, u1_incr_not_16x8_r1_0;
+ uint8x16_t u1_incr_8x16_r0_0, x_ref_pos_mask_temp_r0_0, u1_incr_mask_8x16_r0_0,
+ u1_incr_not_8x16_r0_0, u1_y_incr_8x16_r0_0;
+ uint8x16_t u1_incr_8x16_r1_0, x_ref_pos_mask_temp_r1_0, u1_incr_mask_8x16_r1_0,
+ u1_incr_not_8x16_r1_0;
+ int16x8_t ref_arr_temp0_16x8_r0_0, res_16x8_r0_0, vert_res_16x8_r0_0;
+ int16x8_t ref_arr_temp0_16x8_r1_0, res_16x8_r1_0, vert_res_16x8_r1_0;
+ int16x8_t ref_arr_temp1_16x8_r0_0;
+ int16x8_t ref_arr_temp1_16x8_r1_0;
+
+ int32x4_t res_32x4_l_0;
+ int32x4_t res_32x4_l_1;
+ int16x8_t out_16x8_0, out_16x8_1;
+ uint16x8_t phs_mask_div8_16x8_0, phs_mask_div8_msb_16x8_0;
+ int16x8_t const_16_16x8, phs_mask_16min_16x8_0;
+ uint8x8x2_t u1_temp_8x8x2_t;
+ uint8x8_t u1_temp_8x8_t0, u1_temp_8x8_t1;
+
+ uint16x8_t chroma_mask_16x8 = vreinterpretq_u16_u32(vdupq_n_u32(0x0000ffff));
+ uint16x8_t ones = vdupq_n_u16(0xFFFF);
+
+ WORD16 *pi2_ref_array_temp;
+ UWORD8 *pu1_ref_x_ptr_incr_temp, *pu1_ref_y_ptr_incr_temp;
+ WORD32 i4_y_phase;
+ uint8x8x2_t u1_incr_8x8x2_t;
+ uint8x8_t u1_incr_8x8_t0, u1_incr_8x8_t1;
+ int16x8_t prev_res_16x8_r0_0;
+ int16x8_t prev_res_16x8_r1_0;
+ int16x8_t dup_val_1, dup_val_2, dup_abs;
+ uint16x8_t u1_prev_y_incr_16x8_r0_0;
+
+ WORD32 out_stride_temp;
+ WORD32 zero_r0_r1 = 0;
+ WORD32 i4_x2 = 0;
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_phase[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos[i4_y] = (WORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi1_y_ref_pos = arr_y_ref_pos;
+ pi1_y_phase = arr_y_phase;
+
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_x_phase[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ i4_x2 = i4_x << 1;
+ arr_x_ref_pos_low[i4_x2] = (arr_x_ref_pos[i4_x]) << 1;
+ arr_x_ref_pos_low[i4_x2 + 1] = arr_x_ref_pos_low[i4_x2] + 1;
+ }
+
+ pi1_x_ref_pos_low = arr_x_ref_pos_low;
+ pi1_x_phase = arr_x_phase;
+
+ phs_mask_16x8_0 = vmovl_u8(vld1_u8((pi1_x_phase)));
+ x_ref_pos_mask_r0_0 = vld1q_u8((pi1_x_ref_pos_low));
+ const_16_16x8 = vdupq_n_s16(16);
+ phs_mask_div8_16x8_0 = vshrq_n_u16(phs_mask_16x8_0, 3);
+ phs_mask_div8_msb_16x8_0 = vsliq_n_u16(phs_mask_div8_16x8_0, phs_mask_div8_16x8_0, 8);
+
+ phs_mask_16min_16x8_0 = vsubq_s16(const_16_16x8, vreinterpretq_s16_u16(phs_mask_16x8_0));
+
+ x_ref_rnd_mask_r0_0 = vaddq_u8(
+ x_ref_pos_mask_r0_0, vreinterpretq_u8_u16(vshlq_n_u16(phs_mask_div8_msb_16x8_0, 1)));
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ if((i4_y > 0) && (pi1_y_ref_pos[i4_y] == pi1_y_ref_pos[i4_y - 1]))
+ {
+ if(!zero_r0_r1)
+ {
+ res_32x4_l_0 = vdupq_n_s32(0);
+ res_32x4_l_1 = vdupq_n_s32(0);
+
+ out_stride_temp = (i4_y * i4_out_stride);
+
+ out_16x8_0 = vld1q_s16(pi2_out + out_stride_temp);
+ out_16x8_1 = vld1q_s16(pi2_out + out_stride_temp + 8);
+ out_16x8_0 = vbslq_s16(chroma_mask_16x8, vreinterpretq_s16_s32(res_32x4_l_0),
+ out_16x8_0);
+ out_16x8_1 = vbslq_s16(chroma_mask_16x8, vreinterpretq_s16_s32(res_32x4_l_1),
+ out_16x8_1);
+ vst1q_s16((pi2_out + out_stride_temp), out_16x8_0);
+ vst1q_s16((pi2_out + out_stride_temp + 8), out_16x8_1);
+ continue;
+ }
+
+ res_16x8_r0_0 = prev_res_16x8_r0_0;
+ res_16x8_r1_0 = prev_res_16x8_r1_0;
+
+ u1_y_incr_16x8_r0_0 = u1_prev_y_incr_16x8_r0_0;
+ }
+ else
+ {
+ pi2_ref_array_temp = pi2_ref_array + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ pu1_ref_x_ptr_incr_temp =
+ pu1_ref_x_ptr_incr + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ ref_arr_16x8_r0_0 = vld1q_s16((pi2_ref_array_temp));
+ ref_arr_16x8_r1_0 = vld1q_s16((pi2_ref_array_temp + i4_refarray_wd));
+
+ dup_val_1 = vabsq_s16(ref_arr_16x8_r0_0);
+ dup_val_2 = vabsq_s16(ref_arr_16x8_r1_0);
+ dup_abs = vqaddq_s16(dup_val_1, dup_val_2);
+ zero_r0_r1 = dup_abs[0] || dup_abs[1] || dup_abs[2] || dup_abs[3] || dup_abs[4] ||
+ dup_abs[5] || dup_abs[6] || dup_abs[7];
+ if(zero_r0_r1)
+ {
+ u1_incr_16x8_r0_0 = (vmovl_u8(vld1_u8((pu1_ref_x_ptr_incr_temp))));
+ u1_incr_16x8_r1_0 =
+ (vmovl_u8(vld1_u8((pu1_ref_x_ptr_incr_temp + i4_refarray_wd))));
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(vreinterpretq_u8_u16(u1_incr_16x8_r0_0));
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(vreinterpretq_u8_u16(u1_incr_16x8_r0_0));
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x16_r0_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(vreinterpretq_u8_u16(u1_incr_16x8_r1_0));
+ u1_incr_8x8x2_t.val[1] = vget_high_u8(vreinterpretq_u8_u16(u1_incr_16x8_r1_0));
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_pos_mask_r0_0));
+ u1_incr_8x16_r1_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ u1_incr_16x8_r0_0 = vreinterpretq_u16_u8(u1_incr_8x16_r0_0);
+ u1_incr_16x8_r1_0 = vreinterpretq_u16_u8(u1_incr_8x16_r1_0);
+ u1_incr_mask_16x8_r0_0 = vsliq_n_u16(u1_incr_16x8_r0_0, u1_incr_16x8_r0_0, 8);
+ u1_incr_mask_16x8_r1_0 = vsliq_n_u16(u1_incr_16x8_r1_0, u1_incr_16x8_r1_0, 8);
+
+ u1_incr_not_16x8_r0_0 =
+ vbicq_u16(phs_mask_div8_msb_16x8_0, u1_incr_mask_16x8_r0_0);
+ u1_incr_not_16x8_r1_0 =
+ vbicq_u16(phs_mask_div8_msb_16x8_0, u1_incr_mask_16x8_r1_0);
+
+ u1_incr_mask_8x16_r0_0 =
+ vreinterpretq_u8_u16(vshlq_n_u16(u1_incr_mask_16x8_r0_0, 1));
+ u1_incr_mask_8x16_r1_0 =
+ vreinterpretq_u8_u16(vshlq_n_u16(u1_incr_mask_16x8_r1_0, 1));
+ u1_incr_not_8x16_r0_0 =
+ vreinterpretq_u8_u16(vshlq_n_u16(u1_incr_not_16x8_r0_0, 1));
+ u1_incr_not_8x16_r1_0 =
+ vreinterpretq_u8_u16(vshlq_n_u16(u1_incr_not_16x8_r1_0, 1));
+
+ u1_incr_not_8x16_r0_0 = vaddq_u8(u1_incr_not_8x16_r0_0, x_ref_pos_mask_r0_0);
+ u1_incr_not_8x16_r1_0 = vaddq_u8(u1_incr_not_8x16_r1_0, x_ref_pos_mask_r0_0);
+
+ x_ref_pos_mask_temp_r0_0 =
+ vaddq_u8(u1_incr_not_8x16_r0_0, u1_incr_mask_8x16_r0_0);
+ x_ref_pos_mask_temp_r1_0 =
+ vaddq_u8(u1_incr_not_8x16_r1_0, u1_incr_mask_8x16_r1_0);
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r0_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r0_0));
+ ref_arr_temp0_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8_t0 = vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(u1_incr_not_8x16_r1_0));
+ u1_temp_8x8_t1 = vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(u1_incr_not_8x16_r1_0));
+ ref_arr_temp0_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r0_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r0_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r0_0));
+ ref_arr_temp1_16x8_r0_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+
+ u1_temp_8x8x2_t.val[0] =
+ vreinterpret_u8_s8(vget_low_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8x2_t.val[1] =
+ vreinterpret_u8_s8(vget_high_s8(vreinterpretq_s8_s16(ref_arr_16x8_r1_0)));
+ u1_temp_8x8_t0 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_low_u8(x_ref_pos_mask_temp_r1_0));
+ u1_temp_8x8_t1 =
+ vtbl2_u8(u1_temp_8x8x2_t, vget_high_u8(x_ref_pos_mask_temp_r1_0));
+ ref_arr_temp1_16x8_r1_0 = vreinterpretq_s16_s8(vcombine_s8(
+ vreinterpret_s8_u8(u1_temp_8x8_t0), vreinterpret_s8_u8(u1_temp_8x8_t1)));
+ res_16x8_r0_0 = vmulq_s16(ref_arr_temp0_16x8_r0_0, phs_mask_16min_16x8_0);
+ res_16x8_r1_0 = vmulq_s16(ref_arr_temp0_16x8_r1_0, phs_mask_16min_16x8_0);
+ res_16x8_r0_0 = vmlaq_s16(res_16x8_r0_0, ref_arr_temp1_16x8_r0_0,
+ vreinterpretq_s16_u16(phs_mask_16x8_0));
+ res_16x8_r1_0 = vmlaq_s16(res_16x8_r1_0, ref_arr_temp1_16x8_r1_0,
+ vreinterpretq_s16_u16(phs_mask_16x8_0));
+
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + (pi1_y_ref_pos[i4_y] * i4_refarray_wd);
+ u1_y_incr_16x8_r0_0 = vmovl_u8(vld1_u8((pu1_ref_y_ptr_incr_temp)));
+ u1_incr_8x8x2_t.val[0] = vget_low_u8(vreinterpretq_u8_u16(u1_y_incr_16x8_r0_0));
+ u1_incr_8x8x2_t.val[1] =
+ vget_high_u8(vreinterpretq_u8_u16(u1_y_incr_16x8_r0_0));
+ u1_incr_8x8_t0 = vtbl2_u8(u1_incr_8x8x2_t, vget_low_u8(x_ref_rnd_mask_r0_0));
+ u1_incr_8x8_t1 = vtbl2_u8(u1_incr_8x8x2_t, vget_high_u8(x_ref_rnd_mask_r0_0));
+ u1_y_incr_8x16_r0_0 = vcombine_u8(u1_incr_8x8_t0, u1_incr_8x8_t1);
+
+ u1_y_incr_16x8_r0_0 = vreinterpretq_u16_u8(u1_y_incr_8x16_r0_0);
+
+ u1_y_incr_16x8_r0_0 = vtstq_u16(u1_y_incr_16x8_r0_0, ones);
+
+ prev_res_16x8_r0_0 = res_16x8_r0_0;
+ prev_res_16x8_r1_0 = res_16x8_r1_0;
+
+ u1_prev_y_incr_16x8_r0_0 = u1_y_incr_16x8_r0_0;
+ }
+ }
+
+ if(!zero_r0_r1)
+ {
+ res_32x4_l_0 = vdupq_n_s32(0);
+ res_32x4_l_1 = vdupq_n_s32(0);
+ }
+ else
+ {
+ i4_y_phase = pi1_y_phase[i4_y];
+
+ if((i4_y_phase) >> 3)
+ {
+ vert_res_16x8_r0_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r0_0, res_16x8_r1_0);
+ vert_res_16x8_r1_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r1_0, res_16x8_r1_0);
+ }
+ else
+ {
+ vert_res_16x8_r0_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r0_0, res_16x8_r0_0);
+ vert_res_16x8_r1_0 =
+ vbslq_s16(u1_y_incr_16x8_r0_0, res_16x8_r1_0, res_16x8_r0_0);
+ }
+ res_32x4_l_0 = vmull_n_s16(vget_low_s16(vert_res_16x8_r0_0), 16 - i4_y_phase);
+ res_32x4_l_0 =
+ vmlal_n_s16(res_32x4_l_0, vget_low_s16(vert_res_16x8_r1_0), i4_y_phase);
+
+ res_32x4_l_1 = vmull_n_s16(vget_high_s16(vert_res_16x8_r0_0), 16 - i4_y_phase);
+ res_32x4_l_1 =
+ vmlal_n_s16(res_32x4_l_1, vget_high_s16(vert_res_16x8_r1_0), i4_y_phase);
+
+ res_32x4_l_0 = vrshrq_n_s32(res_32x4_l_0, 8);
+ res_32x4_l_1 = vrshrq_n_s32(res_32x4_l_1, 8);
+ }
+ out_stride_temp = (i4_y * i4_out_stride);
+
+ out_16x8_0 = vld1q_s16(pi2_out + out_stride_temp);
+ out_16x8_1 = vld1q_s16(pi2_out + out_stride_temp + 8);
+ out_16x8_0 =
+ vbslq_s16(chroma_mask_16x8, vreinterpretq_s16_s32(res_32x4_l_0), out_16x8_0);
+ out_16x8_1 =
+ vbslq_s16(chroma_mask_16x8, vreinterpretq_s16_s32(res_32x4_l_1), out_16x8_1);
+ vst1q_s16((pi2_out + out_stride_temp), out_16x8_0);
+ vst1q_s16((pi2_out + out_stride_temp + 8), out_16x8_1);
+ }
+ }
+ return;
+} /* End of Interpolation Function */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_reflayer_const_non_boundary_mb_neonintr */
+/* */
+/* Description : */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_residual_reflayer_const_non_boundary_mb_neonintr(
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
+ WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_y;
+ WORD16 *pi2_ref_data_byte;
+ WORD16 *pi2_ref_array_temp;
+
+ if(i4_chroma_flag == 0)
+ {
+ WORD16 index_0[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+ int16x8_t ref_mb_type_16x8_q0, ref_mb_type_16x8_q1, ref_mb_type_16x8_q2,
+ ref_mb_type_16x8_q3, mb_quard1_part_x_16x8;
+ int16x8_t ref_mb_type_16x8_0, ref_mb_type_16x8_1;
+ int16x8_t ref_mb_type_16x8_low_0, ref_mb_type_16x8_low_1;
+ uint16x8_t mb_type_mask_16x8_0, mb_type_mask_16x8_1;
+ uint16x8_t mb_type_mask_16x8_low_0, mb_type_mask_16x8_low_1;
+ uint16x8_t mask_16x8_0;
+
+ int16x8_t index_arr_0;
+ int16x8_t inp_data_16x8_0, inp_data_16x8_1;
+ int16x8_t res_16x8_0, res_16x8_1;
+ int16x8_t one_16x8 = vdupq_n_s16(1);
+ int16x8_t zero_16x8 = vdupq_n_s16(0);
+
+ index_arr_0 = vld1q_s16(&index_0[0]);
+
+ ref_mb_type_16x8_q0 = vdupq_n_s16(i4_ref_mb_type_q0);
+ ref_mb_type_16x8_q1 = vdupq_n_s16(i4_ref_mb_type_q1);
+ ref_mb_type_16x8_q2 = vdupq_n_s16(i4_ref_mb_type_q2);
+ ref_mb_type_16x8_q3 = vdupq_n_s16(i4_ref_mb_type_q3);
+ if((i4_mb_quard1_part_x >= i4_refarray_wd) && (i4_mb_quard1_part_y >= i4_refarray_ht))
+ {
+ // Quard 0
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q0;
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ mb_type_mask_16x8_1 = mb_type_mask_16x8_0;
+ }
+ else if((i4_mb_quard1_part_y >= (i4_refarray_ht - 1)) &&
+ (i4_mb_quard1_part_x < i4_refarray_wd))
+ {
+ // Quard 0 & 1
+ if(i4_mb_quard1_part_x == 8)
+ {
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q1;
+ }
+ else if(i4_mb_quard1_part_x < 8)
+ {
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x));
+ mask_16x8_0 =
+ vcltq_s16(index_arr_0, mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q1;
+ }
+ else
+ {
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x - 8));
+ mask_16x8_0 =
+ vcleq_s16(index_arr_0, mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+ }
+
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ mb_type_mask_16x8_1 = vceqq_s16(ref_mb_type_16x8_1, one_16x8);
+ }
+ else
+ {
+ if(i4_mb_quard1_part_x >= i4_refarray_wd)
+ {
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q0;
+
+ ref_mb_type_16x8_low_0 = ref_mb_type_16x8_q2;
+ ref_mb_type_16x8_low_1 = ref_mb_type_16x8_q2;
+ }
+ else
+ {
+ // Quard 0, 1, 2, 3
+ if(i4_mb_quard1_part_x == 8)
+ {
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q1;
+
+ ref_mb_type_16x8_low_0 = ref_mb_type_16x8_q2;
+ ref_mb_type_16x8_low_1 = ref_mb_type_16x8_q3;
+ }
+ else if(i4_mb_quard1_part_x < 8)
+ {
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x));
+ mask_16x8_0 =
+ vcltq_s16(index_arr_0, mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+ ref_mb_type_16x8_1 = ref_mb_type_16x8_q1;
+
+ ref_mb_type_16x8_low_0 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q2, ref_mb_type_16x8_q3);
+ ref_mb_type_16x8_low_1 = ref_mb_type_16x8_q3;
+ }
+ else
+ {
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x - 8));
+ mask_16x8_0 =
+ vcltq_s16(index_arr_0, mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_1 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+
+ ref_mb_type_16x8_low_0 = ref_mb_type_16x8_q2;
+ ref_mb_type_16x8_low_1 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q2, ref_mb_type_16x8_q3);
+ }
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ mb_type_mask_16x8_1 = vceqq_s16(ref_mb_type_16x8_1, one_16x8);
+
+ mb_type_mask_16x8_low_0 = vceqq_s16(ref_mb_type_16x8_low_0, one_16x8);
+ mb_type_mask_16x8_low_1 = vceqq_s16(ref_mb_type_16x8_low_1, one_16x8);
+ }
+ }
+
+ if(i4_mb_quard1_part_y < i4_refarray_ht - 1)
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = vld1q_s16((pi2_ref_data_byte));
+ inp_data_16x8_1 = vld1q_s16((pi2_ref_data_byte + 8));
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_0, inp_data_16x8_0, zero_16x8);
+ res_16x8_1 = vbslq_s16(mb_type_mask_16x8_1, inp_data_16x8_1, zero_16x8);
+ }
+ else
+ {
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_low_0, inp_data_16x8_0, zero_16x8);
+ res_16x8_1 = vbslq_s16(mb_type_mask_16x8_low_1, inp_data_16x8_1, zero_16x8);
+ }
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ vst1q_s16((pi2_ref_array_temp), res_16x8_0);
+ vst1q_s16((pi2_ref_array_temp + 8), res_16x8_1);
+ }
+ }
+ else
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = vld1q_s16((pi2_ref_data_byte));
+ inp_data_16x8_1 = vld1q_s16((pi2_ref_data_byte + 8));
+
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_0, inp_data_16x8_0, zero_16x8);
+ res_16x8_1 = vbslq_s16(mb_type_mask_16x8_1, inp_data_16x8_1, zero_16x8);
+
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ vst1q_s16((pi2_ref_array_temp), res_16x8_0);
+ vst1q_s16((pi2_ref_array_temp + 8), res_16x8_1);
+ }
+ }
+ }
+ else
+ {
+ WORD16 index_0[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+ int16x8_t ref_mb_type_16x8_q0, ref_mb_type_16x8_q1, ref_mb_type_16x8_q2,
+ ref_mb_type_16x8_q3, mb_quard1_part_x_16x8;
+ int16x8_t ref_mb_type_16x8_0;
+ int16x8_t ref_mb_type_16x8_low_0;
+ uint16x8_t mb_type_mask_16x8_0;
+ uint16x8_t mb_type_mask_16x8_low_0;
+ uint16x8_t mask_16x8_0;
+
+ int16x8_t index_arr_0;
+ int16x8x2_t inp_data_16x8x2;
+ int16x8_t inp_data_16x8;
+ int16x8_t res_16x8_0;
+ int16x8_t one_16x8 = vdupq_n_s16(1);
+ int16x8_t zero_16x8 = vdupq_n_s16(0);
+ index_arr_0 = vld1q_s16(&index_0[0]);
+
+ ref_mb_type_16x8_q0 = vdupq_n_s16(i4_ref_mb_type_q0);
+ ref_mb_type_16x8_q1 = vdupq_n_s16(i4_ref_mb_type_q1);
+ ref_mb_type_16x8_q2 = vdupq_n_s16(i4_ref_mb_type_q2);
+ ref_mb_type_16x8_q3 = vdupq_n_s16(i4_ref_mb_type_q3);
+ if((i4_mb_quard1_part_x >= i4_refarray_wd) && (i4_mb_quard1_part_y >= i4_refarray_ht))
+ {
+ // Quard 0
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ }
+ else if((i4_mb_quard1_part_y >= (i4_refarray_ht - 1)) &&
+ (i4_mb_quard1_part_x < i4_refarray_wd))
+ {
+ // Quard 0 & 1
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x));
+ mask_16x8_0 = vcltq_s16(index_arr_0,
+ mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 = vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ }
+ else
+ {
+ if(i4_mb_quard1_part_x >= i4_refarray_wd)
+ {
+ ref_mb_type_16x8_0 = ref_mb_type_16x8_q0;
+ ref_mb_type_16x8_low_0 = ref_mb_type_16x8_q2;
+ }
+ else
+ {
+ mb_quard1_part_x_16x8 = vdupq_n_s16((i4_mb_quard1_part_x));
+ mask_16x8_0 =
+ vcltq_s16(index_arr_0, mb_quard1_part_x_16x8); // return 1 if a<b, else 0
+
+ ref_mb_type_16x8_0 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q0, ref_mb_type_16x8_q1);
+ ref_mb_type_16x8_low_0 =
+ vbslq_s16(mask_16x8_0, ref_mb_type_16x8_q2, ref_mb_type_16x8_q3);
+
+ mb_type_mask_16x8_0 = vceqq_s16(ref_mb_type_16x8_0, one_16x8);
+ mb_type_mask_16x8_low_0 = vceqq_s16(ref_mb_type_16x8_low_0, one_16x8);
+ }
+ }
+
+ if(i4_mb_quard1_part_y < i4_refarray_ht - 1)
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8x2 = vld2q_s16((pi2_ref_data_byte));
+ inp_data_16x8 = inp_data_16x8x2.val[0];
+
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_0, inp_data_16x8, zero_16x8);
+ }
+ else
+ {
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_low_0, inp_data_16x8, zero_16x8);
+ }
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ vst1q_s16((pi2_ref_array_temp), res_16x8_0);
+ }
+ }
+ else
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8x2 = vld2q_s16((pi2_ref_data_byte));
+ inp_data_16x8 = inp_data_16x8x2.val[0];
+
+ res_16x8_0 = vbslq_s16(mb_type_mask_16x8_0, inp_data_16x8, zero_16x8);
+
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ vst1q_s16((pi2_ref_array_temp), res_16x8_0);
+ }
+ }
+ }
+}
diff --git a/decoder/ih264d.h b/decoder/ih264d.h
index bee6b34..b29b3b0 100644
--- a/decoder/ih264d.h
+++ b/decoder/ih264d.h
@@ -260,7 +260,6 @@ typedef struct
ivd_rel_display_frame_op_t s_ivd_rel_display_frame_op_t;
}ih264d_rel_display_frame_op_t;
-
typedef enum {
/** Set number of cores/threads to be used */
IH264D_CMD_CTL_SET_NUM_CORES = IVD_CMD_CTL_CODEC_SUBCMD_START,
@@ -290,7 +289,13 @@ typedef enum {
IH264D_CMD_CTL_GET_SEI_AVE_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x303,
/** Get SEI CCV parameters */
- IH264D_CMD_CTL_GET_SEI_CCV_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x304
+ IH264D_CMD_CTL_GET_SEI_CCV_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x304,
+
+ /** Get SEI SII parameters */
+ IH264D_CMD_CTL_GET_SEI_SII_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x305,
+
+ /** Get SEI FGC parameters */
+ IH264D_CMD_CTL_GET_SEI_FGC_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x306
}IH264D_CMD_CTL_SUB_CMDS;
/*****************************************************************************/
@@ -807,6 +812,219 @@ typedef struct
UWORD32 u4_ccv_avg_luminance_value;
} ih264d_ctl_get_sei_ccv_params_op_t;
+typedef struct
+{
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+} ih264d_ctl_get_sei_sii_params_ip_t;
+
+typedef struct
+{
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /**
+ * specifies if the sei sii is enabled
+ */
+ UWORD8 u1_shutter_interval_info_present_flag;
+
+ /**
+ * specifies the shutter interval temporal sub-layer index
+ * of the current picture
+ */
+ UWORD32 u4_sii_sub_layer_idx;
+
+ /**
+ * specify the number of time units that pass in one second
+ */
+ UWORD32 u4_sii_time_scale;
+
+ /**
+ * specifies that the indicated shutter interval is the same for all
+ * pictures in the coded video sequence
+ */
+ UWORD8 u1_fixed_shutter_interval_within_cvs_flag;
+
+ /**
+ * specifies the the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the indicated shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 u4_sii_num_units_in_shutter_interval;
+
+ /**
+ * sii_max_sub_layers_minus1 plus 1 specifies the maximum number of
+ * shutter interval temporal sub-layers indexes that may be present
+ * in the coded video sequence
+ */
+ UWORD8 u1_sii_max_sub_layers_minus1;
+
+ /**
+ * specifies the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 au4_sub_layer_num_units_in_shutter_interval[SII_MAX_SUB_LAYERS];
+
+} ih264d_ctl_get_sei_sii_params_op_t;
+
+typedef struct
+{
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+} ih264d_ctl_get_sei_fgc_params_ip_t;
+
+typedef struct
+{
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /**
+ * Flag to control the presence of FGC SEI params
+ */
+ UWORD8 u1_film_grain_characteristics_cancel_flag;
+
+ /**
+ * Specifies the pic order count
+ */
+ WORD32 i4_poc;
+
+ /**
+ * Specifies IDR pic ID
+ */
+ UWORD32 u4_idr_pic_id;
+
+ /**
+ * Specifies film grain model for simulation
+ */
+ UWORD8 u1_film_grain_model_id;
+
+ /**
+ * Specifies separate color format for decoded samples and grain
+ */
+ UWORD8 u1_separate_colour_description_present_flag;
+
+ /**
+ * Specifies the bit depth used for the luma component
+ */
+ UWORD8 u1_film_grain_bit_depth_luma_minus8;
+
+ /**
+ * Specifies the bit depth used for the Cb and Cr components
+ */
+ UWORD8 u1_film_grain_bit_depth_chroma_minus8;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_full_range_flag;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_colour_primaries;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_transfer_characteristics;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_matrix_coefficients;
+
+ /**
+ * identifies the blending mode used to blend the simulated film grain with the decoded images
+ */
+ UWORD8 u1_blending_mode_id;
+
+ /**
+ * Specifies a scale factor used in the film grain characterization equations
+ */
+ UWORD8 u1_log2_scale_factor;
+
+ /**
+ * Indicates whether film grain is modelled or not on the colour component
+ */
+ UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of intensity intervals for which
+ * a specific set of model values has been estimated
+ */
+ UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of model values present for each intensity interval in which
+ * the film grain has been modelled
+ */
+ UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the lower bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Specifies the upper bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Represents each one of the model values present for
+ * the colour component and intensity interval
+ */
+ WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]
+ [SEI_FGC_MAX_NUM_MODEL_VALUES];
+
+ /**
+ * Specifies the persistence of the film grain characteristics SEI message
+ */
+ UWORD32 u4_film_grain_characteristics_repetition_period;
+} ih264d_ctl_get_sei_fgc_params_op_t;
#ifdef __cplusplus
} /* closing brace for extern "C" */
diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c
index cb6462e..221bf3e 100644
--- a/decoder/ih264d_api.c
+++ b/decoder/ih264d_api.c
@@ -155,6 +155,10 @@ WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl,
void *pv_api_ip,
void *pv_api_op);
+WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
@@ -192,6 +196,8 @@ void ih264d_export_sei_params(ivd_sei_decode_op_t *ps_sei_decode_op, dec_struct_
i4_status = ih264d_export_sei_cll_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
i4_status = ih264d_export_sei_ave_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
i4_status = ih264d_export_sei_ccv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
+ i4_status = ih264d_export_sei_sii_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
+ i4_status = ih264d_export_sei_fgc_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export);
UNUSED(i4_status);
}
@@ -484,9 +490,10 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
- if(ps_ip->s_ivd_video_decode_ip_t.u4_size
- != sizeof(ih264d_video_decode_ip_t)&&
- ps_ip->s_ivd_video_decode_ip_t.u4_size != offsetof(ivd_video_decode_ip_t, s_out_buffer))
+ if(ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ih264d_video_decode_ip_t) &&
+ ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ivd_video_decode_ip_t) &&
+ ps_ip->s_ivd_video_decode_ip_t.u4_size !=
+ offsetof(ivd_video_decode_ip_t, s_out_buffer))
{
ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
@@ -495,9 +502,10 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
return (IV_FAIL);
}
- if(ps_op->s_ivd_video_decode_op_t.u4_size
- != sizeof(ih264d_video_decode_op_t)&&
- ps_op->s_ivd_video_decode_op_t.u4_size != offsetof(ivd_video_decode_op_t, u4_output_present))
+ if(ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ih264d_video_decode_op_t) &&
+ ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ivd_video_decode_op_t) &&
+ ps_op->s_ivd_video_decode_op_t.u4_size !=
+ offsetof(ivd_video_decode_op_t, u4_output_present))
{
ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
@@ -940,6 +948,56 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
break;
}
+ case IH264D_CMD_CTL_GET_SEI_SII_PARAMS:
+ {
+ ih264d_ctl_get_sei_sii_params_ip_t *ps_ip;
+ ih264d_ctl_get_sei_sii_params_op_t *ps_op;
+
+ ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip;
+ ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS:
+ {
+ ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip;
+ ih264d_ctl_get_sei_fgc_params_op_t *ps_op;
+
+ ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip;
+ ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
case IH264D_CMD_CTL_SET_NUM_CORES:
{
ih264d_ctl_set_num_cores_ip_t *ps_ip;
@@ -1922,6 +1980,8 @@ UWORD32 ih264d_map_error(UWORD32 i4_err_status)
case ERROR_INV_SEI_CLL_PARAMS:
case ERROR_INV_SEI_AVE_PARAMS:
case ERROR_INV_SEI_CCV_PARAMS:
+ case ERROR_INV_SEI_SII_PARAMS:
+
temp = 1 << IVD_CORRUPTEDHEADER;
break;
@@ -2106,7 +2166,7 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
UWORD32 u4_size;
u4_size = ps_dec_op->u4_size;
- memset(ps_h264d_dec_op, 0, sizeof(ih264d_video_decode_op_t));
+ memset(ps_h264d_dec_op, 0, ps_dec_op->u4_size);
ps_dec_op->u4_size = u4_size;
}
@@ -2221,7 +2281,7 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
ps_dec->u4_slice_start_code_found = 0;
- /* In case the deocder is not in flush mode(in shared mode),
+ /* In case the decoder is not in flush mode(in shared mode),
then decoder has to pick up a buffer to write current frame.
Check if a frame is available in such cases */
@@ -3435,7 +3495,7 @@ WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
ih264d_ctl_set_config_ip_t *ps_h264d_ctl_ip =
(ih264d_ctl_set_config_ip_t *)pv_api_ip;
ih264d_ctl_set_config_op_t *ps_h264d_ctl_op =
- (ih264d_ctl_set_config_op_t *)pv_api_op;;
+ (ih264d_ctl_set_config_op_t *)pv_api_op;
ivd_ctl_set_config_ip_t *ps_ctl_ip =
&ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t;
ivd_ctl_set_config_op_t *ps_ctl_op =
@@ -3723,6 +3783,14 @@ WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
ret = ih264d_get_sei_ccv_params(dec_hdl, (void *)pv_api_ip,
(void *)pv_api_op);
break;
+ case IH264D_CMD_CTL_GET_SEI_SII_PARAMS:
+ ret = ih264d_get_sei_sii_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
+ case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS:
+ ret = ih264d_get_sei_fgc_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
case IH264D_CMD_CTL_SET_PROCESSOR:
ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip,
(void *)pv_api_op);
@@ -4248,6 +4316,196 @@ WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl,
return IV_SUCCESS;
}
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_get_sei_sii_params */
+/* */
+/* Description : This function populates SEI sii message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when SII is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ ih264d_ctl_get_sei_sii_params_ip_t *ps_ip;
+ ih264d_ctl_get_sei_sii_params_op_t *ps_op;
+ dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
+ sei_sii_params_t *ps_sei_sii;
+ int i;
+
+ ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip;
+ ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ if(0 == ps_dec->s_sei_export.u1_sei_sii_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_SII_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+
+ ps_sei_sii = &ps_dec->s_sei_export.s_sei_sii_params;
+
+ if((ps_sei_sii->u4_sii_sub_layer_idx > 0) &&
+ (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 1))
+ {
+ ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_sei_sii->u4_sii_sub_layer_idx > ps_sei_sii->u1_sii_max_sub_layers_minus1) &&
+ (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 0))
+ {
+ ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS;
+ return IV_FAIL;
+ }
+
+ ps_op->u4_sii_sub_layer_idx = ps_sei_sii->u4_sii_sub_layer_idx;
+
+ if(0 == ps_op->u4_sii_sub_layer_idx)
+ {
+ ps_op->u1_shutter_interval_info_present_flag =
+ ps_sei_sii->u1_shutter_interval_info_present_flag;
+
+ if(1 == ps_sei_sii->u1_shutter_interval_info_present_flag)
+ {
+ ps_op->u4_sii_time_scale = ps_sei_sii->u4_sii_time_scale;
+ ps_op->u1_fixed_shutter_interval_within_cvs_flag =
+ ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag;
+
+ if(1 == ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ ps_op->u4_sii_num_units_in_shutter_interval =
+ ps_sei_sii->u4_sii_num_units_in_shutter_interval;
+ }
+ else
+ {
+ ps_op->u1_sii_max_sub_layers_minus1 = ps_sei_sii->u1_sii_max_sub_layers_minus1;
+ for(i = 0; i <= ps_sei_sii->u1_sii_max_sub_layers_minus1; i++)
+ {
+ ps_op->au4_sub_layer_num_units_in_shutter_interval[i] =
+ ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval[i];
+ }
+ }
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_get_sei_fgc_params */
+/* */
+/* Description : This function populates SEI FGC message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when FGC is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip;
+ ih264d_ctl_get_sei_fgc_params_op_t *ps_op;
+ dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;
+ sei_fgc_params_t *ps_sei_fgc;
+ WORD32 i4_count;
+ UWORD32 c, i, j;
+
+ ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip;
+ ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ if(0 == ps_dec->s_sei_export.u1_sei_fgc_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_FGC_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+
+ ps_sei_fgc = &ps_dec->s_sei_export.s_sei_fgc_params;
+
+ ps_op->u1_film_grain_characteristics_cancel_flag =
+ ps_sei_fgc->u1_film_grain_characteristics_cancel_flag;
+
+ if(0 == ps_op->u1_film_grain_characteristics_cancel_flag)
+ {
+ ps_op->i4_poc = ps_sei_fgc->i4_poc;
+ ps_op->u4_idr_pic_id = ps_sei_fgc->u4_idr_pic_id;
+ ps_op->u1_film_grain_model_id = ps_sei_fgc->u1_film_grain_model_id;
+ ps_op->u1_separate_colour_description_present_flag =
+ ps_sei_fgc->u1_separate_colour_description_present_flag;
+
+ if(ps_op->u1_separate_colour_description_present_flag)
+ {
+ ps_op->u1_film_grain_bit_depth_luma_minus8 =
+ ps_sei_fgc->u1_film_grain_bit_depth_luma_minus8;
+ ps_op->u1_film_grain_bit_depth_chroma_minus8 =
+ ps_sei_fgc->u1_film_grain_bit_depth_chroma_minus8;
+ ps_op->u1_film_grain_full_range_flag = ps_sei_fgc->u1_film_grain_full_range_flag;
+ ps_op->u1_film_grain_colour_primaries = ps_sei_fgc->u1_film_grain_colour_primaries;
+ ps_op->u1_film_grain_transfer_characteristics =
+ ps_sei_fgc->u1_film_grain_transfer_characteristics;
+ ps_op->u1_film_grain_matrix_coefficients =
+ ps_sei_fgc->u1_film_grain_matrix_coefficients;
+ }
+ ps_op->u1_blending_mode_id = ps_sei_fgc->u1_blending_mode_id;
+ ps_op->u1_log2_scale_factor = ps_sei_fgc->u1_log2_scale_factor;
+
+ for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
+ {
+ ps_op->au1_comp_model_present_flag[c] = ps_sei_fgc->au1_comp_model_present_flag[c];
+ }
+
+ for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
+ {
+ if(ps_op->au1_comp_model_present_flag[c])
+ {
+ ps_op->au1_num_intensity_intervals_minus1[c] =
+ ps_sei_fgc->au1_num_intensity_intervals_minus1[c];
+
+ ps_op->au1_num_model_values_minus1[c] = ps_sei_fgc->au1_num_model_values_minus1[c];
+
+ for(i = 0; i <= ps_op->au1_num_intensity_intervals_minus1[c]; i++)
+ {
+ ps_op->au1_intensity_interval_lower_bound[c][i] =
+ ps_sei_fgc->au1_intensity_interval_lower_bound[c][i];
+ ps_op->au1_intensity_interval_upper_bound[c][i] =
+ ps_sei_fgc->au1_intensity_interval_upper_bound[c][i];
+
+ for(j = 0; j <= ps_op->au1_num_model_values_minus1[c]; j++)
+ {
+ ps_op->ai4_comp_model_value[c][i][j] =
+ ps_sei_fgc->ai4_comp_model_value[c][i][j];
+ }
+ }
+ }
+ }
+ ps_op->u4_film_grain_characteristics_repetition_period =
+ ps_sei_fgc->u4_film_grain_characteristics_repetition_period;
+ }
+ return IV_SUCCESS;
+}
+
WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
ih264d_ctl_set_num_cores_ip_t *ps_ip;
diff --git a/decoder/ih264d_api_utils.h b/decoder/ih264d_api_utils.h
new file mode 100644
index 0000000..61e474c
--- /dev/null
+++ b/decoder/ih264d_api_utils.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : ih264d_api_utils.h */
+/* */
+/* Description : This file contains function prototypes for non-API */
+/* functions defined in ih264d_api.c */
+/*****************************************************************************/
+
+#ifndef _IH264D_API_UTILS_H_
+#define _IH264D_API_UTILS_H_
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+
+#define MIN_IN_BUFS 1
+#define MIN_OUT_BUFS_420 3
+#define MIN_OUT_BUFS_422ILE 1
+#define MIN_OUT_BUFS_RGB565 1
+#define MIN_OUT_BUFS_420SP 2
+
+extern WORD32 ih264d_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_set_degrade(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+extern UWORD32 ih264d_get_outbuf_size(WORD32 u4_pic_wd, UWORD32 u4_pic_ht, UWORD8 u1_chroma_format,
+ UWORD32 *pu4_buf_size);
+
+extern void ih264d_export_sei_params(ivd_sei_decode_op_t *ps_sei_decode_op, dec_struct_t *ps_dec);
+
+extern UWORD32 ih264d_map_error(UWORD32 i4_err_status);
+
+extern void ih264d_signal_decode_thread(dec_struct_t *ps_dec);
+
+extern void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec);
+
+extern WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
+
+#endif
diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h
index a651c46..dfa0b01 100644
--- a/decoder/ih264d_error_handler.h
+++ b/decoder/ih264d_error_handler.h
@@ -123,7 +123,11 @@ typedef enum
ERROR_INV_SEI_CLL_PARAMS = 0x9D,
ERROR_INV_SEI_AVE_PARAMS = 0x9E,
ERROR_INV_SEI_CCV_PARAMS = 0x9F,
- ERROR_INV_FRAME_NUM = 0xA0
+ ERROR_INV_FRAME_NUM = 0xA0,
+ ERROR_SEI_SII_PARAMS_NOT_FOUND = 0xA1,
+ ERROR_INV_SEI_SII_PARAMS = 0xA2,
+ ERROR_SEI_FGC_PARAMS_NOT_FOUND = 0xA3,
+ ERROR_INV_SEI_FGC_PARAMS = 0xA4
} h264_decoder_error_code_t;
diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c
index 936963a..27f0197 100644
--- a/decoder/ih264d_parse_bslice.c
+++ b/decoder/ih264d_parse_bslice.c
@@ -1601,16 +1601,19 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice)
COPYTHECONTEXT("SH: cabac_init_idc",ps_slice->u1_cabac_init_idc);
}
- /* Read slice_qp_delta */
- WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
{
- return ERROR_INV_RANGE_QP_T;
+ WORD64 i8_temp;
+ /* Read slice_qp_delta */
+ i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_slice->u1_slice_qp = i8_temp;
+ COPYTHECONTEXT("SH: slice_qp_delta",
+ (WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
}
- ps_slice->u1_slice_qp = i8_temp;
- COPYTHECONTEXT("SH: slice_qp_delta",
- (WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
{
@@ -1691,4 +1694,3 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice)
return ret;
return OK;
}
-
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index dc11adb..b25af69 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -125,6 +125,16 @@ void ih264d_get_pre_sei_params(dec_struct_t *ps_dec, UWORD8 u1_nal_unit_type)
ps_dec->ps_sei->u1_sei_ave_params_present_flag =
ps_dec->ps_sei_parse->u1_sei_ave_params_present_flag;
ps_dec->ps_sei->s_sei_ave_params = ps_dec->ps_sei_parse->s_sei_ave_params;
+ ps_dec->ps_sei->u1_sei_sii_params_present_flag =
+ ps_dec->ps_sei_parse->u1_sei_sii_params_present_flag;
+ ps_dec->ps_sei->s_sei_sii_params = ps_dec->ps_sei_parse->s_sei_sii_params;
+ }
+
+ if(NULL != ps_dec->ps_sei)
+ {
+ ps_dec->ps_sei->u1_sei_fgc_params_present_flag =
+ ps_dec->ps_sei_parse->u1_sei_fgc_params_present_flag;
+ ps_dec->ps_sei->s_sei_fgc_params = ps_dec->ps_sei_parse->s_sei_fgc_params;
}
ps_dec->ps_sei_parse->u1_sei_mdcv_params_present_flag = 0;
@@ -135,7 +145,8 @@ void ih264d_get_pre_sei_params(dec_struct_t *ps_dec, UWORD8 u1_nal_unit_type)
memset(&ps_dec->ps_sei_parse->s_sei_ave_params, 0, sizeof(sei_ave_params_t));
ps_dec->ps_sei_parse->u1_sei_ccv_params_present_flag = 0;
memset(&ps_dec->ps_sei_parse->s_sei_ccv_params, 0, sizeof(sei_ccv_params_t));
-
+ ps_dec->ps_sei_parse->u1_sei_sii_params_present_flag = 0;
+ memset(&ps_dec->ps_sei_parse->s_sei_sii_params, 0, sizeof(sei_sii_params_t));
}
/*****************************************************************************/
@@ -362,23 +373,24 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm)
if(ps_pps->u1_wted_bipred_idc > MAX_WEIGHT_BIPRED_IDC)
return ERROR_INV_SPS_PPS_T;
+ {
+ WORD64 i8_temp;
+ i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- WORD64 i8_temp = (WORD64)26
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
-
- if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
- return ERROR_INV_RANGE_QP_T;
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ return ERROR_INV_RANGE_QP_T;
- ps_pps->u1_pic_init_qp = i8_temp;
- COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26);
+ ps_pps->u1_pic_init_qp = i8_temp;
+ COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26);
- i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
- return ERROR_INV_RANGE_QP_T;
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ return ERROR_INV_RANGE_QP_T;
- ps_pps->u1_pic_init_qs = i8_temp;
- COPYTHECONTEXT("PPS: pic_init_qs_minus26",ps_pps->u1_pic_init_qs - 26);
+ ps_pps->u1_pic_init_qs = i8_temp;
+ COPYTHECONTEXT("PPS: pic_init_qs_minus26",ps_pps->u1_pic_init_qs - 26);
+ }
i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((i_temp < -12) || (i_temp > 12))
@@ -1373,4 +1385,3 @@ WORD32 ih264d_parse_nal_unit(iv_obj_t *dec_hdl,
return i_status;
}
-
diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c
index 21c50ea..21e3798 100644
--- a/decoder/ih264d_parse_islice.c
+++ b/decoder/ih264d_parse_islice.c
@@ -1388,6 +1388,7 @@ WORD32 ih264d_parse_islice(dec_struct_t *ps_dec,
UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
UWORD32 u4_temp;
WORD32 i_temp;
+ WORD64 i8_temp;
WORD32 ret;
/*--------------------------------------------------------------------*/
@@ -1412,7 +1413,7 @@ WORD32 ih264d_parse_islice(dec_struct_t *ps_dec,
/* G050 */
/* Read slice_qp_delta */
- WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
return ERROR_INV_RANGE_QP_T;
diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c
index beb24d4..729e308 100644
--- a/decoder/ih264d_parse_pslice.c
+++ b/decoder/ih264d_parse_pslice.c
@@ -2164,17 +2164,19 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice)
ps_cur_slice->u1_cabac_init_idc = u4_temp;
COPYTHECONTEXT("SH: cabac_init_idc",ps_cur_slice->u1_cabac_init_idc);
}
-
- /* Read slice_qp_delta */
- WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
{
- return ERROR_INV_RANGE_QP_T;
+ WORD64 i8_temp;
+ /* Read slice_qp_delta */
+ i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_cur_slice->u1_slice_qp = i8_temp;
+ COPYTHECONTEXT("SH: slice_qp_delta",
+ (WORD8)(ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
}
- ps_cur_slice->u1_slice_qp = i8_temp;
- COPYTHECONTEXT("SH: slice_qp_delta",
- (WORD8)(ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
{
diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c
index 59d187e..87c59e9 100644
--- a/decoder/ih264d_parse_slice.c
+++ b/decoder/ih264d_parse_slice.c
@@ -459,6 +459,14 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec,
ps_dec->ps_cur_pic = ps_cur_pic;
ps_dec->u1_pic_buf_id = cur_pic_buf_id;
ps_cur_pic->u4_ts = ps_dec->u4_ts;
+
+ /* Update POC and inter_pic_id in sei structure,
+ * later can be used by application for grain synthesis(SMPTE-RDD5) */
+ if(ps_dec->ps_sei->u1_sei_fgc_params_present_flag)
+ {
+ ps_dec->ps_sei->s_sei_fgc_params.i4_poc = i4_poc;
+ ps_dec->ps_sei->s_sei_fgc_params.u4_idr_pic_id = ps_cur_slice->u4_idr_pic_id;
+ }
memcpy(&ps_cur_pic->s_sei_pic, ps_dec->ps_sei, sizeof(sei));
ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id;
@@ -692,10 +700,10 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec,
{
ret = ih264d_form_default_scaling_matrix(ps_dec);
}
-
+
if(ret != OK)
return ret;
-
+
/* required while reading the transform_size_8x8 u4_flag */
ps_dec->s_high_profile.u1_direct_8x8_inference_flag =
ps_seq->u1_direct_8x8_inference_flag;
@@ -1427,6 +1435,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
if(ps_cur_slice->u1_mmco_equalto5)
{
+ WORD64 i8_result;
WORD32 i4_temp_poc;
WORD32 i4_top_field_order_poc, i4_bot_field_order_poc;
@@ -1443,8 +1452,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
else
i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
- WORD64 i8_result = (WORD64)i4_temp_poc
- - ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ i8_result = (WORD64)i4_temp_poc - ps_dec->ps_cur_pic->i4_top_field_order_cnt;
if(IS_OUT_OF_RANGE_S32(i8_result))
{
return ERROR_INV_POC;
@@ -1944,4 +1952,3 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
return ret;
}
-
diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c
index ac4d056..079f036 100644
--- a/decoder/ih264d_sei.c
+++ b/decoder/ih264d_sei.c
@@ -644,6 +644,287 @@ WORD32 ih264d_parse_ccv(dec_bit_stream_t *ps_bitstrm,
/*****************************************************************************/
/* */
+/* Function Name : ih264d_parse_sii */
+/* */
+/* Description : This function parses SEI message sii */
+/* Inputs : ps_bitstrm Bitstream */
+/* ps_dec Poniter decoder context */
+/* ui4_payload_size pay load i4_size */
+/* Globals : None */
+/* Processing : */
+/* Outputs : None */
+/* Return : 0 for successfull parsing, else -1 */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* Draft */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_parse_sii(dec_bit_stream_t *ps_bitstrm, dec_struct_t *ps_dec,
+ UWORD32 ui4_payload_size)
+{
+ sei *ps_sei;
+ dec_err_status_t *ps_err;
+ int i;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UNUSED(ui4_payload_size);
+
+ if(ps_dec == NULL)
+ {
+ return NOT_OK;
+ }
+ ps_sei = ps_dec->ps_sei_parse;
+
+ if(ps_sei == NULL)
+ {
+ return NOT_OK;
+ }
+ ps_err = ps_dec->ps_dec_err_status;
+
+ ps_sei->u1_sei_sii_params_present_flag = 0;
+ memset(&ps_sei->s_sei_sii_params, 0, sizeof(ps_sei->s_sei_sii_params));
+
+ ps_sei->s_sei_sii_params.u4_sii_sub_layer_idx = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(0 == ps_sei->s_sei_sii_params.u4_sii_sub_layer_idx)
+ {
+ ps_sei->s_sei_sii_params.u1_shutter_interval_info_present_flag =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(1 == ps_sei->s_sei_sii_params.u1_shutter_interval_info_present_flag)
+ {
+ ps_sei->s_sei_sii_params.u4_sii_time_scale =
+ (UWORD32) ih264d_get_bits_h264(ps_bitstrm, 32);
+
+ ps_sei->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(1 == ps_sei->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ ps_sei->s_sei_sii_params.u4_sii_num_units_in_shutter_interval =
+ (UWORD32) ih264d_get_bits_h264(ps_bitstrm, 32);
+ }
+ else
+ {
+ ps_sei->s_sei_sii_params.u1_sii_max_sub_layers_minus1 =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 3);
+ for(i = 0; i <= ps_sei->s_sei_sii_params.u1_sii_max_sub_layers_minus1; i++)
+ {
+ ps_sei->s_sei_sii_params.au4_sub_layer_num_units_in_shutter_interval[i] =
+ (UWORD32) ih264d_get_bits_h264(ps_bitstrm, 32);
+ }
+ }
+ }
+ }
+
+ if((ps_sei->s_sei_sii_params.u4_sii_sub_layer_idx >
+ ps_sei->s_sei_sii_params.u1_sii_max_sub_layers_minus1) &&
+ (ps_sei->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag == 0))
+ {
+ return ERROR_INV_SEI_SII_PARAMS;
+ }
+
+ ps_sei->u1_sei_sii_params_present_flag = 1;
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_parse_fgc */
+/* */
+/* Description : This function parses SEI message film grain charcaristics*/
+/* Inputs : ps_bitstrm Bitstream */
+/* ps_dec Poniter decoder context */
+/* ui4_payload_size pay load i4_size */
+/* Globals : None */
+/* Processing : */
+/* Outputs : None */
+/* Return : 0 for successfull parsing, else -1 */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* Draft */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_parse_fgc(dec_bit_stream_t *ps_bitstrm, dec_struct_t *ps_dec,
+ UWORD32 ui4_payload_size)
+{
+ sei *ps_sei = ps_dec->ps_sei_parse;
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 u4_count;
+ WORD32 i4_luma_bitdepth, i4_chroma_bitdepth;
+ UWORD32 c, i, j;
+ UNUSED(ui4_payload_size);
+
+ if((ps_dec == NULL) || (ps_sei == NULL))
+ {
+ return NOT_OK;
+ }
+
+ ps_sei->u1_sei_fgc_params_present_flag = 0;
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_characteristics_cancel_flag =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(0 == ps_sei->s_sei_fgc_params.u1_film_grain_characteristics_cancel_flag)
+ {
+ ps_sei->s_sei_fgc_params.u1_film_grain_model_id =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 2);
+ if(ps_sei->s_sei_fgc_params.u1_film_grain_model_id > 1)
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+ ps_sei->s_sei_fgc_params.u1_separate_colour_description_present_flag =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_sei->s_sei_fgc_params.u1_separate_colour_description_present_flag)
+ {
+ ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_luma_minus8 =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 3);
+
+ i4_luma_bitdepth = ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_luma_minus8 + 8;
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_chroma_minus8 =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 3);
+
+ i4_chroma_bitdepth = ps_sei->s_sei_fgc_params.u1_film_grain_bit_depth_chroma_minus8 + 8;
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_full_range_flag =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_colour_primaries =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_transfer_characteristics =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ ps_sei->s_sei_fgc_params.u1_film_grain_matrix_coefficients =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+ }
+ else
+ {
+ if(ps_dec->ps_cur_sps == NULL)
+ {
+ return NOT_OK;
+ }
+ i4_luma_bitdepth = ps_dec->ps_cur_sps->i4_bit_depth_luma_minus8 + 8;
+ i4_chroma_bitdepth = ps_dec->ps_cur_sps->i4_bit_depth_chroma_minus8 + 8;
+ }
+ ps_sei->s_sei_fgc_params.u1_blending_mode_id = (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 2);
+
+ if(ps_sei->s_sei_fgc_params.u1_blending_mode_id > 1)
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+
+ ps_sei->s_sei_fgc_params.u1_log2_scale_factor =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 4);
+
+ for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
+ {
+ ps_sei->s_sei_fgc_params.au1_comp_model_present_flag[c] =
+ (UWORD8) ih264d_get_bit_h264(ps_bitstrm);
+ }
+
+ for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++)
+ {
+ if(ps_sei->s_sei_fgc_params.au1_comp_model_present_flag[c])
+ {
+ ps_sei->s_sei_fgc_params.au1_num_intensity_intervals_minus1[c] =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c] =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 3);
+
+ if(ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c] >
+ (SEI_FGC_MAX_NUM_MODEL_VALUES - 1))
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+
+ for(i = 0; i <= ps_sei->s_sei_fgc_params.au1_num_intensity_intervals_minus1[c]; i++)
+ {
+ ps_sei->s_sei_fgc_params.au1_intensity_interval_lower_bound[c][i] =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ ps_sei->s_sei_fgc_params.au1_intensity_interval_upper_bound[c][i] =
+ (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ for(j = 0; j <= ps_sei->s_sei_fgc_params.au1_num_model_values_minus1[c]; j++)
+ {
+ ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] =
+ (WORD32) ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(0 == ps_sei->s_sei_fgc_params.u1_film_grain_model_id)
+ {
+ if((1 == j) || (2 == j))
+ {
+ if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) ||
+ (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] > 16))
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+ else if((3 == j) || (4 == j))
+ {
+ if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) ||
+ (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] >
+ ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j - 2]))
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+ else
+ {
+ WORD32 max_lim = (c == 0) ? (1 << i4_luma_bitdepth) - 1
+ : (1 << i4_chroma_bitdepth) - 1;
+
+ if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] < 0) ||
+ (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] >
+ max_lim))
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+ }
+ }
+ else
+ {
+ WORD32 max_lim = (c == 0) ? (1 << (i4_luma_bitdepth - 1))
+ : (1 << (i4_chroma_bitdepth - 1));
+
+ if((ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] <
+ -max_lim) ||
+ (ps_sei->s_sei_fgc_params.ai4_comp_model_value[c][i][j] >= max_lim))
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period =
+ (UWORD32) ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period < 0 ||
+ ps_sei->s_sei_fgc_params.u4_film_grain_characteristics_repetition_period > 16384)
+ {
+ return ERROR_INV_SEI_FGC_PARAMS;
+ }
+
+ ps_sei->u1_sei_fgc_params_present_flag = 1;
+ }
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
/* Function Name : ih264d_parse_sei_payload */
/* */
/* Description : This function parses SEI pay loads. Currently it's */
@@ -719,6 +1000,15 @@ WORD32 ih264d_parse_sei_payload(dec_bit_stream_t *ps_bitstrm,
i4_status = ih264d_parse_ccv(ps_bitstrm, ps_dec,
ui4_payload_size);
break;
+ case SEI_SHUTTER_INTERVAL_INFO:
+
+ i4_status = ih264d_parse_sii(ps_bitstrm, ps_dec, ui4_payload_size);
+ break;
+
+ case SEI_FILM_GRAIN_CHARACTERISTICS:
+ i4_status = ih264d_parse_fgc(ps_bitstrm, ps_dec, ui4_payload_size);
+
+ break;
default:
i4_status = ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3));
break;
@@ -985,3 +1275,87 @@ WORD32 ih264d_export_sei_ccv_params(ivd_sei_decode_op_t *ps_sei_decode_op,
return (OK);
}
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_export_sei_sii_params */
+/* */
+/* Description : This function populates SEI sii message in */
+/* output structure */
+/* Inputs : ps_sei_sii_op pointer to sei sii o\p struct */
+/* : ps_sei pointer to decoded sei params */
+/* Outputs : */
+/* Returns : returns 0 for success; -1 for failure */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_export_sei_sii_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei *ps_sei,
+ sei *ps_sei_export)
+{
+ if((ps_sei_export == NULL) || (ps_sei == NULL))
+ {
+ return NOT_OK;
+ }
+
+ ps_sei_export->u1_sei_sii_params_present_flag = ps_sei->u1_sei_sii_params_present_flag;
+ ps_sei_decode_op->u1_sei_sii_params_present_flag = ps_sei->u1_sei_sii_params_present_flag;
+
+ if(0 == ps_sei_export->u1_sei_sii_params_present_flag)
+ {
+ memset(&ps_sei_export->s_sei_sii_params, 0, sizeof(sei_sii_params_t));
+ }
+ else
+ {
+ memcpy(&ps_sei_export->s_sei_sii_params, &ps_sei->s_sei_sii_params,
+ sizeof(sei_sii_params_t));
+ }
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_export_sei_fgc_params */
+/* */
+/* Description : This function populates SEI film grain params in */
+/* output structure */
+/* Inputs : ps_sei_fgc_op pointer to sei fgc o\p struct */
+/* : ps_sei pointer to decoded sei params */
+/* Outputs : */
+/* Returns : returns 0 for success; -1 for failure */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 ih264d_export_sei_fgc_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei *ps_sei,
+ sei *ps_sei_export)
+{
+ if((ps_sei_export == NULL) || (ps_sei == NULL))
+ {
+ return NOT_OK;
+ }
+
+ ps_sei_export->u1_sei_fgc_params_present_flag = ps_sei->u1_sei_fgc_params_present_flag;
+ ps_sei_decode_op->u1_sei_fgc_params_present_flag = ps_sei->u1_sei_fgc_params_present_flag;
+
+ if(0 == ps_sei_export->u1_sei_fgc_params_present_flag)
+ {
+ memset(&ps_sei_export->s_sei_fgc_params, 0, sizeof(sei_fgc_params_t));
+ }
+ else
+ {
+ memcpy(&ps_sei_export->s_sei_fgc_params, &ps_sei->s_sei_fgc_params,
+ sizeof(sei_fgc_params_t));
+ }
+
+ return (OK);
+}
diff --git a/decoder/ih264d_sei.h b/decoder/ih264d_sei.h
index af143ac..4f58020 100644
--- a/decoder/ih264d_sei.h
+++ b/decoder/ih264d_sei.h
@@ -64,10 +64,12 @@
#define SEI_PROG_REF_SEGMENT_START 16
#define SEI_PROG_REF_SEGMENT_END 17
#define SEI_MOT_CON_SLICE_GRP_SET 18
+#define SEI_FILM_GRAIN_CHARACTERISTICS 19
#define SEI_MASTERING_DISP_COL_VOL 137
#define SEI_CONTENT_LIGHT_LEVEL_DATA 144
#define SEI_AMBIENT_VIEWING_ENVIRONMENT 148
#define SEI_CONTENT_COLOR_VOLUME 149
+#define SEI_SHUTTER_INTERVAL_INFO 205
/* Declaration of dec_struct_t to avoid CCS compilation Error */
struct _DecStruct;
@@ -234,6 +236,168 @@ typedef struct
}sei_ccv_params_t;
+/**
+ * Structure to hold Shutter Interval Info SEI
+ */
+typedef struct
+{
+ /**
+ * specifies if the sei sii is enabled
+ */
+ UWORD8 u1_shutter_interval_info_present_flag;
+
+ /**
+ * specifies the shutter interval temporal sub-layer index
+ * of the current picture
+ */
+ UWORD32 u4_sii_sub_layer_idx;
+
+ /**
+ * specify the number of time units that pass in one second
+ */
+ UWORD32 u4_sii_time_scale;
+
+ /**
+ * specifies that the indicated shutter interval is the same for all
+ * pictures in the coded video sequence
+ */
+ UWORD8 u1_fixed_shutter_interval_within_cvs_flag;
+
+ /**
+ * specifies the the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the indicated shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 u4_sii_num_units_in_shutter_interval;
+
+ /**
+ * sii_max_sub_layers_minus1 plus 1 specifies the maximum number of
+ * shutter interval temporal sub-layers indexes that may be present
+ * in the coded video sequence
+ */
+ UWORD8 u1_sii_max_sub_layers_minus1;
+
+ /**
+ * specifies the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the shutter
+ * interval of each picture in the coded video sequence
+ */
+ UWORD32 au4_sub_layer_num_units_in_shutter_interval[SII_MAX_SUB_LAYERS];
+
+} sei_sii_params_t;
+
+typedef struct
+{
+ /**
+ * Flag to control the presence of FGC SEI params
+ */
+ UWORD8 u1_film_grain_characteristics_cancel_flag;
+
+ /**
+ * Specifies the pic order count
+ */
+ WORD32 i4_poc;
+
+ /**
+ * Specifies IDR pic ID
+ */
+ UWORD32 u4_idr_pic_id;
+
+ /**
+ * Specifies film grain model for simulation
+ */
+ UWORD8 u1_film_grain_model_id;
+
+ /**
+ * Specifies separate color format for decoded samples and grain
+ */
+ UWORD8 u1_separate_colour_description_present_flag;
+
+ /**
+ * Specifies the bit depth used for the luma component
+ */
+ UWORD8 u1_film_grain_bit_depth_luma_minus8;
+
+ /**
+ * Specifies the bit depth used for the Cb and Cr components
+ */
+ UWORD8 u1_film_grain_bit_depth_chroma_minus8;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_full_range_flag;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_colour_primaries;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_transfer_characteristics;
+
+ /**
+ * Specifies the colour space of the FGC in SEI
+ */
+ UWORD8 u1_film_grain_matrix_coefficients;
+
+ /**
+ * identifies the blending mode used to blend the simulated film grain with the decoded images
+ */
+ UWORD8 u1_blending_mode_id;
+
+ /**
+ * Specifies a scale factor used in the film grain characterization equations
+ */
+ UWORD8 u1_log2_scale_factor;
+
+ /**
+ * Indicates whether film grain is modelled or not on the colour component
+ */
+ UWORD8 au1_comp_model_present_flag[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of intensity intervals for which
+ * a specific set of model values has been estimated
+ */
+ UWORD8 au1_num_intensity_intervals_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the number of model values present for each intensity interval in which
+ * the film grain has been modelled
+ */
+ UWORD8 au1_num_model_values_minus1[SEI_FGC_NUM_COLOUR_COMPONENTS];
+
+ /**
+ * Specifies the lower bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_lower_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Specifies the upper bound of the interval of intensity levels for which
+ * the set of model values applies
+ */
+ UWORD8 au1_intensity_interval_upper_bound[SEI_FGC_NUM_COLOUR_COMPONENTS]
+ [SEI_FGC_MAX_NUM_INTENSITY_INTERVALS];
+
+ /**
+ * Represents each one of the model values present for
+ * the colour component and intensity interval
+ */
+ WORD32 ai4_comp_model_value[SEI_FGC_NUM_COLOUR_COMPONENTS][SEI_FGC_MAX_NUM_INTENSITY_INTERVALS]
+ [SEI_FGC_MAX_NUM_MODEL_VALUES];
+
+ /**
+ * Specifies the persistence of the film grain characteristics SEI message
+ */
+ UWORD32 u4_film_grain_characteristics_repetition_period;
+
+} sei_fgc_params_t;
+
struct _sei
{
UWORD8 u1_seq_param_set_id;
@@ -285,6 +449,25 @@ struct _sei
*/
sei_ccv_params_t s_sei_ccv_params;
+ /**
+ * shutter interval info present flag
+ */
+ UWORD8 u1_sei_sii_params_present_flag;
+
+ /*
+ * SII parameters
+ */
+ sei_sii_params_t s_sei_sii_params;
+
+ /**
+ * film grain params info present flag
+ */
+ UWORD8 u1_sei_fgc_params_present_flag;
+
+ /*
+ * film grain characteristics parameters
+ */
+ sei_fgc_params_t s_sei_fgc_params;
};
typedef struct _sei sei;
@@ -300,5 +483,11 @@ WORD32 ih264d_export_sei_ave_params(ivd_sei_decode_op_t *ps_sei_decode_op,
WORD32 ih264d_export_sei_ccv_params(ivd_sei_decode_op_t *ps_sei_decode_op,
sei *ps_sei, sei *ps_sei_export);
+WORD32 ih264d_export_sei_sii_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei *ps_sei,
+ sei *ps_sei_export);
+
+WORD32 ih264d_export_sei_fgc_params(ivd_sei_decode_op_t *ps_sei_decode_op, sei *ps_sei,
+ sei *ps_sei_export);
+
#endif /* _IH264D_SEI_H_ */
diff --git a/decoder/ih264d_vui.h b/decoder/ih264d_vui.h
index b882f72..7289894 100644
--- a/decoder/ih264d_vui.h
+++ b/decoder/ih264d_vui.h
@@ -93,5 +93,7 @@ typedef struct
WORD32 ih264d_parse_vui_parametres(vui_t *ps_vu4,
dec_bit_stream_t *ps_bitstrm);
+WORD32 ih264d_parse_hrd_parametres(hrd_t *ps_hrd,
+ dec_bit_stream_t *ps_bitstrm);
#endif /* _SEI_H_ */
diff --git a/decoder/ivd.h b/decoder/ivd.h
index bac5847..1b4b86e 100644
--- a/decoder/ivd.h
+++ b/decoder/ivd.h
@@ -55,6 +55,15 @@
*/
#define NUM_SEI_CCV_PRIMARIES 3
+/*
+ * @brief specifies maximum number of sub-layers available in the sequence
+ */
+#define SII_MAX_SUB_LAYERS 8
+
+#define SEI_FGC_NUM_COLOUR_COMPONENTS 3
+#define SEI_FGC_MAX_NUM_MODEL_VALUES 6
+#define SEI_FGC_MAX_NUM_INTENSITY_INTERVALS 256
+
/*****************************************************************************/
/* Typedefs */
/*****************************************************************************/
@@ -390,6 +399,10 @@ typedef struct {
UWORD8 u1_sei_ccv_params_present_flag;
+ UWORD8 u1_sei_sii_params_present_flag;
+
+ UWORD8 u1_sei_fgc_params_present_flag;
+
}ivd_sei_decode_op_t;
/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_DECODE */
diff --git a/decoder/mvc/imvcd.h b/decoder/mvc/imvcd.h
new file mode 100644
index 0000000..0160e17
--- /dev/null
+++ b/decoder/mvc/imvcd.h
@@ -0,0 +1,279 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* imvcd.h
+*
+* @brief
+* This file contains all the necessary structure and enumeration
+* definitions needed for the Application Program Interface(API) of the
+* Ittiam MVC Decoder
+*
+*******************************************************************************
+*/
+
+#ifndef _IMVCD_H_
+#define _IMVCD_H_
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+
+/* Extern functions */
+extern IV_API_CALL_STATUS_T imvcd_api_function(iv_obj_t *ps_dec_hdl, void *pv_ip, void *pv_op);
+
+/* Typedefs */
+typedef enum IMVCD_CTL_SUB_CMDS
+{
+ IMVCD_CTL_SET_NUM_CORES = IVD_CMD_CTL_CODEC_SUBCMD_START,
+ IMVCD_CTL_SET_PROCESSOR = IVD_CMD_CTL_CODEC_SUBCMD_START + 1,
+ IMVCD_CTL_GET_VUI_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 2,
+ IMVCD_CTL_DEGRADE = IVD_CMD_CTL_CODEC_SUBCMD_START + 3,
+
+} IMVCD_CTL_SUB_CMDS;
+
+typedef struct imvcd_create_ip_t
+{
+ ivd_create_ip_t s_ivd_ip;
+
+} imvcd_create_ip_t;
+
+typedef struct imvcd_create_op_t
+{
+ ivd_create_op_t s_ivd_op;
+
+} imvcd_create_op_t;
+
+typedef struct imvcd_delete_ip_t
+{
+ ivd_delete_ip_t s_ivd_ip;
+
+} imvcd_delete_ip_t;
+
+typedef struct imvcd_delete_op_t
+{
+ ivd_delete_op_t s_ivd_op;
+
+} imvcd_delete_op_t;
+
+typedef struct imvcd_video_decode_ip_t
+{
+ ivd_video_decode_ip_t s_ivd_ip;
+
+} imvcd_video_decode_ip_t;
+
+typedef struct imvcd_video_decode_op_t
+{
+ ivd_video_decode_op_t s_ivd_op;
+
+ iv_yuv_buf_t *ps_view_disp_bufs;
+
+} imvcd_video_decode_op_t;
+
+typedef struct imvcd_set_config_ip_t
+{
+ ivd_ctl_set_config_ip_t s_ivd_ip;
+} imvcd_set_config_ip_t;
+
+typedef struct imvcd_set_config_op_t
+{
+ ivd_ctl_set_config_op_t s_ivd_op;
+} imvcd_set_config_op_t;
+
+typedef struct imvcd_set_num_cores_ip_t
+{
+ UWORD32 u4_size;
+
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ UWORD32 u4_num_cores;
+} imvcd_set_num_cores_ip_t;
+
+typedef struct imvcd_set_num_cores_op_t
+{
+ UWORD32 u4_size;
+
+ UWORD32 u4_error_code;
+} imvcd_set_num_cores_op_t;
+
+typedef struct imvcd_set_arch_ip_t
+{
+ UWORD32 u4_size;
+
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ IVD_ARCH_T e_arch;
+
+ IVD_SOC_T e_soc;
+
+} imvcd_set_arch_ip_t;
+
+typedef struct imvcd_set_arch_op_t
+{
+ UWORD32 u4_size;
+
+ UWORD32 u4_error_code;
+} imvcd_set_arch_op_t;
+
+typedef struct imvcd_set_degrade_mode_ip_t
+{
+ UWORD32 u4_size;
+
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /**
+ * Pictures that are are degraded
+ * 0 : No degrade
+ * 1 : Only on non-reference frames
+ * 2 : Use interval specified by u4_nondegrade_interval
+ * 3 : All non-key frames
+ * 4 : All frames
+ */
+ WORD32 i4_degrade_pics;
+
+ /**
+ * Interval for pictures which are completely decoded without any degradation
+ */
+ WORD32 i4_nondegrade_interval;
+
+ /**
+ * bit position (lsb is zero): Type of degradation
+ * 1 : Disable deblocking
+ * 2 : Faster inter prediction filters
+ * 3 : Fastest inter prediction filters
+ */
+ WORD32 i4_degrade_type;
+
+} imvcd_set_degrade_mode_ip_t;
+
+typedef struct imvcd_set_degrade_mode_op_t
+{
+ UWORD32 u4_size;
+
+ UWORD32 u4_error_code;
+} imvcd_set_degrade_mode_op_t;
+
+typedef struct imvcd_flush_dec_ip_t
+{
+ ivd_ctl_flush_ip_t s_ivd_ip;
+} imvcd_flush_dec_ip_t;
+
+typedef struct imvcd_flush_dec_op_t
+{
+ ivd_ctl_flush_op_t s_ivd_op;
+} imvcd_flush_dec_op_t;
+
+typedef struct imvcd_get_buf_info_ip_t
+{
+ ivd_ctl_getbufinfo_ip_t s_ivd_ip;
+} imvcd_get_buf_info_ip_t;
+
+typedef struct ivd_mvc_buf_info_t
+{
+ UWORD16 u2_num_views;
+} ivd_mvc_buf_info_t;
+
+typedef struct imvcd_get_buf_info_op_t
+{
+ ivd_ctl_getbufinfo_op_t s_ivd_op;
+
+ ivd_mvc_buf_info_t s_mvc_buf_info;
+
+} imvcd_get_buf_info_op_t;
+
+typedef struct imvcd_get_vui_ip_t
+{
+ UWORD32 u4_size;
+
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+} imvcd_get_vui_ip_t;
+
+typedef struct imvcd_get_vui_op_t
+{
+ bool b_is_vui_available;
+
+ UWORD32 u4_error_code;
+
+ UWORD8 u1_aspect_ratio_idc;
+
+ UWORD16 u2_sar_width;
+
+ UWORD16 u2_sar_height;
+
+ UWORD8 u1_overscan_appropriate_flag;
+
+ UWORD8 u1_video_format;
+
+ UWORD8 u1_video_full_range_flag;
+
+ UWORD8 u1_colour_primaries;
+
+ UWORD8 u1_tfr_chars;
+
+ UWORD8 u1_matrix_coeffs;
+
+ UWORD8 u1_cr_top_field;
+
+ UWORD8 u1_cr_bottom_field;
+
+ UWORD32 u4_num_units_in_tick;
+
+ UWORD32 u4_time_scale;
+
+ UWORD8 u1_fixed_frame_rate_flag;
+
+ UWORD8 u1_nal_hrd_params_present;
+
+ UWORD8 u1_vcl_hrd_params_present;
+
+ UWORD8 u1_low_delay_hrd_flag;
+
+ UWORD8 u1_pic_struct_present_flag;
+
+ UWORD8 u1_bitstream_restriction_flag;
+
+ UWORD8 u1_mv_over_pic_boundaries_flag;
+
+ UWORD32 u4_max_bytes_per_pic_denom;
+
+ UWORD32 u4_max_bits_per_mb_denom;
+
+ UWORD32 u4_log2_max_mv_length_horz;
+
+ UWORD32 u4_log2_max_mv_length_vert;
+
+ UWORD32 u4_num_reorder_frames;
+
+ UWORD32 u4_max_dec_frame_buffering;
+
+} imvcd_get_vui_op_t;
+
+#endif
diff --git a/decoder/mvc/imvcd_api.c b/decoder/mvc/imvcd_api.c
new file mode 100644
index 0000000..45fffd1
--- /dev/null
+++ b/decoder/mvc/imvcd_api.c
@@ -0,0 +1,1599 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_api.c */
+/* */
+/* Description : Has all MVC API functions */
+/* */
+/* */
+/* List of Functions : */
+/* */
+/*****************************************************************************/
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "imvcd.h"
+#include "ih264_debug.h"
+#include "ih264_disp_mgr.h"
+#include "ih264_error.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_structs.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_function_selector.h"
+#include "ih264d_nal.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_parse_headers.h"
+#include "ih264d_tables.h"
+#include "ih264d_thread_compute_bs.h"
+#include "ih264d_utils.h"
+#include "ih264d_api_utils.h"
+#include "ithread.h"
+#include "imvcd_api_utils.h"
+#include "imvcd_dpb_manager.h"
+#include "imvcd_error_handler.h"
+#include "imvcd_nalu_parser.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+static void imvcd_free_static_bufs(iv_obj_t *ps_dec_hdl)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt;
+ dec_struct_t *ps_view_ctxt;
+
+ FT_ALIGNED_FREE *pf_aligned_free;
+
+ void *pv_mem_ctxt;
+
+ if(!ps_dec_hdl)
+ {
+ return;
+ }
+
+ ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+
+ if(!ps_mvcd_ctxt)
+ {
+ return;
+ }
+
+ ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ pf_aligned_free = ps_view_ctxt->pf_aligned_free;
+ pv_mem_ctxt = ps_view_ctxt->pv_mem_ctxt;
+
+ imvcd_free_dynamic_bufs(ps_mvcd_ctxt);
+
+ imvcd_bitsteam_buf_free(ps_view_ctxt);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_left_mvpred_addr);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu4_wts_ofsts_mat);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu4_mbaff_wt_mat);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_init_dpb_base);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_temp_mc_buffer);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pi2_pred1);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_ref_buff_base);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_left_mb_ctxt_info);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->p_cabac_ctxt_table_t);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ppv_map_ref_idx_to_poc_base);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_bits_buf_static);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_scratch_sps_pps);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_bitstrm);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_dpb_cmds);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sei_parse);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sei);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_dec_err_status);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_pred);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_bs_deblk_thread_handle);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pv_dec_thread_handle);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_pps);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_sps);
+
+ ih264_buf_mgr_free(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
+
+ ih264_buf_mgr_free(ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->ps_dpb_mgr);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt);
+
+ if(ps_dec_hdl)
+ {
+ pf_aligned_free(pv_mem_ctxt, ps_dec_hdl);
+ }
+}
+
+static IV_API_CALL_STATUS_T imvcd_view_ctxt_init(imvcd_create_ip_t *ps_ip,
+ dec_struct_t *ps_view_ctxt)
+{
+ pocstruct_t *ps_prev_poc, *ps_cur_poc;
+
+ WORD32 i4_mem_size;
+ void *pv_buf;
+
+ FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
+
+ void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
+ const WORD32 i4_default_alignment = 128;
+
+ ps_view_ctxt->u4_share_disp_buf = 0;
+ ps_view_ctxt->u1_chroma_format = ps_ip->s_ivd_ip.e_output_format;
+
+ ps_view_ctxt->pf_aligned_alloc = pf_aligned_alloc;
+ ps_view_ctxt->pf_aligned_free = ps_ip->s_ivd_ip.pf_aligned_free;
+ ps_view_ctxt->pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
+
+ i4_mem_size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_sps = pv_buf;
+
+ i4_mem_size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_pps = pv_buf;
+
+ i4_mem_size = ithread_get_handle_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pv_dec_thread_handle = pv_buf;
+
+ i4_mem_size = ithread_get_handle_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pv_bs_deblk_thread_handle = pv_buf;
+
+ i4_mem_size = sizeof(pred_info_t) * 2 * 32;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_pred = pv_buf;
+
+ ps_view_ctxt->pv_disp_buf_mgr = NULL;
+
+ ps_view_ctxt->pv_pic_buf_mgr = NULL;
+
+ ps_view_ctxt->ps_pic_buf_base = NULL;
+
+ i4_mem_size = sizeof(dec_err_status_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_dec_err_status = (dec_err_status_t *) pv_buf;
+
+ i4_mem_size = sizeof(sei);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_sei = (sei *) pv_buf;
+
+ i4_mem_size = sizeof(sei);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_sei_parse = (sei *) pv_buf;
+
+ i4_mem_size = sizeof(dpb_commands_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_dpb_cmds = (dpb_commands_t *) pv_buf;
+
+ i4_mem_size = sizeof(dec_bit_stream_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_bitstrm = (dec_bit_stream_t *) pv_buf;
+
+ i4_mem_size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pv_scratch_sps_pps = pv_buf;
+
+ ps_view_ctxt->u4_static_bits_buf_size = MIN_BITSTREAMS_BUF_SIZE;
+ pv_buf =
+ pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, ps_view_ctxt->u4_static_bits_buf_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, ps_view_ctxt->u4_static_bits_buf_size);
+ ps_view_ctxt->pu1_bits_buf_static = pv_buf;
+
+ i4_mem_size = (TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->ppv_map_ref_idx_to_poc_base = pv_buf;
+ ps_view_ctxt->ppv_map_ref_idx_to_poc =
+ ps_view_ctxt->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
+ memset(ps_view_ctxt->ppv_map_ref_idx_to_poc_base, 0, i4_mem_size);
+
+ i4_mem_size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->p_cabac_ctxt_table_t = pv_buf;
+
+ i4_mem_size = sizeof(ctxt_inc_mb_info_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_left_mb_ctxt_info = pv_buf;
+
+ i4_mem_size = MAX_REF_BUF_SIZE * 2;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu1_ref_buff_base = pv_buf;
+ ps_view_ctxt->pu1_ref_buff = ps_view_ctxt->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
+
+ i4_mem_size = sizeof(WORD16) * PRED_BUFFER_WIDTH * PRED_BUFFER_HEIGHT * 2;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pi2_pred1 = pv_buf;
+
+ i4_mem_size = sizeof(UWORD8) * (MB_LUM_SIZE);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu1_temp_mc_buffer = pv_buf;
+
+ i4_mem_size = (sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu4_mbaff_wt_mat = pv_buf;
+
+ i4_mem_size = sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu4_wts_ofsts_mat = pv_buf;
+
+ i4_mem_size = (sizeof(neighbouradd_t) << 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_left_mvpred_addr = pv_buf;
+
+ ps_view_ctxt->pv_mv_buf_mgr = NULL;
+
+ ps_view_ctxt->ps_col_mv_base = NULL;
+
+ ps_view_ctxt->init_done = 0;
+ ps_view_ctxt->u4_num_cores = 1;
+ ps_view_ctxt->u2_pic_ht = ps_view_ctxt->u2_pic_wd = 0;
+ ps_view_ctxt->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
+ ps_view_ctxt->u4_app_disable_deblk_frm = 0;
+ ps_view_ctxt->i4_degrade_type = 0;
+ ps_view_ctxt->i4_degrade_pics = 0;
+
+ memset(ps_view_ctxt->ps_pps, 0, ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS));
+ memset(ps_view_ctxt->ps_sps, 0, ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS));
+
+ ps_view_ctxt->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
+ ps_view_ctxt->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
+ ps_view_ctxt->s_cab_dec_env.pv_codec_handle = ps_view_ctxt;
+ ps_view_ctxt->u4_num_fld_in_frm = 0;
+ ps_view_ctxt->ps_sei->u1_is_valid = 0;
+ ps_view_ctxt->ps_cur_pps = NULL;
+ ps_view_ctxt->ps_cur_sps = NULL;
+ ps_view_ctxt->ps_cur_slice = NULL;
+ ps_view_ctxt->u1_init_dec_flag = 0;
+ ps_view_ctxt->u1_first_slice_in_stream = 1;
+ ps_view_ctxt->u1_last_pic_not_decoded = 0;
+ ps_view_ctxt->u4_app_disp_width = 0;
+ ps_view_ctxt->i4_header_decoded = 0;
+ ps_view_ctxt->u4_total_frames_decoded = 0;
+ ps_view_ctxt->i4_error_code = 0;
+ ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
+ ps_view_ctxt->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS;
+ ps_view_ctxt->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
+ ps_view_ctxt->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
+ ps_view_ctxt->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
+ ps_view_ctxt->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
+ ps_view_ctxt->u1_pr_sl_type = 0xFF;
+ ps_view_ctxt->u2_mbx = 0xffff;
+ ps_view_ctxt->u2_mby = 0;
+ ps_view_ctxt->u2_total_mbs_coded = 0;
+
+ ps_prev_poc = &ps_view_ctxt->s_prev_pic_poc;
+ ps_cur_poc = &ps_view_ctxt->s_cur_pic_poc;
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
+ ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = 0;
+ ps_prev_poc->i4_bottom_field_order_count = ps_cur_poc->i4_bottom_field_order_count = 0;
+ ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
+
+ ps_view_ctxt->i4_max_poc = 0;
+ ps_view_ctxt->i4_prev_max_display_seq = 0;
+ ps_view_ctxt->u1_recon_mb_grp = 4;
+ ps_view_ctxt->i4_reorder_depth = -1;
+ ps_view_ctxt->u1_second_field = 0;
+ ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending = 0;
+ ps_view_ctxt->u2_crop_offset_y = 0;
+ ps_view_ctxt->u2_crop_offset_uv = 0;
+ ps_view_ctxt->i4_vui_frame_rate = -1;
+ ps_view_ctxt->i4_pic_type = NA_SLICE;
+ ps_view_ctxt->i4_frametype = IV_NA_FRAME;
+ ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
+ ps_view_ctxt->u1_res_changed = 0;
+ ps_view_ctxt->u1_frame_decoded_flag = 0;
+ ps_view_ctxt->u4_skip_frm_mask = SKIP_NONE;
+
+ ps_view_ctxt->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
+ ps_view_ctxt->pf_cavlc_4x4res_block[1] = ih264d_cavlc_4x4res_block_totalcoeff_2to10;
+ ps_view_ctxt->pf_cavlc_4x4res_block[2] = ih264d_cavlc_4x4res_block_totalcoeff_11to16;
+ ps_view_ctxt->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
+ ps_view_ctxt->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
+ ps_view_ctxt->pf_cavlc_parse_8x8block[0] = ih264d_cavlc_parse_8x8block_none_available;
+ ps_view_ctxt->pf_cavlc_parse_8x8block[1] = ih264d_cavlc_parse_8x8block_left_available;
+ ps_view_ctxt->pf_cavlc_parse_8x8block[2] = ih264d_cavlc_parse_8x8block_top_available;
+ ps_view_ctxt->pf_cavlc_parse_8x8block[3] = ih264d_cavlc_parse_8x8block_both_available;
+
+ ps_view_ctxt->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
+ ps_view_ctxt->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
+ ps_view_ctxt->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
+ ps_view_ctxt->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
+ ps_view_ctxt->pf_fill_bs_xtra_left_edge[0] = ih264d_fill_bs_xtra_left_edge_cur_frm;
+ ps_view_ctxt->pf_fill_bs_xtra_left_edge[1] = ih264d_fill_bs_xtra_left_edge_cur_fld;
+
+ ps_view_ctxt->u2_prv_frame_num = 0;
+ ps_view_ctxt->u1_top_bottom_decoded = 0;
+ ps_view_ctxt->u1_dangling_field = 0;
+ ps_view_ctxt->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
+ ps_view_ctxt->pu1_left_mv_ctxt_inc = ps_view_ctxt->u1_left_mv_ctxt_inc_arr[0];
+ ps_view_ctxt->pi1_left_ref_idx_ctxt_inc = &ps_view_ctxt->i1_left_ref_idx_ctx_inc_arr[0][0];
+ ps_view_ctxt->pu1_left_yuv_dc_csbp = &ps_view_ctxt->u1_yuv_dc_csbp_topmb;
+ ps_view_ctxt->u1_flushfrm = 0;
+ ps_view_ctxt->s_cab_dec_env.pv_codec_handle = ps_view_ctxt;
+ ps_view_ctxt->ps_bitstrm->pv_codec_handle = ps_view_ctxt;
+
+ memset(ps_view_ctxt->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
+ memset(ps_view_ctxt->u4_disp_buf_mapping, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
+ memset(ps_view_ctxt->u4_disp_buf_to_be_freed, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
+
+ ih264d_init_arch(ps_view_ctxt);
+ ih264d_init_function_ptr(ps_view_ctxt);
+ ps_view_ctxt->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_view_ctxt->init_done = 1;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctxt_init(imvcd_create_ip_t *ps_ip, mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i4_mem_size;
+ void *pv_buf;
+
+ FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
+
+ void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
+ const WORD32 i4_default_alignment = 128;
+
+ memset(ps_mvcd_ctxt, 0, sizeof(ps_mvcd_ctxt[0]));
+
+ i4_mem_size = sizeof(mvc_dpb_manager_t);
+ ps_mvcd_ctxt->ps_dpb_mgr = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == ps_mvcd_ctxt->ps_dpb_mgr), IV_FAIL);
+ memset(ps_mvcd_ctxt->ps_dpb_mgr, 0, i4_mem_size);
+
+ imvcd_init_dpb_mgr(ps_mvcd_ctxt->ps_dpb_mgr, &ps_mvcd_ctxt->s_mvc_au_buf_mgr,
+ &ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr, &ps_mvcd_ctxt->s_mvc_disp_buf_mgr);
+
+ ih264_disp_mgr_init(&ps_mvcd_ctxt->s_mvc_disp_buf_mgr);
+
+ i4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem = pv_buf;
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt = pv_buf;
+
+ ih264_buf_mgr_init(ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_mem);
+
+ i4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem = pv_buf;
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt = pv_buf;
+
+ ih264_buf_mgr_init(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_mem);
+
+ if(IV_SUCCESS != imvcd_view_ctxt_init(ps_ip, &ps_mvcd_ctxt->s_view_dec_ctxt))
+ {
+ return IV_FAIL;
+ }
+
+ ps_mvcd_ctxt->u2_num_views = 0;
+ ps_mvcd_ctxt->u2_num_views_decoded = 0;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_allocate_static_bufs(imvcd_create_ip_t *ps_ip,
+ imvcd_create_op_t *ps_op)
+{
+ iv_obj_t *ps_dec_hdl;
+ mvc_dec_ctxt_t *ps_mvcd_ctxt;
+
+ WORD32 i4_mem_size;
+
+ FT_ALIGNED_ALLOC *pf_aligned_alloc = ps_ip->s_ivd_ip.pf_aligned_alloc;
+
+ void *pv_mem_ctxt = ps_ip->s_ivd_ip.pv_mem_ctxt;
+ const WORD32 i4_default_alignment = 128;
+
+ i4_mem_size = sizeof(ps_dec_hdl[0]);
+ ps_op->s_ivd_op.pv_handle = ps_dec_hdl =
+ (iv_obj_t *) pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+
+ if(NULL == ps_dec_hdl)
+ {
+ return IV_FAIL;
+ }
+
+ i4_mem_size = sizeof(ps_mvcd_ctxt[0]);
+ ps_dec_hdl->pv_codec_handle = ps_mvcd_ctxt =
+ (mvc_dec_ctxt_t *) pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+
+ if(NULL == ps_mvcd_ctxt)
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_SUCCESS != imvcd_ctxt_init(ps_ip, ps_mvcd_ctxt))
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+/* Description - 'Create' API for MVC Decoder */
+static IV_API_CALL_STATUS_T imvcd_create(imvcd_create_ip_t *ps_ip, imvcd_create_op_t *ps_op)
+{
+ if(IV_SUCCESS != imvcd_check_create_structs(ps_ip, ps_op))
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_SUCCESS != imvcd_allocate_static_bufs(ps_ip, ps_op))
+ {
+ imvcd_free_static_bufs((iv_obj_t *) ps_op->s_ivd_op.pv_handle);
+
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+/* Description - 'Delete' API for MVC Decoder */
+static IV_API_CALL_STATUS_T imvcd_delete(iv_obj_t *ps_dec_hdl)
+{
+ if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
+ {
+ return IV_FAIL;
+ }
+
+ imvcd_free_static_bufs(ps_dec_hdl);
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_flush_mode_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_op_t *ps_op)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ if(!ps_view_ctxt->u1_init_dec_flag)
+ {
+ ps_view_ctxt->u1_flushfrm = 0;
+ ps_mvcd_ctxt->b_flush_enabled = false;
+ ps_op->s_ivd_op.u4_output_present = 0;
+
+ return IV_FAIL;
+ }
+
+ if(IV_SUCCESS != imvcd_get_next_display_au_buf(ps_mvcd_ctxt))
+ {
+ ps_view_ctxt->u1_flushfrm = 0;
+ ps_mvcd_ctxt->b_flush_enabled = false;
+ ps_op->s_ivd_op.u4_output_present = false;
+
+ return IV_SUCCESS;
+ }
+
+ ih264d_export_sei_params(&ps_op->s_ivd_op.s_sei_decode_op, ps_view_ctxt);
+
+ ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
+ ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
+ ps_op->s_ivd_op.u4_ts = ps_view_ctxt->s_disp_op.u4_ts;
+ ps_op->s_ivd_op.u4_output_present = 1;
+ ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
+
+ imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
+
+ return IV_SUCCESS;
+}
+
+static void imvcd_fill_output_struct_from_context(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_op_t *ps_op)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ if((ps_op->s_ivd_op.u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
+ {
+ ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
+ ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
+ }
+
+ ps_op->s_ivd_op.u4_output_present = ps_view_ctxt->u4_output_present;
+
+ ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
+
+ imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
+
+ ih264d_export_sei_params(&ps_op->s_ivd_op.s_sei_decode_op, ps_view_ctxt);
+}
+
+static void imvcd_video_decode_clean_return(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ih264d_signal_decode_thread(ps_view_ctxt);
+ ih264d_signal_bs_deblk_thread(ps_view_ctxt);
+
+ imvcd_fill_output_struct_from_context(ps_mvcd_ctxt, ps_op);
+
+ ps_op->s_ivd_op.u4_frame_decoded_flag = 0;
+ ps_op->s_ivd_op.u4_num_bytes_consumed = ps_ip->s_ivd_ip.u4_num_Bytes;
+}
+
+static FORCEINLINE void imvcd_update_num_pps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_mvcd_ctxt->u1_num_pps = 0;
+
+ for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
+ {
+ if(ps_view_ctxt->ps_pps[i].u1_is_valid)
+ {
+ UWORD8 u1_sps_id = ps_view_ctxt->ps_pps[i].ps_sps->u1_seq_parameter_set_id;
+
+ if(ps_mvcd_ctxt->as_subset_sps[u1_sps_id].s_sps_data.u1_is_valid)
+ {
+ ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[i] =
+ &ps_mvcd_ctxt->as_subset_sps[u1_sps_id];
+ }
+
+ ps_mvcd_ctxt->u1_num_pps++;
+ }
+ }
+}
+
+static FORCEINLINE void imvcd_update_num_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_mvcd_ctxt->u1_num_sps = 0;
+
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_view_ctxt->ps_sps[i].u1_is_valid)
+ {
+ ps_mvcd_ctxt->u1_num_sps++;
+ }
+ }
+}
+
+static FORCEINLINE void imvcd_update_num_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ ps_mvcd_ctxt->u1_num_subset_sps = 0;
+
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
+ {
+ ps_mvcd_ctxt->u1_num_subset_sps++;
+ }
+ }
+}
+
+static IV_API_CALL_STATUS_T imvcd_view_decode(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op)
+{
+ UWORD8 *pu1_input_buffer;
+ UWORD8 *pu1_bitstream_buf;
+ UWORD32 u4_bitstream_buf_size;
+ WORD32 i4_nalu_length;
+ UWORD32 u4_length_of_start_code;
+ WORD32 i4_error_code;
+
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD32 u4_num_bytes_consumed = 0;
+ UWORD32 u4_num_bytes_remaining = ps_ip->s_ivd_ip.u4_num_Bytes;
+ bool b_first_start_code_found = false;
+ bool b_frame_data_left = true;
+ bool b_header_data_left = true;
+ UWORD32 u4_next_is_aud = 0;
+
+ ASSERT(u4_num_bytes_remaining > 0);
+
+ imvcd_view_init(ps_mvcd_ctxt);
+
+ do
+ {
+ pu1_input_buffer = ((UWORD8 *) ps_ip->s_ivd_ip.pv_stream_buffer) + u4_num_bytes_consumed;
+
+ if(!ps_view_ctxt->pu1_bits_buf_dynamic &&
+ is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS))
+ {
+ if(IV_SUCCESS !=
+ imvcd_bitstream_buf_alloc(
+ ps_view_ctxt, is_header_decoded(ps_view_ctxt->i4_header_decoded, SUBSET_SPS)
+ ? ps_mvcd_ctxt->u2_num_views
+ : 1))
+ {
+ return IV_FAIL;
+ }
+ }
+
+ if(ps_view_ctxt->pu1_bits_buf_dynamic)
+ {
+ pu1_bitstream_buf = ps_view_ctxt->pu1_bits_buf_dynamic;
+ u4_bitstream_buf_size = ps_view_ctxt->u4_dynamic_bits_buf_size;
+ }
+ else
+ {
+ pu1_bitstream_buf = ps_view_ctxt->pu1_bits_buf_static;
+ u4_bitstream_buf_size = ps_view_ctxt->u4_static_bits_buf_size;
+ }
+
+ i4_nalu_length = ih264d_find_start_code(pu1_input_buffer, 0, u4_num_bytes_remaining,
+ &u4_length_of_start_code, &u4_next_is_aud);
+
+ if(i4_nalu_length == -1)
+ {
+ i4_nalu_length = 0;
+ }
+
+ if((0 != u4_next_is_aud) && (1 != u4_next_is_aud))
+ {
+ return IV_FAIL;
+ }
+
+ /* Ignore bytes beyond the allocated size of intermediate buffer */
+ /* Since 8 bytes are read ahead, ensure 8 bytes are free at the
+ end of the buffer, which will be memset to 0 after emulation prevention */
+ i4_nalu_length = MIN((UWORD32) i4_nalu_length, u4_bitstream_buf_size - 8);
+
+ if(i4_nalu_length)
+ {
+ memcpy(pu1_bitstream_buf, pu1_input_buffer + u4_length_of_start_code, i4_nalu_length);
+
+ /* Decoder may read extra 8 bytes near end of the frame */
+ if(((UWORD32) (i4_nalu_length + 8)) < u4_bitstream_buf_size)
+ {
+ memset(pu1_bitstream_buf + i4_nalu_length, 0, 8 * sizeof(pu1_bitstream_buf[0]));
+ }
+
+ b_first_start_code_found = true;
+ }
+ else
+ {
+ if(!b_first_start_code_found)
+ {
+ ps_view_ctxt->i4_error_code = ERROR_START_CODE_NOT_FOUND;
+ ps_op->s_ivd_op.u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
+
+ if(ps_view_ctxt->u4_pic_buf_got == 0)
+ {
+ imvcd_fill_output_struct_from_context(ps_mvcd_ctxt, ps_op);
+
+ ps_op->s_ivd_op.u4_error_code = ps_view_ctxt->i4_error_code;
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+ else
+ {
+ ps_view_ctxt->u1_pic_decode_done = 1;
+
+ continue;
+ }
+ }
+ else
+ {
+ /* a start code has already been found earlier in the same process
+ * call*/
+ b_frame_data_left = false;
+ b_header_data_left = false;
+
+ if(!ps_view_ctxt->i4_decode_header && !ps_view_ctxt->u4_pic_buf_got)
+ {
+ ps_op->s_ivd_op.u4_error_code = ih264d_map_error(ERROR_UNKNOWN_NAL);
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+
+ continue;
+ }
+ }
+
+ ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded] =
+ NAL_UNIT_TYPE(pu1_bitstream_buf[0]);
+ ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] =
+ NAL_REF_IDC(pu1_bitstream_buf[0]);
+
+ if(ps_view_ctxt->u4_dec_thread_created &&
+ !is_slice_nalu_type(ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded]))
+ {
+ ps_op->s_ivd_op.u4_error_code = ERROR_FEATURE_UNAVAIL;
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+
+ if(!is_mvc_nalu(ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded]))
+ {
+ ivd_video_decode_op_t s_avc_op;
+
+ i4_error_code =
+ ih264d_parse_nal_unit(ps_dec_hdl, &s_avc_op, pu1_bitstream_buf, i4_nalu_length);
+ }
+ else
+ {
+ i4_error_code = imvcd_nalu_parser(ps_mvcd_ctxt, pu1_bitstream_buf, i4_nalu_length);
+ }
+
+ if(OK != i4_error_code)
+ {
+ ps_op->s_ivd_op.u4_error_code = i4_error_code;
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+ else if(PPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
+ {
+ imvcd_update_num_pps(ps_mvcd_ctxt);
+ }
+ else if(SPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
+ {
+ imvcd_update_num_sps(ps_mvcd_ctxt);
+ }
+ else if(SUBSET_SPS == ps_mvcd_ctxt->ae_nalu_id[ps_mvcd_ctxt->u2_num_views_decoded])
+ {
+ imvcd_update_num_subset_sps(ps_mvcd_ctxt);
+ }
+
+ b_header_data_left = ps_view_ctxt->i4_decode_header &&
+ (!is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) ||
+ !is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS)) &&
+ (u4_num_bytes_consumed < ps_ip->s_ivd_ip.u4_num_Bytes);
+ b_frame_data_left = (!ps_view_ctxt->i4_decode_header &&
+ (!ps_view_ctxt->u1_pic_decode_done || u4_next_is_aud)) &&
+ (u4_num_bytes_consumed < ps_ip->s_ivd_ip.u4_num_Bytes);
+
+ u4_num_bytes_consumed += i4_nalu_length + u4_length_of_start_code;
+ u4_num_bytes_remaining -= i4_nalu_length + u4_length_of_start_code;
+
+ } while(b_header_data_left || b_frame_data_left);
+
+ if((i4_error_code == IVD_RES_CHANGED) || (i4_error_code == IVD_MEM_ALLOC_FAILED) ||
+ (i4_error_code == ERROR_UNAVAIL_PICBUF_T) || (i4_error_code == ERROR_UNAVAIL_MVBUF_T) ||
+ (i4_error_code == ERROR_INV_SPS_PPS_T))
+ {
+ ih264d_signal_decode_thread(ps_view_ctxt);
+
+ if(ps_view_ctxt->u4_num_cores == 3)
+ {
+ ih264d_signal_bs_deblk_thread(ps_view_ctxt);
+ }
+
+ /* dont consume bitstream for change in resolution case */
+ if(i4_error_code == IVD_RES_CHANGED)
+ {
+ ps_op->s_ivd_op.u4_num_bytes_consumed -= u4_num_bytes_consumed;
+ }
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ if(ps_view_ctxt->u4_num_cores == 2)
+ {
+ if((ps_view_ctxt->u4_nmb_deblk == 0) && (ps_view_ctxt->u4_start_recon_deblk == 1))
+ {
+ tfr_ctxt_t s_tfr_ctxt;
+
+ UWORD32 u4_num_mbs, u4_max_addr;
+
+ tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
+ pad_mgr_t *ps_pad_mgr = &ps_view_ctxt->s_pad_mgr;
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+
+ /*BS is done for all mbs while parsing*/
+ u4_max_addr = (ps_view_ctxt->u2_frm_wd_in_mbs * ps_view_ctxt->u2_frm_ht_in_mbs) - 1;
+ ps_view_ctxt->u4_cur_bs_mb_num = u4_max_addr + 1;
+
+ ps_view_ctxt->ps_cur_pic = &ps_view_ctxt->s_cur_pic;
+ imvcd_convert_au_buf_to_view_buf(ps_mvcd_ctxt->ps_cur_au, &ps_view_ctxt->s_cur_pic,
+ ps_mvcd_ctxt->u2_num_views_decoded,
+ ps_cur_nalu_mvc_ext->u2_view_id);
+
+ ih264d_init_deblk_tfr_ctxt(ps_view_ctxt, ps_pad_mgr, ps_tfr_cxt,
+ ps_view_ctxt->u2_frm_wd_in_mbs, 0);
+
+ u4_num_mbs = u4_max_addr - ps_view_ctxt->u4_cur_deblk_mb_num + 1;
+
+ if(u4_num_mbs != 0)
+ {
+ ih264d_check_mb_map_deblk(ps_view_ctxt, u4_num_mbs, ps_tfr_cxt, 1);
+ }
+
+ ps_view_ctxt->u4_start_recon_deblk = 0;
+ }
+ }
+
+ ih264d_signal_decode_thread(ps_view_ctxt);
+
+ if(ps_view_ctxt->u4_num_cores == 3)
+ {
+ ih264d_signal_bs_deblk_thread(ps_view_ctxt);
+ }
+ }
+
+ DATA_SYNC();
+
+ // Report if header (sps and pps) has not been decoded yet
+ if(ps_view_ctxt->i4_decode_header &&
+ (!is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) &&
+ !is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS)))
+ {
+ ps_op->s_ivd_op.u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
+
+ imvcd_video_decode_clean_return(ps_mvcd_ctxt, ps_ip, ps_op);
+
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->u4_pic_buf_got)
+ {
+ ps_view_ctxt->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
+
+ if(((ps_view_ctxt->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0) &&
+ ps_view_ctxt->u1_pic_decode_done)
+ {
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+
+ if(!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] &&
+ ps_cur_nalu_mvc_ext->u1_inter_view_flag)
+ {
+ ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc = 1;
+ }
+
+ /* Padding only. Deblk has happened already. */
+ ih264d_deblock_picture_progressive(ps_view_ctxt);
+
+ if(!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views_decoded] &&
+ ps_cur_nalu_mvc_ext->u1_inter_view_flag)
+ {
+ ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc = 0;
+ }
+ }
+
+ /*Update the i4_frametype at the end of picture*/
+ if(imvcd_is_idr_au(ps_mvcd_ctxt))
+ {
+ ps_view_ctxt->i4_frametype = IV_IDR_FRAME;
+ }
+ else if(ps_view_ctxt->i4_pic_type == B_SLICE)
+ {
+ ps_view_ctxt->i4_frametype = IV_B_FRAME;
+ }
+ else if(ps_view_ctxt->i4_pic_type == P_SLICE)
+ {
+ ps_view_ctxt->i4_frametype = IV_P_FRAME;
+ }
+ else if(ps_view_ctxt->i4_pic_type == I_SLICE)
+ {
+ ps_view_ctxt->i4_frametype = IV_I_FRAME;
+ }
+
+ ps_view_ctxt->i4_content_type = ps_view_ctxt->ps_cur_slice->u1_field_pic_flag;
+ }
+
+ /* close deblock thread if it is not closed yet*/
+ if(ps_view_ctxt->u4_num_cores == 3)
+ {
+ ih264d_signal_bs_deblk_thread(ps_view_ctxt);
+ }
+
+ if(ps_view_ctxt->u4_dec_thread_created)
+ {
+ ih264d_signal_decode_thread(ps_view_ctxt);
+ }
+
+ if(ps_view_ctxt->u4_bs_deblk_thread_created)
+ {
+ ih264d_signal_bs_deblk_thread(ps_view_ctxt);
+ }
+
+ ps_op->s_ivd_op.u4_num_bytes_consumed = u4_num_bytes_consumed;
+
+ DATA_SYNC();
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_finish_au_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_op_t *ps_op)
+{
+ WORD32 i4_error_code;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ mvc_au_buffer_t *ps_cur_au = ps_mvcd_ctxt->ps_cur_au;
+ mvc_dpb_manager_t *ps_dpb_mgr = ps_mvcd_ctxt->ps_dpb_mgr;
+
+ bool b_is_idr = imvcd_is_idr_au(ps_mvcd_ctxt);
+ bool b_is_ref_au = !!ps_mvcd_ctxt->au1_nal_ref_idc[ps_mvcd_ctxt->u2_num_views - 1];
+ WORD64 i8_display_poc =
+ ((WORD64) ps_view_ctxt->i4_prev_max_display_seq) + ((WORD64) ps_cur_au->i4_poc);
+
+ imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+
+ if(ps_cur_slice->u1_mmco_equalto5 || b_is_idr)
+ {
+ ps_cur_au->i4_poc = 0;
+ ps_cur_au->i4_avg_poc = 0;
+
+ if(ps_view_ctxt->u2_total_mbs_coded == (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1))
+ {
+ imvcd_reset_dpb(ps_dpb_mgr);
+ }
+
+ imvcd_dpb_release_display_bufs(ps_dpb_mgr);
+ }
+
+ if(IVD_DECODE_FRAME_OUT != ps_view_ctxt->e_frm_out_mode)
+ {
+ i4_error_code = imvcd_dpb_assign_display_seq(ps_dpb_mgr);
+
+ if(OK != i4_error_code)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ if(b_is_ref_au)
+ {
+ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
+ ps_cur_au->i4_pic_buf_id, BUF_MGR_REF);
+
+ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ ps_cur_au->i4_mv_buf_id, BUF_MGR_REF);
+
+ ps_view_ctxt->au1_pic_buf_ref_flag[ps_cur_au->i4_pic_buf_id] = 1;
+ }
+ else
+ {
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
+ ps_cur_au->i4_pic_buf_id, BUF_MGR_REF);
+
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ ps_cur_au->i4_mv_buf_id, BUF_MGR_REF | BUF_MGR_IO);
+
+ ps_view_ctxt->au1_pic_buf_ref_flag[ps_cur_au->i4_pic_buf_id] = 0;
+ }
+
+ if((!ps_view_ctxt->u1_last_pic_not_decoded &&
+ (0 == (ps_view_ctxt->ps_cur_pic->u4_pack_slc_typ & ps_view_ctxt->u4_skip_frm_mask))) ||
+ b_is_idr)
+ {
+ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
+ ps_cur_au->i4_pic_buf_id, BUF_MGR_IO);
+ }
+
+ if(IS_OUT_OF_RANGE_S32(i8_display_poc))
+ {
+ ps_view_ctxt->i4_prev_max_display_seq = 0;
+ }
+
+ i4_error_code = imvcd_dpb_insert_pic_in_display_list(
+ ps_dpb_mgr, i8_display_poc, ps_cur_au->i4_frame_num, ps_cur_au->i4_pic_buf_id);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+
+ if(IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode)
+ {
+ i4_error_code = imvcd_dpb_assign_display_seq(ps_dpb_mgr);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ ps_view_ctxt->u4_total_frames_decoded++;
+
+ /* In case the decoder is configured to run in low delay mode,
+ * then get display buffer and then format convert.
+ * Note in this mode, format conversion does not run paralelly in a thread
+ * and adds to the codec cycles
+ */
+ if((IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode) && ps_view_ctxt->u1_init_dec_flag)
+ {
+ i4_error_code = imvcd_get_next_display_au_buf(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+
+ ps_op->s_ivd_op.u4_output_present = 1;
+ }
+
+ ps_cur_au->u1_pic_type |= TOP_REF | BOT_REF;
+
+ if(ps_view_ctxt->u4_pic_buf_got)
+ {
+ if(ps_view_ctxt->u1_last_pic_not_decoded)
+ {
+ return IV_FAIL;
+ }
+ else if(b_is_ref_au)
+ {
+ if(b_is_idr)
+ {
+ ps_dpb_mgr->u1_mmco_error_in_seq = 0;
+
+ if(!ps_view_ctxt->ps_dpb_cmds->u1_long_term_reference_flag)
+ {
+ imvcd_reset_dpb(ps_dpb_mgr);
+
+ i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+
+ ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
+ }
+ else
+ {
+ i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+
+ imvcd_dpb_delete_st_node_or_make_lt(ps_dpb_mgr, ps_cur_au->i4_pic_num, 0);
+
+ ps_dpb_mgr->u1_max_lt_frame_idx = 0;
+ }
+ }
+ else if(!ps_dpb_mgr->u1_mmco_error_in_seq)
+ {
+ i4_error_code = imvcd_dpb_do_mmco(ps_view_ctxt->ps_dpb_cmds, ps_dpb_mgr, ps_cur_au,
+ ps_view_ctxt->ps_cur_sps->u1_num_ref_frames,
+ ps_view_ctxt->e_dec_status);
+
+ ps_dpb_mgr->u1_mmco_error_in_seq = i4_error_code != OK;
+ }
+
+ i4_error_code = imvcd_dpb_update_default_index_list(ps_dpb_mgr);
+
+ if(i4_error_code != OK)
+ {
+ return IV_FAIL;
+ }
+ }
+ }
+
+ ps_op->s_ivd_op.u4_frame_decoded_flag = 1;
+
+ return IV_SUCCESS;
+}
+
+/* Description - 'AU Decode' API for MVC Decoder */
+static IV_API_CALL_STATUS_T imvcd_decode(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op)
+{
+ IV_API_CALL_STATUS_T e_retval;
+
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ imvcd_video_decode_ip_t s_view_ip = ps_ip[0];
+ imvcd_video_decode_op_t s_view_op = ps_op[0];
+
+ UWORD16 u2_num_views_decoded = 0;
+ UWORD16 u2_num_views = (ps_mvcd_ctxt->b_flush_enabled || ps_mvcd_ctxt->b_header_only_decode)
+ ? 1
+ : ps_mvcd_ctxt->u2_num_views;
+
+ ps_mvcd_ctxt->u2_num_views_decoded = 0;
+
+ if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_SUCCESS != imvcd_check_decode_structs(ps_dec_hdl, ps_ip, ps_op))
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_mvcd_ctxt->b_header_only_decode)
+ {
+ if(IV_SUCCESS != imvcd_au_error_checks(ps_mvcd_ctxt, ps_ip))
+ {
+ return IV_FAIL;
+ }
+ }
+
+ /*Data memory barries instruction,so that bitstream write by the application
+ * is complete*/
+ DATA_SYNC();
+
+ imvcd_au_init(ps_dec_hdl, ps_ip, ps_op);
+
+ if(ps_mvcd_ctxt->b_flush_enabled)
+ {
+ return imvcd_flush_mode_decode(ps_mvcd_ctxt, ps_op);
+ }
+
+ while(u2_num_views_decoded < u2_num_views)
+ {
+ e_retval = imvcd_view_decode(ps_dec_hdl, &s_view_ip, &s_view_op);
+
+ if(IV_SUCCESS != e_retval)
+ {
+ ps_op->s_ivd_op.u4_error_code = s_view_op.s_ivd_op.u4_error_code;
+
+ return IV_FAIL;
+ }
+
+ s_view_ip.s_ivd_ip.pv_stream_buffer = ((UWORD8 *) s_view_ip.s_ivd_ip.pv_stream_buffer) +
+ s_view_op.s_ivd_op.u4_num_bytes_consumed;
+ s_view_ip.s_ivd_ip.u4_num_Bytes -= s_view_op.s_ivd_op.u4_num_bytes_consumed;
+ ps_op->s_ivd_op.u4_num_bytes_consumed += s_view_op.s_ivd_op.u4_num_bytes_consumed;
+
+ u2_num_views_decoded++;
+ ps_mvcd_ctxt->u2_num_views_decoded++;
+ }
+
+ if(!ps_mvcd_ctxt->b_header_only_decode)
+ {
+ e_retval = imvcd_finish_au_decode(ps_mvcd_ctxt, ps_op);
+
+ if(IV_SUCCESS != e_retval)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ ps_op->s_ivd_op.u4_pic_wd = ps_view_ctxt->u2_disp_width;
+ ps_op->s_ivd_op.u4_pic_ht = ps_view_ctxt->u2_disp_height;
+ ps_op->s_ivd_op.u4_output_present = ps_view_ctxt->u4_output_present;
+ ps_op->s_ivd_op.u4_ts = ps_view_ctxt->s_disp_op.u4_ts;
+ ps_op->s_ivd_op.i4_reorder_depth = ps_view_ctxt->i4_reorder_depth;
+ ps_op->s_ivd_op.e_output_format = IV_YUV_420P;
+
+ if(ps_op->s_ivd_op.u4_output_present)
+ {
+ imvcd_convert_to_app_disp_buf(ps_mvcd_ctxt, ps_op->ps_view_disp_bufs);
+ }
+
+ return e_retval;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_set_dec_mode(iv_obj_t *ps_dec_hdl,
+ imvcd_set_config_ip_t *ps_ip,
+ imvcd_set_config_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_view_ctxt->u4_skip_frm_mask = SKIP_NONE;
+
+ ps_op->s_ivd_op.u4_error_code = 0;
+
+ ps_view_ctxt->u4_app_disp_width = 0;
+
+ if(ps_ip->s_ivd_ip.e_frm_skip_mode != IVD_SKIP_NONE)
+ {
+ ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ivd_ip.e_vid_dec_mode == IVD_DECODE_FRAME)
+ {
+ ps_view_ctxt->i4_decode_header = 0;
+ ps_mvcd_ctxt->b_header_only_decode = false;
+ }
+ else if(ps_ip->s_ivd_ip.e_vid_dec_mode == IVD_DECODE_HEADER)
+ {
+ ps_view_ctxt->i4_decode_header = 1;
+ ps_mvcd_ctxt->b_header_only_decode = true;
+ }
+ else
+ {
+ ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ivd_ip.e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
+ (ps_ip->s_ivd_ip.e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
+ {
+ ps_op->s_ivd_op.u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+
+ return IV_FAIL;
+ }
+
+ ps_mvcd_ctxt->b_flush_enabled = false;
+ ps_view_ctxt->e_frm_out_mode = ps_ip->s_ivd_ip.e_frm_out_mode;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_set_num_cores(iv_obj_t *ps_dec_hdl,
+ imvcd_set_num_cores_ip_t *ps_ip,
+ imvcd_set_num_cores_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_view_ctxt->u4_num_cores = ps_ip->u4_num_cores;
+
+ ps_op->u4_error_code = 0;
+
+ if(ps_view_ctxt->u4_num_cores == 1)
+ {
+ ps_view_ctxt->u1_separate_parse = 0;
+ }
+ else
+ {
+ ps_view_ctxt->u1_separate_parse = 1;
+ }
+
+ /*using only upto three threads currently*/
+ if(ps_view_ctxt->u4_num_cores > 3)
+ {
+ ps_view_ctxt->u4_num_cores = 3;
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_set_arch(iv_obj_t *ps_dec_hdl, imvcd_set_arch_ip_t *ps_ip,
+ imvcd_set_arch_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_view_ctxt->e_processor_arch = ps_ip->e_arch;
+ ps_view_ctxt->e_processor_soc = ps_ip->e_soc;
+
+ ps_op->u4_error_code = 0;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_set_degrade_mode(iv_obj_t *ps_dec_hdl,
+ imvcd_set_degrade_mode_ip_t *ps_ip,
+ imvcd_set_degrade_mode_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_view_ctxt->i4_degrade_type = ps_ip->i4_degrade_type;
+ ps_view_ctxt->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
+ ps_view_ctxt->i4_degrade_pics = ps_ip->i4_degrade_pics;
+ ps_view_ctxt->i4_degrade_pic_cnt = 0;
+
+ ps_op->u4_error_code = 0;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_flush_dec(iv_obj_t *ps_dec_hdl, imvcd_flush_dec_ip_t *ps_ip,
+ imvcd_flush_dec_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UNUSED(ps_ip);
+
+ ps_op->s_ivd_op.u4_error_code = 0;
+
+ ps_mvcd_ctxt->b_flush_enabled = true;
+ ps_view_ctxt->u1_flushfrm = 1;
+
+ if(ps_view_ctxt->u1_init_dec_flag)
+ {
+ imvcd_release_all_ref_bufs(ps_mvcd_ctxt, ps_view_ctxt->u1_pic_bufs);
+ imvcd_dpb_release_display_bufs(ps_mvcd_ctxt->ps_dpb_mgr);
+ }
+
+ /* Ignore dangling fields during flush */
+ ps_view_ctxt->u1_top_bottom_decoded = 0;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_get_buf_info(iv_obj_t *ps_dec_hdl,
+ imvcd_get_buf_info_ip_t *ps_ip,
+ imvcd_get_buf_info_op_t *ps_op)
+{
+ UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
+ UWORD32 u4_pic_wd, u4_pic_ht;
+ UWORD32 i;
+
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UNUSED(ps_ip);
+
+ ps_op->s_ivd_op.u4_error_code = 0;
+
+ ps_op->s_ivd_op.u4_num_disp_bufs = 0;
+ ps_op->s_ivd_op.u4_min_num_in_bufs = MIN_IN_BUFS;
+
+ u4_pic_wd = 0;
+ u4_pic_ht = 0;
+
+ if(is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS))
+ {
+ u4_pic_wd = ps_view_ctxt->u2_disp_width;
+ u4_pic_ht = ps_view_ctxt->u2_disp_height;
+ }
+
+ ps_op->s_mvc_buf_info.u2_num_views = ps_mvcd_ctxt->u2_num_views;
+
+ for(i = 0; i < ps_op->s_ivd_op.u4_min_num_in_bufs; i++)
+ {
+ ps_op->s_ivd_op.u4_min_in_buf_size[i] =
+ MAX(256000, u4_pic_wd * u4_pic_ht * ps_mvcd_ctxt->u2_num_views * 3 / 2);
+ }
+
+ ps_op->s_ivd_op.u4_min_num_out_bufs = ih264d_get_outbuf_size(
+ u4_pic_wd, u4_pic_ht, ps_view_ctxt->u1_chroma_format, &au4_min_out_buf_size[0]);
+ ps_op->s_ivd_op.u4_min_num_out_bufs *= ps_mvcd_ctxt->u2_num_views;
+
+ for(i = 0; i < ps_op->s_ivd_op.u4_min_num_out_bufs; i++)
+ {
+ ps_op->s_ivd_op.u4_min_out_buf_size[i] = au4_min_out_buf_size[i % NUM_COMPONENTS];
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_ctl_get_vui(iv_obj_t *ps_dec_hdl, imvcd_get_vui_ip_t *ps_ip,
+ imvcd_get_vui_op_t *ps_op)
+{
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UNUSED(ps_ip);
+
+ ps_op->u4_error_code = 0;
+ ps_op->b_is_vui_available = false;
+
+ if((ps_mvcd_ctxt->u1_num_sps > 0) && ps_view_ctxt->ps_cur_sps)
+ {
+ ps_op->b_is_vui_available = ps_view_ctxt->ps_cur_sps->u1_vui_parameters_present_flag;
+
+ if(ps_op->b_is_vui_available)
+ {
+ ps_op->u1_aspect_ratio_idc = ps_view_ctxt->ps_cur_sps->s_vui.u1_aspect_ratio_idc;
+ ps_op->u2_sar_width = ps_view_ctxt->ps_cur_sps->s_vui.u2_sar_width;
+ ps_op->u2_sar_height = ps_view_ctxt->ps_cur_sps->s_vui.u2_sar_height;
+ ps_op->u1_overscan_appropriate_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_overscan_appropriate_flag;
+ ps_op->u1_video_format = ps_view_ctxt->ps_cur_sps->s_vui.u1_video_format;
+ ps_op->u1_video_full_range_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_video_full_range_flag;
+ ps_op->u1_colour_primaries = ps_view_ctxt->ps_cur_sps->s_vui.u1_colour_primaries;
+ ps_op->u1_tfr_chars = ps_view_ctxt->ps_cur_sps->s_vui.u1_tfr_chars;
+ ps_op->u1_matrix_coeffs = ps_view_ctxt->ps_cur_sps->s_vui.u1_matrix_coeffs;
+ ps_op->u1_cr_top_field = ps_view_ctxt->ps_cur_sps->s_vui.u1_cr_top_field;
+ ps_op->u1_cr_bottom_field = ps_view_ctxt->ps_cur_sps->s_vui.u1_cr_bottom_field;
+ ps_op->u4_num_units_in_tick = ps_view_ctxt->ps_cur_sps->s_vui.u4_num_units_in_tick;
+ ps_op->u4_time_scale = ps_view_ctxt->ps_cur_sps->s_vui.u4_time_scale;
+ ps_op->u1_fixed_frame_rate_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_fixed_frame_rate_flag;
+ ps_op->u1_nal_hrd_params_present =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_nal_hrd_params_present;
+ ps_op->u1_vcl_hrd_params_present =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_vcl_hrd_params_present;
+ ps_op->u1_low_delay_hrd_flag = ps_view_ctxt->ps_cur_sps->s_vui.u1_low_delay_hrd_flag;
+ ps_op->u1_pic_struct_present_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_pic_struct_present_flag;
+ ps_op->u1_bitstream_restriction_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_bitstream_restriction_flag;
+ ps_op->u1_mv_over_pic_boundaries_flag =
+ ps_view_ctxt->ps_cur_sps->s_vui.u1_mv_over_pic_boundaries_flag;
+ ps_op->u4_max_bytes_per_pic_denom =
+ ps_view_ctxt->ps_cur_sps->s_vui.u4_max_bytes_per_pic_denom;
+ ps_op->u4_max_bits_per_mb_denom =
+ ps_view_ctxt->ps_cur_sps->s_vui.u4_max_bits_per_mb_denom;
+ ps_op->u4_log2_max_mv_length_horz =
+ ps_view_ctxt->ps_cur_sps->s_vui.u4_log2_max_mv_length_horz;
+ ps_op->u4_log2_max_mv_length_vert =
+ ps_view_ctxt->ps_cur_sps->s_vui.u4_log2_max_mv_length_vert;
+ ps_op->u4_num_reorder_frames = ps_view_ctxt->ps_cur_sps->s_vui.u4_num_reorder_frames;
+ ps_op->u4_max_dec_frame_buffering =
+ ps_view_ctxt->ps_cur_sps->s_vui.u4_max_dec_frame_buffering;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+/* Description - 'Control Cmd' API for MVC Decoder */
+static IV_API_CALL_STATUS_T imvcd_ctl_cmd_handler(iv_obj_t *ps_dec_hdl, void *pv_ip, void *pv_op)
+{
+ ivd_ctl_set_config_ip_t *ps_ip = (ivd_ctl_set_config_ip_t *) pv_ip;
+
+ WORD32 i4_sub_cmd = ps_ip->e_sub_cmd;
+
+ if(IV_SUCCESS != imvcd_check_dec_handle(ps_dec_hdl))
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_SUCCESS != imvcd_check_ctl_structs(pv_ip, pv_op))
+ {
+ return IV_FAIL;
+ }
+
+ switch(i4_sub_cmd)
+ {
+ case IVD_CMD_CTL_SETPARAMS:
+ {
+ return imvcd_ctl_set_dec_mode(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IMVCD_CTL_SET_NUM_CORES:
+ {
+ return imvcd_ctl_set_num_cores(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IMVCD_CTL_SET_PROCESSOR:
+ {
+ return imvcd_ctl_set_arch(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IMVCD_CTL_DEGRADE:
+ {
+ return imvcd_ctl_set_degrade_mode(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IVD_CMD_CTL_FLUSH:
+ {
+ return imvcd_ctl_flush_dec(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IVD_CMD_CTL_GETBUFINFO:
+ {
+ return imvcd_ctl_get_buf_info(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IMVCD_CTL_GET_VUI_PARAMS:
+ {
+ return imvcd_ctl_get_vui(ps_dec_hdl, pv_ip, pv_op);
+ }
+ default:
+ {
+ return IV_FAIL;
+ }
+ }
+}
+
+IV_API_CALL_STATUS_T imvcd_api_function(iv_obj_t *ps_dec_hdl, void *pv_ip, void *pv_op)
+{
+ IVD_API_COMMAND_TYPE_T e_cmd = ((WORD32 *) pv_ip)[1];
+
+ switch(e_cmd)
+ {
+ case IVD_CMD_CREATE:
+ {
+ return imvcd_create(pv_ip, pv_op);
+ }
+ case IVD_CMD_DELETE:
+ {
+ return imvcd_delete(ps_dec_hdl);
+ }
+ case IVD_CMD_VIDEO_CTL:
+ {
+ return imvcd_ctl_cmd_handler(ps_dec_hdl, pv_ip, pv_op);
+ }
+ case IVD_CMD_VIDEO_DECODE:
+ {
+ return imvcd_decode(ps_dec_hdl, pv_ip, pv_op);
+ }
+ default:
+ {
+ return IV_FAIL;
+ }
+ }
+}
diff --git a/decoder/mvc/imvcd_api_utils.c b/decoder/mvc/imvcd_api_utils.c
new file mode 100644
index 0000000..7d1f309
--- /dev/null
+++ b/decoder/mvc/imvcd_api_utils.c
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_api_utils.c */
+/* */
+/* Description : Utility functions used by 'imvcd_api.c' */
+/* */
+/*****************************************************************************/
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "imvcd.h"
+#include "ih264_disp_mgr.h"
+#include "ih264d_structs.h"
+#include "ih264d_tables.h"
+#include "ih264d_utils.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+IV_API_CALL_STATUS_T imvcd_check_dec_handle(iv_obj_t *ps_handle)
+{
+ if(ps_handle == NULL)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_handle->pv_codec_handle == NULL)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+IV_API_CALL_STATUS_T imvcd_check_create_structs(imvcd_create_ip_t *ps_ip, imvcd_create_op_t *ps_op)
+{
+ if(NULL == ps_ip)
+ {
+ return IV_FAIL;
+ }
+
+ if(NULL == ps_op)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ivd_ip.e_output_format != IV_YUV_420P)
+ {
+ return IV_FAIL;
+ }
+
+ if(NULL == ps_ip->s_ivd_ip.pf_aligned_alloc)
+ {
+ return IV_FAIL;
+ }
+
+ if(NULL == ps_ip->s_ivd_ip.pf_aligned_free)
+ {
+ return IV_FAIL;
+ }
+
+ if(0 != ps_ip->s_ivd_ip.u4_share_disp_buf)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+IV_API_CALL_STATUS_T imvcd_check_ctl_structs(void *pv_ip, void *pv_op)
+{
+ ivd_ctl_set_config_ip_t *ps_ip = (ivd_ctl_set_config_ip_t *) pv_ip;
+ ivd_ctl_set_config_op_t *ps_op = (ivd_ctl_set_config_op_t *) pv_op;
+
+ WORD32 i4_sub_cmd = ps_ip->e_sub_cmd;
+
+ if(NULL == ps_ip)
+ {
+ return IV_FAIL;
+ }
+
+ if(NULL == ps_op)
+ {
+ return IV_FAIL;
+ }
+
+ switch(i4_sub_cmd)
+ {
+ case IVD_CMD_CTL_SETPARAMS:
+ {
+ if((ps_ip->u4_size != sizeof(ivd_ctl_set_config_ip_t)) ||
+ (ps_op->u4_size != sizeof(ivd_ctl_set_config_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IMVCD_CTL_SET_NUM_CORES:
+ {
+ if((ps_ip->u4_size != sizeof(imvcd_set_num_cores_ip_t)) ||
+ (ps_op->u4_size != sizeof(imvcd_set_num_cores_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IMVCD_CTL_SET_PROCESSOR:
+ {
+ if((ps_ip->u4_size != sizeof(imvcd_set_arch_ip_t)) ||
+ (ps_op->u4_size != sizeof(imvcd_set_arch_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IMVCD_CTL_DEGRADE:
+ {
+ if((ps_ip->u4_size != sizeof(imvcd_set_degrade_mode_ip_t)) ||
+ (ps_op->u4_size != sizeof(imvcd_set_degrade_mode_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IVD_CMD_CTL_FLUSH:
+ {
+ if((ps_ip->u4_size != sizeof(ivd_ctl_flush_ip_t)) ||
+ (ps_op->u4_size != sizeof(ivd_ctl_flush_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IVD_CMD_CTL_GETBUFINFO:
+ {
+ if((ps_ip->u4_size != sizeof(ivd_ctl_getbufinfo_ip_t)) ||
+ (ps_op->u4_size != sizeof(ivd_ctl_getbufinfo_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ case IMVCD_CTL_GET_VUI_PARAMS:
+ {
+ if((ps_ip->u4_size != sizeof(imvcd_get_vui_ip_t)) ||
+ (ps_op->u4_size != sizeof(imvcd_get_vui_op_t)))
+ {
+ return IV_FAIL;
+ }
+ else
+ {
+ return IV_SUCCESS;
+ }
+ }
+ default:
+ {
+ return IV_FAIL;
+ }
+ }
+}
+
+IV_API_CALL_STATUS_T imvcd_check_decode_structs(iv_obj_t *ps_dec_hdl,
+ imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op)
+{
+ WORD32 i, j;
+
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+
+ UWORD16 u2_num_views = 1;
+
+ if(NULL == ps_ip)
+ {
+ return IV_FAIL;
+ }
+
+ if(NULL == ps_op)
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_mvcd_ctxt->b_flush_enabled && !ps_mvcd_ctxt->b_header_only_decode)
+ {
+ if(NULL == ps_ip->s_ivd_ip.pv_stream_buffer)
+ {
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < u2_num_views; i++)
+ {
+ for(j = 0; j < NUM_COMPONENTS; j++)
+ {
+ if(NULL == ps_ip->s_ivd_ip.s_out_buffer.pu1_bufs[i * NUM_COMPONENTS + j])
+ {
+ return IV_FAIL;
+ }
+ }
+ }
+
+ if(0 == ps_ip->s_ivd_ip.u4_num_Bytes)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+static void imvcd_convert_app_out_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ ivd_out_bufdesc_t *ps_app_buffer)
+{
+ if(!ps_mvcd_ctxt->b_header_only_decode)
+ {
+ WORD32 i, j;
+
+ subset_sps_t *ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD16 u2_num_views =
+ (NULL == ps_subset_sps) ? 1 : ps_subset_sps->s_sps_mvc_ext.u2_num_views;
+
+ for(i = 0; i < u2_num_views; i++)
+ {
+ yuv_buf_props_t *ps_view_buf = &ps_mvcd_ctxt->s_out_buffer.as_view_buf_props[i];
+
+ ps_view_buf->u1_bit_depth = 8;
+ ps_view_buf->u2_height = ps_view_ctxt->u2_disp_height;
+ ps_view_buf->u2_width = ps_view_ctxt->u2_disp_width;
+
+ for(j = 0; j < NUM_COMPONENTS; j++)
+ {
+ buffer_container_t *ps_component_buf = &ps_view_buf->as_component_bufs[j];
+ bool b_is_chroma = (((COMPONENT_TYPES_T) j) != Y);
+
+ ps_component_buf->pv_data = ps_app_buffer->pu1_bufs[i * NUM_COMPONENTS + j];
+ ps_component_buf->i4_data_stride = ps_view_buf->u2_width >> b_is_chroma;
+ }
+ }
+ }
+}
+
+void imvcd_convert_to_app_disp_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt, iv_yuv_buf_t *ps_view_disp_bufs)
+{
+ WORD32 i;
+
+ UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views;
+
+ for(i = 0; i < u2_num_views; i++)
+ {
+ yuv_buf_props_t *ps_view_buf = &ps_mvcd_ctxt->s_out_buffer.as_view_buf_props[i];
+
+ ps_view_disp_bufs[i].u4_size = sizeof(ps_view_disp_bufs[i]);
+
+ ps_view_disp_bufs[i].pv_y_buf = ps_view_buf->as_component_bufs[Y].pv_data;
+ ps_view_disp_bufs[i].u4_y_strd = ps_view_buf->as_component_bufs[Y].i4_data_stride;
+ ps_view_disp_bufs[i].u4_y_wd = ps_view_buf->u2_width;
+ ps_view_disp_bufs[i].u4_y_ht = ps_view_buf->u2_height;
+
+ ps_view_disp_bufs[i].pv_u_buf = ps_view_buf->as_component_bufs[U].pv_data;
+ ps_view_disp_bufs[i].u4_u_strd = ps_view_buf->as_component_bufs[U].i4_data_stride;
+ ps_view_disp_bufs[i].u4_u_wd = ps_view_buf->u2_width / 2;
+ ps_view_disp_bufs[i].u4_u_ht = ps_view_buf->u2_height / 2;
+
+ ps_view_disp_bufs[i].pv_v_buf = ps_view_buf->as_component_bufs[V].pv_data;
+ ps_view_disp_bufs[i].u4_v_strd = ps_view_buf->as_component_bufs[V].i4_data_stride;
+ ps_view_disp_bufs[i].u4_v_wd = ps_view_buf->u2_width / 2;
+ ps_view_disp_bufs[i].u4_v_ht = ps_view_buf->u2_height / 2;
+ }
+}
+
+void imvcd_au_init(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op)
+{
+ subset_sps_t *ps_subset_sps;
+
+ mvc_dec_ctxt_t *ps_mvcd_ctxt = (mvc_dec_ctxt_t *) ps_dec_hdl->pv_codec_handle;
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_mvcd_ctxt->u2_num_views_decoded = 0;
+ ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
+ ps_mvcd_ctxt->u2_num_views =
+ (NULL == ps_subset_sps) ? 1 : ps_subset_sps->s_sps_mvc_ext.u2_num_views;
+ imvcd_convert_app_out_buf(ps_mvcd_ctxt, &ps_ip->s_ivd_ip.s_out_buffer);
+
+ ps_op->s_ivd_op.u4_num_bytes_consumed = 0;
+ ps_op->s_ivd_op.u4_output_present = 0;
+ ps_op->s_ivd_op.u4_error_code = 0;
+ ps_op->s_ivd_op.e_pic_type = IV_FRAMETYPE_DEFAULT;
+ ps_op->s_ivd_op.u4_frame_decoded_flag = 0;
+ ps_op->s_ivd_op.u4_new_seq = 0;
+ ps_op->s_ivd_op.u4_progressive_frame_flag = 1;
+ ps_op->s_ivd_op.u4_is_ref_flag = 1;
+ ps_op->s_ivd_op.e4_fld_type = IV_NA_FLD;
+
+ ps_view_ctxt->u4_fmt_conv_cur_row = 0;
+ ps_view_ctxt->u4_output_present = 0;
+ ps_view_ctxt->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
+ ps_view_ctxt->u4_ts = ps_ip->s_ivd_ip.u4_ts;
+ ps_view_ctxt->i4_frametype = IV_NA_FRAME;
+ ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
+
+ /* Mimicking the hack in lines '2005' in 'ih264d_api.c' and '1323' in
+ * 'ih264d_parse_headers.c */
+ ps_view_ctxt->u4_sps_cnt_in_process = 0;
+
+ memset(ps_mvcd_ctxt->as_nalu_mvc_ext, 0, sizeof(ps_mvcd_ctxt->as_nalu_mvc_ext));
+}
+
+void imvcd_view_init(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_view_ctxt->u4_num_fld_in_frm = 0;
+ ps_view_ctxt->u4_slice_start_code_found = 0;
+ ps_view_ctxt->u2_cur_mb_addr = 0;
+ ps_view_ctxt->u2_total_mbs_coded = 0;
+ ps_view_ctxt->u2_cur_slice_num = 0;
+ ps_view_ctxt->cur_dec_mb_num = 0;
+ ps_view_ctxt->cur_recon_mb_num = 0;
+ ps_view_ctxt->u4_first_slice_in_pic = 1;
+ ps_view_ctxt->u1_slice_header_done = 0;
+ ps_view_ctxt->u1_dangling_field = 0;
+ ps_view_ctxt->u4_dec_thread_created = 0;
+ ps_view_ctxt->u4_bs_deblk_thread_created = 0;
+ ps_view_ctxt->u4_cur_bs_mb_num = 0;
+ ps_view_ctxt->u4_start_recon_deblk = 0;
+ ps_view_ctxt->u4_pic_buf_got = 0;
+ ps_view_ctxt->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
+ ps_view_ctxt->u1_pic_decode_done = 0;
+
+ ps_view_ctxt->pu1_init_dpb_base = NULL;
+ ps_view_ctxt->ps_dpb_mgr = NULL;
+}
+
+IV_API_CALL_STATUS_T imvcd_bitstream_buf_alloc(dec_struct_t *ps_view_ctxt, UWORD16 u2_num_views)
+{
+ UWORD32 u4_size;
+
+ u4_size = MAX(MIN_BITSTREAMS_BUF_SIZE,
+ ((ps_view_ctxt->u2_pic_wd * ps_view_ctxt->u2_pic_ht * 3 / 2) + EXTRA_BS_OFFSET) *
+ u2_num_views * sizeof(ps_view_ctxt->pu1_bits_buf_dynamic[0]));
+ ps_view_ctxt->pu1_bits_buf_dynamic =
+ ps_view_ctxt->pf_aligned_alloc(ps_view_ctxt->pv_mem_ctxt, 128, u4_size);
+ RETURN_IF((NULL == ps_view_ctxt->pu1_bits_buf_dynamic), IV_FAIL);
+
+ memset(ps_view_ctxt->pu1_bits_buf_dynamic, 0, u4_size);
+ ps_view_ctxt->u4_dynamic_bits_buf_size = u4_size;
+
+ return IV_SUCCESS;
+}
+
+void imvcd_bitsteam_buf_free(dec_struct_t *ps_view_ctxt)
+{
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_bits_buf_dynamic);
+}
diff --git a/decoder/mvc/imvcd_api_utils.h b/decoder/mvc/imvcd_api_utils.h
new file mode 100644
index 0000000..0707f45
--- /dev/null
+++ b/decoder/mvc/imvcd_api_utils.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_api_utils.h */
+/* */
+/* Description : Utility functions used by 'imvcd_api.c' */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_API_UTILS_H_
+#define _IMVCD_API_UTILS_H_
+
+#include "iv.h"
+#include "ih264d_structs.h"
+#include "imvcd_structs.h"
+
+extern IV_API_CALL_STATUS_T imvcd_check_dec_handle(iv_obj_t *ps_handle);
+
+extern IV_API_CALL_STATUS_T imvcd_check_create_structs(imvcd_create_ip_t *ps_ip,
+ imvcd_create_op_t *ps_op);
+
+extern IV_API_CALL_STATUS_T imvcd_check_ctl_structs(void *pv_ip, void *pv_op);
+
+extern IV_API_CALL_STATUS_T imvcd_check_decode_structs(iv_obj_t *ps_dec_hdl,
+ imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op);
+
+extern void imvcd_au_init(iv_obj_t *ps_dec_hdl, imvcd_video_decode_ip_t *ps_ip,
+ imvcd_video_decode_op_t *ps_op);
+
+extern void imvcd_view_init(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern IV_API_CALL_STATUS_T imvcd_bitstream_buf_alloc(dec_struct_t *ps_view_ctxt,
+ UWORD16 u2_num_views);
+
+extern void imvcd_bitsteam_buf_free(dec_struct_t *ps_view_ctxt);
+
+extern void imvcd_convert_to_app_disp_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ iv_yuv_buf_t *ps_view_disp_bufs);
+#endif
diff --git a/decoder/mvc/imvcd_defs.h b/decoder/mvc/imvcd_defs.h
new file mode 100644
index 0000000..2bf5e54
--- /dev/null
+++ b/decoder/mvc/imvcd_defs.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _IMVCD_DEFS_H_
+#define _IMVCD_DEFS_H_
+
+#include <stdint.h>
+
+#include "ih264_typedefs.h"
+#include "imvc_defs.h"
+#include "ih264d_defs.h"
+
+#define MVC_MAX_REF_PICS MAX(16 * LOG2_MAX_NUM_VIEWS, 2 * H264_MAX_REF_PICS)
+
+/* Set to identify between actual ref pic with valid u1_pic_buf_id
+ and replicated IVP ref pic! Ensure that MAX_VAL_PIC_BUF_ID-MAX_NUM_VIEWS
+ is still greater than any possible value of u1_pic_buf_id */
+#define IVP_PIC_BUF_ID UINT8_MAX
+
+#define MIN_BITSTREAMS_BUF_SIZE 256000
+
+#endif
diff --git a/decoder/mvc/imvcd_dpb_manager.c b/decoder/mvc/imvcd_dpb_manager.c
new file mode 100644
index 0000000..b05a123
--- /dev/null
+++ b/decoder/mvc/imvcd_dpb_manager.c
@@ -0,0 +1,2203 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_nalu_parser.h */
+/* */
+/* Description : Functions for MVC NALU parsing */
+/* */
+/*****************************************************************************/
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "ih264d_error_handler.h"
+#include "imvcd_dpb_manager.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+void imvcd_dpb_set_display_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_num)
+{
+ ps_dpb_mgr->i4_cur_display_seq = i4_display_num;
+}
+
+void imvcd_dpb_set_max_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_pic_num)
+{
+ ps_dpb_mgr->i4_max_pic_num = i4_max_pic_num;
+}
+
+void imvcd_dpb_set_num_views(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_num_views)
+{
+ ps_dpb_mgr->u2_num_views = u2_num_views;
+}
+
+void imvcd_dpb_set_display_delay(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_delay)
+{
+ ps_dpb_mgr->i4_display_delay = i4_display_delay;
+}
+
+void imvcd_dpb_init_au_bufs(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_cur_au)
+{
+ WORD32 i;
+
+ for(i = 0; i < 2; i++)
+ {
+ ps_dpb_mgr->as_init_dpb[i][0] = ps_cur_au[0];
+ }
+}
+
+void imvcd_dpb_init_view_bufs(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_view_order_id,
+ UWORD16 u2_view_id)
+{
+ WORD32 i;
+
+ for(i = 0; i < 2; i++)
+ {
+ imvcd_convert_au_buf_to_view_buf(&ps_dpb_mgr->as_init_dpb[i][0],
+ &ps_dpb_mgr->as_view_init_dpb[i][0], u2_view_order_id,
+ u2_view_id);
+ }
+}
+
+void imvcd_dpb_init_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr, sps_mvc_ext_t *ps_sps_mvc_ext,
+ nalu_mvc_ext_t *ps_nalu_mvc_exts)
+{
+ ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = ps_nalu_mvc_exts;
+ ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = ps_sps_mvc_ext;
+
+ ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
+}
+
+void imvcd_dpb_reset_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ UWORD32 i;
+
+ for(i = 0; i < ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs; i++)
+ {
+ ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
+ ps_dpb_mgr->s_dpb_ivp_ctxt.au1_au_buf_ids[i],
+ BUF_MGR_REF | BUF_MGR_IO);
+
+ ih264_buf_mgr_release(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
+ ps_dpb_mgr->s_dpb_ivp_ctxt.au1_mv_buf_ids[i],
+ BUF_MGR_REF | BUF_MGR_IO);
+ }
+
+ ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
+}
+
+pic_buffer_t **imvcd_dpb_get_view_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ UWORD16 u2_view_order_id, UWORD16 u2_view_id,
+ UWORD8 u1_pred_dir)
+{
+ WORD32 i;
+
+ UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_dir] +
+ ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_dir];
+
+ for(i = 0; i < u1_num_ref_bufs; i++)
+ {
+ imvcd_convert_au_buf_to_view_buf(ps_dpb_mgr->aps_mod_dpb[u1_pred_dir][i],
+ &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i],
+ u2_view_order_id, u2_view_id);
+
+ ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir][i] =
+ &ps_dpb_mgr->as_view_init_dpb[u1_pred_dir][i];
+ }
+
+ return ps_dpb_mgr->aps_view_mod_dpb[u1_pred_dir];
+}
+
+void imvcd_init_dpb_mgr(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
+ disp_mgr_t *ps_disp_buf_mgr)
+{
+ WORD32 i, j, k, l;
+
+ mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
+
+ for(i = 0; i < 2; i++)
+ {
+ mvc_au_buffer_t *ps_init_dpb = ps_dpb_mgr->as_init_dpb[i];
+ pic_buffer_t *ps_view_init_dpb = ps_dpb_mgr->as_view_init_dpb[i];
+
+ for(j = 0; j < MVC_MAX_REF_PICS; j++)
+ {
+ for(k = 0; k < MAX_NUM_VIEWS; k++)
+ {
+ for(l = 0; l < NUM_COMPONENTS; l++)
+ {
+ ps_init_dpb->as_view_buffers[k].as_component_bufs[l].pv_data = NULL;
+ }
+ }
+
+ ps_view_init_dpb->pu1_buf1 = NULL;
+ ps_view_init_dpb->pu1_buf2 = NULL;
+ ps_view_init_dpb->pu1_buf3 = NULL;
+
+ ps_dpb_mgr->aps_mod_dpb[i][j] = ps_init_dpb;
+ ps_dpb_mgr->aps_view_mod_dpb[i][j] = ps_view_init_dpb;
+
+ ps_init_dpb++;
+ ps_view_init_dpb++;
+ }
+ }
+
+ for(i = 0; i < MVC_MAX_REF_PICS; i++)
+ {
+ ps_dpb_info[i].b_used_as_ref = false;
+ ps_dpb_info[i].ps_prev_short = NULL;
+ ps_dpb_info[i].ps_prev_long = NULL;
+ ps_dpb_info[i].ps_au_buf = NULL;
+ ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
+ ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
+ }
+
+ ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
+ ps_dpb_mgr->ps_dpb_st_head = NULL;
+ ps_dpb_mgr->ps_dpb_lt_head = NULL;
+ ps_dpb_mgr->i1_gaps_deleted = 0;
+ ps_dpb_mgr->i1_poc_buf_id_entries = 0;
+ ps_dpb_mgr->u1_mmco_error_in_seq = 0;
+ ps_dpb_mgr->u1_num_gaps = 0;
+ ps_dpb_mgr->i4_display_delay = 0;
+ ps_dpb_mgr->i4_cur_display_seq = 0;
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
+ ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
+ ps_dpb_mgr->as_display_buf_info[i].i4_poc_buf_id = -1;
+ ps_dpb_mgr->as_display_buf_info[i].i4_poc = INT32_MAX;
+ ps_dpb_mgr->as_display_buf_info[i].i4_frame_num = 0;
+ }
+
+ ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
+ ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts = NULL;
+ ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext = NULL;
+
+ ps_dpb_mgr->ps_mvc_au_buf_mgr = ps_mvc_au_buf_mgr;
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr = ps_mvc_au_mv_pred_buf_mgr;
+ ps_dpb_mgr->ps_disp_buf_mgr = ps_disp_buf_mgr;
+}
+
+WORD32 imvcd_dpb_assign_display_seq(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ WORD32 i;
+
+ display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
+
+ WORD32 i4_min_poc = INT32_MAX;
+ WORD32 i4_min_poc_buf_id = -1;
+ WORD32 i4_min_index = -1;
+
+ if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dpb_mgr->i4_display_delay)
+ {
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ if((-1 != ps_display_buf_info[i].i4_poc_buf_id) &&
+ (DO_NOT_DISP != ps_display_buf_info[i].i4_poc_buf_id))
+ {
+ /* Checking for <= is necessary to handle cases where there is one
+ valid buffer with poc set to 0x7FFFFFFF. */
+ if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
+ {
+ i4_min_poc = ps_display_buf_info[i].i4_poc;
+ i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
+ i4_min_index = i;
+ }
+ }
+ }
+
+ if((i4_min_index != -1) && (DO_NOT_DISP != i4_min_poc_buf_id))
+ {
+ ps_dpb_mgr->i4_cur_display_seq++;
+
+ ih264_disp_mgr_add(
+ ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
+ ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);
+
+ ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
+ ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
+
+ ps_dpb_mgr->i1_poc_buf_id_entries--;
+ }
+ else if(DO_NOT_DISP == i4_min_poc_buf_id)
+ {
+ return ERROR_GAPS_IN_FRM_NUM;
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_insert_pic_in_display_list(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_poc,
+ UWORD32 u4_frame_num, WORD32 i4_buf_id)
+{
+ WORD32 i;
+
+ display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ /* Find an empty slot */
+ if(ps_display_buf_info[i].i4_poc_buf_id == -1)
+ {
+ if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
+ {
+ ps_dpb_mgr->i1_gaps_deleted--;
+ }
+ else
+ {
+ ps_dpb_mgr->i1_poc_buf_id_entries++;
+ }
+
+ ps_display_buf_info[i].i4_poc_buf_id = i4_buf_id;
+ ps_display_buf_info[i].i4_poc = i4_display_poc;
+ ps_display_buf_info[i].i4_frame_num = u4_frame_num;
+
+ break;
+ }
+ }
+
+ if(MAX_FRAMES == i)
+ {
+ return ERROR_GAPS_IN_FRM_NUM;
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_dpb_delete_gap_frm_sliding(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
+ UWORD8 *pu1_del_node)
+{
+ WORD32 i, j, j_min;
+ WORD8 i1_gap_idx;
+ WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num;
+ WORD32 i4_start_frm_num, i4_end_frm_num;
+ WORD32 i4_max_pic_num;
+ WORD32 i4_frm_num, i4_gap_frm_num_min;
+
+ /* find the least frame num from gaps and current DPB node */
+ /* Delete the least one */
+ *pu1_del_node = 1;
+
+ if(0 == ps_dpb_mgr->u1_num_gaps)
+ {
+ return OK;
+ }
+
+ pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
+ pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num;
+ i4_gap_frame_num = INVALID_FRAME_NUM;
+ i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
+
+ i1_gap_idx = -1;
+
+ if(INVALID_FRAME_NUM != i4_pic_num)
+ {
+ i4_gap_frame_num = i4_pic_num;
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ i4_start_frm_num = pi4_gaps_start_frm_num[i];
+
+ if(INVALID_FRAME_NUM != i4_start_frm_num)
+ {
+ i4_end_frm_num = pi4_gaps_end_frm_num[i];
+
+ if(i4_end_frm_num < i4_max_pic_num)
+ {
+ if(i4_start_frm_num <= i4_gap_frame_num)
+ {
+ i4_gap_frame_num = i4_start_frm_num;
+ i1_gap_idx = i;
+ }
+ }
+ else
+ {
+ if(((i4_start_frm_num <= i4_gap_frame_num) &&
+ (i4_gap_frame_num <= i4_max_pic_num)) ||
+ ((i4_start_frm_num >= i4_gap_frame_num) &&
+ ((i4_gap_frame_num + i4_max_pic_num) >= i4_end_frm_num)))
+ {
+ i4_gap_frame_num = i4_start_frm_num;
+ i1_gap_idx = i;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* no valid short term buffers, delete one gap from the least start */
+ /* of gap sequence */
+ i4_gap_frame_num = pi4_gaps_start_frm_num[0];
+ i1_gap_idx = 0;
+
+ for(i = 1; i < MAX_FRAMES; i++)
+ {
+ if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i])
+ {
+ if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num)
+ {
+ i4_gap_frame_num = pi4_gaps_start_frm_num[i];
+ i1_gap_idx = i;
+ }
+ }
+ }
+ if(INVALID_FRAME_NUM == i4_gap_frame_num)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ }
+
+ if(-1 != i1_gap_idx)
+ {
+ /* find least frame_num in the poc_map, which is in this range */
+ i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx];
+
+ if(i4_start_frm_num < 0)
+ {
+ i4_start_frm_num += i4_max_pic_num;
+ }
+
+ i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx];
+
+ if(i4_end_frm_num < 0)
+ {
+ i4_end_frm_num += i4_max_pic_num;
+ }
+
+ i4_gap_frm_num_min = INT32_MIN;
+ j_min = MAX_FRAMES;
+
+ for(j = 0; j < MAX_FRAMES; j++)
+ {
+ i4_frm_num = ps_dpb_mgr->as_display_buf_info[j].i4_frame_num;
+
+ if((i4_start_frm_num <= i4_frm_num) && (i4_end_frm_num >= i4_frm_num))
+ {
+ if(i4_frm_num < i4_gap_frm_num_min)
+ {
+ j_min = j;
+ i4_gap_frm_num_min = i4_frm_num;
+ }
+ }
+ }
+
+ if(j_min != MAX_FRAMES)
+ {
+ ps_dpb_mgr->as_display_buf_info[j_min].i4_poc_buf_id = -1;
+ ps_dpb_mgr->as_display_buf_info[j_min].i4_poc = 0x7fffffff;
+ ps_dpb_mgr->as_display_buf_info[j_min].i4_frame_num = GAP_FRAME_NUM;
+
+ ps_dpb_mgr->i1_gaps_deleted++;
+ ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--;
+ ps_dpb_mgr->u1_num_gaps--;
+ *pu1_del_node = 0;
+
+ if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx])
+ {
+ ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = INVALID_FRAME_NUM;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0;
+ }
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_do_mmco_for_gaps(mvc_dpb_manager_t *ps_dpb_mgr, UWORD8 u1_num_ref_frames)
+{
+ mvc_dpb_info_t *ps_next_dpb;
+
+ WORD32 i;
+ WORD32 i4_error_code;
+ UWORD8 u1_num_gaps;
+ UWORD8 u1_num_st_ref_bufs, u1_num_lt_ref_bufs, u1_del_node;
+
+ WORD32 i4_frame_gaps = 1;
+
+ // Sliding window - implements 8.2.5.3, flush out buffers
+ u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs;
+ u1_num_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs;
+
+ while(1)
+ {
+ u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
+
+ if((u1_num_st_ref_bufs + u1_num_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) >
+ u1_num_ref_frames)
+ {
+ if(0 == (u1_num_st_ref_bufs + u1_num_gaps))
+ {
+ i4_frame_gaps = 0;
+
+ ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames - u1_num_lt_ref_bufs);
+ }
+ else
+ {
+ u1_del_node = 1;
+ ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+
+ if(u1_num_st_ref_bufs > 1)
+ {
+ for(i = 1; i < (u1_num_st_ref_bufs - 1); i++)
+ {
+ if(ps_next_dpb == NULL)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+
+ if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(u1_num_gaps)
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
+ ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
+ &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ if(u1_del_node)
+ {
+ u1_num_st_ref_bufs--;
+ ps_next_dpb->ps_prev_short->b_used_as_ref = false;
+ ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
+ ps_next_dpb->ps_prev_short = NULL;
+ }
+ }
+ else
+ {
+ if(u1_num_st_ref_bufs)
+ {
+ if(u1_num_gaps)
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
+ ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ if(u1_del_node)
+ {
+ u1_num_st_ref_bufs--;
+ ps_next_dpb->b_used_as_ref = false;
+ ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_next_dpb->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_au_buf = NULL;
+ ps_next_dpb = NULL;
+ ps_dpb_mgr->ps_dpb_st_head = NULL;
+ ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;
+ }
+ }
+ else
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
+ ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ if(u1_del_node)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ps_dpb_mgr->u1_num_gaps += i4_frame_gaps;
+
+ break;
+ }
+ }
+
+ ps_dpb_mgr->u1_num_st_ref_bufs = u1_num_st_ref_bufs;
+
+ return OK;
+}
+
+void imvcd_dpb_delete_nonref_nondisplay_pics(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ WORD32 i;
+
+ display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
+
+ /* remove all gaps marked as unused for ref */
+ for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++)
+ {
+ if(GAP_FRAME_NUM == ps_display_buf_info[i].i4_frame_num)
+ {
+ ps_dpb_mgr->i1_gaps_deleted--;
+ ps_dpb_mgr->i1_poc_buf_id_entries--;
+ ps_display_buf_info[i].i4_poc_buf_id = -1;
+ ps_display_buf_info[i].i4_poc = 0x7fffffff;
+ ps_display_buf_info[i].i4_frame_num = 0;
+ }
+ }
+}
+
+void imvcd_reset_dpb(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ WORD32 i;
+
+ mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
+
+ for(i = 0; i < MVC_MAX_REF_PICS; i++)
+ {
+ if(ps_dpb_info[i].b_used_as_ref)
+ {
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_dpb_info[i].ps_au_buf->i4_pic_buf_id);
+
+ ps_dpb_info[i].b_used_as_ref = false;
+ ps_dpb_info[i].ps_prev_short = NULL;
+ ps_dpb_info[i].ps_prev_long = NULL;
+ ps_dpb_info[i].ps_au_buf = NULL;
+ ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
+ ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MVC_MAX_REF_PICS + 1;
+ }
+ }
+
+ ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
+ ps_dpb_mgr->ps_dpb_st_head = NULL;
+ ps_dpb_mgr->ps_dpb_lt_head = NULL;
+ ps_dpb_mgr->u1_mmco_error_in_seq = 0;
+
+ /* release all gaps */
+ ps_dpb_mgr->u1_num_gaps = 0;
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
+ ps_dpb_mgr->ai1_gaps_per_seq[i] = 0;
+ }
+}
+
+void imvcd_dpb_release_display_bufs(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ WORD32 i, j;
+
+ display_buf_info_t *ps_display_buf_info = ps_dpb_mgr->as_display_buf_info;
+
+ WORD32 i4_min_poc = 0x7fffffff;
+ WORD32 i4_min_poc_buf_id = 0;
+ WORD32 i4_min_index = 0;
+
+ imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+
+ for(j = 0; j < ps_dpb_mgr->i1_poc_buf_id_entries; j++)
+ {
+ i4_min_poc = 0x7fffffff;
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ if(ps_display_buf_info[i].i4_poc_buf_id != -1)
+ {
+ /* Checking for <= is necessary to handle cases where there is one
+ valid buffer with poc set to 0x7FFFFFFF. */
+ if(ps_display_buf_info[i].i4_poc <= i4_min_poc)
+ {
+ i4_min_poc = ps_display_buf_info[i].i4_poc;
+ i4_min_poc_buf_id = ps_display_buf_info[i].i4_poc_buf_id;
+ i4_min_index = i;
+ }
+ }
+ }
+
+ if(DO_NOT_DISP != i4_min_poc_buf_id)
+ {
+ ps_dpb_mgr->i4_cur_display_seq++;
+
+ ih264_disp_mgr_add(
+ ps_dpb_mgr->ps_disp_buf_mgr, i4_min_poc_buf_id, ps_dpb_mgr->i4_cur_display_seq,
+ ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_min_poc_buf_id]);
+
+ ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
+ ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
+ ps_display_buf_info[i4_min_index].i4_frame_num = 0;
+ }
+ else
+ {
+ ps_display_buf_info[i4_min_index].i4_poc_buf_id = -1;
+ ps_display_buf_info[i4_min_index].i4_poc = 0x7fffffff;
+ ps_display_buf_info[i4_min_index].i4_frame_num = 0;
+ }
+ }
+
+ ps_dpb_mgr->i1_poc_buf_id_entries = 0;
+}
+
+void imvcd_assign_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_frame_num,
+ WORD32 i4_cur_frame_num, bool b_are_gaps_in_frame_num_value_allowed)
+{
+ mvc_dpb_info_t *ps_next_dpb;
+
+ WORD32 i;
+ WORD32 i4_ref_frame_num;
+
+ /* Start from ST head */
+ ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ WORD32 i4_pic_num;
+
+ i4_ref_frame_num = ps_next_dpb->ps_au_buf->i4_pic_num;
+
+ if(i4_ref_frame_num > i4_cur_frame_num)
+ {
+ i4_pic_num = i4_ref_frame_num - i4_max_frame_num;
+ }
+ else
+ {
+ i4_pic_num = i4_ref_frame_num;
+ }
+
+ ps_next_dpb->ps_au_buf->i4_pic_num = i4_pic_num;
+
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+
+ if(b_are_gaps_in_frame_num_value_allowed && ps_dpb_mgr->u1_num_gaps)
+ {
+ WORD32 i4_start_frm, i4_end_frm;
+
+ /* Assign pic numbers for gaps */
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ i4_start_frm = ps_dpb_mgr->ai4_gaps_start_frm_num[i];
+
+ if(i4_start_frm != INVALID_FRAME_NUM)
+ {
+ if(i4_start_frm > i4_cur_frame_num)
+ {
+ /* gap's frame_num is before Current frame_num in
+ decode order */
+ i4_start_frm -= i4_max_frame_num;
+ }
+
+ ps_dpb_mgr->ai4_gaps_start_frm_num[i] = i4_start_frm;
+ i4_end_frm = ps_dpb_mgr->ai4_gaps_end_frm_num[i];
+
+ if(i4_end_frm > i4_cur_frame_num)
+ {
+ /* gap's frame_num is before Current frame_num in
+ decode order */
+ i4_end_frm -= i4_max_frame_num;
+ }
+
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i] = i4_end_frm;
+ }
+ }
+ }
+}
+
+/* If there is common node in both lt_list and st_list, then delete it from */
+/* st_list */
+UWORD8 imvcd_dpb_st_lt_deduplicator(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ mvc_dpb_info_t *ps_dpb_lt_head = ps_dpb_mgr->ps_dpb_lt_head;
+ mvc_dpb_info_t *ps_lt_curr_dpb = ps_dpb_mgr->ps_dpb_lt_head;
+ mvc_dpb_info_t *ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head;
+
+ UWORD8 u1_no_of_nodes_deleted = 0;
+ UWORD8 u1_num_lt_refs = ps_dpb_mgr->u1_num_lt_ref_bufs;
+ UWORD8 u1_num_st_refs = ps_dpb_mgr->u1_num_st_ref_bufs;
+
+ while(u1_num_lt_refs && ps_dpb_lt_head)
+ {
+ if(ps_dpb_st_head &&
+ ((ps_dpb_lt_head->s_bot_field.u1_reference_info |
+ ps_dpb_lt_head->s_top_field.u1_reference_info) == (IS_SHORT_TERM | IS_LONG_TERM)))
+ {
+ mvc_dpb_info_t *ps_st_next_dpb = ps_dpb_st_head;
+ mvc_dpb_info_t *ps_st_curr_dpb = ps_dpb_st_head;
+
+ while(u1_num_st_refs && ps_st_curr_dpb)
+ {
+ if(ps_st_curr_dpb == ps_lt_curr_dpb)
+ {
+ if(u1_num_st_refs == ps_dpb_mgr->u1_num_st_ref_bufs)
+ {
+ ps_dpb_mgr->ps_dpb_st_head = ps_dpb_mgr->ps_dpb_st_head->ps_prev_short;
+ ps_st_curr_dpb = ps_dpb_mgr->ps_dpb_st_head;
+ }
+ else
+ {
+ ps_st_next_dpb->ps_prev_short = ps_st_curr_dpb->ps_prev_short;
+ }
+
+ ps_dpb_mgr->u1_num_st_ref_bufs--;
+ u1_no_of_nodes_deleted++;
+
+ break;
+ }
+
+ ps_st_next_dpb = ps_st_curr_dpb;
+ ps_st_curr_dpb = ps_st_curr_dpb->ps_prev_short;
+ u1_num_st_refs--;
+ }
+ }
+
+ ps_lt_curr_dpb = ps_lt_curr_dpb->ps_prev_long;
+ u1_num_lt_refs--;
+ }
+
+ return u1_no_of_nodes_deleted;
+}
+
+static int qsort_pic_num_compare(const void *pv_au1, const void *pv_au2)
+{
+ return ((mvc_au_buffer_t **) pv_au1)[0]->i4_pic_num -
+ ((mvc_au_buffer_t **) pv_au2)[0]->i4_pic_num;
+}
+
+static int qsort_poc_compare(const void *pv_au1, const void *pv_au2)
+{
+ return ((mvc_au_buffer_t **) pv_au1)[0]->i4_poc - ((mvc_au_buffer_t **) pv_au2)[0]->i4_poc;
+}
+
+static int qsort_lt_idx_compare(const void *pv_au1, const void *pv_au2)
+{
+ return ((mvc_au_buffer_t **) pv_au1)[0]->u1_long_term_frm_idx -
+ ((mvc_au_buffer_t **) pv_au2)[0]->u1_long_term_frm_idx;
+}
+
+WORD32 imvcd_init_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
+ mvc_au_buffer_t *ps_cur_au, UWORD16 u2_view_order_id)
+{
+ mvc_dpb_info_t *ps_ref_au_data;
+ mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;
+
+ WORD32 i, j;
+
+ mvc_au_buffer_t *aps_st_au_bufs[MVC_MAX_REF_PICS] = {NULL};
+ mvc_au_buffer_t *aps_lt_au_bufs[MVC_MAX_REF_PICS] = {NULL};
+ mvc_au_buffer_t *aps_ref_pic_buf_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
+ ps_dpb_mgr->as_init_dpb[1]};
+ sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;
+
+ UWORD16 u2_view_id = ps_cur_nalu_mvc_ext->u2_view_id;
+ WORD32 i4_cur_poc = ps_cur_au->i4_poc;
+ bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
+ UWORD8 *pu1_num_short_term_refs = ps_dpb_mgr->au1_num_active_st_refs;
+ UWORD8 *pu1_num_long_term_refs = ps_dpb_mgr->au1_num_active_lt_refs;
+ UWORD8 au1_total_num_refs[2] = {0};
+
+ memset(pu1_num_short_term_refs, 0, 2 * sizeof(pu1_num_short_term_refs[0]));
+
+ memset(pu1_num_long_term_refs, 0, 2 * sizeof(pu1_num_long_term_refs[0]));
+
+ ps_ref_au_data = ps_dpb_mgr->ps_dpb_st_head;
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ aps_st_au_bufs[i] = ps_ref_au_data->ps_au_buf;
+ ps_ref_au_data = ps_ref_au_data->ps_prev_short;
+ }
+
+ qsort(aps_st_au_bufs, ps_dpb_mgr->u1_num_st_ref_bufs, sizeof(aps_st_au_bufs[0]),
+ b_is_b_pic ? qsort_poc_compare : qsort_pic_num_compare);
+
+ ps_ref_au_data = ps_dpb_mgr->ps_dpb_lt_head;
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ aps_lt_au_bufs[i] = ps_ref_au_data->ps_au_buf;
+ ps_ref_au_data = ps_ref_au_data->ps_prev_long;
+ }
+
+ qsort(aps_lt_au_bufs, ps_dpb_mgr->u1_num_lt_ref_bufs, sizeof(aps_lt_au_bufs[0]),
+ qsort_lt_idx_compare);
+
+ if(b_is_b_pic)
+ {
+ for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ if(aps_st_au_bufs[i]->i4_poc >= i4_cur_poc)
+ {
+ break;
+ }
+ }
+
+ for(j = i - 1; j >= 0; j--)
+ {
+ aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[j][0];
+ aps_ref_pic_buf_lx[0]++;
+ pu1_num_short_term_refs[0]++;
+ }
+
+ for(j = i; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
+ {
+ aps_ref_pic_buf_lx[1][0] = aps_st_au_bufs[j][0];
+ aps_ref_pic_buf_lx[1]++;
+ pu1_num_short_term_refs[1]++;
+ }
+ }
+ else
+ {
+ for(i = ps_dpb_mgr->u1_num_st_ref_bufs - 1; i >= 0; i--)
+ {
+ aps_ref_pic_buf_lx[0][0] = aps_st_au_bufs[i][0];
+ aps_ref_pic_buf_lx[0]++;
+ pu1_num_short_term_refs[0]++;
+ }
+ }
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ for(j = 0; j < 1 + ((WORD32) b_is_b_pic); j++)
+ {
+ aps_ref_pic_buf_lx[j][0] = aps_lt_au_bufs[i][0];
+ aps_ref_pic_buf_lx[j]->u1_long_term_pic_num =
+ aps_ref_pic_buf_lx[j]->u1_long_term_frm_idx;
+ aps_ref_pic_buf_lx[j]++;
+ pu1_num_long_term_refs[j]++;
+ }
+ }
+
+ if(0 != u2_view_order_id)
+ {
+ ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs = 0;
+
+ for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
+ {
+ WORD32 i4_num_refs;
+
+ if(ps_cur_nalu_mvc_ext->u1_anchor_pic_flag)
+ {
+ ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id];
+ }
+ else
+ {
+ ps_mvc_ivp_ref_data = &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id];
+ }
+
+ i4_num_refs = ps_mvc_ivp_ref_data->u1_num_refs;
+
+ for(j = 0; j < i4_num_refs; j++)
+ {
+ mvc_au_buffer_t *ps_au_buf;
+ mvc_au_mv_pred_t *ps_au_mv_data;
+ nalu_mvc_ext_t *ps_ref_nalu_mvc_ext;
+
+ WORD32 i4_pic_buf_id;
+ WORD32 i4_mv_buf_id;
+
+ UWORD16 u2_ref_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[j];
+
+ ps_ref_nalu_mvc_ext = imvcd_get_nalu_mvc_ext(
+ ps_dpb_mgr->s_dpb_ivp_ctxt.ps_nalu_mvc_exts, u2_view_order_id, u2_ref_view_id);
+
+ if(!ps_ref_nalu_mvc_ext->u1_inter_view_flag)
+ {
+ continue;
+ }
+
+ ps_au_buf = ih264_buf_mgr_get_next_free(
+ ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt, &i4_pic_buf_id);
+
+ if(NULL == ps_au_buf)
+ {
+ return ERROR_UNAVAIL_PICBUF_T;
+ }
+ else
+ {
+ ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt,
+ i4_pic_buf_id, BUF_MGR_REF);
+ }
+
+ ps_au_mv_data = ih264_buf_mgr_get_next_free(
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt, &i4_mv_buf_id);
+
+ if(NULL == ps_au_mv_data)
+ {
+ return ERROR_UNAVAIL_PICBUF_T;
+ }
+ else
+ {
+ ih264_buf_mgr_set_status(ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
+ i4_mv_buf_id, BUF_MGR_REF);
+ }
+
+ ps_au_buf->i4_pic_buf_id = i4_pic_buf_id;
+ ps_au_buf->i4_mv_buf_id = i4_mv_buf_id;
+ ps_au_buf->s_ivp_data.b_is_ivp_ref = true;
+ ps_au_buf->s_ivp_data.u2_ref_view_id = u2_ref_view_id;
+
+ imvcd_ivp_buf_copier(ps_cur_au, ps_au_buf, ps_cur_au->ps_au_mv_data, ps_au_mv_data,
+ u2_ref_view_id, u2_view_id);
+
+ ps_dpb_mgr->ps_mvc_au_buf_mgr->au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id] =
+ i4_mv_buf_id;
+ ps_dpb_mgr->ps_mvc_au_buf_mgr->aps_buf_id_to_au_buf_map[i4_pic_buf_id] = ps_au_buf;
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr->aps_buf_id_to_mv_pred_buf_map[i4_mv_buf_id] =
+ ps_au_mv_data;
+
+ ps_dpb_mgr->s_dpb_ivp_ctxt
+ .au1_au_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_pic_buf_id;
+ ps_dpb_mgr->s_dpb_ivp_ctxt
+ .au1_mv_buf_ids[ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs] = i4_mv_buf_id;
+
+ aps_ref_pic_buf_lx[i][0] = ps_au_buf[0];
+
+ aps_ref_pic_buf_lx[i]++;
+ pu1_num_short_term_refs[i]++;
+ ps_dpb_mgr->s_dpb_ivp_ctxt.u4_num_ivp_refs++;
+ }
+ }
+ }
+
+ for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
+ {
+ au1_total_num_refs[i] = pu1_num_short_term_refs[i] + pu1_num_long_term_refs[i];
+
+ if(pu1_num_short_term_refs[i] > MVC_MAX_REF_PICS)
+ {
+ return ERROR_NUM_REF;
+ }
+
+ if(au1_total_num_refs[i] > MVC_MAX_REF_PICS)
+ {
+ return ERROR_NUM_REF;
+ }
+
+ if(0 == au1_total_num_refs[i])
+ {
+ return ERROR_NUM_REF;
+ }
+ }
+
+ /* If list0 and list1 entries are same then swap the 0th and 1st entry */
+ /* of list 1 */
+ {
+ mvc_au_buffer_t *aps_ref_pic_bufs_lx[2] = {ps_dpb_mgr->as_init_dpb[0],
+ ps_dpb_mgr->as_init_dpb[1]};
+
+ if((au1_total_num_refs[0] == au1_total_num_refs[1]) && (au1_total_num_refs[0] > 1))
+ {
+ bool b_swap;
+
+ b_swap = true;
+
+ for(i = 0; i < au1_total_num_refs[0]; i++)
+ {
+ if(aps_ref_pic_bufs_lx[0][i]
+ .as_view_buffers[u2_view_id]
+ .as_component_bufs[Y]
+ .pv_data != aps_ref_pic_bufs_lx[1][i]
+ .as_view_buffers[u2_view_id]
+ .as_component_bufs[Y]
+ .pv_data)
+ {
+ b_swap = false;
+
+ break;
+ }
+ }
+
+ if(b_swap)
+ {
+ SWAP(aps_ref_pic_bufs_lx[1][0], aps_ref_pic_bufs_lx[1][1], mvc_au_buffer_t);
+ }
+ }
+ }
+
+ return OK;
+}
+
+void imvcd_dpb_set_missing_refs_to_default(mvc_dpb_manager_t *ps_dpb_mgr,
+ ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
+ mvc_au_buffer_t *ps_cur_au, UWORD8 u1_pred_lx)
+{
+ UWORD8 u1_num_refs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
+ ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];
+
+ while(u1_num_refs < ps_ref_pic_list_mod_data->au1_num_active_refs[u1_pred_lx])
+ {
+ ps_dpb_mgr->as_init_dpb[u1_pred_lx][u1_num_refs] = ps_cur_au[0];
+ ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx]++;
+ u1_num_refs++;
+ }
+}
+
+void imvcd_dpb_normalise_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_buf_mod_bitfield,
+ UWORD8 u1_num_bufs_modified, UWORD8 u1_pred_lx)
+{
+ WORD32 i;
+
+ UWORD8 u1_num_ref_bufs = ps_dpb_mgr->au1_num_active_st_refs[u1_pred_lx] +
+ ps_dpb_mgr->au1_num_active_lt_refs[u1_pred_lx];
+
+ for(i = 0; i < u1_num_ref_bufs; i++)
+ {
+ if(!(u2_buf_mod_bitfield & (1 << i)))
+ {
+ ps_dpb_mgr->aps_mod_dpb[u1_pred_lx][u1_num_bufs_modified++] =
+ &ps_dpb_mgr->as_init_dpb[u1_pred_lx][i];
+ }
+ }
+}
+
+WORD32 imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
+ mvc_au_buffer_t *ps_cur_au,
+ ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
+ UWORD16 u2_view_order_id)
+{
+ WORD32 i, j;
+
+ sps_mvc_ext_t *ps_sps_mvc_ext = ps_dpb_mgr->s_dpb_ivp_ctxt.ps_sps_mvc_ext;
+
+ UWORD8 u1_anchor_pic_flag = ps_cur_nalu_mvc_ext->u1_anchor_pic_flag;
+ WORD32 i4_cur_pic_num = ps_cur_au->i4_pic_num;
+ WORD32 i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
+ bool b_is_b_pic = !!(ps_cur_au->au4_pack_slc_typ[u2_view_order_id] & B_SLC_BIT);
+
+ for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
+ {
+ mvc_ivp_ref_data_t *ps_mvc_ivp_ref_data;
+
+ UWORD16 u2_max_view_idx;
+
+ WORD32 i4_pred_pic_num = i4_cur_pic_num;
+ WORD16 i2_pred_view_order_id = 0; // -1; Need to check spec and JMVM implementation match
+ UWORD8 *pu1_modification_of_pic_nums_idc =
+ ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i];
+ WORD32 *pi4_abs_diff_pic_num_minus1 =
+ ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i];
+ WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i];
+ WORD32 *pi4_abs_diff_view_idx_minus1 =
+ ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i];
+ UWORD8 u1_num_ref_bufs =
+ ps_dpb_mgr->au1_num_active_st_refs[i] + ps_dpb_mgr->au1_num_active_lt_refs[i];
+ UWORD16 u2_buf_mod_bitfield = 0;
+ UWORD8 u1_num_bufs_modified = 0;
+
+ if(!ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i] ||
+ (3 == pu1_modification_of_pic_nums_idc[0]))
+ {
+ imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au,
+ i);
+
+ imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified,
+ i);
+
+ continue;
+ }
+
+ ps_mvc_ivp_ref_data =
+ (0 == u2_view_order_id)
+ ? NULL
+ : (u1_anchor_pic_flag
+ ? &ps_sps_mvc_ext->as_anchor_ref_data[i][u2_view_order_id]
+ : &ps_sps_mvc_ext->as_non_anchor_ref_data[i][u2_view_order_id]);
+ u2_max_view_idx = (0 == u2_view_order_id) ? 0 : ps_mvc_ivp_ref_data->u1_num_refs;
+
+ do
+ {
+ if((0 == pu1_modification_of_pic_nums_idc[0]) ||
+ (1 == pu1_modification_of_pic_nums_idc[0]))
+ {
+ WORD32 i4_mod_pic_num = pi4_abs_diff_pic_num_minus1[0];
+
+ UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
+
+ /* According to section 7.4.3.1 from spec, */
+ /* this value is expected to be from the */
+ /* closed interval [0, i4_max_pic_num - 1] */
+ if((i4_mod_pic_num < 0) || (i4_mod_pic_num >= i4_max_pic_num))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ /* +1 not accounted during initialisation, */
+ /* mainly to preclude integer overflow */
+ i4_mod_pic_num++;
+
+ if(0 == pu1_modification_of_pic_nums_idc[0])
+ {
+ i4_mod_pic_num = i4_pred_pic_num - i4_mod_pic_num;
+
+ if(i4_mod_pic_num < 0)
+ {
+ i4_mod_pic_num += i4_max_pic_num;
+ }
+ }
+ else
+ {
+ i4_mod_pic_num = i4_pred_pic_num + i4_mod_pic_num;
+
+ if(i4_mod_pic_num >= i4_max_pic_num)
+ {
+ i4_mod_pic_num -= i4_max_pic_num;
+ }
+ }
+
+ if(i4_mod_pic_num > i4_cur_pic_num)
+ {
+ i4_mod_pic_num -= i4_max_pic_num;
+ }
+
+ for(j = 0; j < u1_num_ref_bufs; j++)
+ {
+ if(ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_mod_pic_num)
+ {
+ u1_mod_buf_idx = j;
+
+ break;
+ }
+ }
+
+ if(u1_mod_buf_idx == u1_num_ref_bufs)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
+ &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
+
+ u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
+ i4_pred_pic_num = i4_mod_pic_num;
+ }
+ else if(2 == pu1_modification_of_pic_nums_idc[0])
+ {
+ WORD32 i4_mod_lt_pic_num = pi4_long_term_pic_num[0];
+ UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
+
+ if(pi4_long_term_pic_num[0] > (MAX_REF_BUFS + 1))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ for(j = 0; j < u1_num_ref_bufs; j++)
+ {
+ if(!ps_dpb_mgr->as_init_dpb[i][j].b_is_short_term_ref &&
+ (i4_mod_lt_pic_num == ps_dpb_mgr->as_init_dpb[i][j].u1_long_term_pic_num))
+ {
+ u1_mod_buf_idx = j;
+
+ break;
+ }
+ }
+
+ if(u1_mod_buf_idx == u1_num_ref_bufs)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
+ &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
+
+ u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
+ }
+ else if((4 == pu1_modification_of_pic_nums_idc[0]) ||
+ (5 == pu1_modification_of_pic_nums_idc[0]))
+ {
+ WORD32 i4_target_view_id;
+
+ WORD32 i4_mod_view_order_id = pi4_abs_diff_view_idx_minus1[0];
+ UWORD8 u1_mod_buf_idx = u1_num_ref_bufs;
+
+ /* According to section H.7.4.3.1.1 from spec, */
+ /* this value is expected to be from the */
+ /* closed interval [0, u2_max_view_idx - 1] */
+ if((i4_mod_view_order_id < 0) || (i4_mod_view_order_id >= u2_max_view_idx))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ /* +1 not accounted during initialisation, */
+ /* mainly to preclude integer overflow */
+ i4_mod_view_order_id++;
+
+ if(4 == pu1_modification_of_pic_nums_idc[0])
+ {
+ i4_mod_view_order_id = i2_pred_view_order_id - i4_mod_view_order_id;
+
+ if(i4_mod_view_order_id < 0)
+ {
+ i4_mod_view_order_id += u2_max_view_idx;
+ }
+ }
+ else
+ {
+ i4_mod_view_order_id = i2_pred_view_order_id + i4_mod_view_order_id;
+
+ if(i4_mod_view_order_id >= u2_max_view_idx)
+ {
+ i4_mod_view_order_id -= u2_max_view_idx;
+ }
+ }
+
+ if((0 == u2_view_order_id) || (NULL == ps_mvc_ivp_ref_data))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ i4_target_view_id = ps_mvc_ivp_ref_data->au2_ref_view_ids[i4_mod_view_order_id];
+
+ for(j = 0; j < u1_num_ref_bufs; j++)
+ {
+ if(ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.b_is_ivp_ref)
+ {
+ if((ps_dpb_mgr->as_init_dpb[i][j].i4_pic_num == i4_cur_pic_num) &&
+ (ps_dpb_mgr->as_init_dpb[i][j].s_ivp_data.u2_ref_view_id ==
+ i4_target_view_id))
+ {
+ u1_mod_buf_idx = j;
+
+ break;
+ }
+ }
+ }
+
+ if(u1_mod_buf_idx == u1_num_ref_bufs)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ u2_buf_mod_bitfield |= (1 << u1_mod_buf_idx);
+ ps_dpb_mgr->aps_mod_dpb[i][u1_num_bufs_modified++] =
+ &ps_dpb_mgr->as_init_dpb[i][u1_mod_buf_idx];
+ i2_pred_view_order_id = i4_mod_view_order_id;
+ }
+ else if(3 != pu1_modification_of_pic_nums_idc[0])
+ {
+ return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ {
+ break;
+ }
+
+ pu1_modification_of_pic_nums_idc++;
+ pi4_abs_diff_pic_num_minus1++;
+ pi4_long_term_pic_num++;
+ pi4_abs_diff_view_idx_minus1++;
+ } while(true);
+
+ imvcd_dpb_set_missing_refs_to_default(ps_dpb_mgr, ps_ref_pic_list_mod_data, ps_cur_au, i);
+
+ imvcd_dpb_normalise_ref_pic_list(ps_dpb_mgr, u2_buf_mod_bitfield, u1_num_bufs_modified, i);
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_insert_st_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_au_buf)
+{
+ WORD32 i;
+
+ mvc_dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info;
+ UWORD8 u1_picture_type = ps_au_buf->u1_picturetype;
+
+ for(i = 0; i < MVC_MAX_REF_PICS; i++)
+ {
+ if((ps_dpb_info[i].ps_au_buf == ps_au_buf) && ps_dpb_info[i].b_used_as_ref)
+ {
+ /* Can occur only for field bottom pictures */
+ if(ps_dpb_info[i].ps_au_buf->u1_pic_type == FRM_PIC)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ else
+ {
+ ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
+
+ return OK;
+ }
+ }
+
+ if(!ps_dpb_info[i].b_used_as_ref &&
+ (ps_dpb_info[i].s_top_field.u1_reference_info == UNUSED_FOR_REF) &&
+ (ps_dpb_info[i].s_bot_field.u1_reference_info == UNUSED_FOR_REF))
+ {
+ break;
+ }
+ }
+
+ if(i == MVC_MAX_REF_PICS)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_dpb_info[i].ps_au_buf = ps_au_buf;
+ ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head;
+ ps_dpb_info[i].b_used_as_ref = true;
+
+ ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i;
+
+ ps_dpb_mgr->u1_num_st_ref_bufs++;
+
+ ps_au_buf->b_is_short_term_ref = true;
+
+ if((u1_picture_type & 0x03) == FRM_PIC)
+ {
+ ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
+ ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
+ }
+ else if((u1_picture_type & 0x03) == TOP_FLD)
+ {
+ ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM;
+ }
+ else if((u1_picture_type & 0x03) == BOT_FLD)
+ {
+ ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM;
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_dpb_delete_gap_frm_mmco(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_frame_num,
+ UWORD8 *pu1_del_node)
+{
+ WORD8 i, j;
+ WORD32 *pi4_start, *pi4_end;
+ WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_pic_num;
+
+ /* find the least frame num from gaps and current DPB node */
+ /* Delete the gaps */
+ *pu1_del_node = 1;
+ pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num;
+ pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num;
+ i4_max_pic_num = ps_dpb_mgr->i4_max_pic_num;
+
+ if(0 == ps_dpb_mgr->u1_num_gaps)
+ {
+ return OK;
+ }
+
+ if(i4_frame_num < 0)
+ {
+ i4_frame_num += i4_max_pic_num;
+ }
+
+ for(i = 0; i < MAX_FRAMES; i++)
+ {
+ i4_start_frm_num = pi4_start[i];
+
+ if(i4_start_frm_num < 0)
+ {
+ i4_start_frm_num += i4_max_pic_num;
+ }
+
+ if(INVALID_FRAME_NUM != i4_start_frm_num)
+ {
+ i4_end_frm_num = pi4_end[i];
+
+ if(i4_end_frm_num < 0)
+ {
+ i4_end_frm_num += i4_max_pic_num;
+ }
+
+ if((i4_frame_num >= i4_start_frm_num) && (i4_frame_num <= i4_end_frm_num))
+ {
+ break;
+ }
+ else
+ {
+ if(((i4_frame_num + i4_max_pic_num) >= i4_start_frm_num) &&
+ ((i4_frame_num + i4_max_pic_num) <= i4_end_frm_num))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ }
+ }
+ }
+
+ /* find frame_num index, in the poc_map which needs to be deleted */
+ for(j = 0; j < MAX_FRAMES; j++)
+ {
+ if(i4_frame_num == ps_dpb_mgr->as_display_buf_info[j].i4_frame_num)
+ {
+ break;
+ }
+ }
+
+ if(MAX_FRAMES != i)
+ {
+ if(j == MAX_FRAMES)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_dpb_mgr->as_display_buf_info[j].i4_poc_buf_id = -1;
+ ps_dpb_mgr->as_display_buf_info[j].i4_poc = 0x7fffffff;
+ ps_dpb_mgr->as_display_buf_info[j].i4_frame_num = GAP_FRAME_NUM;
+
+ ps_dpb_mgr->i1_gaps_deleted++;
+ ps_dpb_mgr->ai1_gaps_per_seq[i]--;
+ ps_dpb_mgr->u1_num_gaps--;
+ *pu1_del_node = 0;
+
+ if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i])
+ {
+ ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0;
+ }
+ }
+ else
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_dpb_insert_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_dpb_info_t *ps_new_node,
+ UWORD32 u4_lt_idx)
+{
+ ps_new_node->s_top_field.u1_reference_info = IS_LONG_TERM;
+ ps_new_node->s_bot_field.u1_reference_info = IS_LONG_TERM;
+ ps_new_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx;
+ ps_new_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx;
+ ps_new_node->ps_au_buf->u1_long_term_frm_idx = u4_lt_idx;
+ ps_new_node->b_used_as_ref = true;
+
+ if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
+ {
+ WORD32 i;
+
+ mvc_dpb_info_t **pps_next_node = &ps_dpb_mgr->ps_dpb_lt_head;
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ if((*pps_next_node)->ps_au_buf->u1_long_term_frm_idx > u4_lt_idx)
+ {
+ ps_new_node->ps_prev_long = *pps_next_node;
+ *pps_next_node = ps_new_node;
+
+ break;
+ }
+ else if(NULL == (*pps_next_node)->ps_prev_long)
+ {
+ (*pps_next_node)->ps_prev_long = ps_new_node;
+ ps_new_node->ps_prev_long = NULL;
+
+ break;
+ }
+
+ pps_next_node = &(*pps_next_node)->ps_prev_long;
+ }
+ }
+ else
+ {
+ ps_dpb_mgr->ps_dpb_lt_head = ps_new_node;
+ ps_new_node->ps_prev_long = NULL;
+ }
+
+ ps_new_node->ps_au_buf->b_is_short_term_ref = false;
+
+ ps_dpb_mgr->u1_num_lt_ref_bufs++;
+
+ return OK;
+}
+
+static WORD32 imvcd_dpb_delete_lt_node(mvc_dpb_manager_t *ps_dpb_mgr, UWORD32 u4_lt_idx)
+{
+ mvc_dpb_info_t *ps_next_dpb;
+ mvc_dpb_info_t *ps_unmark_node;
+
+ WORD32 i;
+
+ if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0)
+ {
+ ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
+
+ if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
+ {
+ ps_unmark_node = ps_next_dpb;
+ }
+ else
+ {
+ for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ if(ps_next_dpb->ps_prev_long->ps_au_buf->u1_long_term_frm_idx == u4_lt_idx)
+ {
+ break;
+ }
+
+ ps_next_dpb = ps_next_dpb->ps_prev_long;
+ }
+
+ if(i < ps_dpb_mgr->u1_num_lt_ref_bufs)
+ {
+ ps_unmark_node = ps_next_dpb->ps_prev_long;
+ }
+ else
+ {
+ return OK;
+ }
+ }
+
+ ps_unmark_node->b_used_as_ref = false;
+
+ if(ps_unmark_node == ps_dpb_mgr->ps_dpb_lt_head)
+ {
+ ps_dpb_mgr->ps_dpb_lt_head = ps_next_dpb->ps_prev_long;
+ }
+
+ ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr, ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_unmark_node->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long;
+ ps_unmark_node->ps_prev_long = NULL;
+ ps_dpb_mgr->u1_num_lt_ref_bufs--;
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_pic_num,
+ UWORD32 u4_lt_idx)
+{
+ WORD32 i4_error_code;
+
+ mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+ mvc_dpb_info_t *ps_unmark_node = NULL;
+
+ UWORD8 u1_del_node = 0, u1_del_st = 0;
+ WORD32 i = 0;
+
+ if(ps_next_dpb->ps_au_buf->i4_pic_num == i4_pic_num)
+ {
+ ps_unmark_node = ps_next_dpb;
+ }
+ else
+ {
+ for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ if(ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num == i4_pic_num)
+ {
+ ps_unmark_node = ps_next_dpb->ps_prev_short;
+
+ break;
+ }
+
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+ }
+
+ if(i == ps_dpb_mgr->u1_num_st_ref_bufs)
+ {
+ if(ps_dpb_mgr->u1_num_gaps)
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_del_st);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(u1_del_st)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ ps_unmark_node->b_used_as_ref = false;
+ ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head)
+ {
+ ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short;
+ }
+ else
+ {
+ ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short;
+ }
+
+ ps_dpb_mgr->u1_num_st_ref_bufs--;
+ u1_del_node = 1;
+
+ if(u4_lt_idx == (MAX_REF_BUFS + 1))
+ {
+ if(u1_del_node)
+ {
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_unmark_node->ps_au_buf->i4_pic_buf_id);
+
+ ps_unmark_node->ps_prev_short = NULL;
+ }
+ }
+ else
+ {
+ i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_dpb_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_do_mmco(dpb_commands_t *ps_dpb_cmds, mvc_dpb_manager_t *ps_dpb_mgr,
+ mvc_au_buffer_t *ps_cur_au, UWORD8 u1_max_num_ref_frames,
+ UWORD8 u1_curr_pic_in_err)
+{
+ mvc_dpb_info_t *ps_next_dpb;
+
+ WORD32 i, j;
+ UWORD8 u1_buf_mode, u1_marked_lt;
+ UWORD8 u1_num_gaps;
+ WORD32 i4_error_code;
+
+ UWORD8 u1_del_node = 1;
+ UWORD8 u1_insert_st_pic = 1;
+
+ // 0 - sliding window; 1 - Adaptive
+ u1_buf_mode = ps_dpb_cmds->u1_buf_mode;
+ u1_marked_lt = 0;
+ u1_num_gaps = ps_dpb_mgr->u1_num_gaps;
+
+ if(!u1_buf_mode)
+ {
+ // Sliding window - implements 8.2.5.3
+ if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) ==
+ u1_max_num_ref_frames)
+ {
+ UWORD8 u1_new_node_flag = 1;
+
+ if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ // Chase the links to reach the last but one picNum, if available
+ ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+
+ if(ps_dpb_mgr->u1_num_st_ref_bufs > 1)
+ {
+ if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++)
+ {
+ if(ps_next_dpb == NULL)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+
+ if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(u1_new_node_flag)
+ {
+ if(u1_num_gaps)
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
+ ps_dpb_mgr, ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_num,
+ &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ if(u1_del_node)
+ {
+ ps_dpb_mgr->u1_num_st_ref_bufs--;
+ ps_next_dpb->ps_prev_short->b_used_as_ref = false;
+ ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_next_dpb->ps_prev_short->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_prev_short->ps_au_buf = NULL;
+ ps_next_dpb->ps_prev_short = NULL;
+ }
+ }
+ }
+ else
+ {
+ if(ps_dpb_mgr->u1_num_st_ref_bufs)
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(
+ ps_dpb_mgr, ps_next_dpb->ps_au_buf->i4_pic_num, &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ if((ps_next_dpb->ps_au_buf->i4_pic_num != ps_cur_au->i4_pic_num) && u1_del_node)
+ {
+ ps_dpb_mgr->u1_num_st_ref_bufs--;
+ ps_next_dpb->b_used_as_ref = false;
+ ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_next_dpb->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_au_buf = NULL;
+ ps_next_dpb->ps_prev_short = NULL;
+ ps_dpb_mgr->ps_dpb_st_head = NULL;
+ ps_next_dpb = NULL;
+ }
+ else if(ps_next_dpb->ps_au_buf->i4_pic_num == ps_cur_au->i4_pic_num)
+ {
+ if(u1_curr_pic_in_err)
+ {
+ u1_insert_st_pic = 0;
+ }
+ else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
+ {
+ ps_dpb_mgr->u1_num_st_ref_bufs--;
+ ps_next_dpb->b_used_as_ref = false;
+ ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_next_dpb->ps_au_buf->i4_pic_buf_id);
+
+ ps_next_dpb->ps_au_buf = NULL;
+ ps_next_dpb = NULL;
+ }
+ }
+ }
+ else
+ {
+ i4_error_code = imvcd_dpb_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM,
+ &u1_del_node);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ if(u1_del_node)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Adaptive memory control - implements 8.2.5.4
+ struct MMCParams *ps_mmc_params;
+
+ UWORD32 u4_mmco;
+ UWORD32 u4_diff_pic_num;
+ UWORD32 u4_lt_idx;
+
+ UWORD32 au4_num_mmco_cmds[NUM_MMCO_CMD_IDS] = {0};
+
+ for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++)
+ {
+ ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j];
+ u4_mmco = ps_mmc_params->u4_mmco;
+
+ switch(u4_mmco)
+ {
+ case MARK_ST_PICNUM_AS_NONREF:
+ {
+ WORD64 i8_pic_num;
+
+ u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
+ i8_pic_num =
+ ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
+
+ if(IS_OUT_OF_RANGE_S32(i8_pic_num))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
+ {
+ i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
+ ps_dpb_mgr, (WORD32) i8_pic_num, MAX_REF_BUFS + 1);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ UWORD8 u1_dummy;
+
+ i4_error_code = imvcd_dpb_delete_gap_frm_mmco(
+ ps_dpb_mgr, (WORD32) i8_pic_num, &u1_dummy);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ break;
+ }
+ case MARK_LT_INDEX_AS_NONREF:
+ {
+ u4_lt_idx = ps_mmc_params->u4_lt_idx;
+
+ i4_error_code = imvcd_dpb_delete_lt_node(ps_dpb_mgr, u4_lt_idx);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ break;
+ }
+ case MARK_ST_PICNUM_AS_LT_INDEX:
+ {
+ WORD64 i8_pic_num;
+
+ u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num;
+
+ i8_pic_num =
+ ((WORD64) ps_cur_au->i4_pic_num) - ((WORD64) (u4_diff_pic_num + 1));
+
+ if(IS_OUT_OF_RANGE_S32(i8_pic_num))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ u4_lt_idx = ps_mmc_params->u4_lt_idx;
+
+ if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
+ (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
+ {
+ i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
+ ps_dpb_mgr, (WORD32) i8_pic_num, u4_lt_idx);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ break;
+ }
+ case SET_MAX_LT_INDEX:
+ {
+ if(au4_num_mmco_cmds[SET_MAX_LT_INDEX] > 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ u4_lt_idx =
+ ps_mmc_params->u4_max_lt_idx_plus1; // Get Max_long_term_index_plus1
+
+ if((u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx) &&
+ (ps_dpb_mgr->u1_num_lt_ref_bufs > 0))
+ {
+ mvc_dpb_info_t *ps_nxtDPB;
+
+ // Set all LT buffers with index >= u4_lt_idx to nonreference
+ ps_nxtDPB = ps_dpb_mgr->ps_dpb_lt_head;
+ ps_next_dpb = ps_nxtDPB->ps_prev_long;
+
+ if(ps_nxtDPB->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
+ {
+ i = 0;
+ ps_dpb_mgr->ps_dpb_lt_head = NULL;
+ }
+ else
+ {
+ for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ if(ps_next_dpb->ps_au_buf->u1_long_term_frm_idx >= u4_lt_idx)
+ {
+ break;
+ }
+
+ ps_nxtDPB = ps_next_dpb;
+ ps_next_dpb = ps_next_dpb->ps_prev_long;
+ }
+
+ ps_nxtDPB->ps_prev_long = NULL; // Terminate the link of the
+ // closest LTIndex that is <=Max
+ }
+
+ ps_dpb_mgr->u1_num_lt_ref_bufs = i;
+
+ if(i == 0)
+ {
+ ps_next_dpb = ps_nxtDPB;
+ }
+
+ for(; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ ps_nxtDPB = ps_next_dpb;
+ ps_nxtDPB->b_used_as_ref = false;
+ ps_nxtDPB->s_top_field.u1_reference_info = UNUSED_FOR_REF;
+ ps_nxtDPB->s_bot_field.u1_reference_info = UNUSED_FOR_REF;
+
+ imvcd_free_ref_bufs(ps_dpb_mgr->ps_mvc_au_buf_mgr,
+ ps_dpb_mgr->ps_mvc_au_mv_pred_buf_mgr,
+ ps_nxtDPB->ps_au_buf->i4_pic_buf_id);
+
+ ps_nxtDPB->ps_au_buf = NULL;
+
+ ps_next_dpb = ps_nxtDPB->ps_prev_long;
+ ps_nxtDPB->ps_prev_long = NULL;
+ }
+ }
+
+ if(u4_lt_idx == 0)
+ {
+ ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
+ }
+ else
+ {
+ ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
+ }
+
+ break;
+ }
+ case SET_LT_INDEX:
+ {
+ if(au4_num_mmco_cmds[SET_LT_INDEX] > 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ u4_lt_idx = ps_mmc_params->u4_lt_idx; // Get long term index
+
+ if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
+ (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
+ {
+ i4_error_code = imvcd_dpb_delete_st_node_or_make_lt(
+ ps_dpb_mgr, ps_cur_au->i4_pic_num, u4_lt_idx);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ u1_marked_lt = 1;
+
+ break;
+ }
+ case RESET_REF_PICTURES:
+ {
+ if((au4_num_mmco_cmds[RESET_REF_PICTURES] > 0) ||
+ (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_NONREF] > 0) ||
+ (au4_num_mmco_cmds[MARK_LT_INDEX_AS_NONREF] > 0) ||
+ (au4_num_mmco_cmds[MARK_ST_PICNUM_AS_LT_INDEX] > 0))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ if((j > 0) && (ps_dpb_cmds->as_mmc_params[j - 1].u4_mmco == SET_LT_INDEX))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ __attribute__((fallthrough));
+ }
+ case RESET_ALL_PICTURES:
+ {
+ WORD32 i4_pic_num = ps_cur_au->i4_frame_num;
+
+ imvcd_reset_dpb(ps_dpb_mgr);
+
+ ps_cur_au->i4_frame_num = 0;
+
+ if(!u1_marked_lt && u1_insert_st_pic)
+ {
+ i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ ps_cur_au->i4_frame_num = i4_pic_num;
+
+ return OK;
+ }
+ default:
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ }
+
+ au4_num_mmco_cmds[u4_mmco]++;
+ }
+ }
+
+ if(!u1_marked_lt && u1_insert_st_pic)
+ {
+ i4_error_code = imvcd_dpb_insert_st_node(ps_dpb_mgr, ps_cur_au);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_dpb_update_default_index_list(mvc_dpb_manager_t *ps_dpb_mgr)
+{
+ WORD32 i;
+
+ mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+
+ for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+
+ ps_next_dpb = ps_dpb_mgr->ps_dpb_lt_head;
+
+ for(; i < ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++)
+ {
+ ps_dpb_mgr->aps_def_dpb[i] = ps_next_dpb->ps_au_buf;
+ ps_next_dpb = ps_next_dpb->ps_prev_long;
+ }
+
+ return OK;
+}
+
+bool imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_curr_poc)
+{
+ WORD32 i;
+
+ mvc_dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
+
+ /* Check in conformance with section 8.2.1 from spec */
+ /* Particularly the statement - */
+ /* 'The bitstream shall not contain data that result in values of DiffPicOrderCnt(picA, picB)
+ * used in the decoding process that exceed the range of -2^15 to 2^15 - 1 inclusive' */
+ for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
+ {
+ if(((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) >= (1 << 15)) ||
+ ((((WORD64) i4_curr_poc) - ((WORD64) ps_next_dpb->ps_au_buf->i4_poc)) < -(1 << 15)))
+ {
+ return false;
+ }
+
+ ps_next_dpb = ps_next_dpb->ps_prev_short;
+ }
+
+ return true;
+}
diff --git a/decoder/mvc/imvcd_dpb_manager.h b/decoder/mvc/imvcd_dpb_manager.h
new file mode 100644
index 0000000..d9757cf
--- /dev/null
+++ b/decoder/mvc/imvcd_dpb_manager.h
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_nalu_parser.h */
+/* */
+/* Description : Functions for MVC NALU parsing */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_DPB_MANAGER_H_
+#define _IMVCD_DPB_MANAGER_H_
+#include <stdbool.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_error.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_disp_mgr.h"
+#include "ih264d_dpb_manager.h"
+#include "imvcd_defs.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+#define NUM_MMCO_CMD_IDS ((RESET_ALL_PICTURES) + 1)
+
+typedef struct mvc_dpb_info_t
+{
+ mvc_au_buffer_t *ps_au_buf;
+
+ struct mvc_dpb_info_t *ps_prev_short;
+
+ struct mvc_dpb_info_t *ps_prev_long;
+
+ struct field_t s_top_field;
+
+ struct field_t s_bot_field;
+
+ bool b_used_as_ref;
+
+} mvc_dpb_info_t;
+
+typedef struct display_buf_info_t
+{
+ WORD32 i4_poc;
+
+ WORD32 i4_poc_buf_id;
+
+ WORD32 i4_frame_num;
+} display_buf_info_t;
+
+typedef struct dpb_ivp_ctxt_t
+{
+ sps_mvc_ext_t *ps_sps_mvc_ext;
+
+ nalu_mvc_ext_t *ps_nalu_mvc_exts;
+
+ UWORD8 au1_au_buf_ids[MVC_MAX_REF_PICS];
+
+ UWORD8 au1_mv_buf_ids[MVC_MAX_REF_PICS];
+
+ UWORD32 u4_num_ivp_refs;
+} dpb_ivp_ctxt_t;
+
+typedef struct mvc_dpb_manager_t
+{
+ /** DPB in default index order */
+ mvc_au_buffer_t *aps_def_dpb[MVC_MAX_REF_PICS];
+
+ /** DPB in reordered index order, 0-fwd,1-bwd */
+ mvc_au_buffer_t *aps_mod_dpb[2][MVC_MAX_REF_PICS];
+
+ /** DPB in reordered index order, 0-fwd,1-bwd */
+ mvc_au_buffer_t as_init_dpb[2][MVC_MAX_REF_PICS];
+
+ /** Replicates view level data in 'aps_mod_dpb' */
+ pic_buffer_t *aps_view_mod_dpb[2][MVC_MAX_REF_PICS];
+
+ /** Replicates view level data in 'aps_init_dpb' */
+ pic_buffer_t as_view_init_dpb[2][MVC_MAX_REF_PICS];
+
+ mvc_dpb_info_t as_dpb_info[MVC_MAX_REF_PICS];
+
+ display_buf_info_t as_display_buf_info[MAX_FRAMES];
+
+ dpb_ivp_ctxt_t s_dpb_ivp_ctxt;
+
+ mvc_dpb_info_t *ps_dpb_st_head;
+
+ mvc_dpb_info_t *ps_dpb_lt_head;
+
+ mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr;
+
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr;
+
+ disp_mgr_t *ps_disp_buf_mgr;
+
+ WORD32 ai4_gaps_start_frm_num[MAX_FRAMES];
+
+ WORD32 ai4_gaps_end_frm_num[MAX_FRAMES];
+
+ WORD8 ai1_gaps_per_seq[MAX_FRAMES];
+
+ UWORD8 au1_num_active_st_refs[2];
+
+ UWORD8 au1_num_active_lt_refs[2];
+
+ WORD32 i4_max_pic_num;
+
+ WORD32 i4_display_delay;
+
+ WORD32 i4_cur_display_seq;
+
+ UWORD16 u2_num_views;
+
+ UWORD8 u1_num_st_ref_bufs;
+
+ UWORD8 u1_num_lt_ref_bufs;
+
+ UWORD8 u1_max_lt_frame_idx;
+
+ UWORD8 u1_num_gaps;
+
+ WORD8 i1_poc_buf_id_entries;
+
+ WORD8 i1_gaps_deleted;
+
+ UWORD8 u1_mmco_error_in_seq;
+
+} mvc_dpb_manager_t;
+
+/* Function declarations */
+extern void imvcd_init_dpb_mgr(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
+ disp_mgr_t *ps_disp_buf_mgr);
+
+extern WORD32 imvcd_dpb_assign_display_seq(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern WORD32 imvcd_dpb_insert_pic_in_display_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ WORD32 i4_display_poc, UWORD32 u4_frame_num,
+ WORD32 i4_buf_id);
+
+extern WORD32 imvcd_dpb_do_mmco_for_gaps(mvc_dpb_manager_t *ps_dpb_mgr, UWORD8 u1_num_ref_frames);
+
+extern void imvcd_dpb_delete_nonref_nondisplay_pics(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern void imvcd_reset_dpb(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern void imvcd_dpb_release_display_bufs(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern void imvcd_assign_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_frame_num,
+ WORD32 i4_cur_frame_num,
+ bool b_are_gaps_in_frame_num_value_allowed);
+
+extern UWORD8 imvcd_dpb_st_lt_deduplicator(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern WORD32 imvcd_init_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
+ mvc_au_buffer_t *ps_cur_au, UWORD16 u2_view_order_id);
+
+extern WORD32 imvcd_dpb_reorder_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext,
+ mvc_au_buffer_t *ps_cur_au,
+ ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data,
+ UWORD16 u2_view_order_id);
+
+extern WORD32 imvcd_dpb_insert_st_node(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_au_buf);
+
+extern WORD32 imvcd_dpb_delete_st_node_or_make_lt(mvc_dpb_manager_t *ps_dpb_mgr,
+ WORD32 i4_frame_num, UWORD32 u4_lt_idx);
+
+extern WORD32 imvcd_dpb_do_mmco(dpb_commands_t *ps_dpb_cmds, mvc_dpb_manager_t *ps_dpb_mgr,
+ mvc_au_buffer_t *ps_cur_au, UWORD8 u1_max_num_ref_frames,
+ UWORD8 u1_curr_pic_in_err);
+
+extern WORD32 imvcd_dpb_update_default_index_list(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern void imvcd_dpb_set_display_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_num);
+
+extern void imvcd_dpb_set_max_pic_num(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_max_pic_num);
+
+extern void imvcd_dpb_set_num_views(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_num_views);
+
+extern void imvcd_dpb_set_display_delay(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_display_delay);
+
+extern void imvcd_dpb_init_au_bufs(mvc_dpb_manager_t *ps_dpb_mgr, mvc_au_buffer_t *ps_cur_au);
+
+extern void imvcd_dpb_init_view_bufs(mvc_dpb_manager_t *ps_dpb_mgr, UWORD16 u2_view_order_id,
+ UWORD16 u2_view_id);
+
+extern void imvcd_dpb_init_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr, sps_mvc_ext_t *ps_sps_mvc_ext,
+ nalu_mvc_ext_t *ps_nalu_mvc_exts);
+
+extern void imvcd_dpb_reset_ivp_ctxt(mvc_dpb_manager_t *ps_dpb_mgr);
+
+extern pic_buffer_t **imvcd_dpb_get_view_ref_pic_list(mvc_dpb_manager_t *ps_dpb_mgr,
+ UWORD16 u2_view_order_id, UWORD16 u2_view_id,
+ UWORD8 u1_pred_dir);
+
+extern bool imvcd_dpb_is_diff_poc_valid(mvc_dpb_manager_t *ps_dpb_mgr, WORD32 i4_curr_poc);
+
+#endif
diff --git a/decoder/mvc/imvcd_error_handler.c b/decoder/mvc/imvcd_error_handler.c
new file mode 100644
index 0000000..4cf4010
--- /dev/null
+++ b/decoder/mvc/imvcd_error_handler.c
@@ -0,0 +1,421 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_error_handler.c */
+/* */
+/* Description : Functions for error handling */
+/* */
+/*****************************************************************************/
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "imvcd.h"
+#include "ih264_macros.h"
+#include "imvc_defs.h"
+#include "ih264d_defs.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_nal.h"
+#include "ih264d_structs.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+static IV_API_CALL_STATUS_T imvcd_check_invalid_numViews(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ UWORD8 u1_num_valid_subset_sps_found = 0;
+ UWORD16 u2_max_views = 1;
+
+ if((ps_mvcd_ctxt->u1_num_subset_sps == 0) && (ps_mvcd_ctxt->u2_num_views_decoded > 0))
+ {
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
+ {
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_mvc_ext.u2_num_views > MAX_NUM_VIEWS)
+ {
+ return IV_FAIL;
+ }
+
+ u2_max_views =
+ MAX(u2_max_views, ps_mvcd_ctxt->as_subset_sps[i].s_sps_mvc_ext.u2_num_views);
+ u1_num_valid_subset_sps_found++;
+ }
+ }
+
+ if(u1_num_valid_subset_sps_found > ps_mvcd_ctxt->u1_num_subset_sps)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_mvcd_ctxt->u2_num_views > u2_max_views)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_mvcd_ctxt->u2_num_views_decoded >= u2_max_views)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_check_sps_and_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ UWORD32 i;
+ UWORD32 u4_cnt;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD32 u4_num_sps = ps_mvcd_ctxt->u1_num_sps;
+ UWORD32 u4_num_subset_sps = ps_mvcd_ctxt->u1_num_subset_sps;
+ WORD32 i4_max_mb_addr = INT32_MIN;
+
+ i = 0;
+ u4_cnt = 0;
+
+ while((u4_cnt < u4_num_sps) && (i < MAX_NUM_SEQ_PARAMS))
+ {
+ if(ps_view_ctxt->ps_sps[i].u1_is_valid)
+ {
+ u4_cnt++;
+
+ if(i4_max_mb_addr == INT32_MIN)
+ {
+ i4_max_mb_addr = ps_view_ctxt->ps_sps[i].u2_max_mb_addr;
+ }
+ else if(i4_max_mb_addr != ps_view_ctxt->ps_sps[i].u2_max_mb_addr)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->ps_sps[i].u2_max_mb_addr >
+ imvcd_get_num_mbs_in_level(ps_view_ctxt->ps_sps[i].u1_level_idc))
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->ps_sps[i].u1_mb_aff_flag)
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_view_ctxt->ps_sps[i].u1_frame_mbs_only_flag)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ i++;
+ }
+
+ if(u4_cnt != u4_num_sps)
+ {
+ return IV_FAIL;
+ }
+
+ i = 0;
+ u4_cnt = 0;
+
+ while((u4_cnt < u4_num_subset_sps) && (i < MAX_NUM_SEQ_PARAMS))
+ {
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
+ {
+ u4_cnt++;
+
+ if(i4_max_mb_addr == INT32_MIN)
+ {
+ i4_max_mb_addr = ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u2_max_mb_addr;
+ }
+ else if(i4_max_mb_addr != ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u2_max_mb_addr)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u2_max_mb_addr >
+ imvcd_get_num_mbs_in_level(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_level_idc))
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_mb_aff_flag)
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_frame_mbs_only_flag)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ i++;
+ }
+
+ if(u4_cnt != u4_num_subset_sps)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T imvcd_check_pps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ bool b_is_valid_pps_found = false;
+
+ for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
+ {
+ if(ps_view_ctxt->ps_pps[i].u1_is_valid)
+ {
+ b_is_valid_pps_found = true;
+
+ if(ps_view_ctxt->ps_pps[i].u1_frame_cropping_flag)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->ps_pps[i].u1_num_slice_groups != 1)
+ {
+ return IV_FAIL;
+ }
+ }
+ }
+
+ return b_is_valid_pps_found ? IV_SUCCESS : IV_FAIL;
+}
+
+static IV_API_CALL_STATUS_T imvcd_check_num_view_slices_in_au(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_ip_t *ps_ip)
+{
+ AVC_EXT_NALU_ID_T e_nalu_id;
+
+ UWORD16 u2_num_view_slices_in_au = 0;
+ UWORD8 *pu1_input_buffer = (UWORD8 *) ps_ip->s_ivd_ip.pv_stream_buffer;
+ UWORD32 u4_num_bytes_remaining = ps_ip->s_ivd_ip.u4_num_Bytes;
+
+ while(true)
+ {
+ UWORD32 u4_length_of_start_code = 0;
+ UWORD32 u4_next_is_aud = 0;
+ WORD32 i4_nalu_length = ih264d_find_start_code(pu1_input_buffer, 0, u4_num_bytes_remaining,
+ &u4_length_of_start_code, &u4_next_is_aud);
+
+ if(i4_nalu_length <= 0)
+ {
+ break;
+ }
+
+ if((0 != u4_next_is_aud) && (1 != u4_next_is_aud))
+ {
+ break;
+ }
+
+ if(u4_length_of_start_code < (NUM_OF_ZERO_BYTES_BEFORE_START_CODE + 1))
+ {
+ break;
+ }
+
+ e_nalu_id = NAL_UNIT_TYPE(pu1_input_buffer[u4_length_of_start_code]);
+ u2_num_view_slices_in_au += (SLICE_NON_IDR == e_nalu_id) || (SLICE_IDR == e_nalu_id) ||
+ (CODED_SLICE_EXTENSION == e_nalu_id);
+
+ if(((WORD64) u4_num_bytes_remaining) <=
+ ((WORD64) (((WORD64) u4_length_of_start_code) + ((WORD64) i4_nalu_length))))
+ {
+ break;
+ }
+ else
+ {
+ pu1_input_buffer += u4_length_of_start_code + i4_nalu_length;
+ u4_num_bytes_remaining -= u4_length_of_start_code + i4_nalu_length;
+ }
+
+ if(u2_num_view_slices_in_au == ps_mvcd_ctxt->u2_num_views)
+ {
+ break;
+ }
+ }
+
+ return (u2_num_view_slices_in_au != ps_mvcd_ctxt->u2_num_views) ? IV_FAIL : IV_SUCCESS;
+}
+
+IV_API_CALL_STATUS_T imvcd_au_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_ip_t *ps_ip)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ if(ps_mvcd_ctxt->b_header_only_decode)
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_view_ctxt->init_done)
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_FAIL == imvcd_check_invalid_numViews(ps_mvcd_ctxt))
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_FAIL == imvcd_check_sps_and_subset_sps(ps_mvcd_ctxt))
+ {
+ return IV_FAIL;
+ }
+
+ if(IV_FAIL == imvcd_check_pps(ps_mvcd_ctxt))
+ {
+ return IV_FAIL;
+ }
+
+ if(!ps_mvcd_ctxt->b_flush_enabled)
+ {
+ if(IV_FAIL == imvcd_check_num_view_slices_in_au(ps_mvcd_ctxt, ps_ip))
+ {
+ return IV_FAIL;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+IV_API_CALL_STATUS_T imvcd_view_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
+
+ bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt);
+
+ if(b_is_idr_slice && (ps_view_ctxt->ps_cur_slice->u1_slice_type != ISLICE))
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->u1_first_slice_in_stream && !b_is_idr_slice)
+ {
+ return IV_FAIL;
+ }
+
+ /* In accordance with section 8.2.1 from spec. It is reproduced below - */
+ /* The bitstream shall not contain data that result in Min( TopFieldOrderCnt,
+ BottomFieldOrderCnt ) not equal to 0 for a coded IDR frame, TopFieldOrderCnt not equal to
+ 0 for a coded IDR top field, or BottomFieldOrderCnt not equal to 0 for a coded IDR bottom
+ field. Thus, at least one of TopFieldOrderCnt and BottomFieldOrderCnt shall be equal to 0
+ for the fields of a coded IDR frame. */
+ if(b_is_idr_slice)
+ {
+ if(ps_view_ctxt->ps_cur_slice->u1_field_pic_flag)
+ {
+ if(ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag &&
+ (ps_pps->i4_bottom_field_order_cnt != 0))
+ {
+ return IV_FAIL;
+ }
+ else if(!ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag &&
+ (ps_pps->i4_top_field_order_cnt != 0))
+ {
+ return IV_FAIL;
+ }
+ }
+ else if(MIN(ps_pps->i4_top_field_order_cnt, ps_pps->i4_bottom_field_order_cnt) != 0)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ if(ps_nalu_mvc_ext->u2_view_id != 0)
+ {
+ subset_sps_t *ps_subset_sps =
+ ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[ps_pps->u1_pic_parameter_set_id];
+
+ if((NULL == ps_subset_sps) || !ps_subset_sps->s_sps_data.u1_is_valid)
+ {
+ return IV_FAIL;
+ }
+
+ if(0 == ps_mvcd_ctxt->u1_num_subset_sps)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_nalu_mvc_ext->u2_view_id >= ps_subset_sps->s_sps_mvc_ext.u2_num_views)
+ {
+ return IV_FAIL;
+ }
+ }
+ else
+ {
+ if(ps_mvcd_ctxt->u2_num_views_decoded > 0)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ if(!ps_view_ctxt->u4_first_slice_in_pic || (ps_view_ctxt->u2_cur_slice_num > 0))
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->u4_first_slice_in_pic &&
+ (ps_view_ctxt->ps_cur_slice->u2_first_mb_in_slice != 0))
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_view_ctxt->ps_cur_slice->u1_mmco_equalto5)
+ {
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_mvcd_ctxt->u2_num_views_decoded; i++)
+ {
+ if(ps_mvcd_ctxt->as_slices[i].i4_poc != ps_view_ctxt->ps_cur_slice->i4_poc)
+ {
+ return IV_FAIL;
+ }
+
+ if(ps_mvcd_ctxt->as_slices[i].u2_frame_num != ps_view_ctxt->ps_cur_slice->u2_frame_num)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ if(SKIP_NONE != ps_view_ctxt->u4_skip_frm_mask)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
diff --git a/decoder/mvc/imvcd_error_handler.h b/decoder/mvc/imvcd_error_handler.h
new file mode 100644
index 0000000..5c5d702
--- /dev/null
+++ b/decoder/mvc/imvcd_error_handler.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_error_handler.h */
+/* */
+/* Description : Functions for error handling */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_ERROR_HANDLER_H_
+#define _IMVCD_ERROR_HANDLER_H_
+
+#include "iv.h"
+#include "imvcd.h"
+#include "imvcd_structs.h"
+
+extern IV_API_CALL_STATUS_T imvcd_au_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt,
+ imvcd_video_decode_ip_t *ps_ip);
+
+extern IV_API_CALL_STATUS_T imvcd_view_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+#endif
diff --git a/decoder/mvc/imvcd_nalu_parser.c b/decoder/mvc/imvcd_nalu_parser.c
new file mode 100644
index 0000000..2699912
--- /dev/null
+++ b/decoder/mvc/imvcd_nalu_parser.c
@@ -0,0 +1,870 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_nalu_parser.h */
+/* */
+/* Description : Functions for MVC NALU parsing */
+/* */
+/*****************************************************************************/
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "imvcd.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_nal.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_structs.h"
+#include "ih264d_vui.h"
+#include "imvcd_defs.h"
+#include "imvcd_slice_functions.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+static WORD32 imvcd_nalu_mvc_ext_parser(mvc_dec_ctxt_t *ps_mvcd_ctxt, dec_bit_stream_t *ps_bitstrm)
+{
+ nalu_mvc_ext_t *ps_nalu_mvc_ext =
+ &ps_mvcd_ctxt->as_nalu_mvc_ext[ps_mvcd_ctxt->u2_num_views_decoded];
+
+ ps_nalu_mvc_ext->u1_non_idr_flag = ih264d_get_bit_h264(ps_bitstrm);
+ ps_nalu_mvc_ext->u1_priority_id = ih264d_get_bits_h264(ps_bitstrm, 6);
+ ps_nalu_mvc_ext->u2_view_id = ih264d_get_bits_h264(ps_bitstrm, 10);
+
+ if((ps_nalu_mvc_ext->u2_view_id >= MAX_NUM_VIEWS) ||
+ (ps_nalu_mvc_ext->u2_view_id >= ps_mvcd_ctxt->u2_num_views))
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+
+ ps_nalu_mvc_ext->u1_temporal_id = ih264d_get_bits_h264(ps_bitstrm, 3);
+ ps_nalu_mvc_ext->u1_anchor_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ ps_nalu_mvc_ext->u1_inter_view_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(0 == ih264d_get_bit_h264(ps_bitstrm))
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_parse_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt, dec_bit_stream_t *ps_bitstrm)
+{
+ subset_sps_t *ps_subset_sps = NULL;
+ dec_seq_params_t *ps_sps = NULL;
+
+ WORD32 i, j, k;
+ UWORD8 u1_profile_idc;
+ UWORD8 au1_constraint_set_flags[6];
+ UWORD8 u1_level_idc;
+ UWORD8 u1_seq_parameter_set_id;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 u4_temp;
+ UWORD16 u2_num_views_m1;
+ UWORD8 u1_num_refs;
+ UWORD8 u1_num_level_values_signalled_m1;
+ UWORD8 u2_num_ops_m1;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ WORD32 i4_error_code = OK;
+
+ if(0 == ps_mvcd_ctxt->u1_num_sps)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_view_ctxt->ps_sps[i].u1_is_valid)
+ {
+ ps_sps = &ps_view_ctxt->ps_sps[i];
+
+ break;
+ }
+ }
+
+ if(NULL == ps_sps)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ u1_profile_idc = ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ for(i = 0; i < 6; i++)
+ {
+ au1_constraint_set_flags[i] = ih264d_get_bit_h264(ps_bitstrm);
+ }
+
+ if((u1_profile_idc != MULTIVIEW_HIGH_PROFILE_IDC) || (au1_constraint_set_flags[1] == 1))
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /*****************************************************/
+ /* Read reserved_zero_2bits (2 bits) */
+ /*****************************************************/
+ ih264d_get_bits_h264(ps_bitstrm, 2);
+
+ u1_level_idc = ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ u1_seq_parameter_set_id = u4_temp;
+
+ if(u4_temp & MASK_ERR_SEQ_SET_ID)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if(ps_sps->u1_level_idc != u1_level_idc)
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+
+ ps_subset_sps = &ps_mvcd_ctxt->as_subset_sps[u1_seq_parameter_set_id];
+
+ /* Accounting for the idiocy in 'ih264d_parse_pps' */
+ ps_subset_sps->s_sps_data.u1_profile_idc = HIGH_PROFILE_IDC;
+ ps_subset_sps->s_sps_data.u1_level_idc = u1_level_idc;
+ ps_subset_sps->s_sps_data.u1_seq_parameter_set_id = u1_seq_parameter_set_id;
+
+ ps_subset_sps->s_sps_data.i4_chroma_format_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.i4_chroma_format_idc != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_subset_sps->s_sps_data.i4_bit_depth_luma_minus8 =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.i4_bit_depth_luma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_subset_sps->s_sps_data.i4_bit_depth_chroma_minus8 =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.i4_bit_depth_chroma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_subset_sps->s_sps_data.i4_qpprime_y_zero_transform_bypass_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_subset_sps->s_sps_data.i4_qpprime_y_zero_transform_bypass_flag != 0)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ ps_subset_sps->s_sps_data.i4_seq_scaling_matrix_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_subset_sps->s_sps_data.i4_seq_scaling_matrix_present_flag)
+ {
+ for(i = 0; i < 8; i++)
+ {
+ ps_subset_sps->s_sps_data.u1_seq_scaling_list_present_flag[i] =
+ ih264d_get_bit_h264(ps_bitstrm);
+ }
+ }
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_temp > (MAX_BITS_IN_FRAME_NUM - 4))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ ps_subset_sps->s_sps_data.u1_bits_in_frm_num = 4 + u4_temp;
+
+ ps_subset_sps->s_sps_data.u2_u4_max_pic_num_minus1 =
+ (1 << (ps_subset_sps->s_sps_data.u1_bits_in_frm_num)) - 1;
+
+ ps_subset_sps->s_sps_data.u1_pic_order_cnt_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.u1_pic_order_cnt_type > MAX_PIC_ORDER_CNT_TYPE)
+ {
+ return ERROR_INV_POC_TYPE_T;
+ }
+
+ ps_subset_sps->s_sps_data.u1_num_ref_frames_in_pic_order_cnt_cycle = 1;
+
+ if(ps_subset_sps->s_sps_data.u1_pic_order_cnt_type == 0)
+ {
+ ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus =
+ 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus > MAX_BITS_IN_POC_LSB)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ ps_subset_sps->s_sps_data.i4_max_pic_order_cntLsb =
+ (1 << ps_subset_sps->s_sps_data.u1_log2_max_pic_order_cnt_lsb_minus);
+ }
+ else if(ps_subset_sps->s_sps_data.u1_pic_order_cnt_type == 1)
+ {
+ ps_subset_sps->s_sps_data.u1_delta_pic_order_always_zero_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+
+ ps_subset_sps->s_sps_data.i4_ofst_for_non_ref_pic =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ ps_subset_sps->s_sps_data.i4_ofst_for_top_to_bottom_field =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ ps_subset_sps->s_sps_data.u1_num_ref_frames_in_pic_order_cnt_cycle =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.u1_num_ref_frames_in_pic_order_cnt_cycle > MVC_MAX_REF_PICS)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ for(i = 0; i < ps_subset_sps->s_sps_data.u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ ps_subset_sps->s_sps_data.i4_ofst_for_ref_frame[i] =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ ps_subset_sps->s_sps_data.u1_num_ref_frames = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((ps_subset_sps->s_sps_data.u1_num_ref_frames > MVC_MAX_REF_PICS))
+ {
+ return ERROR_NUM_REF;
+ }
+
+ ps_subset_sps->s_sps_data.u1_gaps_in_frame_num_value_allowed_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+
+ ps_subset_sps->s_sps_data.u2_frm_wd_in_mbs = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.u2_frm_wd_in_mbs > (H264_MAX_FRAME_WIDTH >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+
+ ps_subset_sps->s_sps_data.u2_frm_ht_in_mbs = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_subset_sps->s_sps_data.u2_frm_ht_in_mbs > (H264_MAX_FRAME_HEIGHT >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+
+ ps_subset_sps->s_sps_data.u2_max_mb_addr =
+ ps_subset_sps->s_sps_data.u2_frm_wd_in_mbs * ps_subset_sps->s_sps_data.u2_frm_ht_in_mbs - 1;
+
+ ps_subset_sps->s_sps_data.u2_total_num_of_mbs = ps_subset_sps->s_sps_data.u2_max_mb_addr + 1;
+
+ ps_subset_sps->s_sps_data.u1_frame_mbs_only_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(!ps_subset_sps->s_sps_data.u1_frame_mbs_only_flag)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_subset_sps->s_sps_data.u1_mb_aff_flag = 0;
+
+ ps_subset_sps->s_sps_data.u1_direct_8x8_inference_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ /* Frame cropping flag */
+ u4_temp = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(u4_temp)
+ {
+ ps_subset_sps->s_disp_offsets.u2_left_offset =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_disp_offsets.u2_right_offset =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_disp_offsets.u2_top_offset = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_disp_offsets.u2_bottom_offset =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ else
+ {
+ memset(&ps_subset_sps->s_disp_offsets, 0, sizeof(ps_subset_sps->s_disp_offsets));
+ }
+
+ if(ps_sps->u2_frm_wd_in_mbs != ps_subset_sps->s_sps_data.u2_frm_wd_in_mbs)
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+
+ if(ps_sps->u2_frm_ht_in_mbs != ps_subset_sps->s_sps_data.u2_frm_ht_in_mbs)
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+
+ if(ps_view_ctxt->u2_disp_width != (ps_subset_sps->s_sps_data.u2_frm_wd_in_mbs * MB_SIZE -
+ ps_subset_sps->s_disp_offsets.u2_left_offset -
+ ps_subset_sps->s_disp_offsets.u2_right_offset))
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+
+ if(ps_view_ctxt->u2_disp_height != (ps_subset_sps->s_sps_data.u2_frm_ht_in_mbs * MB_SIZE -
+ ps_subset_sps->s_disp_offsets.u2_top_offset -
+ ps_subset_sps->s_disp_offsets.u2_bottom_offset))
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+
+ ps_subset_sps->s_sps_data.u1_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_subset_sps->s_sps_data.u1_vui_parameters_present_flag)
+ {
+ i4_error_code = ih264d_parse_vui_parametres(&ps_subset_sps->s_sps_data.s_vui, ps_bitstrm);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_subset_sps->s_sps_data.s_vui.u1_bitstream_restriction_flag &&
+ (ps_sps->s_vui.u4_num_reorder_frames !=
+ ps_subset_sps->s_sps_data.s_vui.u4_num_reorder_frames))
+ {
+ ps_view_ctxt->u1_res_changed = 1;
+
+ return IVD_RES_CHANGED;
+ }
+ }
+
+ if(ih264d_get_bit_h264(ps_bitstrm) != 1)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ u2_num_views_m1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u2_num_views_m1 >= MAX_NUM_VIEWS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ ps_subset_sps->s_sps_mvc_ext.u2_num_views = 1 + u2_num_views_m1;
+
+ if(ps_view_ctxt->i4_decode_header)
+ {
+ ps_mvcd_ctxt->u2_num_views = MAX(ps_mvcd_ctxt->u2_num_views, 1 + u2_num_views_m1);
+ }
+ else if(ps_mvcd_ctxt->u2_num_views != (1 + u2_num_views_m1))
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(i = 0; i <= u2_num_views_m1; i++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.au2_view_ids[i] =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+
+ for(i = 0; i < 2; i++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[i][0].u1_num_refs = 0;
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[i][0].u1_num_refs = 0;
+ }
+
+ for(i = 1; i <= u2_num_views_m1; i++)
+ {
+ u1_num_refs = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[0][i].u1_num_refs = u1_num_refs;
+
+ if(u1_num_refs > MAX_NUM_IVP_REFS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(j = 0; j < u1_num_refs; j++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[0][i].au2_ref_view_ids[j] =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+
+ u1_num_refs = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[1][i].u1_num_refs = u1_num_refs;
+
+ if(u1_num_refs > MAX_NUM_IVP_REFS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(j = 0; j < u1_num_refs; j++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[1][i].au2_ref_view_ids[j] =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ for(i = 1; i <= u2_num_views_m1; i++)
+ {
+ u1_num_refs = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[0][i].u1_num_refs = u1_num_refs;
+
+ if(u1_num_refs > MAX_NUM_IVP_REFS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(j = 0; j < u1_num_refs; j++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[0][i].au2_ref_view_ids[j] =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+
+ u1_num_refs = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[1][i].u1_num_refs = u1_num_refs;
+
+ if(u1_num_refs > MAX_NUM_IVP_REFS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(j = 0; j < u1_num_refs; j++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[1][i].au2_ref_view_ids[j] =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ u1_num_level_values_signalled_m1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.u1_num_level_values_signalled =
+ u1_num_level_values_signalled_m1 + 1;
+
+ if(u1_num_level_values_signalled_m1 >= MAX_NUM_LEVEL_VALUES_SIGNALLED)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(i = 0; i <= u1_num_level_values_signalled_m1; i++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info[i].u4_level_idc =
+ ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ u2_num_ops_m1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info->as_mvc_op_data[i].u2_num_ops =
+ 1 + u2_num_ops_m1;
+
+ if(u2_num_ops_m1 >= MAX_NUM_OPERATING_POINTS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(j = 0; j <= u2_num_ops_m1; j++)
+ {
+ UWORD16 u2_num_target_views_m1;
+
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info->as_mvc_op_data[j].u1_temporal_id =
+ ih264d_get_bits_h264(ps_bitstrm, 3);
+
+ u2_num_target_views_m1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info->as_mvc_op_data[j].u2_num_target_views =
+ 1 + u2_num_target_views_m1;
+
+ if(u2_num_target_views_m1 >= MAX_NUM_VIEWS)
+ {
+ return ERROR_INVALID_SEQ_PARAM;
+ }
+
+ for(k = 0; k <= u2_num_target_views_m1; k++)
+ {
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info->as_mvc_op_data[j]
+ .au2_target_view_ids[k] = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+
+ ps_subset_sps->s_sps_mvc_ext.as_mvc_level_info->as_mvc_op_data[j].u2_num_views =
+ (UWORD16) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ ps_subset_sps->u1_mvc_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_subset_sps->u1_mvc_vui_parameters_present_flag)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ /* In case bitstream read has exceeded the filled size, then
+ return an error */
+ if(EXCEED_OFFSET(ps_bitstrm))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ ps_subset_sps->s_sps_data.u1_is_valid = 1;
+
+ /* This ensures PPS has valid data in SPS array for reference */
+ ps_view_ctxt->ps_sps[ps_subset_sps->s_sps_data.u1_seq_parameter_set_id] =
+ ps_subset_sps->s_sps_data;
+
+ ps_mvcd_ctxt->u1_num_subset_sps++;
+
+ return OK;
+}
+
+/* This function removes emulation byte "0x03" from bitstream(EBSP to RBSP).
+ It also converts bytestream format into 32 bit little - endian format. */
+static WORD32 imvcd_transform_nalu(dec_bit_stream_t *ps_bitstrm, UWORD8 *pu1_nal_unit,
+ UWORD32 u4_numbytes_in_nal_unit)
+{
+ UWORD32 ui4_word;
+ UWORD8 u1_cur_byte;
+
+ static const UWORD32 u4_num_bytes_in_word = sizeof(ui4_word) / sizeof(u1_cur_byte);
+ UWORD32 u4_num_bytes_in_rbsp = 0;
+ WORD32 i = 0, j;
+ WORD8 c_count = 0;
+ UWORD32 *puc_bitstream_buffer = (UWORD32 *) pu1_nal_unit;
+ UWORD8 u1_nal_header_size = 1;
+ UWORD8 u1_num_bytes_copied = 0;
+
+ ps_bitstrm->pu4_buffer = puc_bitstream_buffer;
+
+ ui4_word = *pu1_nal_unit++;
+ u1_num_bytes_copied++;
+
+ if((NAL_UNIT_TYPE(ui4_word) == PREFIX_NAL) ||
+ (NAL_UNIT_TYPE(ui4_word) == CODED_SLICE_EXTENSION))
+ {
+ u1_nal_header_size += 3;
+ }
+
+ for(j = 0; j < 2; j++)
+ {
+ u1_cur_byte = *pu1_nal_unit++;
+
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u1_num_bytes_copied++;
+
+ c_count++;
+ u4_num_bytes_in_rbsp++;
+
+ if(u1_cur_byte != 0x00)
+ {
+ c_count = 0;
+ }
+ }
+
+ if(u4_numbytes_in_nal_unit > 2)
+ {
+ i = ((u4_numbytes_in_nal_unit - 3));
+ }
+
+ for(; i > 8; i -= 4)
+ {
+ // loop 0
+ u1_cur_byte = *pu1_nal_unit++;
+
+ if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE &&
+ u1_cur_byte == EMULATION_PREVENTION_BYTE)
+ {
+ c_count = 0;
+ u1_cur_byte = *pu1_nal_unit++;
+ i--;
+ }
+
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u1_num_bytes_copied++;
+ if(u4_num_bytes_in_word == u1_num_bytes_copied)
+ {
+ *puc_bitstream_buffer = ui4_word;
+ puc_bitstream_buffer++;
+ u1_num_bytes_copied = 0;
+ }
+
+ c_count++;
+ if(u1_cur_byte != 0x00) c_count = 0;
+
+ // loop 1
+ u1_cur_byte = *pu1_nal_unit++;
+
+ if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE &&
+ u1_cur_byte == EMULATION_PREVENTION_BYTE)
+ {
+ c_count = 0;
+ u1_cur_byte = *pu1_nal_unit++;
+ i--;
+ }
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u1_num_bytes_copied++;
+ if(u4_num_bytes_in_word == u1_num_bytes_copied)
+ {
+ *puc_bitstream_buffer = ui4_word;
+ puc_bitstream_buffer++;
+ u1_num_bytes_copied = 0;
+ }
+
+ c_count++;
+ if(u1_cur_byte != 0x00) c_count = 0;
+
+ // loop 2
+ u1_cur_byte = *pu1_nal_unit++;
+
+ if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE &&
+ u1_cur_byte == EMULATION_PREVENTION_BYTE)
+ {
+ c_count = 0;
+ u1_cur_byte = *pu1_nal_unit++;
+ i--;
+ }
+
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u1_num_bytes_copied++;
+ if(u4_num_bytes_in_word == u1_num_bytes_copied)
+ {
+ *puc_bitstream_buffer = ui4_word;
+ puc_bitstream_buffer++;
+ u1_num_bytes_copied = 0;
+ }
+
+ c_count++;
+ if(u1_cur_byte != 0x00) c_count = 0;
+
+ // loop 3
+ u1_cur_byte = *pu1_nal_unit++;
+
+ if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE &&
+ u1_cur_byte == EMULATION_PREVENTION_BYTE)
+ {
+ c_count = 0;
+ u1_cur_byte = *pu1_nal_unit++;
+ i--;
+ }
+
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u1_num_bytes_copied++;
+ if(u4_num_bytes_in_word == u1_num_bytes_copied)
+ {
+ *puc_bitstream_buffer = ui4_word;
+ puc_bitstream_buffer++;
+ u1_num_bytes_copied = 0;
+ }
+
+ c_count++;
+ if(u1_cur_byte != 0x00) c_count = 0;
+
+ u4_num_bytes_in_rbsp += 4;
+ }
+
+ for(; i > 0; i--)
+ {
+ u1_cur_byte = *pu1_nal_unit++;
+
+ if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE &&
+ u1_cur_byte == EMULATION_PREVENTION_BYTE)
+ {
+ c_count = 0;
+ i--;
+ u1_cur_byte = *pu1_nal_unit++;
+ }
+
+ ui4_word = ((ui4_word << 8) | u1_cur_byte);
+ u4_num_bytes_in_rbsp++;
+
+ if((u4_num_bytes_in_rbsp & 0x03) == 0x03)
+ {
+ *puc_bitstream_buffer = ui4_word;
+ puc_bitstream_buffer++;
+ }
+ c_count++;
+ if(u1_cur_byte != 0x00) c_count = 0;
+ }
+
+ *puc_bitstream_buffer = (ui4_word << ((3 - (((u4_num_bytes_in_rbsp << 30) >> 30))) << 3));
+ ps_bitstrm->u4_ofst = 0;
+ ps_bitstrm->u4_max_ofst = ((u4_num_bytes_in_rbsp + u1_nal_header_size) << 3);
+
+ return (u4_num_bytes_in_rbsp);
+}
+
+WORD32 imvcd_nalu_parser(mvc_dec_ctxt_t *ps_mvcd_ctxt, UWORD8 *pu1_bitstream_buf,
+ UWORD32 i4_nalu_length)
+{
+ AVC_EXT_NALU_ID_T e_nalu_id;
+
+ UWORD8 u1_first_byte;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ WORD32 i4_error_code = NOT_OK;
+
+ if((NULL != pu1_bitstream_buf) && (i4_nalu_length > 0))
+ {
+ imvcd_transform_nalu(ps_bitstrm, pu1_bitstream_buf, i4_nalu_length);
+
+ u1_first_byte = ih264d_get_bits_h264(ps_bitstrm, 8);
+
+ if(NAL_FORBIDDEN_BIT(u1_first_byte))
+ {
+ return NOT_OK;
+ }
+
+ e_nalu_id = NAL_UNIT_TYPE(u1_first_byte);
+ ps_view_ctxt->u1_nal_unit_type = e_nalu_id;
+
+ // if any other nal unit other than slice nal is encountered in between a
+ // frame break out of loop without consuming header
+ if((ps_view_ctxt->u4_slice_start_code_found == 1) &&
+ (ps_view_ctxt->u1_pic_decode_done != 1) && is_slice_nalu_type(e_nalu_id))
+ {
+ return ERROR_INCOMPLETE_FRAME;
+ }
+
+ switch(e_nalu_id)
+ {
+ case PREFIX_NAL:
+ {
+ if(!ps_view_ctxt->i4_decode_header)
+ {
+ if(1 == ih264d_get_bit_h264(ps_bitstrm))
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+
+ i4_error_code = imvcd_nalu_mvc_ext_parser(ps_mvcd_ctxt, ps_bitstrm);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ break;
+ }
+ case SUBSET_SPS:
+ {
+ ih264d_rbsp_to_sodb(ps_view_ctxt->ps_bitstrm);
+
+ i4_error_code = imvcd_parse_subset_sps(ps_mvcd_ctxt, ps_bitstrm);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->i4_header_decoded |= 1 << SUBSET_SPS;
+
+ break;
+ }
+ case SLICE_NON_IDR:
+ case SLICE_IDR:
+ {
+ if(!ps_view_ctxt->i4_decode_header)
+ {
+ if(is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) &&
+ is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS))
+ {
+ nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+
+ ps_view_ctxt->u4_slice_start_code_found = 1;
+
+ if((0 == ps_mvcd_ctxt->u2_num_views_decoded) &&
+ !ps_nalu_mvc_ext->u1_inter_view_flag)
+ {
+ ps_nalu_mvc_ext->u1_inter_view_flag = 1;
+ }
+
+ ih264d_rbsp_to_sodb(ps_view_ctxt->ps_bitstrm);
+
+ i4_error_code = imvcd_parse_decode_slice(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+ }
+
+ break;
+ }
+ case CODED_SLICE_EXTENSION:
+ {
+ if(!ps_view_ctxt->i4_decode_header)
+ {
+ if(is_header_decoded(ps_view_ctxt->i4_header_decoded, SPS) &&
+ is_header_decoded(ps_view_ctxt->i4_header_decoded, PPS) &&
+ is_header_decoded(ps_view_ctxt->i4_header_decoded, SUBSET_SPS))
+ {
+ ps_view_ctxt->u4_slice_start_code_found = 1;
+
+ if(1 == ih264d_get_bit_h264(ps_bitstrm))
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+
+ i4_error_code = imvcd_nalu_mvc_ext_parser(ps_mvcd_ctxt, ps_bitstrm);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ih264d_rbsp_to_sodb(ps_view_ctxt->ps_bitstrm);
+
+ i4_error_code = imvcd_parse_decode_slice(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ return IVD_INVALID_BITSTREAM;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ i4_error_code = ERROR_UNKNOWN_NAL;
+
+ break;
+ }
+ }
+ }
+
+ return i4_error_code;
+}
diff --git a/decoder/mvc/imvcd_nalu_parser.h b/decoder/mvc/imvcd_nalu_parser.h
new file mode 100644
index 0000000..1bf2ae4
--- /dev/null
+++ b/decoder/mvc/imvcd_nalu_parser.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_nalu_parser.h */
+/* */
+/* Description : Functions for MVC NALU parsing */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_NALU_PARSER_H_
+#define _IMVCD_NALU_PARSER_H_
+
+#include "ih264_typedefs.h"
+#include "imvcd_structs.h"
+
+extern WORD32 imvcd_nalu_parser(mvc_dec_ctxt_t *ps_mvcd_ctxt, UWORD8 *pu1_bitstream_buf,
+ UWORD32 i4_nalu_length);
+#endif
diff --git a/decoder/mvc/imvcd_slice_functions.c b/decoder/mvc/imvcd_slice_functions.c
new file mode 100644
index 0000000..e44f2a5
--- /dev/null
+++ b/decoder/mvc/imvcd_slice_functions.c
@@ -0,0 +1,2398 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_slice_functions.c */
+/* */
+/* Description : Functions for MVC Slice parsing, etc. */
+/* */
+/*****************************************************************************/
+
+#include "ih264_typedefs.h"
+#include "ih264_error.h"
+#include "ih264_buf_mgr.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_debug.h"
+#include "ih264d_defs.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_quant_scaling.h"
+#include "ih264d_tables.h"
+#include "ih264d_thread_compute_bs.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ih264d_structs.h"
+#include "ih264d_utils.h"
+#include "ih264d_api_utils.h"
+#include "ithread.h"
+#include "imvc_defs.h"
+#include "imvcd_dpb_manager.h"
+#include "imvcd_error_handler.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+static WORD32 imvcd_set_first_mb_in_slice(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u2_first_mb_in_slice = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(ps_cur_slice->u2_first_mb_in_slice >=
+ (ps_view_ctxt->u2_frm_ht_in_mbs * ps_view_ctxt->u2_frm_wd_in_mbs))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ if(((ps_cur_slice->u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) <=
+ ps_view_ctxt->u2_cur_mb_addr) &&
+ (ps_view_ctxt->u4_first_slice_in_pic == 0))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ COPYTHECONTEXT("SH: first_mb_in_slice", ps_cur_slice->u2_first_mb_in_slice);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_slice_type(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u1_slice_type = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(ps_cur_slice->u1_slice_type > 9)
+ {
+ return ERROR_INV_SLC_TYPE_T;
+ }
+
+ if(ps_cur_slice->u1_slice_type > 4)
+ {
+ ps_cur_slice->u1_slice_type -= 5;
+ }
+
+ COPYTHECONTEXT("SH: slice_type", ps_cur_slice->u1_slice_type);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_cur_pps(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_pps_id)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pu1_pps_id[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ ps_view_ctxt->ps_cur_pps = &ps_view_ctxt->ps_pps[pu1_pps_id[0]];
+ ps_view_ctxt->ps_cur_sps = ps_view_ctxt->ps_pps[pu1_pps_id[0]].ps_sps;
+
+ if(!ps_view_ctxt->ps_cur_pps->u1_is_valid || !ps_view_ctxt->ps_cur_pps->ps_sps->u1_is_valid)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: pps_id", pu1_pps_id[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_frame_num(dec_struct_t *ps_view_ctxt, UWORD8 u1_bits_in_frm_num)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, u1_bits_in_frm_num);
+
+ COPYTHECONTEXT("SH: frame_num", ps_cur_slice->u2_frame_num);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_idr_pic_id(dec_struct_t *ps_view_ctxt, UWORD32 *pu4_idr_pic_id)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pu4_idr_pic_id[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(pu4_idr_pic_id[0] > 65535)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: idr_pic_id", pu4_idr_pic_id[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_poc_lsb(dec_struct_t *ps_view_ctxt, WORD32 *pi4_pic_order_cnt_lsb,
+ WORD32 i4_max_poc_lsb, UWORD8 u1_log2_max_poc_lsb)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pi4_pic_order_cnt_lsb[0] = ih264d_get_bits_h264(ps_bitstrm, u1_log2_max_poc_lsb);
+
+ if((pi4_pic_order_cnt_lsb[0] < 0) || (pi4_pic_order_cnt_lsb[0] > i4_max_poc_lsb))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: pic_order_cnt_lsb", pi4_pic_order_cnt_lsb[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_delta_poc(dec_struct_t *ps_view_ctxt, WORD32 *pi4_delta_poc)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pi4_delta_poc[0] = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ COPYTHECONTEXT("SH: delta_pic_order_cnt", pi4_delta_poc[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_redundant_pic_cnt(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_redundant_pic_cnt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pu1_redundant_pic_cnt[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(pu1_redundant_pic_cnt[0] > MAX_REDUNDANT_PIC_CNT)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: redundant_pic_cnt", pu1_redundant_pic_cnt[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_direct_spatial_mv_pred_flag(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ COPYTHECONTEXT("SH: direct_spatial_mv_pred_flag", ps_cur_slice->u1_direct_spatial_mv_pred_flag);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_ref_idx_override_flag(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ COPYTHECONTEXT("SH: num_ref_idx_override_flag",
+ ps_cur_slice->u1_num_ref_idx_active_override_flag);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_num_ref_idx_active(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_num_ref_idx)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ UWORD32 u4_num_ref_idx_m1 = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(u4_num_ref_idx_m1 >= H264_MAX_REF_PICS)
+ {
+ return ERROR_NUM_REF;
+ }
+
+ pu1_num_ref_idx[0] = 1 + u4_num_ref_idx_m1;
+
+ COPYTHECONTEXT("SH: num_ref_idx_lx_active_minus1", u4_num_ref_idx_m1);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_ref_pic_list_reordering_flag(dec_struct_t *ps_view_ctxt,
+ UWORD8 *pu1_ref_idx_reorder_flag)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pu1_ref_idx_reorder_flag[0] = ih264d_get_bit_h264(ps_bitstrm);
+
+ COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_lx", pu1_ref_idx_reorder_flag[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_modification_of_pic_nums_idc(dec_struct_t *ps_view_ctxt,
+ UWORD8 *pu1_modification_of_pic_nums_idc)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pu1_modification_of_pic_nums_idc[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ COPYTHECONTEXT("SH: modification_of_pic_nums_idc", pu1_modification_of_pic_nums_idc[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_abs_diff_pic_num_minus1(dec_struct_t *ps_view_ctxt,
+ WORD32 *pi4_abs_diff_pic_num_minus1)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pi4_abs_diff_pic_num_minus1[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ COPYTHECONTEXT("SH: abs_diff_pic_num_minus1", pi4_abs_diff_pic_num_minus1[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_abs_diff_view_idx_minus1(dec_struct_t *ps_view_ctxt,
+ WORD32 *pi4_abs_diff_view_idx_minus1)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pi4_abs_diff_view_idx_minus1[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ COPYTHECONTEXT("SH: abs_diff_view_idx_minus1", pi4_abs_diff_view_idx_minus1[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_long_term_pic_num(dec_struct_t *ps_view_ctxt, WORD32 *pi4_long_term_pic_num)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ pi4_long_term_pic_num[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ COPYTHECONTEXT("SH: long_term_pic_num", pi4_long_term_pic_num[0]);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_cabac_init_idc(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+
+ ps_cur_slice->u1_cabac_init_idc = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(ps_cur_slice->u1_cabac_init_idc > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: cabac_init_idc", ps_cur_slice->u1_cabac_init_idc);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_slice_qp(dec_struct_t *ps_view_ctxt)
+{
+ WORD8 i1_slice_qp_delta;
+
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ dec_pic_params_t *ps_cur_pps = ps_view_ctxt->ps_cur_pps;
+
+ i1_slice_qp_delta = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+ ps_cur_slice->u1_slice_qp = i1_slice_qp_delta + ps_cur_pps->u1_pic_init_qp;
+
+ if(ps_cur_slice->u1_slice_qp > MAX_H264_QP)
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+
+ COPYTHECONTEXT("SH: slice_qp_delta", i1_slice_qp_delta);
+
+ return OK;
+}
+
+static WORD32 imvcd_set_slice_deblk_params(dec_struct_t *ps_view_ctxt)
+{
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ dec_pic_params_t *ps_cur_pps = ps_view_ctxt->ps_cur_pps;
+
+ if(ps_cur_pps->u1_deblocking_filter_parameters_present_flag)
+ {
+ ps_cur_slice->u1_disable_dblk_filter_idc =
+ ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer);
+
+ if(ps_cur_slice->u1_disable_dblk_filter_idc > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: disable_deblocking_filter_idc",
+ ps_cur_slice->u1_disable_dblk_filter_idc);
+
+ if(ps_cur_slice->u1_disable_dblk_filter_idc != 1)
+ {
+ ps_cur_slice->i1_slice_alpha_c0_offset =
+ ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer) << 1;
+
+ if((MIN_DBLK_FIL_OFF > ps_cur_slice->i1_slice_alpha_c0_offset) ||
+ (ps_cur_slice->i1_slice_alpha_c0_offset > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2",
+ ps_cur_slice->i1_slice_alpha_c0_offset >> 1);
+
+ ps_cur_slice->i1_slice_beta_offset =
+ ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer) << 1;
+
+ if((MIN_DBLK_FIL_OFF > ps_cur_slice->i1_slice_beta_offset) ||
+ (ps_cur_slice->i1_slice_beta_offset > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: slice_beta_offset_div2", ps_cur_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_cur_slice->u1_disable_dblk_filter_idc = 0;
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_set_ref_pic_list_mod_data(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i4_error_code;
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data =
+ imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt);
+
+ bool b_is_b_pic = ps_cur_slice->u1_slice_type == BSLICE;
+
+ for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
+ {
+ ps_ref_pic_list_mod_data->au1_num_active_refs[i] =
+ ps_cur_slice->u1_num_ref_idx_lx_active[i];
+
+ i4_error_code = imvcd_set_ref_pic_list_reordering_flag(
+ ps_view_ctxt, &ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i]);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i])
+ {
+ UWORD8 *pu1_modification_of_pic_nums_idc =
+ ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i];
+ WORD32 *pi4_abs_diff_pic_num_minus1 =
+ ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i];
+ WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i];
+ WORD32 *pi4_abs_diff_view_idx_minus1 =
+ ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i];
+ UWORD32 u4_pic_num_mod_count = 0;
+
+ do
+ {
+ i4_error_code = imvcd_set_modification_of_pic_nums_idc(
+ ps_view_ctxt, pu1_modification_of_pic_nums_idc);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if((0 == pu1_modification_of_pic_nums_idc[0]) ||
+ (1 == pu1_modification_of_pic_nums_idc[0]))
+ {
+ i4_error_code = imvcd_set_abs_diff_pic_num_minus1(ps_view_ctxt,
+ pi4_abs_diff_pic_num_minus1);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ else if(2 == pu1_modification_of_pic_nums_idc[0])
+ {
+ i4_error_code =
+ imvcd_set_long_term_pic_num(ps_view_ctxt, pi4_long_term_pic_num);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ else if((4 == pu1_modification_of_pic_nums_idc[0]) ||
+ (5 == pu1_modification_of_pic_nums_idc[0]))
+ {
+ i4_error_code = imvcd_set_abs_diff_view_idx_minus1(
+ ps_view_ctxt, pi4_abs_diff_view_idx_minus1);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ else if(3 != pu1_modification_of_pic_nums_idc[0])
+ {
+ return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ {
+ break;
+ }
+
+ pu1_modification_of_pic_nums_idc++;
+ pi4_abs_diff_pic_num_minus1++;
+ pi4_long_term_pic_num++;
+ pi4_abs_diff_view_idx_minus1++;
+ u4_pic_num_mod_count++;
+
+ if(u4_pic_num_mod_count > ps_ref_pic_list_mod_data->au1_num_active_refs[i])
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ } while(true);
+ }
+ }
+
+ return OK;
+}
+
+static WORD32 imvcd_decode_gaps_in_frame_num(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ pocstruct_t s_tmp_poc;
+
+ UWORD32 u4_start_frm_num;
+ WORD32 i4_poc;
+ WORD8 i1_gap_idx;
+ WORD8 *pi1_gaps_per_seq;
+ WORD32 i4_error_code;
+ WORD64 i8_display_poc;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
+ mvc_dpb_manager_t *ps_dpb_mgr = ps_mvcd_ctxt->ps_dpb_mgr;
+
+ UWORD16 u2_frame_num = ps_cur_slice->u2_frame_num;
+ WORD32 i4_frame_gaps = 0;
+ UWORD32 u4_next_frm_num = ps_view_ctxt->u2_prev_ref_frame_num + 1;
+ UWORD32 u4_max_frm_num = ps_view_ctxt->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
+ WORD32 *pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
+ bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt);
+
+ if(ps_cur_slice->u1_field_pic_flag)
+ {
+ if(ps_view_ctxt->u2_prev_ref_frame_num == u2_frame_num)
+ {
+ return OK;
+ }
+ }
+
+ if(u4_next_frm_num >= u4_max_frm_num)
+ {
+ u4_next_frm_num -= u4_max_frm_num;
+ }
+
+ if(u4_next_frm_num == u2_frame_num)
+ {
+ return OK;
+ }
+
+ if(b_is_idr_slice && (u4_next_frm_num >= u2_frame_num))
+ {
+ return OK;
+ }
+
+ u4_start_frm_num = u4_next_frm_num;
+
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = 0;
+
+ for(i1_gap_idx = 0; i1_gap_idx < MAX_FRAMES; i1_gap_idx++)
+ {
+ if(INVALID_FRAME_NUM == pi4_gaps_start_frm_num[i1_gap_idx])
+ {
+ break;
+ }
+ }
+
+ if(MAX_FRAMES == i1_gap_idx)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ i4_poc = 0;
+ pi4_gaps_start_frm_num[i1_gap_idx] = u4_start_frm_num;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = u2_frame_num - 1;
+ pi1_gaps_per_seq = ps_dpb_mgr->ai1_gaps_per_seq;
+ pi1_gaps_per_seq[i1_gap_idx] = 0;
+
+ while(u4_next_frm_num != u2_frame_num)
+ {
+ imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+
+ if(ps_pps->ps_sps->u1_pic_order_cnt_type)
+ {
+ /* allocate a picture buffer and insert it as ST node */
+ i4_error_code =
+ ih264d_decode_pic_order_cnt(0, u4_next_frm_num, &ps_view_ctxt->s_prev_pic_poc,
+ &s_tmp_poc, ps_cur_slice, ps_pps, 1, 0, 0, &i4_poc);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ /* Display seq no calculations */
+ if(i4_poc >= ps_view_ctxt->i4_max_poc)
+ {
+ ps_view_ctxt->i4_max_poc = i4_poc;
+ }
+
+ /* IDR Picture or POC wrap around */
+ if(i4_poc == 0)
+ {
+ imvcd_modulate_max_disp_seq(ps_view_ctxt);
+ }
+
+ ps_cur_slice->u1_mmco_equalto5 = 0;
+ ps_cur_slice->u2_frame_num = u4_next_frm_num;
+ }
+
+ if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_view_ctxt->u1_max_dec_frame_buffering)
+ {
+ i4_error_code = imvcd_dpb_assign_display_seq(ps_mvcd_ctxt->ps_dpb_mgr);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ i8_display_poc = ((WORD64) ps_view_ctxt->i4_prev_max_display_seq) + ((WORD64) i4_poc);
+
+ if(IS_OUT_OF_RANGE_S32(i8_display_poc))
+ {
+ ps_view_ctxt->i4_prev_max_display_seq = 0;
+ i8_display_poc = i4_poc;
+ }
+
+ i4_error_code = imvcd_dpb_insert_pic_in_display_list(ps_dpb_mgr, (WORD32) i8_display_poc,
+ u4_next_frm_num, DO_NOT_DISP);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ pi1_gaps_per_seq[i1_gap_idx]++;
+
+ i4_error_code =
+ imvcd_dpb_do_mmco_for_gaps(ps_dpb_mgr, ps_view_ctxt->ps_cur_sps->u1_num_ref_frames);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+
+ u4_next_frm_num++;
+
+ if(u4_next_frm_num >= u4_max_frm_num)
+ {
+ u4_next_frm_num -= u4_max_frm_num;
+ }
+
+ i4_frame_gaps++;
+ }
+
+ return OK;
+}
+
+static void imvcd_pocstruct_init(dec_struct_t *ps_view_ctxt)
+{
+ pocstruct_t *ps_prev_poc = &ps_view_ctxt->s_prev_pic_poc;
+ pocstruct_t *ps_cur_poc = &ps_view_ctxt->s_cur_pic_poc;
+
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst;
+ ps_prev_poc->u2_frame_num = ps_cur_poc->u2_frame_num;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5;
+
+ if(ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc)
+ {
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0];
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1];
+ ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field;
+ }
+}
+
+static WORD32 imvcd_pic_init(mvc_dec_ctxt_t *ps_mvcd_ctxt, pocstruct_t *ps_cur_poc, WORD32 i4_poc,
+ bool b_is_idr_slice)
+{
+ WORD32 i4_error_code;
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ pocstruct_t *ps_prev_poc = &ps_view_ctxt->s_cur_pic_poc;
+ dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice;
+ dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
+ dec_seq_params_t *ps_sps = ps_pps->ps_sps;
+ subset_sps_t *ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
+ nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+ dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status;
+ prev_seq_params_t *ps_prev_seq_params = &ps_view_ctxt->s_prev_seq_params;
+
+ UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views;
+ UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded;
+ UWORD16 u2_view_id = ps_nalu_mvc_ext->u2_view_id;
+ UWORD16 u2_frame_num = ps_cur_slice->u2_frame_num;
+
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0];
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1];
+ ps_prev_poc->u1_bot_field = ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag;
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst;
+ ps_prev_poc->u2_frame_num = u2_frame_num;
+
+ ps_view_ctxt->i1_prev_mb_qp_delta = 0;
+ ps_view_ctxt->i1_next_ctxt_idx = 0;
+ ps_view_ctxt->u4_use_intrapred_line_copy = 1;
+
+ if(ps_view_ctxt->u4_num_cores == 1)
+ {
+ ps_view_ctxt->u4_nmb_deblk = 1;
+ }
+ else
+ {
+ ps_view_ctxt->u4_nmb_deblk = 0;
+ }
+
+ ps_view_ctxt->u4_app_disable_deblk_frm = 0;
+ if(ps_view_ctxt->i4_degrade_type && ps_view_ctxt->i4_degrade_pics)
+ {
+ WORD32 i4_degrade_pic = 0;
+
+ ps_view_ctxt->i4_degrade_pic_cnt++;
+
+ /* If degrade is to be done in all frames, then do not check further */
+ switch(ps_view_ctxt->i4_degrade_pics)
+ {
+ case 4:
+ {
+ i4_degrade_pic = 1;
+
+ break;
+ }
+ case 3:
+ {
+ if(ps_cur_slice->u1_slice_type != I_SLICE)
+ {
+ i4_degrade_pic = 1;
+ }
+
+ break;
+ }
+ case 2:
+ {
+ if((ps_cur_slice->u1_slice_type != I_SLICE) &&
+ (ps_view_ctxt->i4_degrade_pic_cnt != ps_view_ctxt->i4_nondegrade_interval))
+ {
+ i4_degrade_pic = 1;
+ }
+
+ break;
+ }
+ case 1:
+ {
+ if(0 == ps_cur_slice->u1_nal_ref_idc)
+ {
+ i4_degrade_pic = 1;
+ }
+
+ break;
+ }
+ }
+
+ if(i4_degrade_pic)
+ {
+ if(ps_view_ctxt->i4_degrade_type & 0x2)
+ {
+ ps_view_ctxt->u4_app_disable_deblk_frm = 1;
+ }
+
+ if(0 == ps_cur_slice->u1_nal_ref_idc)
+ {
+ if(ps_view_ctxt->i4_degrade_type & 0x4)
+ {
+ ps_view_ctxt->i4_mv_frac_mask = 0;
+ }
+
+ if(ps_view_ctxt->i4_degrade_type & 0x8)
+ {
+ ps_view_ctxt->i4_mv_frac_mask = 0;
+ }
+ }
+ }
+ else
+ {
+ ps_view_ctxt->i4_degrade_pic_cnt = 0;
+ }
+ }
+
+ if((ps_cur_slice->u1_slice_type == I_SLICE) || (ps_cur_slice->u1_slice_type == SI_SLICE))
+ {
+ ps_err->u1_cur_pic_type = PIC_TYPE_I;
+ }
+ else
+ {
+ ps_err->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
+ }
+
+ if(ps_err->u1_pic_aud_i == PIC_TYPE_I)
+ {
+ ps_err->u1_cur_pic_type = PIC_TYPE_I;
+ ps_err->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
+ }
+
+ if(b_is_idr_slice)
+ {
+ if(ps_err->u1_err_flag)
+ {
+ imvcd_reset_dpb(ps_mvcd_ctxt->ps_dpb_mgr);
+ }
+
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ }
+
+ if(ps_view_ctxt->u1_init_dec_flag && ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending &&
+ (u2_view_order_id == (u2_num_views - 1)))
+ {
+ imvcd_release_all_ref_and_io_bufs(ps_mvcd_ctxt, MAX_DISP_BUFS_NEW);
+
+ ps_view_ctxt->u1_second_field = 0;
+ ps_view_ctxt->i4_cur_display_seq = 0;
+ ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending = 0;
+
+ imvcd_dpb_set_display_num(ps_mvcd_ctxt->ps_dpb_mgr, 0);
+ }
+
+ if(0 == u2_view_order_id)
+ {
+ imvcd_dpb_set_max_pic_num(ps_mvcd_ctxt->ps_dpb_mgr, ps_sps->u2_u4_max_pic_num_minus1 + 1);
+ imvcd_dpb_set_num_views(ps_mvcd_ctxt->ps_dpb_mgr, u2_num_views);
+ }
+
+ ps_view_ctxt->i4_pic_type = NA_SLICE;
+ ps_view_ctxt->i4_frametype = IV_NA_FRAME;
+ ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA;
+
+ ps_sps->u2_max_mb_addr = ps_sps->u2_frm_wd_in_mbs * ps_sps->u2_frm_ht_in_mbs - 1;
+ ps_view_ctxt->u2_frm_ht_in_mbs = ps_sps->u2_frm_ht_in_mbs;
+
+ if(!ps_view_ctxt->u1_init_dec_flag)
+ {
+ ps_view_ctxt->u1_max_dec_frame_buffering = ih264d_get_dpb_size(ps_sps);
+
+ ps_view_ctxt->i4_display_delay = ps_view_ctxt->u1_max_dec_frame_buffering;
+
+ if(ps_sps->u1_vui_parameters_present_flag && ps_sps->s_vui.u1_bitstream_restriction_flag)
+ {
+ if(ps_sps->u1_frame_mbs_only_flag)
+ {
+ ps_view_ctxt->i4_display_delay = ps_sps->s_vui.u4_num_reorder_frames + 1;
+ }
+ else
+ {
+ ps_view_ctxt->i4_display_delay = ps_sps->s_vui.u4_num_reorder_frames * 2 + 2;
+ }
+ }
+
+ if(IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode)
+ {
+ ps_view_ctxt->i4_display_delay = 0;
+ }
+
+ imvcd_dpb_set_display_delay(ps_mvcd_ctxt->ps_dpb_mgr, ps_view_ctxt->i4_display_delay);
+
+ ps_view_ctxt->u1_pic_bufs = ps_view_ctxt->i4_display_delay + ps_sps->u1_num_ref_frames + 1;
+ ps_view_ctxt->u1_pic_bufs += imvcd_get_max_num_ivp_refs(ps_mvcd_ctxt);
+ ps_view_ctxt->u1_pic_bufs = CLIP3(2, MVC_MAX_REF_PICS, ps_view_ctxt->u1_pic_bufs);
+
+ ps_view_ctxt->u1_max_dec_frame_buffering =
+ MIN(ps_view_ctxt->u1_max_dec_frame_buffering, ps_view_ctxt->u1_pic_bufs);
+
+ /*********************************************************************/
+ /* Configuring decoder parameters based on level and then */
+ /* fresh pointer initialisation in decoder scratch and state buffers */
+ /*********************************************************************/
+ i4_error_code = ih264d_init_dec_mb_grp(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_allocate_dynamic_bufs(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ imvcd_free_dynamic_bufs(ps_mvcd_ctxt);
+
+ return IVD_MEM_ALLOC_FAILED;
+ }
+
+ i4_error_code = imvcd_init_au_buffers(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_init_au_mv_pred_bufs(ps_mvcd_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->u1_init_dec_flag = 1;
+ ps_prev_seq_params->u2_frm_wd_in_mbs = ps_sps->u2_frm_wd_in_mbs;
+ ps_prev_seq_params->u1_level_idc = ps_sps->u1_level_idc;
+ ps_prev_seq_params->u1_profile_idc = ps_sps->u1_profile_idc;
+ ps_prev_seq_params->u2_frm_ht_in_mbs = ps_sps->u2_frm_ht_in_mbs;
+ ps_prev_seq_params->u1_frame_mbs_only_flag = ps_sps->u1_frame_mbs_only_flag;
+ ps_prev_seq_params->u1_direct_8x8_inference_flag = ps_sps->u1_direct_8x8_inference_flag;
+
+ ps_view_ctxt->i4_cur_display_seq = 0;
+ ps_view_ctxt->i4_prev_max_display_seq = 0;
+ ps_view_ctxt->i4_max_poc = 0;
+
+ imvcd_dpb_set_display_num(ps_mvcd_ctxt->ps_dpb_mgr, 0);
+
+ {
+ /* 0th entry of CtxtIncMbMap will be always be containing default values
+ for CABAC context representing MB not available */
+ ctxt_inc_mb_info_t *p_DefCtxt = ps_view_ctxt->p_ctxt_inc_mb_map - 1;
+ UWORD8 *pu1_temp;
+
+ p_DefCtxt->u1_mb_type = CAB_SKIP;
+
+ p_DefCtxt->u1_cbp = 0x0f;
+ p_DefCtxt->u1_intra_chroma_pred_mode = 0;
+
+ p_DefCtxt->u1_yuv_dc_csbp = 0x7;
+
+ p_DefCtxt->u1_transform8x8_ctxt = 0;
+
+ pu1_temp = (UWORD8 *) p_DefCtxt->i1_ref_idx;
+ for(i = 0; i < 4; i++, pu1_temp++)
+ {
+ (*pu1_temp) = 0;
+ }
+
+ pu1_temp = (UWORD8 *) p_DefCtxt->u1_mv;
+ for(i = 0; i < 16; i++, pu1_temp++)
+ {
+ (*pu1_temp) = 0;
+ }
+
+ ps_view_ctxt->ps_def_ctxt_mb_info = p_DefCtxt;
+ }
+ }
+
+ /* reset DBP commands read u4_flag */
+ ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read = 0;
+
+ ps_view_ctxt->pv_parse_tu_coeff_data = ps_view_ctxt->pv_pic_tu_coeff_data;
+ ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_pic_tu_coeff_data;
+ ps_view_ctxt->ps_nmb_info = ps_view_ctxt->ps_frm_mb_info;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ UWORD32 num_mbs;
+
+ num_mbs = ps_view_ctxt->ps_cur_sps->u2_total_num_of_mbs;
+
+ if(ps_view_ctxt->pu1_dec_mb_map)
+ {
+ memset((void *) ps_view_ctxt->pu1_dec_mb_map, 0, num_mbs);
+ }
+
+ if(ps_view_ctxt->pu1_recon_mb_map)
+ {
+ memset((void *) ps_view_ctxt->pu1_recon_mb_map, 0, num_mbs);
+ }
+
+ if(ps_view_ctxt->pu2_slice_num_map)
+ {
+ memset((void *) ps_view_ctxt->pu2_slice_num_map, 0, (num_mbs * sizeof(UWORD16)));
+ }
+ }
+
+ ps_view_ctxt->ps_parse_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]);
+ ps_view_ctxt->ps_decode_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]);
+ ps_view_ctxt->ps_computebs_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]);
+ ps_view_ctxt->u2_cur_slice_num = 0;
+
+ ps_view_ctxt->s_high_profile.u1_scaling_present = 0;
+ ps_view_ctxt->s_high_profile.u1_transform8x8_present = 0;
+
+ if(0 == u2_view_order_id)
+ {
+ mvc_au_buffer_t *ps_cur_au;
+ mvc_au_mv_pred_t *ps_au_mv_data;
+
+ WORD32 i4_pic_buf_id, i4_mv_buf_id;
+
+ ps_cur_au = (mvc_au_buffer_t *) ih264_buf_mgr_get_next_free(
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, &i4_pic_buf_id);
+
+ if(NULL == ps_cur_au)
+ {
+ return ERROR_UNAVAIL_PICBUF_T;
+ }
+ else
+ {
+ /* Buf will alwys be marked as REF here to ensure IVP works */
+ /* If AU nalRefIdc=0, REF status will be removed during endOfAU processing
+ */
+ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, i4_pic_buf_id,
+ BUF_MGR_IO | BUF_MGR_REF);
+ }
+
+ ps_au_mv_data = (mvc_au_mv_pred_t *) ih264_buf_mgr_get_next_free(
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt, &i4_mv_buf_id);
+
+ if(ps_au_mv_data == NULL)
+ {
+ return ERROR_UNAVAIL_MVBUF_T;
+ }
+ else
+ {
+ /* Buf will alwys be marked as REF here to ensure IVP works */
+ /* If AU nalRefIdc=0, REF status will be removed during endOfAU processing
+ */
+ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ i4_mv_buf_id, BUF_MGR_REF);
+ }
+
+ ps_mvcd_ctxt->ps_cur_au = ps_cur_au;
+
+ ps_cur_au->s_sei_pic = ps_view_ctxt->ps_sei[0];
+
+ ps_cur_au->i4_mv_buf_id = i4_mv_buf_id;
+ ps_cur_au->ps_au_mv_data = ps_au_mv_data;
+ ps_cur_au->i4_poc = i4_poc;
+ ps_cur_au->i4_avg_poc = i4_poc;
+ ps_cur_au->i4_frame_num = u2_frame_num;
+ ps_cur_au->i4_pic_num = u2_frame_num;
+ ps_cur_au->u4_time_stamp = ps_view_ctxt->u4_ts;
+ ps_cur_au->u1_picturetype = FRM_PIC;
+ ps_cur_au->u2_disp_width = ps_view_ctxt->u2_disp_width;
+ ps_cur_au->u2_disp_height = ps_view_ctxt->u2_disp_height;
+
+ memset(ps_cur_au->au4_pack_slc_typ, 0, sizeof(ps_cur_au->au4_pack_slc_typ));
+
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id] = i4_mv_buf_id;
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.aps_buf_id_to_au_buf_map[i4_pic_buf_id] = ps_cur_au;
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.aps_buf_id_to_mv_pred_buf_map[i4_mv_buf_id] =
+ ps_au_mv_data;
+
+ ps_view_ctxt->au1_pic_buf_ref_flag[i4_pic_buf_id] = 0;
+
+ ps_cur_au->s_ivp_data.b_is_ivp_ref = false;
+
+ imvcd_dpb_init_au_bufs(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_au);
+ }
+
+ if(u2_view_order_id > 0)
+ {
+ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id] =
+ ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[ps_pps->u1_pic_parameter_set_id]
+ ->s_disp_offsets;
+ }
+ else
+ {
+ /* Accounting for lihbavc's idiocy */
+ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_left_offset =
+ ps_view_ctxt->u2_crop_offset_y;
+ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_right_offset = 0;
+ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_top_offset = 0;
+ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_bottom_offset = 0;
+ }
+
+ for(i = 0; i < 2; i++)
+ {
+ ps_view_ctxt->ps_ref_pic_buf_lx[i] = imvcd_dpb_get_view_ref_pic_list(
+ ps_mvcd_ctxt->ps_dpb_mgr, u2_view_order_id, u2_view_id, i);
+
+ imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt);
+ }
+
+ if(ps_mvcd_ctxt->u2_num_views > 1)
+ {
+ imvcd_dpb_init_view_bufs(ps_mvcd_ctxt->ps_dpb_mgr, u2_view_order_id, u2_view_id);
+
+ imvcd_dpb_init_ivp_ctxt(ps_mvcd_ctxt->ps_dpb_mgr, &ps_subset_sps->s_sps_mvc_ext,
+ ps_mvcd_ctxt->as_nalu_mvc_ext);
+ }
+
+ ps_view_ctxt->u4_pic_buf_got = 1;
+ ps_cur_slice->u1_mbaff_frame_flag = 0;
+
+ ps_view_ctxt->ps_cur_mb_row = ps_view_ctxt->ps_nbr_mb_row;
+ // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be
+ // valid
+ ps_view_ctxt->ps_cur_mb_row += 2;
+ ps_view_ctxt->ps_top_mb_row = ps_view_ctxt->ps_nbr_mb_row;
+ ps_view_ctxt->ps_top_mb_row += ps_view_ctxt->u2_frm_wd_in_mbs + 2;
+ // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be
+ // valid
+ ps_view_ctxt->ps_top_mb_row += 2;
+ ps_view_ctxt->u1_mb_idx = 0;
+ ps_view_ctxt->u2_total_mbs_coded = 0;
+ ps_view_ctxt->i4_submb_ofst = -(SUB_BLK_SIZE);
+ ps_view_ctxt->i2_prev_slice_mbx = -1;
+ ps_view_ctxt->i2_prev_slice_mby = 0;
+
+ ps_view_ctxt->u4_pred_info_idx = 0;
+ ps_view_ctxt->u4_pred_info_pkd_idx = 0;
+ ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params;
+
+ ps_view_ctxt->u4_dma_buf_idx = 0;
+
+ ps_view_ctxt->ps_mv_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id];
+ ps_view_ctxt->ps_mv_top = ps_view_ctxt->ps_mv_top_p[0];
+ ps_view_ctxt->u1_mv_top_p = 0;
+ ps_view_ctxt->ps_mv_left = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id];
+ ps_view_ctxt->ps_mv = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id];
+ ps_view_ctxt->ps_mv_bank_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id];
+ ps_view_ctxt->pu1_col_zero_flag =
+ ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->apu1_mode_descriptors[u2_view_id];
+ ps_view_ctxt->u2_mv_2mb[0] = 0;
+ ps_view_ctxt->u2_mv_2mb[1] = 0;
+
+ ps_view_ctxt->u1_last_pic_not_decoded = 0;
+ ps_view_ctxt->u2_cur_slice_num_dec_thread = 0;
+ ps_view_ctxt->u2_cur_slice_num_bs = 0;
+
+ ps_view_ctxt->u4_intra_pred_line_ofst = 0;
+ ps_view_ctxt->pu1_cur_y_intra_pred_line = ps_view_ctxt->pu1_y_intra_pred_line;
+ ps_view_ctxt->pu1_cur_u_intra_pred_line = ps_view_ctxt->pu1_u_intra_pred_line;
+ ps_view_ctxt->pu1_cur_v_intra_pred_line = ps_view_ctxt->pu1_v_intra_pred_line;
+ ps_view_ctxt->pu1_cur_y_intra_pred_line_base = ps_view_ctxt->pu1_y_intra_pred_line;
+ ps_view_ctxt->pu1_cur_u_intra_pred_line_base = ps_view_ctxt->pu1_u_intra_pred_line;
+ ps_view_ctxt->pu1_cur_v_intra_pred_line_base = ps_view_ctxt->pu1_v_intra_pred_line;
+ ps_view_ctxt->pu1_prev_y_intra_pred_line =
+ ps_view_ctxt->pu1_y_intra_pred_line + (ps_view_ctxt->u2_frm_wd_in_mbs * MB_SIZE);
+ ps_view_ctxt->pu1_prev_u_intra_pred_line =
+ ps_view_ctxt->pu1_u_intra_pred_line +
+ ps_view_ctxt->u2_frm_wd_in_mbs * BLK8x8SIZE * YUV420SP_FACTOR;
+ ps_view_ctxt->pu1_prev_v_intra_pred_line =
+ ps_view_ctxt->pu1_v_intra_pred_line + ps_view_ctxt->u2_frm_wd_in_mbs * BLK8x8SIZE;
+
+ ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_deblk_pic;
+
+ ps_view_ctxt->pf_compute_bs = ih264d_compute_bs_non_mbaff;
+ ps_view_ctxt->u1_cur_mb_fld_dec_flag = ps_cur_slice->u1_field_pic_flag;
+
+ if(0 == u2_view_order_id)
+ {
+ imvcd_assign_pic_num(ps_mvcd_ctxt->ps_dpb_mgr, ps_sps->u2_u4_max_pic_num_minus1 + 1,
+ ps_mvcd_ctxt->ps_cur_au->i4_frame_num,
+ ps_sps->u1_gaps_in_frame_num_value_allowed_flag);
+
+ ps_view_ctxt->s_tran_addrecon.u2_mv_top_left_inc = (ps_view_ctxt->u1_recon_mb_grp << 2) - 1;
+ ps_view_ctxt->s_tran_addrecon.u2_mv_left_inc = (ps_view_ctxt->u1_recon_mb_grp - 1) << 4;
+ }
+
+ if((ps_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_sps->u1_profile_idc == MULTIVIEW_HIGH_PROFILE_IDC))
+ {
+ if((ps_sps->i4_seq_scaling_matrix_present_flag) ||
+ (ps_pps->i4_pic_scaling_matrix_present_flag))
+ {
+ i4_error_code = ih264d_form_scaling_matrix_picture(ps_sps, ps_pps, ps_view_ctxt);
+ ps_view_ctxt->s_high_profile.u1_scaling_present = 1;
+ }
+ else
+ {
+ i4_error_code = ih264d_form_default_scaling_matrix(ps_view_ctxt);
+ }
+
+ if(ps_pps->i4_transform_8x8_mode_flag)
+ {
+ ps_view_ctxt->s_high_profile.u1_transform8x8_present = 1;
+ }
+ }
+ else
+ {
+ i4_error_code = ih264d_form_default_scaling_matrix(ps_view_ctxt);
+ }
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->s_high_profile.u1_direct_8x8_inference_flag =
+ ps_sps->u1_direct_8x8_inference_flag;
+ ps_view_ctxt->s_high_profile.s_cavlc_ctxt = ps_view_ctxt->s_cavlc_ctxt;
+
+ ps_view_ctxt->i1_recon_in_thread3_flag = 1;
+
+ ps_view_ctxt->ps_cur_pic = &ps_view_ctxt->s_cur_pic;
+ imvcd_convert_au_buf_to_view_buf(ps_mvcd_ctxt->ps_cur_au, &ps_view_ctxt->s_cur_pic,
+ u2_view_order_id, u2_view_id);
+
+ ih264d_init_deblk_tfr_ctxt(ps_view_ctxt, &ps_view_ctxt->s_pad_mgr,
+ &ps_view_ctxt->s_tran_addrecon, ps_view_ctxt->u2_frm_wd_in_mbs, 0);
+
+ ps_view_ctxt->ps_frame_buf_ip_recon = &ps_view_ctxt->s_tran_addrecon;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ ps_view_ctxt->s_tran_addrecon_parse = ps_view_ctxt->s_tran_addrecon;
+
+ if((ps_view_ctxt->u4_num_cores >= 3) && ps_view_ctxt->i1_recon_in_thread3_flag)
+ {
+ ps_view_ctxt->s_tran_iprecon = ps_view_ctxt->s_tran_addrecon;
+ ps_view_ctxt->ps_frame_buf_ip_recon = &ps_view_ctxt->s_tran_iprecon;
+ }
+ }
+
+ ps_view_ctxt->ps_cur_deblk_mb = ps_view_ctxt->ps_deblk_pic;
+ ps_view_ctxt->u4_cur_deblk_mb_num = 0;
+
+ ps_view_ctxt->u4_deblk_mb_x = 0;
+ ps_view_ctxt->u4_deblk_mb_y = 0;
+ ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat;
+
+ ps_view_ctxt->u4_first_slice_in_pic = 0;
+
+ return OK;
+}
+
+static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_mb_info_t *ps_cur_mb_info;
+ parse_pmbarams_t *ps_parse_mb_data;
+ deblk_mb_t *ps_cur_deblk_mb;
+ parse_part_params_t *ps_part_info;
+
+ UWORD32 u4_num_mbs_next;
+ bool b_is_end_of_row;
+ bool b_is_slice_end;
+ bool b_tfr_n_mb;
+ bool b_decode_nmb;
+ UWORD8 u1_inter_mb_type;
+ UWORD8 u1_deblk_mb_type;
+ UWORD32 u4_num_mbsNby2;
+ UWORD16 i2_cur_mb_addr;
+ UWORD32 u4_mb_skip_run;
+ WORD32 i, j;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice;
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+
+ UWORD32 u4_num_mbs = 0;
+ UWORD32 u4_mb_idx = ps_view_ctxt->u1_mb_idx;
+ UWORD32 u4_remaining_mbs =
+ (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1) - ps_view_ctxt->u2_total_mbs_coded;
+
+ if(ps_view_ctxt->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+ {
+ imvcd_free_ref_and_io_bufs(&ps_mvcd_ctxt->s_mvc_au_buf_mgr,
+ &ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr,
+ ps_mvcd_ctxt->ps_cur_au->i4_pic_buf_id);
+
+ return OK;
+ }
+
+ if((ISLICE == ps_slice->u1_slice_type) || (0 == ps_view_ctxt->u2_total_mbs_coded))
+ {
+ yuv_buf_props_t *ps_view_buf =
+ &ps_mvcd_ctxt->ps_cur_au->as_view_buffers[ps_cur_nalu_mvc_ext->u2_view_id];
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ buffer_container_t *ps_component_buf = &ps_view_buf->as_component_bufs[i];
+
+ bool b_is_chroma = ((COMPONENT_TYPES_T) i) != Y;
+ UWORD16 u2_height = ps_view_buf->u2_height >> b_is_chroma;
+ UWORD16 u2_width = ps_view_buf->u2_width;
+
+ for(j = 0; j < u2_height; j++)
+ {
+ UWORD8 *pu1_data =
+ ((UWORD8 *) ps_component_buf->pv_data) + j * ps_component_buf->i4_data_stride;
+
+ memset(pu1_data, 128, u2_width * sizeof(pu1_data[0]));
+ }
+ }
+
+ memset(ps_view_ctxt->apv_buf_id_pic_buf_map, 0,
+ sizeof(ps_view_ctxt->apv_buf_id_pic_buf_map));
+
+ ps_view_ctxt->apv_buf_id_pic_buf_map[ps_mvcd_ctxt->ps_cur_au->i4_pic_buf_id] =
+ &ps_view_ctxt->s_cur_pic;
+ ps_view_ctxt->ps_ref_pic_buf_lx[0] = &ps_view_ctxt->ps_cur_pic;
+ (ps_view_ctxt->ppv_map_ref_idx_to_poc + FRM_LIST_L0)[0] =
+ ps_view_ctxt->ps_cur_pic->pu1_buf1;
+ (ps_view_ctxt->ppv_map_ref_idx_to_poc + FRM_LIST_L1)[0] = NULL;
+ }
+
+ ps_view_ctxt->ps_dpb_cmds->u1_long_term_reference_flag = 0;
+
+ if(ps_view_ctxt->u2_total_mbs_coded > 0)
+ {
+ ps_view_ctxt->u2_total_mbs_coded -=
+ ps_view_ctxt->u2_total_mbs_coded % ps_view_ctxt->ps_cur_sps->u2_frm_wd_in_mbs;
+ u4_remaining_mbs =
+ (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1) - ps_view_ctxt->u2_total_mbs_coded;
+
+ while(ps_view_ctxt->u4_dec_thread_created &&
+ (ps_view_ctxt->cur_dec_mb_num < ps_view_ctxt->u2_total_mbs_coded))
+ {
+ NOP(1 << 10);
+ }
+
+ while(ps_view_ctxt->u4_bs_deblk_thread_created &&
+ (ps_view_ctxt->cur_recon_mb_num < ps_view_ctxt->u2_total_mbs_coded))
+ {
+ NOP(1 << 10);
+ }
+
+ while(ps_view_ctxt->u4_bs_deblk_thread_created &&
+ (ps_view_ctxt->u4_cur_deblk_mb_num < ps_view_ctxt->u2_total_mbs_coded))
+ {
+ NOP(1 << 10);
+ }
+
+ ps_view_ctxt->ps_nmb_info = ps_view_ctxt->ps_frm_mb_info + ps_view_ctxt->u2_total_mbs_coded;
+ ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_cur_deblk_mb =
+ ps_view_ctxt->ps_deblk_pic + ps_view_ctxt->u2_total_mbs_coded;
+ }
+
+ u4_num_mbs = ps_view_ctxt->u4_num_mbs_cur_nmb = 0;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ ps_cur_mb_info = ps_view_ctxt->ps_nmb_info;
+ }
+ else
+ {
+ ps_cur_mb_info = ps_view_ctxt->ps_nmb_info + ps_view_ctxt->u4_num_mbs_prev_nmb - 1;
+ }
+
+ ps_view_ctxt->u2_mby = ps_cur_mb_info->u2_mby;
+ ps_view_ctxt->u2_mbx = ps_cur_mb_info->u2_mbx;
+
+ ps_view_ctxt->u1_mb_ngbr_availablity = ps_cur_mb_info->u1_mb_ngbr_availablity;
+
+ if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1))
+ {
+ ps_view_ctxt->u1_pic_decode_done = 1;
+
+ return OK;
+ }
+
+ /******************************************************/
+ /* Initializations to new slice */
+ /******************************************************/
+ ps_view_ctxt->ps_parse_cur_slice->ppv_map_ref_idx_to_poc =
+ (volatile void **) ps_view_ctxt->pv_map_ref_idx_to_poc_buf;
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ ps_slice->u2_first_mb_in_slice = ps_view_ctxt->u2_total_mbs_coded;
+ ps_view_ctxt->ps_parse_cur_slice->u4_first_mb_in_slice = ps_view_ctxt->u2_total_mbs_coded;
+ ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_slice->u2_log2Y_crwd;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ ps_view_ctxt->ps_parse_cur_slice->pv_tu_coeff_data_start =
+ ps_view_ctxt->pv_parse_tu_coeff_data;
+ }
+ else
+ {
+ ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_parse_tu_coeff_data;
+ }
+
+ /******************************************************/
+ /* Initializations specific to P slice */
+ /******************************************************/
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+
+ ps_slice->u1_slice_type = P_SLICE;
+ ps_view_ctxt->ps_parse_cur_slice->slice_type = P_SLICE;
+ ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb;
+ ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params;
+ ps_view_ctxt->u2_mbx =
+ MOD(ps_view_ctxt->u2_total_mbs_coded - 1, ps_view_ctxt->u2_frm_wd_in_mbs);
+ ps_view_ctxt->u2_mby =
+ DIV(ps_view_ctxt->u2_total_mbs_coded - 1, ps_view_ctxt->u2_frm_wd_in_mbs);
+
+ /******************************************************/
+ /* Parsing / decoding the slice */
+ /******************************************************/
+ ps_view_ctxt->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_view_ctxt, 0);
+ u4_mb_idx = ps_view_ctxt->u1_mb_idx;
+ ps_parse_mb_data = ps_view_ctxt->ps_parse_mb_data;
+ u4_num_mbs = u4_mb_idx;
+
+ b_is_slice_end = false;
+ b_tfr_n_mb = false;
+ b_decode_nmb = false;
+ u4_num_mbsNby2 = 0;
+ i2_cur_mb_addr = ps_view_ctxt->u2_total_mbs_coded;
+ u4_mb_skip_run = u4_remaining_mbs;
+
+ while(!b_is_slice_end)
+ {
+ if(i2_cur_mb_addr > ps_view_ctxt->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_view_ctxt->ps_nmb_info + u4_num_mbs;
+ ps_view_ctxt->u4_num_mbs_cur_nmb = u4_num_mbs;
+
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ ps_view_ctxt->u4_num_pmbair = u4_num_mbs;
+ ps_cur_deblk_mb = ps_view_ctxt->ps_deblk_mbn + u4_num_mbs;
+
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ /**************************************************************/
+ /* Get the required information for decoding of MB */
+ /**************************************************************/
+ /* mb_x, mb_y, neighbor availablity, */
+ ih264d_get_mb_info_cavlc_nonmbaff(ps_view_ctxt, i2_cur_mb_addr, ps_cur_mb_info,
+ u4_mb_skip_run);
+
+ if(ps_view_ctxt->u4_app_disable_deblk_frm == 0)
+ {
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_view_ctxt->u1_mb_ngbr_availablity,
+ ps_view_ctxt->u1_cur_mb_fld_dec_flag);
+ }
+
+ ps_view_ctxt->i1_prev_mb_qp_delta = 0;
+ ps_view_ctxt->u1_sub_mb_num = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_mb_mc_mode = PRED_16x16;
+ ps_cur_mb_info->u1_cbp = 0;
+
+ /* Storing Skip partition info */
+ ps_part_info = ps_view_ctxt->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_view_ctxt->ps_part++;
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_view_ctxt, ps_cur_mb_info, CAVLC);
+
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ u4_mb_skip_run--;
+
+ ps_cur_deblk_mb->u1_mb_qp = ps_view_ctxt->u1_qp;
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+
+ i2_cur_mb_addr++;
+ u4_num_mbs++;
+ u4_num_mbsNby2++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u4_num_mbs_next = ps_view_ctxt->ps_cur_sps->u2_frm_wd_in_mbs - 1 - ps_view_ctxt->u2_mbx;
+ b_is_end_of_row = (0 == u4_num_mbs_next);
+ b_is_slice_end = !u4_mb_skip_run;
+ ps_cur_mb_info->u1_end_of_slice = !u4_mb_skip_run;
+ b_tfr_n_mb =
+ (u4_num_mbs == ps_view_ctxt->u1_recon_mb_grp) || b_is_end_of_row || b_is_slice_end;
+ b_decode_nmb = b_tfr_n_mb || b_is_slice_end;
+
+ if(b_decode_nmb)
+ {
+ ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb(ps_view_ctxt, u4_mb_idx, u4_num_mbs);
+
+ u4_num_mbsNby2 = 0;
+ ps_parse_mb_data = ps_view_ctxt->ps_parse_mb_data;
+ ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_view_ctxt, u4_mb_idx, u4_num_mbs, u4_num_mbs_next,
+ b_tfr_n_mb, b_is_end_of_row);
+
+ ps_view_ctxt->ps_nmb_info += u4_num_mbs;
+ }
+ else
+ {
+ ih264d_decode_recon_tfr_nmb(ps_view_ctxt, u4_mb_idx, u4_num_mbs, u4_num_mbs_next,
+ b_tfr_n_mb, b_is_end_of_row);
+ }
+
+ ps_view_ctxt->u2_total_mbs_coded += u4_num_mbs;
+
+ if(b_tfr_n_mb)
+ {
+ u4_num_mbs = 0;
+ }
+
+ u4_mb_idx = u4_num_mbs;
+ ps_view_ctxt->u1_mb_idx = u4_num_mbs;
+ }
+ }
+
+ ps_view_ctxt->u4_num_mbs_cur_nmb = 0;
+ ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx;
+ ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby;
+
+ if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1))
+ {
+ ps_view_ctxt->u1_pic_decode_done = 1;
+ }
+
+ return 0;
+}
+
+static WORD32 imvcd_parse_pslice(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ UWORD8 u1_num_ref_idx_l0, u1_num_ref_idx_l1;
+ WORD32 i4_error_code;
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+ dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ ps_view_ctxt->s_default_mv_pred = imvcd_get_default_mv_pred();
+
+ i4_error_code = imvcd_set_ref_idx_override_flag(ps_view_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_slice->u1_num_ref_idx_active_override_flag)
+ {
+ i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l0);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ u1_num_ref_idx_l0 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ }
+
+ u1_num_ref_idx_l1 = 0;
+
+ ps_slice->u1_num_ref_idx_lx_active[0] = u1_num_ref_idx_l0;
+ ps_slice->u1_num_ref_idx_lx_active[1] = u1_num_ref_idx_l1;
+ ps_view_ctxt->u1_num_ref_idx_lx_active_prev = ps_slice->u1_num_ref_idx_lx_active[0];
+
+ i4_error_code =
+ imvcd_init_ref_pic_list(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext,
+ ps_mvcd_ctxt->ps_cur_au, ps_mvcd_ctxt->u2_num_views_decoded);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_ref_pic_list_mod_data(ps_mvcd_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_dpb_reorder_ref_pic_list(
+ ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au,
+ imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt), ps_mvcd_ctxt->u2_num_views_decoded);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->ps_ref_pic_buf_lx[0] = imvcd_dpb_get_view_ref_pic_list(
+ ps_mvcd_ctxt->ps_dpb_mgr, ps_mvcd_ctxt->u2_num_views_decoded,
+ ps_cur_nalu_mvc_ext->u2_view_id, 0);
+
+ for(i = 0; i < u1_num_ref_idx_l0; i++)
+ {
+ if(NULL == ps_view_ctxt->ps_ref_pic_buf_lx[0][i]->pu1_buf1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+ }
+
+ imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt);
+
+ imvcd_init_ref_idx_to_ref_buf_map(ps_mvcd_ctxt);
+
+ if(ps_pps->u1_wted_pred_flag)
+ {
+ i4_error_code = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ih264d_form_pred_weight_matrix(ps_view_ctxt);
+ }
+ else
+ {
+ ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd = 0;
+ }
+
+ ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat;
+ ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd;
+
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ WORD32 i4_bit_offset = ih264d_read_mmco_commands(ps_view_ctxt);
+
+ if(i4_bit_offset < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_view_ctxt->u4_bitoffset = i4_bit_offset;
+ }
+ else
+ {
+ ps_bitstrm->u4_ofst += ps_view_ctxt->u4_bitoffset;
+ }
+ }
+
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ i4_error_code = imvcd_set_cabac_init_idc(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ i4_error_code = imvcd_set_slice_qp(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_slice_deblk_params(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->u1_slice_header_done = 1;
+
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac;
+ ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_pmb_cabac;
+ ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff;
+
+ ih264d_init_cabac_contexts(P_SLICE, ps_view_ctxt);
+ }
+ else
+ {
+ ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc;
+ ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_pmb_cavlc;
+ ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff;
+ }
+
+ ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb;
+
+ ps_view_ctxt->u1_B = 0;
+
+ i4_error_code =
+ ps_view_ctxt->pf_parse_inter_slice(ps_view_ctxt, ps_slice, ps_slice->u2_first_mb_in_slice);
+
+ return i4_error_code;
+}
+
+static WORD32 imvcd_parse_bslice(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ UWORD8 u1_num_ref_idx_l0, u1_num_ref_idx_l1;
+ WORD32 i4_error_code;
+ WORD32 i, j;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+ dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+
+ ps_view_ctxt->s_default_mv_pred = imvcd_get_default_mv_pred();
+
+ i4_error_code = imvcd_set_ref_idx_override_flag(ps_view_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_slice->u1_num_ref_idx_active_override_flag)
+ {
+ i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l0);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l1);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ u1_num_ref_idx_l0 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ u1_num_ref_idx_l1 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[1];
+ }
+
+ if((0 == u1_num_ref_idx_l0) || (0 == u1_num_ref_idx_l1))
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_slice->u1_num_ref_idx_lx_active[0] = u1_num_ref_idx_l0;
+ ps_slice->u1_num_ref_idx_lx_active[1] = u1_num_ref_idx_l1;
+ ps_view_ctxt->u1_num_ref_idx_lx_active_prev =
+ ps_view_ctxt->ps_cur_slice->u1_num_ref_idx_lx_active[0];
+
+ i4_error_code =
+ imvcd_init_ref_pic_list(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext,
+ ps_mvcd_ctxt->ps_cur_au, ps_mvcd_ctxt->u2_num_views_decoded);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_ref_pic_list_mod_data(ps_mvcd_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_dpb_reorder_ref_pic_list(
+ ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au,
+ imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt), ps_mvcd_ctxt->u2_num_views_decoded);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ for(i = 0; i < 2; i++)
+ {
+ ps_view_ctxt->ps_ref_pic_buf_lx[i] = imvcd_dpb_get_view_ref_pic_list(
+ ps_mvcd_ctxt->ps_dpb_mgr, ps_mvcd_ctxt->u2_num_views_decoded,
+ ps_cur_nalu_mvc_ext->u2_view_id, i);
+
+ for(j = 0; j < ps_slice->u1_num_ref_idx_lx_active[i]; j++)
+ {
+ if(NULL == ps_view_ctxt->ps_ref_pic_buf_lx[i][j]->pu1_buf1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+ }
+ }
+
+ imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt);
+
+ imvcd_init_ref_idx_to_ref_buf_map(ps_mvcd_ctxt);
+
+ if(ps_pps->u1_wted_bipred_idc == 1)
+ {
+ i4_error_code = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ih264d_form_pred_weight_matrix(ps_view_ctxt);
+
+ ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat;
+ }
+ else if(ps_pps->u1_wted_bipred_idc == 2)
+ {
+ /* Implicit Weighted prediction */
+ ps_slice->u2_log2Y_crwd = 0x0505;
+ ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat;
+
+ ih264d_get_implicit_weights(ps_view_ctxt);
+ }
+ else
+ {
+ ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd = 0;
+ }
+
+ ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd;
+
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ WORD32 i4_bit_offset = ih264d_read_mmco_commands(ps_view_ctxt);
+
+ if(i4_bit_offset < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
+ ps_view_ctxt->u4_bitoffset = i4_bit_offset;
+ }
+ else
+ {
+ ps_bitstrm->u4_ofst += ps_view_ctxt->u4_bitoffset;
+ }
+ }
+
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ i4_error_code = imvcd_set_cabac_init_idc(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+
+ i4_error_code = imvcd_set_slice_qp(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_slice_deblk_params(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->u1_slice_header_done = 1;
+
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac;
+ ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_bmb_cabac;
+ ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff;
+
+ ih264d_init_cabac_contexts(B_SLICE, ps_view_ctxt);
+ }
+ else
+ {
+ ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc;
+ ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_bmb_cavlc;
+ ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff;
+ }
+
+ i4_error_code = ih264d_cal_col_pic(ps_view_ctxt);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ ps_view_ctxt->u1_B = 1;
+
+ ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_bmb;
+
+ i4_error_code =
+ ps_view_ctxt->pf_parse_inter_slice(ps_view_ctxt, ps_slice, ps_slice->u2_first_mb_in_slice);
+
+ return i4_error_code;
+}
+
+static WORD32 imvcd_parse_islice(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i4_error_code;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ i4_error_code =
+ ih264d_parse_islice(ps_view_ctxt, ps_view_ctxt->ps_cur_slice->u2_first_mb_in_slice);
+
+ return i4_error_code;
+}
+
+static WORD32 imvcd_finish_slice_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status;
+
+ UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded;
+ UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views;
+
+ imvcd_dpb_reset_ivp_ctxt(ps_mvcd_ctxt->ps_dpb_mgr);
+
+ /* End of Picture detection */
+ if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1))
+ {
+ ps_view_ctxt->u1_pic_decode_done = 1;
+ }
+ else
+ {
+ imvcd_corrupted_slice_handler(ps_mvcd_ctxt);
+
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ if((ps_view_ctxt->u1_slice_header_done) && (u2_view_order_id == (u2_num_views - 1)))
+ {
+ ps_view_ctxt->u1_first_slice_in_stream = 0;
+ }
+
+ if((ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id] != 0) && (0 == u2_view_order_id))
+ {
+ if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ ps_view_ctxt->ps_dpb_cmds[0] = ps_view_ctxt->s_dpb_cmds_scratch;
+ }
+ }
+
+ /* storing last Mb X and MbY of the slice */
+ ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx;
+ ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby;
+
+ if((ps_err->u1_err_flag & REJECT_PB_PICS) && (ps_err->u1_cur_pic_type == PIC_TYPE_I))
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ }
+
+ /* Accounting for idiocy in 'ih264d_parse_sps' */
+ if(u2_view_order_id > 0)
+ {
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_view_ctxt->ps_sps->u1_is_valid)
+ {
+ ps_view_ctxt->ps_cur_sps = ps_view_ctxt->ps_sps;
+
+ break;
+ }
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_parse_decode_slice(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_pic_params_t *ps_pps;
+ dec_seq_params_t *ps_sps;
+ dec_slice_params_t *ps_cur_slice;
+
+ WORD32 i4_error_code;
+ UWORD8 u1_pps_id;
+ UWORD8 u1_pic_order_cnt_type;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
+ dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm;
+ pocstruct_t s_tmp_poc = {0};
+ dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status;
+
+ WORD32 ai4_delta_poc[2] = {0};
+ WORD32 i4_poc = 0;
+ UWORD32 u4_idr_pic_id = 0;
+ UWORD16 u2_view_id = ps_nalu_mvc_ext->u2_view_id;
+ UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded;
+ bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt);
+ UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views;
+ UWORD8 u1_redundant_pic_cnt = 0;
+ const UWORD8 u1_field_pic_flag = 0;
+ const UWORD8 u1_bottom_field_flag = 0;
+
+ ps_view_ctxt->ps_cur_slice = ps_cur_slice = &ps_mvcd_ctxt->as_slices[u2_view_id];
+ ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read_slc = 0;
+
+ ps_cur_slice->u1_nal_unit_type = ps_mvcd_ctxt->ae_nalu_id[u2_view_order_id];
+ ps_cur_slice->u1_nal_ref_idc = ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id];
+
+ i4_error_code = imvcd_set_first_mb_in_slice(ps_view_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_slice_type(ps_view_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ i4_error_code = imvcd_set_cur_pps(ps_view_ctxt, &u1_pps_id);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ ps_pps = ps_view_ctxt->ps_cur_pps;
+ ps_sps = ps_view_ctxt->ps_cur_sps;
+
+ i4_error_code = imvcd_set_frame_num(ps_view_ctxt, ps_sps->u1_bits_in_frm_num);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(!ps_view_ctxt->u1_first_slice_in_stream && ps_view_ctxt->u4_first_slice_in_pic)
+ {
+ ps_view_ctxt->u2_mbx = 0xffff;
+ ps_view_ctxt->u2_mby = 0;
+ ps_view_ctxt->u2_total_mbs_coded = 0;
+
+ if(0 == u2_view_order_id)
+ {
+ if(b_is_idr_slice || ps_cur_slice->u1_mmco_equalto5)
+ {
+ ps_view_ctxt->u2_prev_ref_frame_num = 0;
+ }
+
+ if(ps_view_ctxt->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag)
+ {
+ i4_error_code = imvcd_decode_gaps_in_frame_num(ps_mvcd_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+
+ if(!b_is_idr_slice && ps_cur_slice->u1_nal_ref_idc)
+ {
+ ps_view_ctxt->u2_prev_ref_frame_num = ps_cur_slice->u2_frame_num;
+ }
+
+ imvcd_pocstruct_init(ps_view_ctxt);
+ }
+ }
+
+ if(b_is_idr_slice)
+ {
+ i4_error_code = imvcd_set_idr_pic_id(ps_view_ctxt, &u4_idr_pic_id);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ /* 'ih264d_read_mmco_commands' asssumes AVC semantics */
+ ps_view_ctxt->u1_nal_unit_type = SLICE_IDR;
+ }
+ else
+ {
+ ps_view_ctxt->u1_nal_unit_type = SLICE_NON_IDR;
+ }
+
+ u1_pic_order_cnt_type = ps_sps->u1_pic_order_cnt_type;
+
+ if(0 == u1_pic_order_cnt_type)
+ {
+ i4_error_code = imvcd_set_poc_lsb(ps_view_ctxt, &s_tmp_poc.i4_pic_order_cnt_lsb,
+ ps_sps->i4_max_pic_order_cntLsb,
+ ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_pps->u1_pic_order_present_flag)
+ {
+ i4_error_code =
+ imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt_bottom);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ }
+
+ if((1 == u1_pic_order_cnt_type) && !ps_sps->u1_delta_pic_order_always_zero_flag)
+ {
+ i4_error_code = imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt[0]);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_pps->u1_pic_order_present_flag)
+ {
+ i4_error_code = imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt[1]);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+ }
+
+ if(ps_pps->u1_redundant_pic_cnt_present_flag)
+ {
+ i4_error_code = imvcd_set_redundant_pic_cnt(ps_view_ctxt, &u1_redundant_pic_cnt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+ }
+
+ ps_view_ctxt->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC;
+
+ ps_view_ctxt->u1_slice_header_done = 0;
+
+ if(ps_view_ctxt->u4_first_slice_in_pic)
+ {
+ i4_error_code = ih264d_decode_pic_order_cnt(
+ b_is_idr_slice, ps_cur_slice->u2_frame_num, &ps_view_ctxt->s_prev_pic_poc, &s_tmp_poc,
+ ps_cur_slice, ps_pps, ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id],
+ u1_bottom_field_flag, u1_field_pic_flag, &i4_poc);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+
+ /* Display seq no calculations */
+ if(i4_poc >= ps_view_ctxt->i4_max_poc)
+ {
+ ps_view_ctxt->i4_max_poc = i4_poc;
+ }
+
+ /* IDR Picture or POC wrap around */
+ if(i4_poc == 0)
+ {
+ imvcd_modulate_max_disp_seq(ps_view_ctxt);
+ }
+ }
+
+ if((0 == i4_poc) && (ps_mvcd_ctxt->ae_nalu_id[u2_view_order_id] == SLICE_IDR) &&
+ (ps_cur_slice->u1_slice_type != ISLICE))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Copy the values read from the bitstream to the slice header and then*/
+ /* If the slice is first slice in picture, then do Start of Picture */
+ /* processing. */
+ /*--------------------------------------------------------------------*/
+ ps_cur_slice->i4_delta_pic_order_cnt[0] = ai4_delta_poc[0];
+ ps_cur_slice->i4_delta_pic_order_cnt[1] = ai4_delta_poc[1];
+ ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id;
+ ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag;
+ ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+ ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb;
+ ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt;
+ ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type;
+ ps_cur_slice->i4_poc = i4_poc;
+
+ ps_cur_slice->u1_direct_8x8_inference_flag = ps_sps->u1_direct_8x8_inference_flag;
+
+ if(IV_SUCCESS != imvcd_view_error_checks(ps_mvcd_ctxt))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(ps_cur_slice->u1_slice_type == B_SLICE)
+ {
+ i4_error_code = imvcd_set_direct_spatial_mv_pred_flag(ps_view_ctxt);
+
+ if(OK != i4_error_code)
+ {
+ return i4_error_code;
+ }
+
+ if(ps_cur_slice->u1_direct_spatial_mv_pred_flag)
+ {
+ ps_cur_slice->pf_decodeDirect = ih264d_decode_spatial_direct;
+ }
+ else
+ {
+ ps_cur_slice->pf_decodeDirect = ih264d_decode_temporal_direct;
+ }
+
+ ps_view_ctxt->pf_mvpred = ih264d_mvpred_nonmbaffB;
+ }
+ else
+ {
+ ps_view_ctxt->pf_mvpred = ih264d_mvpred_nonmbaff;
+ }
+
+ if(ps_view_ctxt->u4_first_slice_in_pic)
+ {
+ if(0 == ps_cur_slice->u2_first_mb_in_slice)
+ {
+ i4_error_code = imvcd_pic_init(ps_mvcd_ctxt, &s_tmp_poc, i4_poc, b_is_idr_slice);
+
+ if(i4_error_code != OK)
+ {
+ return i4_error_code;
+ }
+ }
+ else
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_view_ctxt->u4_output_present = 0;
+
+ if(u2_view_order_id == (u2_num_views - 1))
+ {
+ if(IV_SUCCESS == imvcd_get_next_display_au_buf(ps_mvcd_ctxt))
+ {
+ ps_view_ctxt->u4_output_present = 1;
+ }
+ }
+
+ if(!imvcd_dpb_is_diff_poc_valid(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_slice->i4_poc))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(ps_view_ctxt->u1_separate_parse == 1)
+ {
+ if(!ps_view_ctxt->u4_dec_thread_created)
+ {
+ ithread_create(ps_view_ctxt->pv_dec_thread_handle, NULL,
+ ih264d_decode_picture_thread, ps_view_ctxt);
+
+ ps_view_ctxt->u4_dec_thread_created = 1;
+ }
+
+ if((3 == ps_view_ctxt->u4_num_cores) &&
+ (!ps_view_ctxt->u4_app_disable_deblk_frm ||
+ ps_view_ctxt->i1_recon_in_thread3_flag) &&
+ !ps_view_ctxt->u4_bs_deblk_thread_created)
+ {
+ ps_view_ctxt->u4_start_recon_deblk = 0;
+
+ ithread_create(ps_view_ctxt->pv_bs_deblk_thread_handle, NULL,
+ ih264d_recon_deblk_thread, ps_view_ctxt);
+
+ ps_view_ctxt->u4_bs_deblk_thread_created = 1;
+ }
+ }
+ }
+
+ if((ps_cur_slice->u1_slice_type != B_SLICE) &&
+ (ps_view_ctxt->ps_cur_pps->u1_wted_pred_flag == 0))
+ {
+ ps_view_ctxt->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
+ ps_view_ctxt->p_motion_compensate = ih264d_motion_compensate_bp;
+ }
+ else
+ {
+ ps_view_ctxt->p_form_mb_part_info = ih264d_form_mb_part_info_mp;
+ ps_view_ctxt->p_motion_compensate = ih264d_motion_compensate_mp;
+ }
+
+ if(ps_err->u4_frm_sei_sync == ps_cur_slice->u2_frame_num)
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ ps_err->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
+ }
+
+ ps_err->u4_cur_frm = ps_cur_slice->u2_frame_num;
+
+ ps_view_ctxt->i4_submb_ofst = -SUB_BLK_SIZE;
+
+ ps_view_ctxt->u2_cur_mb_addr = 0;
+ ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_deblk_pic;
+ ps_view_ctxt->ps_mv_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id];
+
+ ps_view_ctxt->s_tran_addrecon.pu1_dest_y =
+ ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[Y].pv_data;
+ ps_view_ctxt->s_tran_addrecon.pu1_dest_u =
+ ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[UV].pv_data;
+ ps_view_ctxt->s_tran_addrecon.pu1_dest_v = NULL;
+
+ ps_view_ctxt->s_tran_addrecon.pu1_mb_y =
+ ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[Y].pv_data;
+ ps_view_ctxt->s_tran_addrecon.pu1_mb_u =
+ ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[UV].pv_data;
+ ps_view_ctxt->s_tran_addrecon.pu1_mb_v = NULL;
+
+ ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params;
+
+ ps_view_ctxt->u2_mbx = (MOD(ps_cur_slice->u2_first_mb_in_slice - 1, ps_sps->u2_frm_wd_in_mbs));
+ ps_view_ctxt->u2_mby = (DIV(ps_cur_slice->u2_first_mb_in_slice - 1, ps_sps->u2_frm_wd_in_mbs));
+ ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx;
+ ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby;
+
+ /* RBSP stop bit is used for CABAC decoding*/
+ ps_bitstrm->u4_max_ofst += ps_view_ctxt->ps_cur_pps->u1_entropy_coding_mode;
+
+ ps_view_ctxt->u1_B = (ps_cur_slice->u1_slice_type == B_SLICE);
+ ps_view_ctxt->u4_next_mb_skip = 0;
+
+ ps_view_ctxt->ps_parse_cur_slice->u4_first_mb_in_slice = ps_cur_slice->u2_first_mb_in_slice;
+ ps_view_ctxt->ps_parse_cur_slice->slice_type = ps_cur_slice->u1_slice_type;
+
+ ps_view_ctxt->u4_start_recon_deblk = 1;
+
+ ps_view_ctxt->ps_parse_cur_slice->ppv_map_ref_idx_to_poc =
+ ps_view_ctxt->pv_map_ref_idx_to_poc_buf;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ ps_view_ctxt->ps_parse_cur_slice->pv_tu_coeff_data_start =
+ ps_view_ctxt->pv_parse_tu_coeff_data;
+ }
+ else
+ {
+ ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_parse_tu_coeff_data;
+ }
+
+ if(0 == u2_view_order_id)
+ {
+ i4_error_code = imvcd_dpb_st_lt_deduplicator(ps_mvcd_ctxt->ps_dpb_mgr);
+
+ if(i4_error_code < 0)
+ {
+ i4_error_code = ERROR_DBP_MANAGER_T;
+ }
+ }
+
+ if(ps_cur_slice->u1_slice_type == I_SLICE)
+ {
+ ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= I_SLC_BIT;
+
+ i4_error_code = imvcd_parse_islice(ps_mvcd_ctxt);
+
+ ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type;
+
+ if(ps_view_ctxt->i4_pic_type != B_SLICE && ps_view_ctxt->i4_pic_type != P_SLICE)
+ {
+ ps_view_ctxt->i4_pic_type = I_SLICE;
+ }
+ }
+ else if(ps_cur_slice->u1_slice_type == P_SLICE)
+ {
+ ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= P_SLC_BIT;
+
+ i4_error_code = imvcd_parse_pslice(ps_mvcd_ctxt);
+
+ ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type;
+
+ if(ps_view_ctxt->i4_pic_type != B_SLICE)
+ {
+ ps_view_ctxt->i4_pic_type = P_SLICE;
+ }
+ }
+ else if(ps_cur_slice->u1_slice_type == B_SLICE)
+ {
+ ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= B_SLC_BIT;
+
+ i4_error_code = imvcd_parse_bslice(ps_mvcd_ctxt);
+
+ ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type;
+
+ ps_view_ctxt->i4_pic_type = B_SLICE;
+ }
+ else
+ {
+ i4_error_code = ERROR_INV_SLC_TYPE_T;
+ }
+
+ i4_error_code = imvcd_finish_slice_decode(ps_mvcd_ctxt);
+
+ return i4_error_code;
+}
diff --git a/decoder/mvc/imvcd_slice_functions.h b/decoder/mvc/imvcd_slice_functions.h
new file mode 100644
index 0000000..62f85bf
--- /dev/null
+++ b/decoder/mvc/imvcd_slice_functions.h
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_slice_functions.h */
+/* */
+/* Description : Functions for MVC Slice parsing, etc. */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_SLICE_FUNCTIONS_H_
+#define _IMVCD_SLICE_FUNCTIONS_H_
+
+#include "ih264_typedefs.h"
+#include "imvcd_structs.h"
+
+extern WORD32 imvcd_parse_decode_slice(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+#endif
diff --git a/decoder/mvc/imvcd_structs.h b/decoder/mvc/imvcd_structs.h
new file mode 100644
index 0000000..7af1877
--- /dev/null
+++ b/decoder/mvc/imvcd_structs.h
@@ -0,0 +1,234 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#ifndef _IMVCD_STRUCTS_H_
+#define _IMVCD_STRUCTS_H_
+
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "imvcd.h"
+#include "ih264_error.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_disp_mgr.h"
+#include "ih264d_sei.h"
+#include "ih264d_structs.h"
+#include "imvc_defs.h"
+#include "imvc_structs.h"
+#include "imvcd_defs.h"
+
+/* structs */
+typedef struct mvc_au_mv_pred_t
+{
+ mv_pred_t *aps_mvs[MAX_NUM_VIEWS];
+
+ /* colZeroFlag | // 0th bit
+ field_flag | // 1st bit
+ XX | // 2:3 bit don't cares
+ subMbMode | // 4:5 bit
+ MbMode | // 6:7 bit */
+ UWORD8 *apu1_mode_descriptors[MAX_NUM_VIEWS];
+
+} mvc_au_mv_pred_t;
+
+typedef struct ivp_data_t
+{
+ bool b_is_ivp_ref;
+
+ /* Due to the structuring of dpb_mgr_t, */
+ /* mvc_pic_buffer_t used for referencing ought to contain */
+ /* all data in indices corresponding to view_id doing the referencing. */
+ /* This struct, and this variable in particular, is used for identifying */
+ /* the reference view's view_id */
+
+ UWORD16 u2_ref_view_id;
+} ivp_data_t;
+
+typedef struct mvc_au_buffer_t
+{
+ /** pic_buffer for all views */
+ yuv_buf_props_t as_view_buffers[MAX_NUM_VIEWS];
+
+ /** display offsets for all views */
+ offsets_t as_disp_offsets[MAX_NUM_VIEWS];
+
+ ivp_data_t s_ivp_data;
+
+ /** SEI data */
+ sei s_sei_pic;
+
+ /** AU MV Data */
+ mvc_au_mv_pred_t *ps_au_mv_data;
+
+ /* It will contain information about types of slices */
+ UWORD32 au4_pack_slc_typ[MAX_NUM_VIEWS];
+
+ /** Width of the display luma frame in pixels */
+ UWORD16 u2_disp_width;
+
+ /** Height of the display luma frame in pixels */
+ UWORD16 u2_disp_height;
+
+ /** Time at which frame has to be displayed */
+ UWORD32 u4_time_stamp;
+
+ /** (1: short 0: long) term ref pic */
+ bool b_is_short_term_ref;
+
+ /** frame / field / complementary field pair */
+ UWORD8 u1_pic_type;
+
+ /** Idx into the picBufAPI array */
+ WORD32 i4_pic_buf_id;
+
+ WORD32 i4_mv_buf_id;
+
+ WORD32 i4_poc;
+
+ WORD32 i4_frame_num;
+
+ /* Derived based on '8.2.4.1' */
+ WORD32 i4_pic_num;
+
+ /** minPOC */
+ WORD32 i4_avg_poc;
+
+ /*Same as u1_pic_type..u1_pic_type gets overwritten whereas this doesnot get
+ overwritten
+ ...stores the pictype of frame/complementary field pair/ mbaff */
+ UWORD8 u1_picturetype;
+
+ UWORD8 u1_long_term_frm_idx;
+
+ UWORD8 u1_long_term_pic_num;
+
+ /* Refer to SEI table D-1 */
+ UWORD8 u1_pic_struct;
+
+} mvc_au_buffer_t;
+
+typedef struct mvc_au_buf_mgr_t
+{
+ void *pv_mem;
+
+ buf_mgr_t *ps_buf_mgr_ctxt;
+
+ void *pv_au_buf_base;
+
+ mvc_au_buffer_t *aps_buf_id_to_au_buf_map[MAX_DISP_BUFS_NEW];
+
+ UWORD8 au1_au_buf_id_to_mv_buf_id_map[MAX_DISP_BUFS_NEW];
+
+ UWORD8 au1_au_buf_ref_flag[MAX_DISP_BUFS_NEW];
+
+} mvc_au_buf_mgr_t;
+
+typedef struct mvc_au_mv_pred_buf_mgr_t
+{
+ void *pv_mem;
+
+ buf_mgr_t *ps_buf_mgr_ctxt;
+
+ void *pv_au_mv_pred_buf_base;
+
+ mvc_au_mv_pred_t *aps_buf_id_to_mv_pred_buf_map[MAX_DISP_BUFS_NEW];
+
+} mvc_au_mv_pred_buf_mgr_t;
+
+typedef struct subset_sps_t
+{
+ dec_seq_params_t s_sps_data;
+
+ sps_mvc_ext_t s_sps_mvc_ext;
+
+ mvc_vui_ext_t s_mvc_vui_ext;
+
+ offsets_t s_disp_offsets;
+
+ UWORD8 u1_mvc_vui_parameters_present_flag;
+
+} subset_sps_t;
+
+typedef struct ref_pic_list_mod_data_t
+{
+ UWORD8 au1_num_active_refs[2];
+
+ UWORD8 au1_ref_pic_list_modification_flag_lx[2];
+
+ UWORD8 au1_modification_of_pic_nums_idc[2][MVC_MAX_REF_PICS + 1];
+
+ WORD32 ai4_abs_diff_pic_num_minus1[2][MVC_MAX_REF_PICS + 1];
+
+ WORD32 ai4_long_term_pic_num[2][MVC_MAX_REF_PICS + 1];
+
+ WORD32 ai4_abs_diff_view_idx_minus1[2][MVC_MAX_REF_PICS + 1];
+} ref_pic_list_mod_data_t;
+
+typedef struct mvc_dec_ctxt_t
+{
+ dec_struct_t s_view_dec_ctxt;
+
+ iv_mvc_yuv_buf_t s_out_buffer;
+
+ /* Resolves circular dependency with mvc_dpb_manager_t */
+ void *ps_dpb_mgr;
+
+ subset_sps_t as_subset_sps[MAX_NUM_SEQ_PARAMS];
+
+ /* Indexed via viewOrderID */
+ nalu_mvc_ext_t as_nalu_mvc_ext[MAX_NUM_VIEWS];
+
+ /* Indexed via viewOrderID */
+ dec_slice_params_t as_slices[MAX_NUM_VIEWS];
+
+ ref_pic_list_mod_data_t as_ref_pic_list_mod_data[MAX_NUM_VIEWS];
+
+ subset_sps_t *aps_pps_id_to_subset_sps_map[MAX_NUM_PIC_PARAMS];
+
+ disp_mgr_t s_mvc_disp_buf_mgr;
+
+ mvc_au_buf_mgr_t s_mvc_au_buf_mgr;
+
+ mvc_au_mv_pred_buf_mgr_t s_mvc_au_mv_pred_buf_mgr;
+
+ mvc_au_buffer_t *ps_cur_au;
+
+ AVC_EXT_NALU_ID_T ae_nalu_id[MAX_NUM_VIEWS];
+
+ UWORD8 au1_nal_ref_idc[MAX_NUM_VIEWS];
+
+ UWORD32 u4_num_aus_decoded;
+
+ UWORD16 u2_num_views;
+
+ UWORD16 u2_num_views_decoded;
+
+ UWORD8 u1_num_sps;
+
+ UWORD8 u1_num_subset_sps;
+
+ UWORD8 u1_num_pps;
+
+ bool b_header_only_decode;
+
+ bool b_flush_enabled;
+
+} mvc_dec_ctxt_t;
+
+#endif
diff --git a/decoder/mvc/imvcd_utils.c b/decoder/mvc/imvcd_utils.c
new file mode 100644
index 0000000..5fc1014
--- /dev/null
+++ b/decoder/mvc/imvcd_utils.c
@@ -0,0 +1,1140 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_utils.c */
+/* */
+/* Description : MVCD Utility functions used by 'imvcd_api.c' */
+/* */
+/*****************************************************************************/
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ih264_debug.h"
+#include "ih264_disp_mgr.h"
+#include "ih264_macros.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_utils.h"
+#include "imvcd_structs.h"
+#include "imvcd_utils.h"
+
+void imvcd_free_ref_bufs(mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr, WORD32 i4_pic_buf_id)
+{
+ ih264_buf_mgr_release(ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt, i4_pic_buf_id, BUF_MGR_REF);
+
+ ih264_buf_mgr_release(ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
+ ps_mvc_au_buf_mgr->au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id],
+ BUF_MGR_REF);
+}
+
+void imvcd_release_all_ref_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt, WORD32 i4_num_bufs)
+{
+ WORD32 i;
+
+ for(i = 0; i < i4_num_bufs; i++)
+ {
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, i, BUF_MGR_REF);
+
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.au1_au_buf_id_to_mv_buf_id_map[i],
+ BUF_MGR_REF);
+ }
+}
+
+void imvcd_free_ref_and_io_bufs(mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
+ WORD32 i4_pic_buf_id)
+{
+ ih264_buf_mgr_release(ps_mvc_au_buf_mgr->ps_buf_mgr_ctxt, i4_pic_buf_id,
+ BUF_MGR_REF | BUF_MGR_IO);
+
+ ih264_buf_mgr_release(ps_mvc_au_mv_pred_buf_mgr->ps_buf_mgr_ctxt,
+ ps_mvc_au_buf_mgr->au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id],
+ BUF_MGR_REF | BUF_MGR_IO);
+}
+
+void imvcd_release_all_ref_and_io_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt, WORD32 i4_num_bufs)
+{
+ WORD32 i;
+
+ for(i = 0; i < i4_num_bufs; i++)
+ {
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, i,
+ BUF_MGR_REF | BUF_MGR_IO);
+
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.au1_au_buf_id_to_mv_buf_id_map[i],
+ BUF_MGR_REF | BUF_MGR_IO);
+ }
+}
+
+bool is_header_decoded(WORD32 i4_header_decoded, AVC_EXT_NALU_ID_T e_nalu_id)
+{
+ /* Accounting for idiocy in 'ih264d_parse_nal_unit' */
+ e_nalu_id = (SPS == e_nalu_id) ? UNSPEC_0 : ((PPS == e_nalu_id) ? SLICE_NON_IDR : e_nalu_id);
+ return !!(i4_header_decoded & (1 << e_nalu_id));
+}
+
+bool is_mvc_nalu(AVC_EXT_NALU_ID_T e_nalu_id)
+{
+ switch(e_nalu_id)
+ {
+ case SLICE_NON_IDR:
+ case SLICE_DPA:
+ case SLICE_DPB:
+ case SLICE_DPC:
+ case SLICE_IDR:
+ case PREFIX_NAL:
+ case SUBSET_SPS:
+ case CODED_SLICE_EXTENSION:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+bool is_slice_nalu_type(AVC_EXT_NALU_ID_T e_nalu_id)
+{
+ switch(e_nalu_id)
+ {
+ case SLICE_NON_IDR:
+ case SLICE_DPA:
+ case SLICE_DPB:
+ case SLICE_DPC:
+ case SLICE_IDR:
+ case CODED_SLICE_EXTENSION:
+ case PREFIX_NAL:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+nalu_mvc_ext_t *imvcd_get_cur_nalu_mvc_ext(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ return &ps_mvcd_ctxt->as_nalu_mvc_ext[ps_mvcd_ctxt->u2_num_views_decoded];
+}
+
+nalu_mvc_ext_t *imvcd_get_nalu_mvc_ext(nalu_mvc_ext_t *ps_nalu_mvc_exts,
+ UWORD16 u2_num_views_decoded, UWORD16 u2_view_id)
+{
+ WORD32 i;
+
+ for(i = 0; i < u2_num_views_decoded; i++)
+ {
+ if(ps_nalu_mvc_exts[i].u2_view_id == u2_view_id)
+ {
+ return &ps_nalu_mvc_exts[i];
+ }
+ }
+
+ return NULL;
+}
+
+ref_pic_list_mod_data_t *imvcd_get_cur_ref_pic_list_mod_data(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ return &ps_mvcd_ctxt->as_ref_pic_list_mod_data[ps_mvcd_ctxt->u2_num_views_decoded];
+}
+
+subset_sps_t *imvcd_get_valid_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ if(0 != ps_mvcd_ctxt->u2_num_views_decoded)
+ {
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ return ps_mvcd_ctxt
+ ->aps_pps_id_to_subset_sps_map[ps_view_ctxt->ps_cur_pps->u1_pic_parameter_set_id];
+ }
+ else
+ {
+ WORD32 i;
+
+ for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
+ {
+ if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
+ {
+ return &ps_mvcd_ctxt->as_subset_sps[i];
+ }
+ }
+
+ return NULL;
+ }
+}
+
+void imvcd_modulate_max_disp_seq(dec_struct_t *ps_view_ctxt)
+{
+ WORD64 i8_temp;
+
+ i8_temp = ((WORD64) ps_view_ctxt->i4_prev_max_display_seq) +
+ ((WORD64) ps_view_ctxt->i4_max_poc) +
+ ((WORD64) ps_view_ctxt->u1_max_dec_frame_buffering) + 1ll;
+
+ ps_view_ctxt->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp) ? 0 : ((WORD32) i8_temp);
+ ps_view_ctxt->i4_max_poc = 0;
+}
+
+mv_pred_t imvcd_get_default_mv_pred(void)
+{
+ mv_pred_t s_mv_pred = {.i2_mv = {0},
+ .i1_ref_frame = {OUT_OF_RANGE_REF, OUT_OF_RANGE_REF},
+ .u1_col_ref_pic_idx = UINT8_MAX,
+ .u1_pic_type = UINT8_MAX};
+
+ return s_mv_pred;
+}
+
+UWORD32 imvcd_get_max_num_ivp_refs(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ WORD32 i;
+
+ subset_sps_t *ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt);
+
+ UWORD32 u4_max_ivp_refs = 0;
+
+ if(!ps_subset_sps)
+ {
+ return u4_max_ivp_refs;
+ }
+
+ for(i = 0; i < ps_subset_sps->s_sps_mvc_ext.u2_num_views; i++)
+ {
+ u4_max_ivp_refs = MAX(
+ u4_max_ivp_refs, ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[0][i].u1_num_refs +
+ ps_subset_sps->s_sps_mvc_ext.as_anchor_ref_data[1][i].u1_num_refs);
+ u4_max_ivp_refs =
+ MAX(u4_max_ivp_refs,
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[0][i].u1_num_refs +
+ ps_subset_sps->s_sps_mvc_ext.as_non_anchor_ref_data[1][i].u1_num_refs);
+ }
+
+ return u4_max_ivp_refs;
+}
+
+bool imvcd_is_idr_au(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ return (ps_mvcd_ctxt->u2_num_views_decoded > 1)
+ ? !ps_mvcd_ctxt->as_nalu_mvc_ext->u1_non_idr_flag
+ : (ps_mvcd_ctxt->ae_nalu_id[0] == SLICE_IDR);
+}
+
+coordinates_t imvcd_get_buf_pad_dims(bool b_is_chroma)
+{
+ coordinates_t s_dims;
+
+ /* Vert pad is '4 * PAD_LEN_UV_V' to account for field Pics */
+ if(b_is_chroma)
+ {
+ s_dims.i4_abscissa = (PAD_LEN_UV_H * 4);
+ s_dims.i4_ordinate = (PAD_LEN_UV_V * 4);
+ }
+ else
+ {
+ s_dims.i4_abscissa = (PAD_LEN_Y_H * 2);
+ s_dims.i4_ordinate = (PAD_LEN_Y_V * 4);
+ }
+
+ return s_dims;
+}
+
+WORD32 imvcd_get_ref_pic_pad_offset(WORD32 i4_stride, bool b_is_chroma)
+{
+ return !b_is_chroma ? (i4_stride * PAD_LEN_Y_V * 2 + PAD_LEN_Y_H)
+ : (i4_stride * PAD_LEN_UV_V * 2 + PAD_LEN_UV_H * 2);
+}
+
+UWORD32 imvcd_get_next_bits(dec_bit_stream_t *ps_bitstream)
+{
+ UWORD32 u4_next_word;
+
+ NEXTBITS(u4_next_word, ps_bitstream->u4_ofst, ps_bitstream->pu4_buffer, 32);
+
+ return u4_next_word;
+}
+
+void imvcd_set_view_buf_id_to_buf_map(dec_struct_t *ps_view_ctxt)
+{
+ WORD32 i, j;
+
+ memset(ps_view_ctxt->apv_buf_id_pic_buf_map, 0, sizeof(ps_view_ctxt->apv_buf_id_pic_buf_map));
+
+ for(i = 0; i < 2; i++)
+ {
+ for(j = 0; j < ps_view_ctxt->ps_cur_slice->u1_num_ref_idx_lx_active[i]; j++)
+ {
+ ps_view_ctxt
+ ->apv_buf_id_pic_buf_map[ps_view_ctxt->ps_ref_pic_buf_lx[i][j]->u1_pic_buf_id] =
+ (void *) ps_view_ctxt->ps_ref_pic_buf_lx[i][j];
+ }
+ }
+}
+
+IV_API_CALL_STATUS_T imvcd_get_next_display_au_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ mvc_au_buffer_t *ps_au_buf;
+
+ IV_API_CALL_STATUS_T e_retval = IV_FAIL;
+
+ UWORD32 i;
+ WORD32 i4_buf_id;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ ps_au_buf =
+ (mvc_au_buffer_t *) ih264_disp_mgr_get(&ps_mvcd_ctxt->s_mvc_disp_buf_mgr, &i4_buf_id);
+
+ ps_view_ctxt->i4_display_index = DEFAULT_POC;
+
+ if(ps_au_buf != NULL)
+ {
+ ps_view_ctxt->pv_disp_sei_params = &ps_au_buf->s_sei_pic;
+ ps_view_ctxt->i4_display_index = ps_au_buf->i4_poc;
+ ps_view_ctxt->u4_num_fld_in_frm += 2;
+ ps_view_ctxt->s_disp_op.u4_ts = ps_au_buf->u4_time_stamp;
+
+ e_retval = IV_SUCCESS;
+ }
+
+ if(ps_au_buf)
+ {
+ for(i = 0; i < ps_mvcd_ctxt->u2_num_views; i++)
+ {
+ yuv_buf_props_t *ps_src = &ps_au_buf->as_view_buffers[i];
+ yuv_buf_props_t *ps_dst = &ps_mvcd_ctxt->s_out_buffer.as_view_buf_props[i];
+
+ WORD32 i4_y_src_stride = ps_src->as_component_bufs[Y].i4_data_stride;
+ WORD32 i4_uv_src_stride = ps_src->as_component_bufs[UV].i4_data_stride;
+ UWORD8 *pu1_y_src = (UWORD8 *) ps_src->as_component_bufs[Y].pv_data;
+ UWORD8 *pu1_uv_src = (UWORD8 *) ps_src->as_component_bufs[UV].pv_data;
+
+ pu1_y_src += (0 == i) ? ps_view_ctxt->u2_crop_offset_y
+ : (ps_au_buf->as_disp_offsets[i].u2_left_offset +
+ ps_au_buf->as_disp_offsets[i].u2_top_offset * i4_y_src_stride);
+ pu1_uv_src +=
+ (0 == i) ? ps_view_ctxt->u2_crop_offset_uv
+ : (ps_au_buf->as_disp_offsets[i].u2_left_offset +
+ (ps_au_buf->as_disp_offsets[i].u2_top_offset * i4_uv_src_stride) / 2);
+
+ ps_dst->u2_width = ps_au_buf->u2_disp_width;
+ ps_dst->u2_height = ps_au_buf->u2_disp_height;
+
+ ASSERT(ps_dst->as_component_bufs[U].i4_data_stride ==
+ ps_dst->as_component_bufs[V].i4_data_stride);
+
+ ih264d_fmt_conv_420sp_to_420p(
+ pu1_y_src, pu1_uv_src, (UWORD8 *) ps_dst->as_component_bufs[Y].pv_data,
+ (UWORD8 *) ps_dst->as_component_bufs[U].pv_data,
+ (UWORD8 *) ps_dst->as_component_bufs[V].pv_data, ps_dst->u2_width,
+ ps_dst->u2_height, i4_y_src_stride, i4_uv_src_stride,
+ ps_dst->as_component_bufs[Y].i4_data_stride,
+ ps_dst->as_component_bufs[U].i4_data_stride, 1, 0);
+ }
+
+ ih264_buf_mgr_release(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt,
+ ps_au_buf->i4_pic_buf_id, BUF_MGR_IO);
+ }
+
+ return e_retval;
+}
+
+UWORD32 imvcd_get_num_mbs_in_level(UWORD8 u1_level_idc)
+{
+ switch(u1_level_idc)
+ {
+ case H264_LEVEL_1_0:
+ {
+ return MAX_MBS_LEVEL_10;
+ }
+ case H264_LEVEL_1_1:
+ {
+ return MAX_MBS_LEVEL_11;
+ }
+ case H264_LEVEL_1_2:
+ {
+ return MAX_MBS_LEVEL_12;
+ }
+ case H264_LEVEL_1_3:
+ {
+ return MAX_MBS_LEVEL_13;
+ }
+ case H264_LEVEL_2_0:
+ {
+ return MAX_MBS_LEVEL_20;
+ }
+ case H264_LEVEL_2_1:
+ {
+ return MAX_MBS_LEVEL_21;
+ }
+ case H264_LEVEL_2_2:
+ {
+ return MAX_MBS_LEVEL_22;
+ }
+ case H264_LEVEL_3_0:
+ {
+ return MAX_MBS_LEVEL_30;
+ }
+ case H264_LEVEL_3_1:
+ {
+ return MAX_MBS_LEVEL_31;
+ }
+ case H264_LEVEL_3_2:
+ {
+ return MAX_MBS_LEVEL_32;
+ }
+ case H264_LEVEL_4_0:
+ {
+ return MAX_MBS_LEVEL_40;
+ }
+ case H264_LEVEL_4_1:
+ {
+ return MAX_MBS_LEVEL_41;
+ }
+ case H264_LEVEL_4_2:
+ {
+ return MAX_MBS_LEVEL_42;
+ }
+ case H264_LEVEL_5_0:
+ {
+ return MAX_MBS_LEVEL_50;
+ }
+ case H264_LEVEL_5_1:
+ default:
+ {
+ return MAX_MBS_LEVEL_51;
+ }
+ }
+}
+
+WORD16 imvcd_free_dynamic_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_deblk_pic);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_dec_mb_map);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_recon_mb_map);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu2_slice_num_map);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_dec_slice_buf);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_frm_mb_info);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pi2_coeff_data);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_parse_mb_data);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_parse_part_params);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_deblk_top_mb);
+
+ if(ps_view_ctxt->p_ctxt_inc_mb_map)
+ {
+ ps_view_ctxt->p_ctxt_inc_mb_map -= 1;
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->p_ctxt_inc_mb_map);
+ }
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_mv_p[0]);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_mv_p[1]);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_pred_pkd);
+ {
+ UWORD8 i;
+ for(i = 0; i < MV_SCRATCH_BUFS; i++)
+ {
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_mv_top_p[i]);
+ }
+ }
+
+ if(ps_view_ctxt->pu1_y_intra_pred_line)
+ {
+ ps_view_ctxt->pu1_y_intra_pred_line -= MB_SIZE;
+ }
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_y_intra_pred_line);
+
+ if(ps_view_ctxt->pu1_u_intra_pred_line)
+ {
+ ps_view_ctxt->pu1_u_intra_pred_line -= MB_SIZE;
+ }
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_u_intra_pred_line);
+
+ if(ps_view_ctxt->pu1_v_intra_pred_line)
+ {
+ ps_view_ctxt->pu1_v_intra_pred_line -= MB_SIZE;
+ }
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->pu1_v_intra_pred_line);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_view_ctxt->ps_nbr_mb_row);
+
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt, ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_au_buf_base);
+ PS_DEC_ALIGNED_FREE(ps_view_ctxt,
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_au_mv_pred_buf_base);
+
+ return OK;
+}
+
+static UWORD32 imvcd_get_num_au_data_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ return ps_view_ctxt->u1_pic_bufs;
+}
+
+static UWORD32 imvcd_get_num_elements_in_mv_pred_buf(UWORD32 u4_view_wd, UWORD32 u4_view_ht)
+{
+ return (u4_view_wd * (u4_view_ht + PAD_MV_BANK_ROW)) / MB_SIZE;
+}
+
+static UWORD32 imvcd_get_mv_pred_buf_padding_length(UWORD32 u4_view_wd)
+{
+ return (u4_view_wd * OFFSET_MV_BANK_ROW) / MB_SIZE;
+}
+
+static UWORD32 imvcd_get_au_mv_pred_buf_size(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD32 u4_num_bufs = imvcd_get_num_au_data_bufs(ps_mvcd_ctxt);
+
+ UWORD32 u4_size = 0;
+
+ u4_size += sizeof(mvc_au_mv_pred_t);
+
+ u4_size +=
+ imvcd_get_num_elements_in_mv_pred_buf(ps_view_ctxt->u2_pic_wd, ps_view_ctxt->u2_pic_ht) *
+ (sizeof(mv_pred_t) + sizeof(UWORD8));
+
+ u4_size *= u4_num_bufs;
+ u4_size *= ps_mvcd_ctxt->u2_num_views;
+
+ return u4_size;
+}
+
+static UWORD32 imvcd_get_au_buf_size(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD32 u4_size = 0;
+ UWORD32 u4_num_bufs = imvcd_get_num_au_data_bufs(ps_mvcd_ctxt);
+
+ u4_size += sizeof(mvc_au_buffer_t);
+
+ /* All rvalues below incorporate both padding and pic dimensions */
+ u4_size += ALIGN64(ps_view_ctxt->u2_frm_wd_y * ps_view_ctxt->u2_frm_ht_y) * sizeof(UWORD8);
+ u4_size += ALIGN64(ps_view_ctxt->u2_frm_wd_uv * ps_view_ctxt->u2_frm_ht_uv) * sizeof(UWORD8);
+
+ u4_size *= ps_mvcd_ctxt->u2_num_views;
+ u4_size *= u4_num_bufs;
+
+ return u4_size;
+}
+
+WORD32 imvcd_init_au_buffers(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ UWORD32 i, j;
+ UWORD32 u4_luma_size, u4_chroma_size;
+ WORD32 i4_error_code;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ WORD64 i8_alloc_mem_size = imvcd_get_au_buf_size(ps_mvcd_ctxt);
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_au_buf_base;
+ UWORD32 u4_num_bufs = imvcd_get_num_au_data_bufs(ps_mvcd_ctxt);
+
+ if(ps_mvcd_ctxt->u2_num_views > MAX_NUM_VIEWS)
+ {
+ ps_view_ctxt->i4_error_code = ERROR_BUF_MGR;
+ return ERROR_BUF_MGR;
+ }
+
+ u4_luma_size = ps_view_ctxt->u2_frm_wd_y * ps_view_ctxt->u2_frm_ht_y;
+ u4_chroma_size = ps_view_ctxt->u2_frm_wd_uv * ps_view_ctxt->u2_frm_ht_uv;
+
+ for(i = 0; i < u4_num_bufs; i++)
+ {
+ WORD32 i4_stride;
+
+ mvc_au_buffer_t *ps_au_buf = (mvc_au_buffer_t *) pu1_buf;
+
+ pu1_buf += sizeof(ps_au_buf[0]);
+
+ for(j = 0; j < ps_mvcd_ctxt->u2_num_views; j++)
+ {
+ i4_stride = ps_view_ctxt->u2_frm_wd_y;
+ ps_au_buf->as_view_buffers[j].as_component_bufs[Y].i4_data_stride = i4_stride;
+ ps_au_buf->as_view_buffers[j].as_component_bufs[Y].pv_data =
+ pu1_buf + imvcd_get_ref_pic_pad_offset(i4_stride, false);
+ pu1_buf += ALIGN64(u4_luma_size) * sizeof(pu1_buf[0]);
+ i8_alloc_mem_size -= ALIGN64(u4_luma_size) * sizeof(pu1_buf[0]);
+
+ i4_stride = ps_view_ctxt->u2_frm_wd_uv;
+ ps_au_buf->as_view_buffers[j].as_component_bufs[UV].i4_data_stride = i4_stride;
+ ps_au_buf->as_view_buffers[j].as_component_bufs[UV].pv_data =
+ pu1_buf + imvcd_get_ref_pic_pad_offset(i4_stride, true);
+ pu1_buf += ALIGN64(u4_chroma_size) * sizeof(pu1_buf[0]);
+ i8_alloc_mem_size -= ALIGN64(u4_chroma_size) * sizeof(pu1_buf[0]);
+
+ ps_au_buf->as_view_buffers[j].as_component_bufs[V].pv_data = NULL;
+
+ ps_au_buf->as_view_buffers[j].u2_height =
+ ps_view_ctxt->ps_cur_sps->u2_frm_ht_in_mbs * MB_SIZE;
+ ps_au_buf->as_view_buffers[j].u2_width =
+ ps_view_ctxt->ps_cur_sps->u2_frm_wd_in_mbs * MB_SIZE;
+ ps_au_buf->as_view_buffers[j].u1_bit_depth = 8;
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+
+ ps_au_buf->i4_pic_buf_id = i;
+
+ i4_error_code =
+ ih264_buf_mgr_add(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, ps_au_buf, i);
+
+ if(0 != i4_error_code)
+ {
+ ps_view_ctxt->i4_error_code = ERROR_BUF_MGR;
+
+ return ERROR_BUF_MGR;
+ }
+
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.aps_buf_id_to_au_buf_map[i] = ps_au_buf;
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_init_au_mv_pred_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ UWORD32 i, j;
+ WORD32 buf_ret;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ UWORD32 u4_width = ps_view_ctxt->u2_pic_wd;
+ UWORD32 u4_height = ps_view_ctxt->u2_pic_ht;
+ UWORD32 u4_mode_info_buf_size = imvcd_get_num_elements_in_mv_pred_buf(u4_width, u4_height);
+ UWORD8 *pu1_buf = ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_au_mv_pred_buf_base;
+ WORD64 i8_alloc_mem_size = imvcd_get_au_mv_pred_buf_size(ps_mvcd_ctxt);
+ UWORD32 u4_num_bufs = imvcd_get_num_au_data_bufs(ps_mvcd_ctxt);
+
+ if(ps_mvcd_ctxt->u2_num_views > MAX_NUM_VIEWS)
+ {
+ return ERROR_BUF_MGR;
+ }
+
+ for(i = 0; i < u4_num_bufs; i++)
+ {
+ mvc_au_mv_pred_t *ps_au_mv_data = (mvc_au_mv_pred_t *) pu1_buf;
+
+ pu1_buf += sizeof(ps_au_mv_data[0]);
+
+ buf_ret = ih264_buf_mgr_add(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt,
+ ps_au_mv_data, i);
+
+ if(0 != buf_ret)
+ {
+ return ERROR_BUF_MGR;
+ }
+
+ for(j = 0; j < ps_mvcd_ctxt->u2_num_views; j++)
+ {
+ UWORD32 u4_mv_buf_size = u4_mode_info_buf_size * sizeof(ps_au_mv_data->aps_mvs[j][0]);
+ UWORD32 u4_mode_desc_buf_size =
+ u4_mode_info_buf_size * sizeof(ps_au_mv_data->apu1_mode_descriptors[j][0]);
+
+ ps_au_mv_data->aps_mvs[j] = (mv_pred_t *) pu1_buf;
+ ps_au_mv_data->aps_mvs[j] += imvcd_get_mv_pred_buf_padding_length(u4_width);
+ pu1_buf += u4_mv_buf_size;
+ i8_alloc_mem_size -= u4_mv_buf_size;
+
+ ps_au_mv_data->apu1_mode_descriptors[j] = pu1_buf;
+ pu1_buf += u4_mode_desc_buf_size;
+ i8_alloc_mem_size -= u4_mode_desc_buf_size;
+
+ memset(ps_au_mv_data->aps_mvs[j] - imvcd_get_mv_pred_buf_padding_length(u4_width), 0,
+ u4_mv_buf_size);
+
+ memset(ps_au_mv_data->apu1_mode_descriptors[j], 0, u4_mode_desc_buf_size);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+ }
+
+ return OK;
+}
+
+WORD32 imvcd_allocate_dynamic_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+ dec_seq_params_t *ps_sps = ps_view_ctxt->ps_cur_sps;
+
+ UWORD32 u4_total_mbs = ps_sps->u2_total_num_of_mbs;
+ UWORD32 u4_wd_mbs = ps_view_ctxt->u2_frm_wd_in_mbs;
+ UWORD32 u4_ht_mbs = ps_view_ctxt->u2_frm_ht_in_mbs;
+ const WORD32 i4_default_alignment = 128;
+ void *pv_mem_ctxt = ps_view_ctxt->pv_mem_ctxt;
+
+ UWORD8 *pu1_buf;
+ WORD32 i4_mem_size;
+ WORD32 i;
+ void *pv_buf;
+ WORD32 i4_num_entries;
+
+ if(ps_mvcd_ctxt->u2_num_views > MAX_NUM_VIEWS)
+ {
+ return IV_FAIL;
+ }
+
+ i4_mem_size = u4_total_mbs * sizeof(ps_view_ctxt->pu1_dec_mb_map[0]);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu1_dec_mb_map = pv_buf;
+
+ i4_mem_size = u4_total_mbs * sizeof(ps_view_ctxt->pu1_recon_mb_map[0]);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu1_recon_mb_map = pv_buf;
+
+ i4_mem_size = u4_total_mbs * sizeof(ps_view_ctxt->pu2_slice_num_map[0]);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->pu2_slice_num_map = pv_buf;
+
+ ps_view_ctxt->ps_parse_cur_slice = ps_view_ctxt->ps_dec_slice_buf;
+ ps_view_ctxt->ps_decode_cur_slice = ps_view_ctxt->ps_dec_slice_buf;
+ ps_view_ctxt->ps_computebs_cur_slice = ps_view_ctxt->ps_dec_slice_buf;
+ ps_view_ctxt->ps_pred_start = ps_view_ctxt->ps_pred;
+
+ i4_mem_size = sizeof(parse_pmbarams_t) * (ps_view_ctxt->u1_recon_mb_grp);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_parse_mb_data = pv_buf;
+
+ i4_mem_size = sizeof(parse_part_params_t) * ((ps_view_ctxt->u1_recon_mb_grp) << 4);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_parse_part_params = pv_buf;
+
+ i4_mem_size = (u4_wd_mbs * sizeof(deblkmb_neighbour_t));
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_deblk_top_mb = pv_buf;
+
+ i4_mem_size = sizeof(ctxt_inc_mb_info_t) * (u4_wd_mbs + 2);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->p_ctxt_inc_mb_map = pv_buf;
+ /* 0th entry of CtxtIncMbMap will be always be containing default values
+ for CABAC context representing MB not available */
+ ps_view_ctxt->p_ctxt_inc_mb_map += 1;
+
+ i4_mem_size = sizeof(mv_pred_t) * ps_view_ctxt->u1_recon_mb_grp * 16;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_mv_p[0] = pv_buf;
+
+ i4_mem_size = sizeof(mv_pred_t) * ps_view_ctxt->u1_recon_mb_grp * 16;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_mv_p[1] = pv_buf;
+
+ for(i = 0; i < MV_SCRATCH_BUFS; i++)
+ {
+ i4_mem_size = (sizeof(mv_pred_t) * ps_view_ctxt->u1_recon_mb_grp * 4);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_mv_top_p[i] = pv_buf;
+ }
+
+ i4_mem_size = sizeof(UWORD8) * ((u4_wd_mbs + 2) * MB_SIZE) * 2;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->pu1_y_intra_pred_line = pv_buf;
+ memset(ps_view_ctxt->pu1_y_intra_pred_line, 0, i4_mem_size);
+ ps_view_ctxt->pu1_y_intra_pred_line += MB_SIZE;
+
+ i4_mem_size = sizeof(UWORD8) * ((u4_wd_mbs + 2) * MB_SIZE) * 2;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->pu1_u_intra_pred_line = pv_buf;
+ memset(ps_view_ctxt->pu1_u_intra_pred_line, 0, i4_mem_size);
+ ps_view_ctxt->pu1_u_intra_pred_line += MB_SIZE;
+
+ i4_mem_size = sizeof(UWORD8) * ((u4_wd_mbs + 2) * MB_SIZE) * 2;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->pu1_v_intra_pred_line = pv_buf;
+ memset(ps_view_ctxt->pu1_v_intra_pred_line, 0, i4_mem_size);
+ ps_view_ctxt->pu1_v_intra_pred_line += MB_SIZE;
+
+ if(ps_view_ctxt->u1_separate_parse)
+ {
+ /* Needs one extra row of info, to hold top row data */
+ i4_mem_size = sizeof(mb_neigbour_params_t) * 2 * ((u4_wd_mbs + 2) * (u4_ht_mbs + 1));
+ }
+ else
+ {
+ i4_mem_size = sizeof(mb_neigbour_params_t) * 2 * (u4_wd_mbs + 2);
+ }
+
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+
+ ps_view_ctxt->ps_nbr_mb_row = pv_buf;
+ memset(ps_view_ctxt->ps_nbr_mb_row, 0, i4_mem_size);
+
+ i4_mem_size = (u4_total_mbs + u4_wd_mbs) * sizeof(deblk_mb_t);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->ps_deblk_pic = pv_buf;
+ memset(ps_view_ctxt->ps_deblk_pic, 0, i4_mem_size);
+
+ i4_mem_size = sizeof(dec_mb_info_t) * u4_total_mbs;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_view_ctxt->ps_frm_mb_info = pv_buf;
+ memset(ps_view_ctxt->ps_frm_mb_info, 0, i4_mem_size);
+
+ if((1 >= ps_view_ctxt->ps_cur_sps->u1_num_ref_frames) && (0 == ps_view_ctxt->i4_display_delay))
+ {
+ i4_num_entries = 1;
+ }
+ else
+ {
+ i4_num_entries = MAX_FRAMES;
+ }
+
+ i4_num_entries = (2 * i4_num_entries) + 1;
+ i4_num_entries *= 2;
+
+ i4_mem_size = i4_num_entries * sizeof(void *);
+ i4_mem_size += PAD_MAP_IDX_POC * sizeof(void *);
+ i4_mem_size *= u4_total_mbs;
+ i4_mem_size += sizeof(dec_slice_struct_t) * u4_total_mbs;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+
+ ps_view_ctxt->ps_dec_slice_buf = pv_buf;
+ memset(ps_view_ctxt->ps_dec_slice_buf, 0, i4_mem_size);
+ pu1_buf = (UWORD8 *) ps_view_ctxt->ps_dec_slice_buf;
+ pu1_buf += sizeof(dec_slice_struct_t) * u4_total_mbs;
+ ps_view_ctxt->pv_map_ref_idx_to_poc_buf = (void *) pu1_buf;
+
+ /* Allocate memory for packed pred info */
+ i4_num_entries = u4_total_mbs;
+ i4_num_entries *= 16 * 2;
+
+ i4_mem_size = sizeof(pred_info_pkd_t) * i4_num_entries;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_view_ctxt->ps_pred_pkd = pv_buf;
+
+ /* Allocate memory for coeff data */
+ i4_mem_size = MB_LUM_SIZE * sizeof(WORD16);
+ /*For I16x16 MBs, 16 4x4 AC coeffs and 1 4x4 DC coeff TU blocks will be sent
+ For all MBs along with 8 4x4 AC coeffs 2 2x2 DC coeff TU blocks will be sent
+ So use 17 4x4 TU blocks for luma and 9 4x4 TU blocks for chroma */
+ i4_mem_size += u4_total_mbs *
+ (MAX(17 * sizeof(tu_sblk4x4_coeff_data_t), 4 * sizeof(tu_blk8x8_coeff_data_t)) +
+ 9 * sizeof(tu_sblk4x4_coeff_data_t));
+ // 32 bytes for each mb to store u1_prev_intra4x4_pred_mode and
+ // u1_rem_intra4x4_pred_mode data
+ i4_mem_size += u4_total_mbs * 32;
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+
+ ps_view_ctxt->pi2_coeff_data = pv_buf;
+
+ ps_view_ctxt->pv_pic_tu_coeff_data = (void *) (ps_view_ctxt->pi2_coeff_data + MB_LUM_SIZE);
+
+ i4_mem_size = imvcd_get_au_mv_pred_buf_size(ps_mvcd_ctxt);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.pv_au_mv_pred_buf_base = pv_buf;
+
+ i4_mem_size = imvcd_get_au_buf_size(ps_mvcd_ctxt);
+ pv_buf = ps_view_ctxt->pf_aligned_alloc(pv_mem_ctxt, i4_default_alignment, i4_mem_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, i4_mem_size);
+ ps_mvcd_ctxt->s_mvc_au_buf_mgr.pv_au_buf_base = pv_buf;
+
+ /***************************************************************************/
+ /*Initialize cabac context pointers for every SE that has fixed contextIdx */
+ /***************************************************************************/
+ {
+ bin_ctxt_model_t *const p_cabac_ctxt_table_t = ps_view_ctxt->p_cabac_ctxt_table_t;
+ bin_ctxt_model_t **p_coeff_abs_level_minus1_t = ps_view_ctxt->p_coeff_abs_level_minus1_t;
+ bin_ctxt_model_t **p_cbf_t = ps_view_ctxt->p_cbf_t;
+
+ ps_view_ctxt->p_mb_field_dec_flag_t = p_cabac_ctxt_table_t + MB_FIELD_DECODING_FLAG;
+ ps_view_ctxt->p_prev_intra4x4_pred_mode_flag_t =
+ p_cabac_ctxt_table_t + PREV_INTRA4X4_PRED_MODE_FLAG;
+ ps_view_ctxt->p_rem_intra4x4_pred_mode_t = p_cabac_ctxt_table_t + REM_INTRA4X4_PRED_MODE;
+ ps_view_ctxt->p_intra_chroma_pred_mode_t = p_cabac_ctxt_table_t + INTRA_CHROMA_PRED_MODE;
+ ps_view_ctxt->p_mb_qp_delta_t = p_cabac_ctxt_table_t + MB_QP_DELTA;
+ ps_view_ctxt->p_ref_idx_t = p_cabac_ctxt_table_t + REF_IDX;
+ ps_view_ctxt->p_mvd_x_t = p_cabac_ctxt_table_t + MVD_X;
+ ps_view_ctxt->p_mvd_y_t = p_cabac_ctxt_table_t + MVD_Y;
+ p_cbf_t[0] = p_cabac_ctxt_table_t + CBF + 0;
+ p_cbf_t[1] = p_cabac_ctxt_table_t + CBF + 4;
+ p_cbf_t[2] = p_cabac_ctxt_table_t + CBF + 8;
+ p_cbf_t[3] = p_cabac_ctxt_table_t + CBF + 12;
+ p_cbf_t[4] = p_cabac_ctxt_table_t + CBF + 16;
+ ps_view_ctxt->p_cbp_luma_t = p_cabac_ctxt_table_t + CBP_LUMA;
+ ps_view_ctxt->p_cbp_chroma_t = p_cabac_ctxt_table_t + CBP_CHROMA;
+
+ p_coeff_abs_level_minus1_t[LUMA_DC_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_0_OFFSET;
+
+ p_coeff_abs_level_minus1_t[LUMA_AC_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_1_OFFSET;
+
+ p_coeff_abs_level_minus1_t[LUMA_4X4_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_2_OFFSET;
+
+ p_coeff_abs_level_minus1_t[CHROMA_DC_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_3_OFFSET;
+
+ p_coeff_abs_level_minus1_t[CHROMA_AC_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_4_OFFSET;
+
+ p_coeff_abs_level_minus1_t[LUMA_8X8_CTXCAT] =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1_8X8 + COEFF_ABS_LEVEL_CAT_5_OFFSET;
+
+ /********************************************************/
+ /* context for the high profile related syntax elements */
+ /* This is maintained seperately in s_high_profile */
+ /********************************************************/
+ {
+ ps_view_ctxt->s_high_profile.ps_transform8x8_flag =
+ p_cabac_ctxt_table_t + TRANSFORM_SIZE_8X8_FLAG;
+
+ ps_view_ctxt->s_high_profile.ps_sigcoeff_8x8_frame =
+ p_cabac_ctxt_table_t + SIGNIFICANT_COEFF_FLAG_8X8_FRAME;
+
+ ps_view_ctxt->s_high_profile.ps_last_sigcoeff_8x8_frame =
+ p_cabac_ctxt_table_t + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FRAME;
+
+ ps_view_ctxt->s_high_profile.ps_coeff_abs_levelminus1 =
+ p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1_8X8;
+
+ ps_view_ctxt->s_high_profile.ps_sigcoeff_8x8_field =
+ p_cabac_ctxt_table_t + SIGNIFICANT_COEFF_FLAG_8X8_FIELD;
+
+ ps_view_ctxt->s_high_profile.ps_last_sigcoeff_8x8_field =
+ p_cabac_ctxt_table_t + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FIELD;
+ }
+ }
+
+ return OK;
+}
+
+void imvcd_convert_au_buf_to_view_buf(mvc_au_buffer_t *ps_au_buf, pic_buffer_t *ps_view_buf,
+ UWORD16 u2_view_order_id, UWORD16 u2_view_id)
+{
+ yuv_buf_props_t *ps_view_buffer = &ps_au_buf->as_view_buffers[u2_view_id];
+ offsets_t *ps_disp_offsets = &ps_au_buf->as_disp_offsets[u2_view_id];
+ mvc_au_mv_pred_t *ps_au_mv_data = ps_au_buf->ps_au_mv_data;
+
+ ps_view_buf->pu1_buf1 = ps_view_buffer->as_component_bufs[Y].pv_data;
+ ps_view_buf->pu1_buf2 = ps_view_buffer->as_component_bufs[UV].pv_data;
+ ps_view_buf->pu1_buf3 = NULL;
+ ps_view_buf->u2_frm_wd_y = ps_view_buffer->as_component_bufs[Y].i4_data_stride;
+ ps_view_buf->u2_frm_wd_uv = ps_view_buffer->as_component_bufs[UV].i4_data_stride;
+ ps_view_buf->pu1_buf3 = NULL;
+
+ ps_view_buf->u2_disp_width = ps_au_buf->u2_disp_width;
+ ps_view_buf->u2_disp_height = ps_au_buf->u2_disp_height;
+ ps_view_buf->u2_frm_ht_y = ps_view_buffer->u2_height;
+ ps_view_buf->u2_frm_ht_uv = ps_view_buffer->u2_height / 2;
+
+ ps_view_buf->u4_time_stamp = ps_au_buf->u4_time_stamp;
+ ps_view_buf->u4_ts = ps_au_buf->u4_time_stamp;
+
+ ps_view_buf->u2_crop_offset_y =
+ ps_disp_offsets->u2_left_offset + ps_disp_offsets->u2_top_offset * ps_view_buf->u2_frm_wd_y;
+ ps_view_buf->u2_crop_offset_uv =
+ ps_disp_offsets->u2_left_offset +
+ (ps_disp_offsets->u2_top_offset / 2) * ps_view_buf->u2_frm_wd_uv;
+
+ ps_view_buf->i4_poc = ps_au_buf->i4_poc;
+ ps_view_buf->i4_pic_num = ps_au_buf->i4_frame_num;
+ ps_view_buf->i4_frame_num = ps_au_buf->i4_frame_num;
+ ps_view_buf->i4_avg_poc = ps_au_buf->i4_poc;
+ ps_view_buf->u1_is_short = ps_au_buf->b_is_short_term_ref;
+ ps_view_buf->u1_pic_type = ps_au_buf->u1_pic_type;
+ ps_view_buf->i4_top_field_order_cnt = ps_au_buf->i4_poc;
+ ps_view_buf->i4_bottom_field_order_cnt = ps_au_buf->i4_poc;
+ ps_view_buf->u1_picturetype = FRM_PIC;
+ ps_view_buf->u1_long_term_frm_idx = ps_au_buf->u1_long_term_frm_idx;
+ ps_view_buf->u1_long_term_pic_num = ps_au_buf->u1_long_term_pic_num;
+ ps_view_buf->u4_pack_slc_typ = ps_au_buf->au4_pack_slc_typ[u2_view_order_id];
+ ps_view_buf->u1_pic_struct = ps_au_buf->u1_pic_struct;
+ ps_view_buf->s_sei_pic = ps_au_buf->s_sei_pic;
+
+ ps_view_buf->u1_pic_buf_id = ps_au_buf->i4_pic_buf_id;
+ ps_view_buf->u1_mv_buf_id = ps_au_buf->i4_mv_buf_id;
+
+ ps_view_buf->pu1_col_zero_flag = ps_au_mv_data->apu1_mode_descriptors[u2_view_id];
+ ps_view_buf->ps_mv = ps_au_mv_data->aps_mvs[u2_view_id];
+}
+
+void imvcd_init_ref_idx_to_ref_buf_map(mvc_dec_ctxt_t *ps_mvcd_ctxt)
+{
+ pic_buffer_t *ps_pic;
+
+ void **ppv_map_ref_idx_to_poc_lx;
+ WORD8 i, j;
+
+ dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
+
+ bool b_is_b_pic = !!(
+ ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[ps_mvcd_ctxt->u2_num_views_decoded] & B_SLC_BIT);
+
+ for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++)
+ {
+ ppv_map_ref_idx_to_poc_lx =
+ ps_view_ctxt->ppv_map_ref_idx_to_poc + ((0 == i) ? FRM_LIST_L0 : FRM_LIST_L1);
+ ppv_map_ref_idx_to_poc_lx[0] = NULL;
+ ppv_map_ref_idx_to_poc_lx++;
+
+ for(j = 0; j < ps_view_ctxt->ps_cur_slice->u1_num_ref_idx_lx_active[i]; j++)
+ {
+ ps_pic = ps_view_ctxt->ps_ref_pic_buf_lx[i][j];
+
+ ppv_map_ref_idx_to_poc_lx[j] = ps_pic->pu1_buf1;
+ }
+ }
+
+ if(!b_is_b_pic)
+ {
+ ppv_map_ref_idx_to_poc_lx = ps_view_ctxt->ppv_map_ref_idx_to_poc + FRM_LIST_L1;
+ ppv_map_ref_idx_to_poc_lx[0] = NULL;
+ }
+
+ if(ps_view_ctxt->u4_num_cores >= 3)
+ {
+ WORD32 i4_size;
+
+ WORD32 i4_num_entries = MAX_FRAMES;
+
+ if((1 >= ps_view_ctxt->ps_cur_sps->u1_num_ref_frames) &&
+ (0 == ps_view_ctxt->i4_display_delay))
+ {
+ i4_num_entries = 1;
+ }
+
+ i4_num_entries = 2 * i4_num_entries + 1;
+ i4_num_entries *= 2;
+
+ i4_size = i4_num_entries * sizeof(void *);
+ i4_size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ memcpy(ps_view_ctxt->ps_parse_cur_slice->ppv_map_ref_idx_to_poc,
+ ps_view_ctxt->ppv_map_ref_idx_to_poc, i4_size);
+ }
+}
+
+void imvcd_ivp_buf_copier(mvc_au_buffer_t *ps_au_buf_src, mvc_au_buffer_t *ps_au_buf_dst,
+ mvc_au_mv_pred_t *ps_au_mv_data_src, mvc_au_mv_pred_t *ps_au_mv_data_dst,
+ UWORD16 u2_src_view_id, UWORD16 u2_dst_view_id)
+{
+ UWORD32 i, j;
+
+ mv_pred_t *ps_mode_info_src = ps_au_mv_data_src->aps_mvs[u2_src_view_id];
+ mv_pred_t *ps_mode_info_dst = ps_au_mv_data_dst->aps_mvs[u2_dst_view_id];
+
+ UWORD32 u4_view_wd = ps_au_buf_src->as_view_buffers[u2_src_view_id].u2_width;
+ UWORD32 u4_view_ht = ps_au_buf_src->as_view_buffers[u2_src_view_id].u2_height;
+ UWORD32 u4_mode_info_buf_size = imvcd_get_num_elements_in_mv_pred_buf(u4_view_wd, u4_view_ht);
+ UWORD32 u4_mode_info_pad_size = imvcd_get_mv_pred_buf_padding_length(u4_view_wd);
+
+ ps_mode_info_src -= u4_mode_info_pad_size;
+ ps_mode_info_dst -= u4_mode_info_pad_size;
+
+ ps_au_buf_dst->ps_au_mv_data = ps_au_mv_data_dst;
+
+ ps_au_buf_dst->as_disp_offsets[u2_dst_view_id] = ps_au_buf_src->as_disp_offsets[u2_src_view_id];
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ bool b_is_chroma = ((COMPONENT_TYPES_T) i) != Y;
+
+ coordinates_t s_pad_dims = imvcd_get_buf_pad_dims(b_is_chroma);
+ buffer_container_t *ps_src =
+ &ps_au_buf_src->as_view_buffers[u2_src_view_id].as_component_bufs[i];
+ buffer_container_t *ps_dst =
+ &ps_au_buf_dst->as_view_buffers[u2_dst_view_id].as_component_bufs[i];
+
+ WORD32 i4_src_pad_offset =
+ imvcd_get_ref_pic_pad_offset(ps_src->i4_data_stride, b_is_chroma);
+ WORD32 i4_dst_pad_offset =
+ imvcd_get_ref_pic_pad_offset(ps_dst->i4_data_stride, b_is_chroma);
+
+ for(j = 0; j < ((u4_view_ht >> b_is_chroma) + s_pad_dims.i4_ordinate); j++)
+ {
+ UWORD8 *pu1_src =
+ ((UWORD8 *) ps_src->pv_data) + j * ps_src->i4_data_stride - i4_src_pad_offset;
+ UWORD8 *pu1_dst =
+ ((UWORD8 *) ps_dst->pv_data) + j * ps_dst->i4_data_stride - i4_dst_pad_offset;
+
+ memcpy(pu1_dst, pu1_src, (u4_view_wd + s_pad_dims.i4_abscissa) * sizeof(pu1_dst[0]));
+ }
+ }
+
+ memcpy(ps_mode_info_dst, ps_mode_info_src, u4_mode_info_buf_size * sizeof(ps_mode_info_dst[0]));
+
+ for(i = 0; i < u4_mode_info_buf_size; i++)
+ {
+ /* In accordance with 'H.8.4' */
+ ps_au_mv_data_dst->apu1_mode_descriptors[u2_dst_view_id][i] =
+ ps_au_mv_data_src->apu1_mode_descriptors[u2_src_view_id][i] & 0xFE;
+ }
+
+ ps_au_buf_dst->au4_pack_slc_typ[u2_dst_view_id] =
+ ps_au_buf_src->au4_pack_slc_typ[u2_src_view_id];
+ ps_au_buf_dst->b_is_short_term_ref = ps_au_buf_src->b_is_short_term_ref;
+ ps_au_buf_dst->i4_avg_poc = ps_au_buf_src->i4_avg_poc;
+ ps_au_buf_dst->i4_frame_num = ps_au_buf_src->i4_frame_num;
+ ps_au_buf_dst->i4_pic_num = ps_au_buf_src->i4_pic_num;
+ ps_au_buf_dst->i4_poc = ps_au_buf_src->i4_poc;
+ ps_au_buf_dst->s_sei_pic = ps_au_buf_src->s_sei_pic;
+ ps_au_buf_dst->u1_long_term_frm_idx = ps_au_buf_src->u1_long_term_frm_idx;
+ ps_au_buf_dst->u1_long_term_pic_num = ps_au_buf_src->u1_long_term_pic_num;
+ ps_au_buf_dst->u1_picturetype = ps_au_buf_src->u1_picturetype;
+ ps_au_buf_dst->u1_pic_struct = ps_au_buf_src->u1_pic_struct;
+ ps_au_buf_dst->u2_disp_height = ps_au_buf_src->u2_disp_height;
+ ps_au_buf_dst->u2_disp_width = ps_au_buf_src->u2_disp_width;
+ ps_au_buf_dst->u4_time_stamp = ps_au_buf_src->u4_time_stamp;
+}
diff --git a/decoder/mvc/imvcd_utils.h b/decoder/mvc/imvcd_utils.h
new file mode 100644
index 0000000..ce65854
--- /dev/null
+++ b/decoder/mvc/imvcd_utils.h
@@ -0,0 +1,121 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* */
+/* File Name : imvcd_utils.c */
+/* */
+/* Description : MVCD Utility functions used by 'imvcd_api.c' */
+/* */
+/*****************************************************************************/
+
+#ifndef _IMVCD_UTILS_H_
+#define _IMVCD_UTILS_H_
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "imvc_defs.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_structs.h"
+#include "imvcd_structs.h"
+
+#define SWAP(x, y, data_type) \
+ { \
+ data_type temp; \
+ memcpy(&temp, &y, sizeof(data_type)); \
+ memcpy(&y, &x, sizeof(data_type)); \
+ memcpy(&x, &temp, sizeof(data_type)); \
+ }
+
+extern IV_API_CALL_STATUS_T imvcd_get_next_display_au_buf(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern UWORD32 imvcd_get_num_mbs_in_level(UWORD8 u1_level_idc);
+
+extern WORD32 imvcd_allocate_dynamic_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern WORD16 imvcd_free_dynamic_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern WORD32 imvcd_init_au_buffers(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern WORD32 imvcd_init_au_mv_pred_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern void imvcd_convert_au_buf_to_view_buf(mvc_au_buffer_t *ps_au_buf, pic_buffer_t *ps_view_buf,
+ UWORD16 u2_view_order_id, UWORD16 u2_view_id);
+
+extern void imvcd_init_ref_idx_to_ref_buf_map(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern void imvcd_ivp_buf_copier(mvc_au_buffer_t *ps_au_buf_src, mvc_au_buffer_t *ps_au_buf_dst,
+ mvc_au_mv_pred_t *ps_au_mv_data_src,
+ mvc_au_mv_pred_t *ps_au_mv_data_dst, UWORD16 u2_src_view_id,
+ UWORD16 u2_dst_view_id);
+
+/* Function defined in 'ih264d_utils.c' and declared nowhere else */
+extern WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec);
+
+extern void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+
+extern void ih264d_get_implicit_weights(dec_struct_t *ps_dec);
+
+extern void imvcd_free_ref_bufs(mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
+ WORD32 i4_pic_buf_id);
+
+extern void imvcd_release_all_ref_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt, WORD32 i4_num_bufs);
+
+extern void imvcd_free_ref_and_io_bufs(mvc_au_buf_mgr_t *ps_mvc_au_buf_mgr,
+ mvc_au_mv_pred_buf_mgr_t *ps_mvc_au_mv_pred_buf_mgr,
+ WORD32 i4_pic_buf_id);
+
+extern void imvcd_release_all_ref_and_io_bufs(mvc_dec_ctxt_t *ps_mvcd_ctxt, WORD32 i4_num_bufs);
+
+extern bool is_header_decoded(WORD32 i4_header_decoded, AVC_EXT_NALU_ID_T e_nalu_id);
+
+extern bool is_mvc_nalu(AVC_EXT_NALU_ID_T e_nalu_id);
+
+extern bool is_slice_nalu_type(AVC_EXT_NALU_ID_T e_nalu_id);
+
+extern nalu_mvc_ext_t *imvcd_get_cur_nalu_mvc_ext(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern nalu_mvc_ext_t *imvcd_get_nalu_mvc_ext(nalu_mvc_ext_t *ps_nalu_mvc_exts,
+ UWORD16 u2_num_views_decoded, UWORD16 u2_view_id);
+
+extern ref_pic_list_mod_data_t *imvcd_get_cur_ref_pic_list_mod_data(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern subset_sps_t *imvcd_get_valid_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern void imvcd_modulate_max_disp_seq(dec_struct_t *ps_view_ctxt);
+
+extern mv_pred_t imvcd_get_default_mv_pred(void);
+
+extern UWORD32 imvcd_get_max_num_ivp_refs(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern bool imvcd_is_idr_au(mvc_dec_ctxt_t *ps_mvcd_ctxt);
+
+extern coordinates_t imvcd_get_buf_pad_dims(bool b_is_chroma);
+
+extern WORD32 imvcd_get_ref_pic_pad_offset(WORD32 i4_stride, bool b_is_chroma);
+
+extern UWORD32 imvcd_get_next_bits(dec_bit_stream_t *ps_bitstream);
+
+extern void imvcd_set_view_buf_id_to_buf_map(dec_struct_t *ps_view_ctxt);
+
+#endif
diff --git a/decoder/mvc/libmvcdec.cmake b/decoder/mvc/libmvcdec.cmake
new file mode 100644
index 0000000..4eb7643
--- /dev/null
+++ b/decoder/mvc/libmvcdec.cmake
@@ -0,0 +1,61 @@
+# src files
+list(
+ APPEND
+ LIBMVCDEC_SRCS
+ "${AVC_ROOT}/decoder/ih264d_api.c"
+ "${AVC_ROOT}/decoder/ih264d_bitstrm.c"
+ "${AVC_ROOT}/decoder/ih264d_cabac.c"
+ "${AVC_ROOT}/decoder/ih264d_cabac_init_tables.c"
+ "${AVC_ROOT}/decoder/ih264d_compute_bs.c"
+ "${AVC_ROOT}/decoder/ih264d_deblocking.c"
+ "${AVC_ROOT}/decoder/ih264d_dpb_mgr.c"
+ "${AVC_ROOT}/decoder/ih264d_format_conv.c"
+ "${AVC_ROOT}/decoder/ih264d_function_selector_generic.c"
+ "${AVC_ROOT}/decoder/ih264d_inter_pred.c"
+ "${AVC_ROOT}/decoder/ih264d_mb_utils.c"
+ "${AVC_ROOT}/decoder/ih264d_mvpred.c"
+ "${AVC_ROOT}/decoder/ih264d_nal.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_bslice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_cabac.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_cavlc.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_headers.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_islice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_mb_header.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_pslice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_slice.c"
+ "${AVC_ROOT}/decoder/ih264d_process_bslice.c"
+ "${AVC_ROOT}/decoder/ih264d_process_intra_mb.c"
+ "${AVC_ROOT}/decoder/ih264d_process_pslice.c"
+ "${AVC_ROOT}/decoder/ih264d_quant_scaling.c"
+ "${AVC_ROOT}/decoder/ih264d_sei.c"
+ "${AVC_ROOT}/decoder/ih264d_tables.c"
+ "${AVC_ROOT}/decoder/ih264d_thread_compute_bs.c"
+ "${AVC_ROOT}/decoder/ih264d_thread_parse_decode.c"
+ "${AVC_ROOT}/decoder/ih264d_utils.c"
+ "${AVC_ROOT}/decoder/ih264d_vui.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_api.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_api_utils.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_dpb_manager.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_error_handler.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_nalu_parser.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_slice_functions.c"
+ "${AVC_ROOT}/decoder/mvc/imvcd_utils.c")
+
+include_directories(${AVC_ROOT}/decoder)
+include_directories(${AVC_ROOT}/decoder/mvc)
+
+if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${CMAKE_SYSTEM_PROCESSOR}"
+ STREQUAL "aarch32")
+ list(
+ APPEND LIBMVCDEC_ASMS "${AVC_ROOT}/decoder/arm/ih264d_function_selector.c"
+ "${AVC_ROOT}/decoder/arm/ih264d_function_selector_a9q.c"
+ "${AVC_ROOT}/decoder/arm/ih264d_function_selector_av8.c")
+else()
+ list(
+ APPEND LIBMVCDEC_ASMS "${AVC_ROOT}/decoder/x86/ih264d_function_selector.c"
+ "${AVC_ROOT}/decoder/x86/ih264d_function_selector_sse42.c"
+ "${AVC_ROOT}/decoder/x86/ih264d_function_selector_ssse3.c")
+endif()
+
+add_library(libmvcdec STATIC ${LIBAVC_COMMON_SRCS} ${LIBAVC_COMMON_ASMS}
+ ${LIBMVCDEC_SRCS} ${LIBMVCDEC_ASMS})
diff --git a/decoder/mips/ih264d_function_selector.c b/decoder/riscv/ih264d_function_selector.c
index 13680ed..13680ed 100644
--- a/decoder/mips/ih264d_function_selector.c
+++ b/decoder/riscv/ih264d_function_selector.c
diff --git a/decoder/riscv/svc/isvcd_function_selector.c b/decoder/riscv/svc/isvcd_function_selector.c
new file mode 100644
index 0000000..39d9678
--- /dev/null
+++ b/decoder/riscv/svc/isvcd_function_selector.c
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in hevc
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_init_function_ptr()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264_defs.h"
+#include "ih264_size_defs.h"
+#include "ih264_error.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264d_structs.h"
+#include "ih264d_function_selector.h"
+#include "isvcd_structs.h"
+#include "isvcd_function_selector.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing arm v8/x86/a9q architecture
+*
+* @param[in] ps_codec
+* ps_codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvcd_init_function_ptr(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ isvcd_init_function_ptr_generic(ps_svc_lyr_dec);
+}
diff --git a/decoder/svc/isvcd.h b/decoder/svc/isvcd.h
new file mode 100644
index 0000000..df779f5
--- /dev/null
+++ b/decoder/svc/isvcd.h
@@ -0,0 +1,831 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd.h
+ *
+ * @brief
+ * This file contains all the necessary structure and enumeration definitions
+ * needed for the Application.
+ * Program Interface(API) of the Ittiam SVC ASP
+ * Decoder on Cortex A8 - Neon platform
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_H_
+#define _ISVCD_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "iv.h"
+#include "ivd.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+#define IVD_ERROR_MASK 0xFF
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+#define IS_IVD_CONCEALMENT_APPLIED(x) (x & (1 << IVD_APPLIEDCONCEALMENT))
+#define IS_IVD_INSUFFICIENTDATA_ERROR(x) (x & (1 << IVD_INSUFFICIENTDATA))
+#define IS_IVD_CORRUPTEDDATA_ERROR(x) (x & (1 << IVD_CORRUPTEDDATA))
+#define IS_IVD_CORRUPTEDHEADER_ERROR(x) (x & (1 << IVD_CORRUPTEDHEADER))
+#define IS_IVD_UNSUPPORTEDINPUT_ERROR(x) (x & (1 << IVD_UNSUPPORTEDINPUT))
+#define IS_IVD_UNSUPPORTEDPARAM_ERROR(x) (x & (1 << IVD_UNSUPPORTEDPARAM))
+#define IS_IVD_FATAL_ERROR(x) (x & (1 << IVD_FATALERROR))
+#define IS_IVD_INVALID_BITSTREAM_ERROR(x) (x & (1 << IVD_INVALID_BITSTREAM))
+#define IS_IVD_INCOMPLETE_BITSTREAM_ERROR(x) (x & (1 << IVD_INCOMPLETE_BITSTREAM))
+
+ /*****************************************************************************/
+ /* API Function Prototype */
+ /*****************************************************************************/
+ IV_API_CALL_STATUS_T isvcd_api_function(iv_obj_t *ps_handle, void *pv_api_ip, void *pv_api_op);
+
+ /*****************************************************************************/
+ /* Enums */
+ /*****************************************************************************/
+ /* Codec Error codes for SVC ASP Decoder */
+
+ typedef enum
+ {
+
+ ISVCD_VID_HDR_DEC_NUM_FRM_BUF_NOT_SUFFICIENT = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 1,
+ ISVCD_FRAME_INFO_OP_BUF_NULL,
+ ISVCD_INSUFFICIENT_METADATA_BUFFER,
+
+ } ISVCD_ERROR_CODES_T;
+
+ /*****************************************************************************/
+ /* Extended Structures */
+ /*****************************************************************************/
+
+ /*****************************************************************************/
+ /* Delete Codec */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_delete_ip_t s_ivd_delete_ip_t;
+ } isvcd_delete_ip_t;
+
+ typedef struct
+ {
+ ivd_delete_op_t s_ivd_delete_op_t;
+ } isvcd_delete_op_t;
+
+ /*****************************************************************************/
+ /* Initialize decoder */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_create_ip_t s_ivd_create_ip_t;
+ /**
+ * enable_frm_info
+ */
+ UWORD32 u4_enable_frame_info;
+ } isvcd_create_ip_t;
+
+ typedef struct
+ {
+ ivd_create_op_t s_ivd_create_op_t;
+ } isvcd_create_op_t;
+
+ /*****************************************************************************/
+ /* Video Decode */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_video_decode_ip_t s_ivd_video_decode_ip_t;
+ /**
+ * 8x8 block QP map size
+ */
+ UWORD32 u4_8x8_blk_qp_map_size;
+
+ /**
+ * 8x8 block QP map
+ */
+ UWORD8 *pu1_8x8_blk_qp_map;
+
+ /**
+ * 8x8 block type map size
+ */
+ UWORD32 u4_8x8_blk_type_map_size;
+
+ /**
+ * 8x8 block type map
+ */
+ UWORD8 *pu1_8x8_blk_type_map;
+ } isvcd_video_decode_ip_t;
+
+ /*****************************************************************************/
+ /* QP and block type maps are defined for each 8x8 MB sub-block. */
+ /* QP can range from <0, 51> and block type can be INTER/INTRA/SKIP. */
+ /* */
+ /* Let’s say, a frame has a total of ‘m’ MBs (each 16x16). Since the QP */
+ /* and block type are defined for each 8x8 block, hence each MB has */
+ /* 4 entries giving m x 4 total entires for QP and block type map each. */
+ /* */
+ /* For example, for a frame of size 60x60 shown in the figure down, both */
+ /* maps (QP and MB type) have the same layout. */
+ /* Each block represents an 8x8 sub-block. Both width and height are aligned */
+ /* to next largest multiple of 8, 64 in this case. */
+ /* */
+ /* 0 8 16 24 32 40 48 56 64 */
+ /* 0 ------------------------------------------------ */
+ /* | 0th | 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | */
+ /* 8 ------------------------------------------------ */
+ /* | 8th | 9th | 10th | - | - | - | - | - | */
+ /* 16 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 24 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 32 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 40 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 48 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 56 ------------------------------------------------ */
+ /* | - | - | - | - | - | - | - | - | */
+ /* 64 ------------------------------------------------ */
+ /* */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_video_decode_op_t s_ivd_video_decode_op_t;
+
+ /**
+ * 8x8 block QP map size
+ */
+ UWORD32 u4_8x8_blk_qp_map_size;
+
+ /**
+ * 8x8 block QP map
+ */
+ UWORD8 *pu1_8x8_blk_qp_map;
+
+ /**
+ * 8x8 block type map size
+ */
+ UWORD32 u4_8x8_blk_type_map_size;
+
+ /**
+ * 8x8 block type map
+ */
+ UWORD8 *pu1_8x8_blk_type_map;
+
+ } isvcd_video_decode_op_t;
+
+ /*****************************************************************************/
+ /* Get Display Frame */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_get_display_frame_ip_t s_ivd_get_display_frame_ip_t;
+ } isvcd_get_display_frame_ip_t;
+
+ typedef struct
+ {
+ ivd_get_display_frame_op_t s_ivd_get_display_frame_op_t;
+ } isvcd_get_display_frame_op_t;
+
+ /*****************************************************************************/
+ /* Set Display Frame */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_set_display_frame_ip_t s_ivd_set_display_frame_ip_t;
+ } isvcd_set_display_frame_ip_t;
+
+ typedef struct
+ {
+ ivd_set_display_frame_op_t s_ivd_set_display_frame_op_t;
+ } isvcd_set_display_frame_op_t;
+
+ /*****************************************************************************/
+ /* Release Display Buffers */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_rel_display_frame_ip_t s_ivd_rel_display_frame_ip_t;
+ } isvcd_rel_display_frame_ip_t;
+
+ typedef struct
+ {
+ ivd_rel_display_frame_op_t s_ivd_rel_display_frame_op_t;
+ } isvcd_rel_display_frame_op_t;
+
+ /*****************************************************************************/
+ /* Set Target Layer for SVC */
+ /*****************************************************************************/
+
+ /* IVD_API_COMMAND_TYPE_T::e_cmd = ISVCD_CMD_CTL_SET_TGT_LAYER */
+
+ typedef struct
+ {
+ /**
+ * u4_size of the structure
+ */
+ UWORD32 u4_size;
+
+ /**
+ * e_cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /**
+ * set the tgt dependency id
+ */
+ UWORD8 u1_tgt_dep_id;
+
+ /**
+ * set the tgt quality id
+ */
+ UWORD8 u1_tgt_quality_id;
+
+ /**
+ * set the tgt temporal id
+ */
+ UWORD8 u1_tgt_temp_id;
+
+ /**
+ * set the tgt priority id
+ */
+ UWORD8 u1_tgt_priority_id;
+
+ } isvcd_set_target_layer_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size of the structure
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error code
+ */
+ UWORD32 u4_error_code;
+
+ } isvcd_set_target_layer_op_t;
+
+ typedef enum
+ {
+
+ /* Set TGT Layer for SVC */
+ ISVCD_CMD_CTL_SET_TGT_LAYER = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x305
+
+ } ISVCD_CMD_CTL_SUB_CMDS;
+ /*****************************************************************************/
+ /* Video control Flush */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_flush_ip_t s_ivd_ctl_flush_ip_t;
+ } isvcd_ctl_flush_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_flush_op_t s_ivd_ctl_flush_op_t;
+ } isvcd_ctl_flush_op_t;
+
+ /*****************************************************************************/
+ /* Video control reset */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_reset_ip_t s_ivd_ctl_reset_ip_t;
+ } isvcd_ctl_reset_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_reset_op_t s_ivd_ctl_reset_op_t;
+ } isvcd_ctl_reset_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Params */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_set_config_ip_t s_ivd_ctl_set_config_ip_t;
+ } isvcd_ctl_set_config_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_set_config_op_t s_ivd_ctl_set_config_op_t;
+ } isvcd_ctl_set_config_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Get Buf Info */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_getbufinfo_ip_t s_ivd_ctl_getbufinfo_ip_t;
+ } isvcd_ctl_getbufinfo_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_getbufinfo_op_t s_ivd_ctl_getbufinfo_op_t;
+ } isvcd_ctl_getbufinfo_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Getstatus Call */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_getstatus_ip_t s_ivd_ctl_getstatus_ip_t;
+ } isvcd_ctl_getstatus_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_getstatus_op_t s_ivd_ctl_getstatus_op_t;
+ } isvcd_ctl_getstatus_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Get Version Info */
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ ivd_ctl_getversioninfo_ip_t s_ivd_ctl_getversioninfo_ip_t;
+ } isvcd_ctl_getversioninfo_ip_t;
+
+ typedef struct
+ {
+ ivd_ctl_getversioninfo_op_t s_ivd_ctl_getversioninfo_op_t;
+ } isvcd_ctl_getversioninfo_op_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /**
+ * Pictures that are are degraded
+ * 0 : No degrade
+ * 1 : Only on non-reference frames
+ * 2 : Use interval specified by u4_nondegrade_interval
+ * 3 : All non-key frames
+ * 4 : All frames
+ */
+ WORD32 i4_degrade_pics;
+
+ /**
+ * Interval for pictures which are completely decoded without any degradation
+ */
+ WORD32 i4_nondegrade_interval;
+
+ /**
+ * bit position (lsb is zero): Type of degradation
+ * 1 : Disable deblocking
+ * 2 : Faster inter prediction filters
+ * 3 : Fastest inter prediction filters
+ */
+ WORD32 i4_degrade_type;
+
+ } isvcd_ctl_degrade_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+ } isvcd_ctl_degrade_op_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ UWORD32 u4_disable_deblk_level;
+ } isvcd_ctl_disable_deblock_ip_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ UWORD32 u4_error_code;
+ } isvcd_ctl_disable_deblock_op_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ UWORD32 u4_num_cores;
+ } isvcd_ctl_set_num_cores_ip_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ UWORD32 u4_error_code;
+ } isvcd_ctl_set_num_cores_op_t;
+
+ typedef struct
+ {
+ /**
+ * i4_size
+ */
+ UWORD32 u4_size;
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ /**
+ * sub cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ /**
+ * Processor type
+ */
+ UWORD32 u4_arch;
+ /**
+ * SOC type
+ */
+ UWORD32 u4_soc;
+
+ /**
+ * num_cores
+ */
+ UWORD32 u4_num_cores;
+
+ } isvcd_ctl_set_processor_ip_t;
+
+ typedef struct
+ {
+ /**
+ * i4_size
+ */
+ UWORD32 u4_size;
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+ } isvcd_ctl_set_processor_op_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_frame_dimensions_ip_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ UWORD32 u4_error_code;
+ UWORD32 u4_x_offset[3];
+ UWORD32 u4_y_offset[3];
+ UWORD32 u4_disp_wd[3];
+ UWORD32 u4_disp_ht[3];
+ UWORD32 u4_buffer_wd[3];
+ UWORD32 u4_buffer_ht[3];
+ } isvcd_ctl_get_frame_dimensions_op_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_vui_params_ip_t;
+
+ typedef struct
+ {
+ UWORD32 u4_size;
+ UWORD32 u4_error_code;
+ UWORD8 u1_aspect_ratio_idc;
+ UWORD16 u2_sar_width;
+ UWORD16 u2_sar_height;
+ UWORD8 u1_overscan_appropriate_flag;
+ UWORD8 u1_video_format;
+ UWORD8 u1_video_full_range_flag;
+ UWORD8 u1_colour_primaries;
+ UWORD8 u1_tfr_chars;
+ UWORD8 u1_matrix_coeffs;
+ UWORD8 u1_cr_top_field;
+ UWORD8 u1_cr_bottom_field;
+ UWORD32 u4_num_units_in_tick;
+ UWORD32 u4_time_scale;
+ UWORD8 u1_fixed_frame_rate_flag;
+ UWORD8 u1_nal_hrd_params_present;
+ UWORD8 u1_vcl_hrd_params_present;
+ UWORD8 u1_low_delay_hrd_flag;
+ UWORD8 u1_pic_struct_present_flag;
+ UWORD8 u1_bitstream_restriction_flag;
+ UWORD8 u1_mv_over_pic_boundaries_flag;
+ UWORD32 u4_max_bytes_per_pic_denom;
+ UWORD32 u4_max_bits_per_mb_denom;
+ UWORD32 u4_log2_max_mv_length_horz;
+ UWORD32 u4_log2_max_mv_length_vert;
+ UWORD32 u4_num_reorder_frames;
+ UWORD32 u4_max_dec_frame_buffering;
+ } isvcd_ctl_get_vui_params_op_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_sei_mdcv_params_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /**
+ * Array to store the display_primaries_x values
+ */
+ UWORD16 au2_display_primaries_x[NUM_SEI_MDCV_PRIMARIES];
+
+ /**
+ * Array to store the display_primaries_y values
+ */
+ UWORD16 au2_display_primaries_y[NUM_SEI_MDCV_PRIMARIES];
+
+ /**
+ * Variable to store the white point x value
+ */
+ UWORD16 u2_white_point_x;
+
+ /**
+ * Variable to store the white point y value
+ */
+ UWORD16 u2_white_point_y;
+
+ /**
+ * Variable to store the max display mastering luminance value
+ */
+ UWORD32 u4_max_display_mastering_luminance;
+
+ /**
+ * Variable to store the min display mastering luminance value
+ */
+ UWORD32 u4_min_display_mastering_luminance;
+ } isvcd_ctl_get_sei_mdcv_params_op_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_sei_cll_params_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /**
+ * The maximum pixel intensity of all samples
+ */
+ UWORD16 u2_max_content_light_level;
+
+ /**
+ * The average pixel intensity of all samples
+ */
+ UWORD16 u2_max_pic_average_light_level;
+ } isvcd_ctl_get_sei_cll_params_op_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_sei_ave_params_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /**
+ * specifies the environmental illluminance of the ambient viewing environment
+ */
+ UWORD32 u4_ambient_illuminance;
+
+ /*
+ * specify the normalized x chromaticity coordinates of the
+ * environmental ambient light in the nominal viewing environment
+ */
+ UWORD16 u2_ambient_light_x;
+
+ /*
+ * specify the normalized y chromaticity coordinates of the
+ * environmental ambient light in the nominal viewing environment
+ */
+ UWORD16 u2_ambient_light_y;
+ } isvcd_ctl_get_sei_ave_params_op_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * cmd
+ */
+ IVD_API_COMMAND_TYPE_T e_cmd;
+
+ /**
+ * sub_cmd
+ */
+ IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+ } isvcd_ctl_get_sei_ccv_params_ip_t;
+
+ typedef struct
+ {
+ /**
+ * u4_size
+ */
+ UWORD32 u4_size;
+
+ /**
+ * error_code
+ */
+ UWORD32 u4_error_code;
+
+ /*
+ * Flag used to control persistence of CCV SEI messages
+ */
+ UWORD8 u1_ccv_cancel_flag;
+
+ /*
+ * specifies the persistence of the CCV SEI message for the current layer
+ */
+ UWORD8 u1_ccv_persistence_flag;
+
+ /*
+ * specifies the presence of syntax elements ccv_primaries_x and
+ * ccv_primaries_y
+ */
+ UWORD8 u1_ccv_primaries_present_flag;
+
+ /*
+ * specifies that the syntax element ccv_min_luminance_value is present
+ */
+ UWORD8 u1_ccv_min_luminance_value_present_flag;
+
+ /*
+ * specifies that the syntax element ccv_max_luminance_value is present
+ */
+ UWORD8 u1_ccv_max_luminance_value_present_flag;
+
+ /*
+ * specifies that the syntax element ccv_avg_luminance_value is present
+ */
+ UWORD8 u1_ccv_avg_luminance_value_present_flag;
+
+ /*
+ * shall be equal to 0 in bitstreams conforming to this version. Other values
+ * for reserved_zero_2bits are reserved for future use
+ */
+ UWORD8 u1_ccv_reserved_zero_2bits;
+
+ /*
+ * specify the normalized x chromaticity coordinates of the colour
+ * primary component c of the nominal content colour volume
+ */
+ WORD32 ai4_ccv_primaries_x[NUM_SEI_CCV_PRIMARIES];
+
+ /*
+ * specify the normalized y chromaticity coordinates of the colour
+ * primary component c of the nominal content colour volume
+ */
+ WORD32 ai4_ccv_primaries_y[NUM_SEI_CCV_PRIMARIES];
+
+ /*
+ * specifies the normalized minimum luminance value
+ */
+ UWORD32 u4_ccv_min_luminance_value;
+
+ /*
+ * specifies the normalized maximum luminance value
+ */
+ UWORD32 u4_ccv_max_luminance_value;
+
+ /*
+ * specifies the normalized average luminance value
+ */
+ UWORD32 u4_ccv_avg_luminance_value;
+ } isvcd_ctl_get_sei_ccv_params_op_t;
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+#endif /* _ISVCD_H_ */
diff --git a/decoder/svc/isvcd_api.c b/decoder/svc/isvcd_api.c
new file mode 100644
index 0000000..c449fba
--- /dev/null
+++ b/decoder/svc/isvcd_api.c
@@ -0,0 +1,7291 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_api.c
+ *
+ * @brief
+ * Contains all the API related functions
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - api_check_struct_sanity()
+ * - isvcd_set_processor()
+ * - isvcd_init_decoder()
+ * - isvcd_nal_parse_ctxt_free()
+ * - isvcd_residual_resample_ctxt_free()
+ * - isvcd_intra_resample_ctxt_free()
+ * - isvcd_mode_mv_resample_ctxt_free()
+ * - isvcd_free_static_bufs()
+ * - isvcd_nal_parse_ctxt_create()
+ * - isvcd_intra_resample_ctxt_create()
+ * - isvcd_residual_resample_ctxt_create()
+ * - isvcd_mode_mv_resample_ctxt_create()
+ * - isvcd_allocate_static_bufs()
+ * - isvcd_create()
+ * - isvcd_update_dqid()
+ * - isvcd_detect_res_change()
+ * - isvcd_parse_ref_pic_list_modify()
+ * - isvcd_parse_slice_hdr_refdq_id()
+ * - isvcd_get_ref_lyr_dqid()
+ * - isvcd_conceal_node_params()
+ * - isvcd_refine_dep_list()
+ * - isvcd_dec_non_vcl()
+ * - isvcd_seq_hdr_dec()
+ * - isvcd_pre_parse_refine_au()
+ * - isvcd_video_decode()
+ * - isvcd_set_display_frame()
+ * - isvcd_set_flush_mode()
+ * - isvcd_get_status()
+ * - isvcd_get_buf_info()
+ * - isvcd_set_params()
+ * - isvcd_set_target_layer()
+ * - isvcd_set_default_params()
+ * - isvcd_delete()
+ * - isvcd_reset()
+ * - isvcd_ctl()
+ * - isvcd_rel_display_frame()
+ * - isvcd_set_degrade()
+ * - isvcd_get_frame_dimensions()
+ * - isvcd_get_vui_params()
+ * - isvcd_get_sei_mdcv_params()
+ * - isvcd_get_sei_cll_params()
+ * - isvcd_get_sei_ave_params()
+ * - isvcd_get_sei_ccv_params()
+ * - isvcd_set_num_cores()
+ * - isvcd_fill_output_struct_from_context()
+ * - isvcd_api_function()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include <limits.h>
+#include <stddef.h>
+#include <assert.h>
+#include "ih264_defs.h"
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_tables.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264_debug.h"
+#include "ih264d_inter_pred.h"
+#include "isvcd_structs.h"
+#include "ih264d_nal.h"
+#include "ih264d_error_handler.h"
+#include "ithread.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_function_selector.h"
+#include "ih264_error.h"
+#include "ih264_disp_mgr.h"
+#include "ih264_buf_mgr.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_parse_cabac.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_utils.h"
+#include "ih264d_api_utils.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_parse_headers.h"
+#include "ih264d_thread_compute_bs.h"
+#include "isvcd_utils.h"
+#include "isvcd.h"
+#include "isvcd_mode_mv_resamp.h"
+#include "isvcd_parse_headers.h"
+#include "isvcd_thread_compute_bs.h"
+#include "isvcd_function_selector.h"
+/*********************/
+/* Codec Versioning */
+/*********************/
+// Move this to where it is used
+#define CODEC_NAME "H264VDEC"
+#define CODEC_RELEASE_TYPE "production"
+#define CODEC_RELEASE_VER "05.00"
+#define CODEC_VENDOR "ITTIAM"
+#define MAXVERSION_STRLEN 511
+#ifdef ANDROID
+#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
+ snprintf(version_string, MAXVERSION_STRLEN, "@(#)Id:%s_%s Ver:%s Released by %s", codec_name, \
+ codec_release_type, codec_release_ver, codec_vendor)
+#else
+#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
+ snprintf(version_string, MAXVERSION_STRLEN, \
+ "@(#)Id:%s_%s Ver:%s Released by %s Build: %s @ %s", codec_name, codec_release_type, \
+ codec_release_ver, codec_vendor, __DATE__, __TIME__)
+#endif
+
+#define MIN_IN_BUFS 1
+#define MIN_OUT_BUFS_420 3
+#define MIN_OUT_BUFS_422ILE 1
+#define MIN_OUT_BUFS_RGB565 1
+#define MIN_OUT_BUFS_420SP 2
+
+#define NUM_FRAMES_LIMIT_ENABLED 0
+
+#if NUM_FRAMES_LIMIT_ENABLED
+#define NUM_FRAMES_LIMIT 10000
+#else
+#define NUM_FRAMES_LIMIT 0x7FFFFFFF
+#endif
+WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 ih264d_parse_sei(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm);
+WORD32 check_app_out_buf_size(dec_struct_t *ps_dec);
+UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height);
+WORD32 isvcd_get_frame_dimensions(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 isvcd_get_vui_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+WORD32 isvcd_get_sei_mdcv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 isvcd_get_sei_cll_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 isvcd_get_sei_ave_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 isvcd_get_sei_ccv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+WORD32 isvcd_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
+WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
+
+void ih264d_signal_decode_thread(dec_struct_t *ps_dec);
+
+void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec);
+void ih264d_decode_picture_thread(dec_struct_t *ps_dec);
+void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_set_degrade(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op);
+
+void isvcd_fill_output_struct_from_context(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ ivd_video_decode_op_t *ps_dec_op);
+
+static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, void *pv_api_ip,
+ void *pv_api_op)
+{
+ IVD_API_COMMAND_TYPE_T e_cmd;
+ UWORD32 *pu4_api_ip;
+ UWORD32 *pu4_api_op;
+ UWORD32 i;
+
+ if(NULL == pv_api_op) return (IV_FAIL);
+
+ if(NULL == pv_api_ip) return (IV_FAIL);
+
+ pu4_api_ip = (UWORD32 *) pv_api_ip;
+ pu4_api_op = (UWORD32 *) pv_api_op;
+ e_cmd = *(pu4_api_ip + 1);
+
+ /* error checks on handle */
+ switch((WORD32) e_cmd)
+ {
+ case IVD_CMD_CREATE:
+ break;
+
+ case IVD_CMD_REL_DISPLAY_FRAME:
+ case IVD_CMD_SET_DISPLAY_FRAME:
+ case IVD_CMD_GET_DISPLAY_FRAME:
+ case IVD_CMD_VIDEO_DECODE:
+ case IVD_CMD_DELETE:
+ case IVD_CMD_VIDEO_CTL:
+ if(ps_handle == NULL)
+ {
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->u4_size != sizeof(iv_obj_t))
+ {
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->pv_fxns != isvcd_api_function)
+ {
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->pv_codec_handle == NULL)
+ {
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
+ return IV_FAIL;
+ }
+ break;
+ default:
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
+ return IV_FAIL;
+ }
+
+ switch((WORD32) e_cmd)
+ {
+ case IVD_CMD_CREATE:
+ {
+ isvcd_create_ip_t *ps_ip = (isvcd_create_ip_t *) pv_api_ip;
+ isvcd_create_op_t *ps_op = (isvcd_create_op_t *) pv_api_op;
+
+ ps_op->s_ivd_create_op_t.u4_error_code = 0;
+
+ if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(isvcd_create_ip_t)) ||
+ (ps_ip->s_ivd_create_ip_t.u4_size < sizeof(ivd_create_ip_t)))
+ {
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_create_op_t.u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ H264_DEC_DEBUG_PRINT("\n");
+ return (IV_FAIL);
+ }
+
+ if((ps_op->s_ivd_create_op_t.u4_size != sizeof(isvcd_create_op_t)) &&
+ (ps_op->s_ivd_create_op_t.u4_size != sizeof(ivd_create_op_t)))
+ {
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_create_op_t.u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ H264_DEC_DEBUG_PRINT("\n");
+ return (IV_FAIL);
+ }
+
+ if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) &&
+ (ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_422ILE) &&
+ (ps_ip->s_ivd_create_ip_t.e_output_format != IV_RGB_565) &&
+ (ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_UV) &&
+ (ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_VU))
+ {
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_create_op_t.u4_error_code |= IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
+ H264_DEC_DEBUG_PRINT("\n");
+ return (IV_FAIL);
+ }
+ }
+ break;
+
+ case IVD_CMD_GET_DISPLAY_FRAME:
+ {
+ isvcd_get_display_frame_ip_t *ps_ip = (isvcd_get_display_frame_ip_t *) pv_api_ip;
+ isvcd_get_display_frame_op_t *ps_op = (isvcd_get_display_frame_op_t *) pv_api_op;
+
+ ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
+
+ if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size !=
+ sizeof(isvcd_get_display_frame_ip_t)) &&
+ (ps_ip->s_ivd_get_display_frame_ip_t.u4_size != sizeof(ivd_get_display_frame_ip_t)))
+ {
+ ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if((ps_op->s_ivd_get_display_frame_op_t.u4_size !=
+ sizeof(isvcd_get_display_frame_op_t)) &&
+ (ps_op->s_ivd_get_display_frame_op_t.u4_size != sizeof(ivd_get_display_frame_op_t)))
+ {
+ ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+ }
+ break;
+
+ case IVD_CMD_REL_DISPLAY_FRAME:
+ {
+ isvcd_rel_display_frame_ip_t *ps_ip = (isvcd_rel_display_frame_ip_t *) pv_api_ip;
+ isvcd_rel_display_frame_op_t *ps_op = (isvcd_rel_display_frame_op_t *) pv_api_op;
+
+ ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
+
+ if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size !=
+ sizeof(isvcd_rel_display_frame_ip_t)) &&
+ (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size != sizeof(ivd_rel_display_frame_ip_t)))
+ {
+ ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if((ps_op->s_ivd_rel_display_frame_op_t.u4_size !=
+ sizeof(isvcd_rel_display_frame_op_t)) &&
+ (ps_op->s_ivd_rel_display_frame_op_t.u4_size != sizeof(ivd_rel_display_frame_op_t)))
+ {
+ ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+ }
+ break;
+
+ case IVD_CMD_SET_DISPLAY_FRAME:
+ {
+ isvcd_set_display_frame_ip_t *ps_ip = (isvcd_set_display_frame_ip_t *) pv_api_ip;
+ isvcd_set_display_frame_op_t *ps_op = (isvcd_set_display_frame_op_t *) pv_api_op;
+ UWORD32 j;
+
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
+
+ if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size !=
+ sizeof(isvcd_set_display_frame_ip_t)) &&
+ (ps_ip->s_ivd_set_display_frame_ip_t.u4_size != sizeof(ivd_set_display_frame_ip_t)))
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if((ps_op->s_ivd_set_display_frame_op_t.u4_size !=
+ sizeof(isvcd_set_display_frame_op_t)) &&
+ (ps_op->s_ivd_set_display_frame_op_t.u4_size != sizeof(ivd_set_display_frame_op_t)))
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
+ return IV_FAIL;
+ }
+
+ for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs; j++)
+ {
+ if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs == 0)
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
+ i++)
+ {
+ if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i] == NULL)
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ IVD_DISP_FRM_OP_BUF_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j]
+ .u4_min_out_buf_size[i] == 0)
+ {
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
+ IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+ return IV_FAIL;
+ }
+ }
+ }
+ }
+ break;
+
+ case IVD_CMD_VIDEO_DECODE:
+ {
+ isvcd_video_decode_ip_t *ps_ip = (isvcd_video_decode_ip_t *) pv_api_ip;
+ isvcd_video_decode_op_t *ps_op = (isvcd_video_decode_op_t *) pv_api_op;
+
+ H264_DEC_DEBUG_PRINT("The input bytes is: %d",
+ ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
+ ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
+
+ if(ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(isvcd_video_decode_ip_t) &&
+ ps_ip->s_ivd_video_decode_ip_t.u4_size !=
+ offsetof(ivd_video_decode_ip_t, s_out_buffer))
+ {
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(isvcd_video_decode_op_t) &&
+ ps_op->s_ivd_video_decode_op_t.u4_size !=
+ offsetof(ivd_video_decode_op_t, u4_output_present))
+ {
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+ {
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ dec_struct_t *ps_dec;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) (ps_handle->pv_codec_handle);
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(ps_dec->u1_enable_mb_info)
+ {
+ if(!ps_ip->pu1_8x8_blk_qp_map && !ps_ip->pu1_8x8_blk_type_map)
+ {
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_video_decode_op_t.u4_error_code |=
+ IH264D_FRAME_INFO_OP_BUF_NULL;
+ return IV_FAIL;
+ }
+ }
+ }
+ }
+ break;
+
+ case IVD_CMD_DELETE:
+ {
+ isvcd_delete_ip_t *ps_ip = (isvcd_delete_ip_t *) pv_api_ip;
+ isvcd_delete_op_t *ps_op = (isvcd_delete_op_t *) pv_api_op;
+
+ ps_op->s_ivd_delete_op_t.u4_error_code = 0;
+
+ if(ps_ip->s_ivd_delete_ip_t.u4_size != sizeof(isvcd_delete_ip_t))
+ {
+ ps_op->s_ivd_delete_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_delete_op_t.u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ivd_delete_op_t.u4_size != sizeof(isvcd_delete_op_t))
+ {
+ ps_op->s_ivd_delete_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_delete_op_t.u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+ }
+ break;
+
+ case IVD_CMD_VIDEO_CTL:
+ {
+ UWORD32 *pu4_ptr_cmd;
+ UWORD32 sub_command;
+
+ pu4_ptr_cmd = (UWORD32 *) pv_api_ip;
+ pu4_ptr_cmd += 2;
+ sub_command = *pu4_ptr_cmd;
+
+ switch(sub_command)
+ {
+ case IVD_CMD_CTL_SETPARAMS:
+ {
+ isvcd_ctl_set_config_ip_t *ps_ip;
+ isvcd_ctl_set_config_op_t *ps_op;
+ ps_ip = (isvcd_ctl_set_config_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
+
+ if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size !=
+ sizeof(isvcd_ctl_set_config_ip_t))
+ {
+ ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_SETDEFAULT:
+ {
+ isvcd_ctl_set_config_op_t *ps_op;
+ ps_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
+ if(ps_op->s_ivd_ctl_set_config_op_t.u4_size !=
+ sizeof(isvcd_ctl_set_config_op_t))
+ {
+ ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_GETPARAMS:
+ {
+ isvcd_ctl_getstatus_ip_t *ps_ip;
+ isvcd_ctl_getstatus_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_getstatus_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_getstatus_op_t *) pv_api_op;
+ if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size != sizeof(isvcd_ctl_getstatus_ip_t))
+ {
+ ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size != sizeof(isvcd_ctl_getstatus_op_t))
+ {
+ ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_GETBUFINFO:
+ {
+ isvcd_ctl_getbufinfo_ip_t *ps_ip;
+ isvcd_ctl_getbufinfo_op_t *ps_op;
+ ps_ip = (isvcd_ctl_getbufinfo_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_getbufinfo_op_t *) pv_api_op;
+
+ if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size !=
+ sizeof(isvcd_ctl_getbufinfo_ip_t))
+ {
+ ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size !=
+ sizeof(isvcd_ctl_getbufinfo_op_t))
+ {
+ ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_GETVERSION:
+ {
+ isvcd_ctl_getversioninfo_ip_t *ps_ip;
+ isvcd_ctl_getversioninfo_op_t *ps_op;
+ ps_ip = (isvcd_ctl_getversioninfo_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_getversioninfo_op_t *) pv_api_op;
+ if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size !=
+ sizeof(isvcd_ctl_getversioninfo_ip_t))
+ {
+ ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
+ 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size !=
+ sizeof(isvcd_ctl_getversioninfo_op_t))
+ {
+ ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
+ 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_FLUSH:
+ {
+ isvcd_ctl_flush_ip_t *ps_ip;
+ isvcd_ctl_flush_op_t *ps_op;
+ ps_ip = (isvcd_ctl_flush_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_flush_op_t *) pv_api_op;
+ if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size != sizeof(isvcd_ctl_flush_ip_t))
+ {
+ ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ if(ps_op->s_ivd_ctl_flush_op_t.u4_size != sizeof(isvcd_ctl_flush_op_t))
+ {
+ ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IVD_CMD_CTL_RESET:
+ {
+ isvcd_ctl_reset_ip_t *ps_ip;
+ isvcd_ctl_reset_op_t *ps_op;
+ ps_ip = (isvcd_ctl_reset_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_reset_op_t *) pv_api_op;
+ if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size != sizeof(isvcd_ctl_reset_ip_t))
+ {
+ ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
+ IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ if(ps_op->s_ivd_ctl_reset_op_t.u4_size != sizeof(isvcd_ctl_reset_op_t))
+ {
+ ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+ break;
+
+ case IH264D_CMD_CTL_DEGRADE:
+ {
+ isvcd_ctl_degrade_ip_t *ps_ip;
+ isvcd_ctl_degrade_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_degrade_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_degrade_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_degrade_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_degrade_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->i4_degrade_pics < 0) || (ps_ip->i4_degrade_pics > 4) ||
+ (ps_ip->i4_nondegrade_interval < 0) || (ps_ip->i4_degrade_type < 0) ||
+ (ps_ip->i4_degrade_type > 15))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
+ {
+ isvcd_ctl_get_frame_dimensions_ip_t *ps_ip;
+ isvcd_ctl_get_frame_dimensions_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_frame_dimensions_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_frame_dimensions_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_frame_dimensions_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_frame_dimensions_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case IH264D_CMD_CTL_GET_VUI_PARAMS:
+ {
+ isvcd_ctl_get_vui_params_ip_t *ps_ip;
+ isvcd_ctl_get_vui_params_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_vui_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_vui_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_vui_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_vui_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
+ {
+ isvcd_ctl_get_sei_mdcv_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_sei_mdcv_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_mdcv_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_mdcv_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
+ {
+ isvcd_ctl_get_sei_cll_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_cll_params_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_sei_cll_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_cll_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_cll_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_cll_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
+ {
+ isvcd_ctl_get_sei_ave_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_ave_params_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_sei_ave_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_ave_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_ave_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_ave_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
+ {
+ isvcd_ctl_get_sei_ccv_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_get_sei_ccv_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_ccv_params_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_ccv_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_ccv_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case IH264D_CMD_CTL_SET_NUM_CORES:
+ {
+ isvcd_ctl_set_num_cores_ip_t *ps_ip;
+ isvcd_ctl_set_num_cores_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_set_num_cores_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_set_num_cores_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_set_num_cores_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_set_num_cores_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2) &&
+ (ps_ip->u4_num_cores != 3) && (ps_ip->u4_num_cores != 4))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+ break;
+ }
+ case IH264D_CMD_CTL_SET_PROCESSOR:
+ {
+ isvcd_ctl_set_processor_ip_t *ps_ip;
+ isvcd_ctl_set_processor_op_t *ps_op;
+
+ ps_ip = (isvcd_ctl_set_processor_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_set_processor_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_ctl_set_processor_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_ctl_set_processor_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ case ISVCD_CMD_CTL_SET_TGT_LAYER:
+ {
+ isvcd_set_target_layer_ip_t *ps_ip;
+ isvcd_set_target_layer_op_t *ps_op;
+
+ ps_ip = (isvcd_set_target_layer_ip_t *) pv_api_ip;
+ ps_op = (isvcd_set_target_layer_op_t *) pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvcd_set_target_layer_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u1_tgt_dep_id > MAX_DEPENDENCY_ID)
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u1_tgt_temp_id > MAX_TEMPORAL_ID)
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u1_tgt_quality_id > MAX_QUALITY_ID)
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u1_tgt_priority_id > MAX_PRIORITY_ID)
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvcd_set_target_layer_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
+ default:
+ *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
+ return IV_FAIL;
+ break;
+ }
+ }
+ break;
+ }
+
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets Processor type
+ *
+ * @par Description:
+ * Sets Processor type
+ *
+ * @param[in] ps_codec_obj
+ * Pointer to codec object at API level
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @returns Status
+ *
+ * @remarks
+ *
+ *
+ *******************************************************************************
+ */
+
+WORD32 isvcd_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_set_processor_ip_t *ps_ip;
+ isvcd_ctl_set_processor_op_t *ps_op;
+ UWORD8 u1_layer_id;
+ svc_dec_lyr_struct_t *ps_codec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_set_processor_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_set_processor_op_t *) pv_api_op;
+
+ ps_svcd_ctxt->e_processor_arch = (IVD_ARCH_T) ps_ip->u4_arch;
+ ps_svcd_ctxt->e_processor_soc = (IVD_SOC_T) ps_ip->u4_soc;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_codec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_codec->s_dec.e_processor_arch = (IVD_ARCH_T) ps_ip->u4_arch;
+ ps_codec->s_dec.e_processor_soc = (IVD_SOC_T) ps_ip->u4_soc;
+
+ isvcd_init_function_ptr(ps_codec);
+ }
+
+ ps_op->u4_error_code = 0;
+ return IV_SUCCESS;
+}
+
+/**************************************************************************
+ * \if Function name : isvcd_init_decoder \endif
+ *
+ *
+ * \brief
+ * Initializes the decoder
+ *
+ * \param apiVersion : Version of the api being used.
+ * \param errorHandlingMechanism : Mechanism to be used for errror handling.
+ * \param postFilteringType: Type of post filtering operation to be used.
+ * \param uc_outputFormat: Format of the decoded picture [default 4:2:0].
+ * \param uc_dispBufs: Number of Display Buffers.
+ * \param p_NALBufAPI: Pointer to NAL Buffer API.
+ * \param p_DispBufAPI: Pointer to Display Buffer API.
+ * \param ih264d_dec_mem_manager :Pointer to the function that will be called
+ *by decoder for memory allocation and freeing.
+ *
+ * \return
+ * 0 on Success and -1 on error
+ *
+ **************************************************************************
+ */
+void isvcd_init_decoder(svc_dec_lyr_struct_t *ps_dec_svc_lyr_params)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) ps_dec_svc_lyr_params;
+ dec_struct_t *ps_dec;
+ dec_slice_params_t *ps_cur_slice;
+ pocstruct_t *ps_prev_poc, *ps_cur_poc;
+ size_t size;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ size = sizeof(pred_info_t) * 2 * 32;
+ memset(ps_dec->ps_pred, 0, size);
+
+ size = sizeof(disp_mgr_t);
+ memset(ps_dec->pv_disp_buf_mgr, 0, size);
+
+ size = ih264_buf_mgr_size();
+ memset(ps_dec->pv_pic_buf_mgr, 0, size);
+
+ size = sizeof(dec_err_status_t);
+ memset(ps_dec->ps_dec_err_status, 0, size);
+
+ size = sizeof(sei);
+ memset(ps_dec->ps_sei, 0, size);
+
+ size = sizeof(sei);
+ memset(ps_dec->ps_sei_parse, 0, size);
+
+ size = sizeof(dpb_commands_t);
+ memset(ps_dec->ps_dpb_cmds, 0, size);
+
+ size = sizeof(dec_bit_stream_t);
+ memset(ps_dec->ps_bitstrm, 0, size);
+
+ size = sizeof(dec_slice_params_t);
+ memset(ps_dec->ps_cur_slice, 0, size);
+
+ size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
+ memset(ps_dec->pv_scratch_sps_pps, 0, size);
+
+ size = sizeof(dec_svc_seq_params_t);
+ memset(ps_svc_lyr_dec->pv_scratch_subset_sps, 0, size);
+
+ size = sizeof(ctxt_inc_mb_info_t);
+ memset(ps_dec->ps_left_mb_ctxt_info, 0, size);
+
+ size = (sizeof(neighbouradd_t) << 2);
+ memset(ps_dec->ps_left_mvpred_addr, 0, size);
+
+ size = ih264_buf_mgr_size();
+ memset(ps_dec->pv_mv_buf_mgr, 0, size);
+
+ /* Free any dynamic buffers that are allocated */
+ isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
+
+ {
+ UWORD8 i;
+ struct pic_buffer_t *ps_init_dpb;
+ ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0];
+ for(i = 0; i < 2 * MAX_REF_BUFS; i++)
+ {
+ ps_init_dpb->pu1_buf1 = NULL;
+ ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
+ ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb;
+ ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb;
+ ps_init_dpb++;
+ }
+
+ ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0];
+ for(i = 0; i < 2 * MAX_REF_BUFS; i++)
+ {
+ ps_init_dpb->pu1_buf1 = NULL;
+ ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
+ ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb;
+ ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb;
+ ps_init_dpb++;
+ }
+ }
+
+ ps_cur_slice = ps_dec->ps_cur_slice;
+ ps_dec->init_done = 0;
+
+ ps_dec->u4_num_cores = 1;
+ ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0;
+
+ ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
+ ps_dec->u4_app_disable_deblk_frm = 0;
+ ps_dec->i4_degrade_type = 0;
+ ps_dec->i4_degrade_pics = 0;
+
+ /* Initialization of function pointers ih264d_deblock_picture function*/
+ ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
+ ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
+
+ ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec;
+ ps_dec->u4_num_fld_in_frm = 0;
+ ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
+
+ /* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/
+ ps_dec->ps_sei->u1_is_valid = 0;
+
+ /* decParams Initializations */
+ ps_dec->ps_cur_pps = NULL;
+ ps_dec->ps_cur_sps = NULL;
+ ps_dec->u1_init_dec_flag = 0;
+ ps_dec->u1_first_slice_in_stream = 1;
+ ps_dec->u1_last_pic_not_decoded = 0;
+ ps_dec->u4_app_disp_width = 0;
+ ps_dec->i4_header_decoded = 0;
+ ps_dec->u4_total_frames_decoded = 0;
+
+ ps_dec->i4_error_code = 0;
+ ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
+ ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0;
+
+ ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS;
+ ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
+ ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
+ ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
+ ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
+
+ ps_dec->u1_pr_sl_type = 0xFF;
+ ps_dec->u2_mbx = 0xffff;
+ ps_dec->u2_mby = 0;
+ ps_dec->u2_total_mbs_coded = 0;
+
+ /* POC initializations */
+ ps_prev_poc = &ps_dec->s_prev_pic_poc;
+ ps_cur_poc = &ps_dec->s_cur_pic_poc;
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
+ ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = 0;
+ ps_prev_poc->i4_bottom_field_order_count = ps_cur_poc->i4_bottom_field_order_count = 0;
+ ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
+ ps_cur_slice->u1_mmco_equalto5 = 0;
+ ps_cur_slice->u2_frame_num = 0;
+
+ ps_dec->i4_max_poc = 0;
+ ps_dec->i4_prev_max_display_seq = 0;
+ ps_dec->u1_recon_mb_grp = 4;
+ ps_dec->i4_reorder_depth = -1;
+
+ /* Field PIC initializations */
+ ps_dec->u1_second_field = 0;
+ ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
+
+ /* Set the cropping parameters as zero */
+ ps_dec->u2_crop_offset_y = 0;
+ ps_dec->u2_crop_offset_uv = 0;
+
+ /* The Initial Frame Rate Info is not Present */
+ ps_dec->i4_vui_frame_rate = -1;
+ ps_dec->i4_pic_type = NA_SLICE;
+ ps_dec->i4_frametype = IV_NA_FRAME;
+ ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
+
+ ps_dec->u1_res_changed = 0;
+
+ ps_dec->u1_frame_decoded_flag = 0;
+
+ /* Set the default frame seek mask mode */
+ ps_dec->u4_skip_frm_mask = SKIP_NONE;
+
+ /********************************************************/
+ /* Initialize CAVLC residual decoding function pointers */
+ /********************************************************/
+ ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
+ ps_dec->pf_cavlc_4x4res_block[1] = ih264d_cavlc_4x4res_block_totalcoeff_2to10;
+ ps_dec->pf_cavlc_4x4res_block[2] = ih264d_cavlc_4x4res_block_totalcoeff_11to16;
+
+ ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
+ ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
+
+ ps_dec->pf_cavlc_parse_8x8block[0] = ih264d_cavlc_parse_8x8block_none_available;
+ ps_dec->pf_cavlc_parse_8x8block[1] = ih264d_cavlc_parse_8x8block_left_available;
+ ps_dec->pf_cavlc_parse_8x8block[2] = ih264d_cavlc_parse_8x8block_top_available;
+ ps_dec->pf_cavlc_parse_8x8block[3] = ih264d_cavlc_parse_8x8block_both_available;
+
+ /***************************************************************************/
+ /* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */
+ /***************************************************************************/
+ ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
+ ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
+
+ ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
+ ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
+
+ ps_dec->pf_fill_bs_xtra_left_edge[0] = ih264d_fill_bs_xtra_left_edge_cur_frm;
+ ps_dec->pf_fill_bs_xtra_left_edge[1] = ih264d_fill_bs_xtra_left_edge_cur_fld;
+
+ /* Initialize Reference Pic Buffers */
+ ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
+
+ ps_dec->u2_prv_frame_num = 0;
+ ps_dec->u1_top_bottom_decoded = 0;
+ ps_dec->u1_dangling_field = 0;
+
+ ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
+
+ ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0];
+ ps_dec->pi1_left_ref_idx_ctxt_inc = &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0];
+ ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb;
+
+ /* ! */
+ /* Initializing flush frame u4_flag */
+ ps_dec->u1_flushfrm = 0;
+
+ ps_dec->s_cab_dec_env.pv_codec_handle = (void *) ps_dec;
+ ps_dec->ps_bitstrm->pv_codec_handle = (void *) ps_dec;
+ ps_dec->ps_cur_slice->pv_codec_handle = (void *) ps_dec;
+ ps_dec->ps_dpb_mgr->pv_codec_handle = (void *) ps_dec;
+
+ memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
+ memset(ps_dec->u4_disp_buf_mapping, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
+ memset(ps_dec->u4_disp_buf_to_be_freed, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
+ memset(ps_dec->ps_cur_slice, 0, sizeof(dec_slice_params_t));
+
+ ih264d_init_arch(ps_dec);
+ isvcd_init_function_ptr(ps_svc_lyr_dec);
+ ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_dec->init_done = 1;
+ ps_svc_lyr_dec->u1_layer_identifier = BASE_LAYER;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_ctxt_free */
+/* */
+/* Description :this function is used to free the nal parse context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_nal_parse_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+ nal_parse_ctxt_t *ps_ctxt;
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ pf_aligned_free = ps_dec->pf_aligned_free;
+
+ pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+ ps_ctxt = (nal_parse_ctxt_t *) ps_svcd_ctxt->pv_nal_parse_ctxt;
+
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->s_dqid_ctxt.ps_dqid_node);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pv_nal_header_buf);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pv_nal_unit);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_vcl_nal_buff);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_non_vcl_nal_buff);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_nal_parse_ctxt);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_resample_ctxt_free */
+/* */
+/* Description :this function is used to free the resd_resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_residual_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+ residual_sampling_ctxt_t *ps_ctxt;
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ pf_aligned_free = ps_dec->pf_aligned_free;
+
+ pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+ ps_ctxt = (residual_sampling_ctxt_t *) ps_svcd_ctxt->pv_residual_sample_ctxt;
+
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pi2_refarray_buffer);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_ref_x_ptr_incr);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_offset_length);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_offset_length);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_pos_phase);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_pos_phase);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_residual_sample_ctxt);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resample_ctxt_free */
+/* */
+/* Description :this function is used to free the intra_resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_intra_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+ intra_sampling_ctxt_t *ps_ctxt;
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ pf_aligned_free = ps_dec->pf_aligned_free;
+
+ pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+ ps_ctxt = (intra_sampling_ctxt_t *) ps_svcd_ctxt->pv_intra_sample_ctxt;
+
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_buffer);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_cb);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_cr);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->pi4_temp_interpolation_buffer);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_offset_length);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_offset_length);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_min_max);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_min_max);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_pos_phase);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_pos_phase);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_xd_index);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_yd_index);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_ya_index);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_seg_lookup_horz);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_seg_lookup_vert);
+ pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pu1_refarray_x_idx);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_intra_sample_ctxt);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_ii_pred_ctxt);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_mode_mv_resample_ctxt_free */
+/* */
+/* Description :this function is used to free the mv resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_mode_mv_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+ mode_motion_ctxt_t *ps_mode_motion;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ pf_aligned_free = ps_dec->pf_aligned_free;
+
+ pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+ ps_mode_motion = (mode_motion_ctxt_t *) ps_svcd_ctxt->pv_mode_mv_sample_ctxt;
+
+ pf_aligned_free(pv_mem_ctxt, ps_mode_motion->ps_motion_pred_struct);
+ pf_aligned_free(pv_mem_ctxt, ps_mode_motion->as_res_lyr_mem[0].pi2_ref_loc_x);
+ pf_aligned_free(pv_mem_ctxt, ps_mode_motion->as_res_lyr_mem[0].pi2_ref_loc_y);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_ref_lyr_offset);
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_mode_mv_sample_ctxt);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_free_static_bufs */
+/* */
+/* Description :this function is used to free the static buffers */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_free_static_bufs(iv_obj_t *dec_hdl)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ isvcd_intra_resample_ctxt_free(ps_svcd_ctxt);
+ isvcd_residual_resample_ctxt_free(ps_svcd_ctxt);
+ isvcd_mode_mv_resample_ctxt_free(ps_svcd_ctxt);
+ isvcd_nal_parse_ctxt_free(ps_svcd_ctxt);
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ pf_aligned_free = ps_dec->pf_aligned_free;
+ pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+
+#ifdef KEEP_THREADS_ACTIVE
+ /* Wait for threads */
+ ps_dec->i4_break_threads = 1;
+ if(ps_dec->u4_dec_thread_created)
+ {
+ ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
+
+ ps_dec->ai4_process_start[0] = PROC_START;
+
+ ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
+
+ ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
+
+ ithread_join(ps_dec->pv_dec_thread_handle, NULL);
+
+ ps_dec->u4_dec_thread_created = 0;
+ }
+
+ if(ps_dec->u4_bs_deblk_thread_created)
+ {
+ ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
+
+ ps_dec->ai4_process_start[1] = PROC_START;
+
+ ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
+
+ ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
+
+ ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL);
+
+ ps_dec->u4_bs_deblk_thread_created = 0;
+ }
+
+ // destroy mutex and condition variable for both the threads
+ // 1. ih264d_decode_picture_thread
+ // 2. ih264d_recon_deblk_thread
+ {
+ UWORD32 i;
+ for(i = 0; i < 2; i++)
+ {
+ ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]);
+ ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]);
+
+ ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]);
+ ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]);
+ }
+ }
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]);
+#endif
+ if(0 == u1_layer_id)
+ {
+ UWORD8 u1_sps_ctr;
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps);
+ for(u1_sps_ctr = 0; u1_sps_ctr < (2 * MAX_NUM_SEQ_PARAMS); u1_sps_ctr++)
+ {
+ if(NULL != ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].s_sps_svc_ext.ps_svc_vui_ext)
+ {
+ PS_DEC_ALIGNED_FREE(
+ ps_dec,
+ ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].s_sps_svc_ext.ps_svc_vui_ext);
+ }
+ }
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_subset_sps);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei_parse);
+ }
+
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_dec_thread_handle);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_bs_deblk_thread_handle);
+
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_mgr);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pred);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_disp_buf_mgr);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pic_buf_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dec_err_status);
+
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_cmds);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_nal_svc_ext);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_cur_slice);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_scratch_sps_pps);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pv_scratch_subset_sps);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_bits_buf_static);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ppv_map_ref_idx_to_poc_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->p_cabac_ctxt_table_t);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mb_ctxt_info);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_ref_buff_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pi2_pred1);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_temp_mc_buffer);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_init_dpb_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_mbaff_wt_mat);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_wts_ofsts_mat);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mvpred_addr);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_col_mv_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma);
+
+ if(NULL != ps_dec->pv_pic_buf_mgr)
+ {
+ if(u1_layer_id < ps_svcd_ctxt->u1_prev_num_res_layers)
+ {
+ if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
+ }
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr);
+ }
+ if(NULL != ps_dec->pv_mv_buf_mgr)
+ {
+ if(u1_layer_id < ps_svcd_ctxt->u1_prev_num_res_layers)
+ {
+ if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
+ }
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr);
+ }
+ }
+
+ pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->ps_svc_dec_lyr);
+ pf_aligned_free(pv_mem_ctxt, dec_hdl->pv_codec_handle);
+
+ if(dec_hdl)
+ {
+ pf_aligned_free(pv_mem_ctxt, dec_hdl);
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_init */
+/* */
+/* Description : Initiaization of allocation of memory */
+/* */
+/* Inputs : pv_mem_rec - Allocated memory records */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Module's handle */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_nal_parse_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ void *pv_buf;
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+ void *pv_mem_ctxt;
+ WORD32 size;
+ nal_parse_ctxt_t *ps_nal_parse_ctxt;
+ UWORD8 *pu1_ptr;
+ UNUSED(pv_api_op);
+
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+
+ pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+
+ /*-----------------------------------------------------------------------*/
+ /* Handle */
+ /*-----------------------------------------------------------------------*/
+ size = sizeof(nal_parse_ctxt_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_nal_parse_ctxt = pv_buf;
+
+ /* set the lowest dqid to -1 */
+ ps_nal_parse_ctxt->i4_prev_dq_id = -1;
+
+ /*-----------------------------------------------------------------------*/
+ /* DQID list buffer and initialization of vcl node buffer context */
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD32 i4_lyr_idx;
+ WORD32 i4_max_num_lyrs;
+ vcl_node_t *ps_vcl_node;
+ dqid_node_t *ps_dqid_node;
+ dqid_ctxt_t *ps_dqid_ctxt;
+
+ size = sizeof(vcl_node_t);
+ size += sizeof(dqid_node_t);
+ size *= MAX_NUM_RES_LYRS;
+
+ ps_dqid_ctxt = &ps_nal_parse_ctxt->s_dqid_ctxt;
+
+ ps_dqid_ctxt->i4_max_num_lyrs = MAX_NUM_RES_LYRS;
+
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ ps_dqid_ctxt->ps_dqid_node = pv_buf;
+ ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
+
+ i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
+
+ pu1_ptr = pv_buf;
+ pu1_ptr += sizeof(dqid_node_t) * i4_max_num_lyrs;
+ ps_vcl_node = (vcl_node_t *) pu1_ptr;
+
+ for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
+ {
+ ps_dqid_node->ps_vcl_node = ps_vcl_node;
+
+ /* Loop updates */
+ ps_vcl_node += 1;
+ ps_dqid_node += 1;
+ } /* Loop over all the layers */
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Common memory */
+ /*-----------------------------------------------------------------------*/
+ size = UP_ALIGN_8(HEADER_BUFFER_LEN_BEFORE_EP);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_nal_parse_ctxt->pv_nal_header_buf = (void *) pv_buf;
+
+ /*-----------------------------------------------------------------------*/
+ /* Layer params memory */
+ /*-----------------------------------------------------------------------*/
+ size = sizeof(nal_unit_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_nal_parse_ctxt->pv_nal_unit = pv_buf;
+
+ size = MAX_VCL_NAL_BUFF_SIZE * sizeof(UWORD8);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->pv_vcl_nal_buff = pv_buf;
+
+ size = MAX_NON_VCL_NAL_BUFF_SIZE * sizeof(UWORD8);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->pv_non_vcl_nal_buff = pv_buf;
+
+ /*-----------------------------------------------------------------------*/
+ /* Registering the seq and pic prms buffer pointers */
+ /*-----------------------------------------------------------------------*/
+ if(NULL == ps_svcd_ctxt->ps_sps || NULL == ps_svcd_ctxt->ps_pps)
+ {
+ return IV_FAIL;
+ }
+
+ ps_svcd_ctxt->pv_nal_parse_ctxt = ps_nal_parse_ctxt;
+ ps_nal_parse_ctxt->pv_seq_prms = ps_svcd_ctxt->ps_sps;
+ ps_nal_parse_ctxt->pv_pic_prms = ps_svcd_ctxt->ps_pps;
+
+ /* register VCL and NON VCL buffer pointers */
+ if(NULL == ps_svcd_ctxt->pv_vcl_nal_buff || NULL == ps_svcd_ctxt->pv_non_vcl_nal_buff)
+ {
+ return IV_FAIL;
+ }
+
+ ps_nal_parse_ctxt->pv_vcl_nal_buf = (UWORD8 *) ps_svcd_ctxt->pv_vcl_nal_buff;
+ ps_nal_parse_ctxt->pv_non_vcl_nal_buf = (UWORD8 *) ps_svcd_ctxt->pv_non_vcl_nal_buff;
+ isvcd_nal_parse_reset_ctxt(ANNEX_B, PARTIAL_INPUT_MODE, ps_nal_parse_ctxt);
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resample_ctxt_create */
+/* */
+/* Description :this function is used to create intra_resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_intra_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
+ void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void *pv_buf;
+ UWORD8 u1_layer_id;
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+ void *pv_mem_ctxt;
+ WORD32 size;
+ intra_inter_pred_ctxt_t *ps_ii_pred_ctxt;
+
+ intra_sampling_ctxt_t *ps_ctxt;
+ UNUSED(pv_api_op);
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+
+ pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+
+ {
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+
+ /* allocate context structure */
+ size = ((sizeof(intra_sampling_ctxt_t) + 127) >> 7) << 7;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt = pv_buf;
+
+ /* luma reference array buffer */
+ size = REF_ARRAY_WIDTH * REF_ARRAY_HEIGHT * sizeof(UWORD8);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pu1_refarray_buffer = pv_buf;
+
+ /* cb reference array buffer */
+ size = REF_ARRAY_WIDTH * REF_ARRAY_HEIGHT * sizeof(UWORD8);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pu1_refarray_cb = pv_buf;
+
+ /* cr reference array buffer */
+ size = ((DYADIC_REF_W_C + 2) * (DYADIC_REF_H_C + 2) * sizeof(UWORD8));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pu1_refarray_cr = pv_buf;
+
+ /* Temp Intermediate Buffer */
+ size = INTERMEDIATE_BUFF_WIDTH * INTERMEDIATE_BUFF_HEIGHT * sizeof(WORD32);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pi4_temp_interpolation_buffer = pv_buf;
+
+ /****************** projected locations buffers ******************/
+ {
+ intra_samp_map_ctxt_t *ps_luma_map;
+ intra_samp_map_ctxt_t *ps_chroma_map;
+ WORD32 i4_lyr_id;
+ ref_mb_map_t *ps_off_len_map;
+ ref_pixel_map_t *ps_pos_phase_map;
+ ref_min_max_map_t *ps_min_max;
+ WORD16 *pi2_mem;
+ UWORD8 *pu1_mem;
+ seg_lookup_desc_t *ps_seg_lookup;
+
+ /****************** Horz offset length ******************/
+
+ size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_off_len_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_x_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
+ ps_chroma_map->ps_x_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Vert offset length ******************/
+ size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_off_len_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_y_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
+ ps_chroma_map->ps_y_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Horz Min Max Pos ******************/
+
+ size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_min_max = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_x_min_max = ps_min_max;
+ ps_min_max += (H264_MAX_FRAME_WIDTH >> 4);
+ ps_chroma_map->ps_x_min_max = ps_min_max;
+ ps_min_max += (H264_MAX_FRAME_WIDTH >> 4);
+ } /* end of loop over resolution layers */
+
+ /****************** Vert Min Max Pos ******************/
+ size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_min_max = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_y_min_max = ps_min_max;
+ ps_min_max += (H264_MAX_FRAME_HEIGHT >> 4);
+ ps_chroma_map->ps_y_min_max = ps_min_max;
+ ps_min_max += (H264_MAX_FRAME_HEIGHT >> 4);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Horz position phase ******************/
+ size = (H264_MAX_FRAME_WIDTH) *MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_pos_phase_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_x_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += (H264_MAX_FRAME_WIDTH);
+ ps_chroma_map->ps_x_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += (H264_MAX_FRAME_WIDTH);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Vert position phase ******************/
+
+ size = (H264_MAX_FRAME_HEIGHT) *MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_pos_phase_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_y_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += (H264_MAX_FRAME_HEIGHT);
+ ps_chroma_map->ps_y_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += (H264_MAX_FRAME_HEIGHT);
+
+ } /* end of loop over resolution layers */
+
+ /**************** XD Index ******************************/
+ size = (MB_WIDTH) *MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pi2_mem = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->pi2_xd_index = pi2_mem;
+ pi2_mem += MB_WIDTH;
+ ps_chroma_map->pi2_xd_index = pi2_mem;
+ pi2_mem += MB_WIDTH;
+
+ } /* end of loop over resolution layers */
+
+ /**************** YD Index ******************************/
+ size = (MB_HEIGHT) *MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pi2_mem = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->pi2_yd_index = pi2_mem;
+ pi2_mem += MB_HEIGHT;
+ ps_chroma_map->pi2_yd_index = pi2_mem;
+ pi2_mem += MB_HEIGHT;
+
+ } /* end of loop over resolution layers */
+
+ /**************** YA Index ******************************/
+ size = MB_HEIGHT * MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pi2_mem = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->pi2_ya_index = pi2_mem;
+ pi2_mem += MB_HEIGHT;
+ ps_chroma_map->pi2_ya_index = pi2_mem;
+ pi2_mem += MB_HEIGHT;
+
+ } /* end of loop over resolution layers */
+
+ /**************** Horizontal segment lookup **************************/
+ /* (MB_WIDTH x seg_lookup_desc_t) x (num layers - 1) (for luma )*/
+ /* (BLOCK_WIDTH x seg_lookup_desc_t) x (num layers - 1) (for chroma )*/
+ size = (MB_WIDTH * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
+
+ size += (BLOCK_WIDTH * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
+
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_seg_lookup = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_seg_lookup_horz = ps_seg_lookup;
+ ps_seg_lookup += MB_WIDTH;
+ ps_chroma_map->ps_seg_lookup_horz = ps_seg_lookup;
+ ps_seg_lookup += BLOCK_WIDTH;
+
+ } /* end of loop over resolution layers */
+
+ /**************** Vertical segment lookup ****************************/
+ /* (MB_HEIGHT x seg_lookup_desc_t) x (num layers - 1) (for luma )*/
+ /* (BLOCK_HEIGHT x seg_lookup_desc_t) x (num layers - 1) (for chroma)*/
+ size = (MB_HEIGHT * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
+
+ size += (BLOCK_HEIGHT * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
+
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_seg_lookup = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_seg_lookup_vert = ps_seg_lookup;
+ ps_seg_lookup += MB_HEIGHT;
+ ps_chroma_map->ps_seg_lookup_vert = ps_seg_lookup;
+ ps_seg_lookup += BLOCK_HEIGHT;
+
+ } /* end of loop over resolution layers */
+
+ /**************** X and Y Reference Array Index lookup ***************/
+ /* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for luma x-index) */
+ /* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for luma y-index) */
+ /* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for chroma x-index) */
+ /* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for chroma y-index) */
+ /*********************************************************************/
+ size = (MAX_REF_IDX_ARRAY * MAX_NUM_RES_LYRS * 4);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pu1_mem = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->pu1_refarray_x_idx = pu1_mem;
+ pu1_mem += MAX_REF_IDX_ARRAY;
+
+ ps_luma_map->pu1_refarray_y_idx = pu1_mem;
+ pu1_mem += MAX_REF_IDX_ARRAY;
+
+ ps_chroma_map->pu1_refarray_x_idx = pu1_mem;
+ pu1_mem += MAX_REF_IDX_ARRAY;
+
+ ps_chroma_map->pu1_refarray_y_idx = pu1_mem;
+ pu1_mem += MAX_REF_IDX_ARRAY;
+
+ } /* end of loop over resolution layers */
+ }
+
+ size = ((sizeof(intra_inter_pred_ctxt_t) + 127) >> 7) << 7;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ii_pred_ctxt = pv_buf;
+ }
+
+ ps_svcd_ctxt->pv_intra_sample_ctxt = ps_ctxt;
+ ps_svcd_ctxt->pv_ii_pred_ctxt = ps_ii_pred_ctxt;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_svc_lyr_dec->pv_intra_sample_ctxt = ps_svcd_ctxt->pv_intra_sample_ctxt;
+ ps_svc_lyr_dec->pv_ii_pred_ctxt = ps_svcd_ctxt->pv_ii_pred_ctxt;
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_resample_ctxt_create */
+/* */
+/* Description :this function is used to create resd_resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 ittiam creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_residual_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
+ void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void *pv_buf;
+ UWORD8 u1_layer_id;
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+ void *pv_mem_ctxt;
+ WORD32 size;
+
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ UNUSED(pv_api_op);
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+
+ pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+
+ /* allocate context structure */
+ size = ((sizeof(residual_sampling_ctxt_t) + 127) >> 7) << 7;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt = pv_buf;
+
+ /* reference array buffer */
+ size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pi2_refarray_buffer = pv_buf;
+
+ /* reference array pointer increment buffer */
+ {
+ WORD32 i4_size;
+
+ i4_size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * sizeof(UWORD8);
+ size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * 2 * sizeof(UWORD8);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_ctxt->pu1_ref_x_ptr_incr = pv_buf;
+ ps_ctxt->pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr + i4_size;
+ }
+
+ /****************** projected locations buffers ******************/
+ {
+ residual_samp_map_ctxt_t *ps_luma_map;
+ residual_samp_map_ctxt_t *ps_chroma_map;
+ WORD32 i4_lyr_id;
+ ref_mb_map_t *ps_off_len_map;
+ ref_pixel_map_t *ps_pos_phase_map;
+
+ /****************** Horz offset length ******************/
+ size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_off_len_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_x_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
+ ps_chroma_map->ps_x_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Vert offset length ******************/
+ size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_off_len_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_y_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
+ ps_chroma_map->ps_y_offset_length = ps_off_len_map;
+ ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
+
+ } /* end of loop over resolution layers */
+
+ /****************** Horz position phase ******************/
+ size = H264_MAX_FRAME_WIDTH * MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_pos_phase_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_x_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += H264_MAX_FRAME_WIDTH;
+ ps_chroma_map->ps_x_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += H264_MAX_FRAME_WIDTH;
+
+ } /* end of loop over resolution layers */
+
+ /****************** Vert position phase ******************/
+
+ size = H264_MAX_FRAME_HEIGHT * MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_pos_phase_map = pv_buf;
+
+ /* loop over num layers -1 */
+ for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
+ {
+ /* derive the layer map ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ /* initialise the pointers */
+ ps_luma_map->ps_y_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += H264_MAX_FRAME_HEIGHT;
+ ps_chroma_map->ps_y_pos_phase = ps_pos_phase_map;
+ ps_pos_phase_map += H264_MAX_FRAME_HEIGHT;
+
+ } /* end of loop over resolution layers */
+ }
+
+ ps_svcd_ctxt->pv_residual_sample_ctxt = ps_ctxt;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_svc_lyr_dec->pv_residual_sample_ctxt = ps_svcd_ctxt->pv_residual_sample_ctxt;
+ }
+ return IV_SUCCESS;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_mode_mv_resample_ctxt_create */
+/* */
+/* Description :this function is used to create mv_resamp context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_mode_mv_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
+ void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ void *pv_buf;
+ WORD16 *pi2_mem;
+ UWORD8 u1_layer_id;
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+ void *pv_mem_ctxt;
+ WORD32 size, i4_res_id;
+ ref_lyr_scaled_offset_t *ps_ref_pic_offsets;
+ mode_motion_ctxt_t *ps_mode_motion;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ UNUSED(pv_api_op);
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+
+ pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+
+ size = ((sizeof(mode_motion_ctxt_t) + 127) >> 7) << 7;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_mode_motion = pv_buf;
+
+ /* motion pred structure */
+ size = 2 * NUM_MB_PARTS * NUM_SUB_MB_PARTS * sizeof(mv_pred_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_mode_motion->ps_motion_pred_struct = (mv_pred_t *) pv_buf;
+
+ /* projected locations X */
+ size = H264_MAX_FRAME_WIDTH * MAX_NUM_RES_LYRS * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pi2_mem = (WORD16 *) pv_buf;
+
+ /* loop over NUM resolution layers */
+ for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
+ {
+ ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
+
+ /* initialise the pointers */
+ ps_lyr_mem->pi2_ref_loc_x = pi2_mem;
+
+ /* increment the buffer pointer */
+ pi2_mem += H264_MAX_FRAME_WIDTH;
+
+ } /* end of loop over num resolution layers */
+
+ /* projected locations Y */
+ size = H264_MAX_FRAME_HEIGHT * MAX_NUM_RES_LYRS * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ pi2_mem = (WORD16 *) pv_buf;
+ /* loop over NUM resolution layers */
+ for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
+ {
+ ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
+
+ /* initialise the pointers */
+ ps_lyr_mem->pi2_ref_loc_y = pi2_mem;
+ /* increment the buffer pointer */
+ pi2_mem += H264_MAX_FRAME_HEIGHT;
+
+ } /* end of loop over num resolution layers */
+
+ size = sizeof(ref_lyr_scaled_offset_t) * MAX_NUM_RES_LYRS * MAX_NUM_PIC_BUFS;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->pv_ref_lyr_offset = pv_buf;
+
+ /* loop over NUM resolution layers */
+ ps_ref_pic_offsets = (ref_lyr_scaled_offset_t *) ps_svcd_ctxt->pv_ref_lyr_offset;
+
+ for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
+ {
+ ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
+
+ /* store the current resolution layer pic offset start pointer */
+ ps_lyr_mem->ps_ref_pic_lyr_offsets = ps_ref_pic_offsets + (i4_res_id * MAX_NUM_PIC_BUFS);
+
+ } /* end of loop over num resolution layers */
+
+ ps_svcd_ctxt->pv_mode_mv_sample_ctxt = ps_mode_motion;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_svc_lyr_dec->pv_mode_mv_sample_ctxt = ps_svcd_ctxt->pv_mode_mv_sample_ctxt;
+ ps_svc_lyr_dec->pv_ref_lyr_offset = ps_svcd_ctxt->pv_ref_lyr_offset;
+ }
+ return IV_SUCCESS;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_allocate_static_bufs */
+/* */
+/* Description : allocates static buffers */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ isvcd_create_op_t *ps_create_op;
+ void *pv_buf;
+ UWORD8 *pu1_buf;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+ WORD32 size;
+ UWORD8 u1_layer_id, u1_sps_ctr;
+ UWORD8 u1_chroma_format;
+ WORD32 ret;
+
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+ ps_create_op = (isvcd_create_op_t *) pv_api_op;
+
+ ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
+ pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
+ pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+ u1_chroma_format = (UWORD8) (ps_create_ip->s_ivd_create_ip_t.e_output_format);
+
+ if((u1_chroma_format != IV_YUV_420P) && (u1_chroma_format != IV_YUV_420SP_UV) &&
+ (u1_chroma_format != IV_YUV_420SP_VU))
+ {
+ ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
+
+ return IV_FAIL;
+ }
+
+ /* Initialize return handle to NULL */
+ ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, sizeof(iv_obj_t));
+ *dec_hdl = (iv_obj_t *) pv_buf;
+ ps_create_op->s_ivd_create_op_t.pv_handle = *dec_hdl;
+
+ (*dec_hdl)->pv_codec_handle = NULL;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(svc_dec_ctxt_t));
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ (*dec_hdl)->pv_codec_handle = (svc_dec_ctxt_t *) pv_buf;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) pv_buf;
+
+ memset(ps_svcd_ctxt, 0, sizeof(svc_dec_ctxt_t));
+
+ ps_svcd_ctxt->u1_prev_num_res_layers = UINT8_MAX;
+ ps_svcd_ctxt->u1_pre_parse_in_flush = 1;
+ /* set default to maximum values supported */
+ ps_svcd_ctxt->u1_tgt_dep_id = MAX_DEPENDENCY_ID;
+ ps_svcd_ctxt->u1_tgt_quality_id = MAX_QUALITY_ID;
+ ps_svcd_ctxt->u1_tgt_temp_id = MAX_TEMPORAL_ID;
+ ps_svcd_ctxt->u1_tgt_priority_id = MAX_PRIORITY_ID;
+
+ /* two sets of MAX_NUM_SEQ_PARAMS are created one for sps-base layer; one for
+ * subset_sps- enhancement*/
+ size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_sps = pv_buf;
+
+ /* two sets of MAX_NUM_SEQ_PARAMS are created one for sps-base layer; one for
+ * subset_sps- enhancement*/
+ size = ((sizeof(dec_svc_seq_params_t)) * MAX_NUM_SEQ_PARAMS * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_subset_sps = pv_buf;
+
+ for(u1_sps_ctr = 0; u1_sps_ctr < (2 * MAX_NUM_SEQ_PARAMS); u1_sps_ctr++)
+ {
+ ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].ps_seq = &ps_svcd_ctxt->ps_sps[u1_sps_ctr];
+ }
+
+ size = sizeof(sei);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_sei = (sei *) pv_buf;
+
+ size = sizeof(sei);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_sei_parse = (sei *) pv_buf;
+
+ size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_pps = pv_buf;
+
+ size = (sizeof(svc_dec_lyr_struct_t)) * MAX_NUM_RES_LYRS;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svcd_ctxt->ps_svc_dec_lyr = pv_buf;
+ ps_svcd_ctxt->u1_target_layer_id = 0;
+ ps_svcd_ctxt->u1_cur_layer_id = 0;
+ ps_svcd_ctxt->i4_eos_flag = 0;
+
+ ret = isvcd_mode_mv_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
+ if(ret != IV_SUCCESS)
+ {
+ return ret;
+ }
+ ret = isvcd_intra_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
+ if(ret != IV_SUCCESS)
+ {
+ return ret;
+ }
+ ret = isvcd_residual_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
+ if(ret != IV_SUCCESS)
+ {
+ return ret;
+ }
+ ret = isvcd_nal_parse_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
+ if(ret != IV_SUCCESS)
+ {
+ return ret;
+ }
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_svc_lyr_dec->ps_svcd_ctxt = ps_svcd_ctxt;
+ ps_svc_lyr_dec->u1_layer_id = u1_layer_id;
+ ps_svc_lyr_dec->u1_dyadic_flag = 1;
+ ps_svc_lyr_dec->u1_restricted_res_change_flag = 1;
+ ps_svc_lyr_dec->u1_base_res_flag = 1;
+ ps_svc_lyr_dec->u1_ref_layer_id = 0;
+ ps_svc_lyr_dec->ps_dec_svc_ref_layer =
+ &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svc_lyr_dec->u1_ref_layer_id];
+ ps_svc_lyr_dec->u4_pps_id_for_layer = UINT32_MAX;
+
+#ifndef LOGO_EN
+ ps_dec->u4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
+#else
+ ps_dec->u4_share_disp_buf = 0;
+#endif
+
+ ps_dec->u1_chroma_format = (UWORD8) (ps_create_ip->s_ivd_create_ip_t.e_output_format);
+
+ if((ps_dec->u1_chroma_format != IV_YUV_420P) &&
+ (ps_dec->u1_chroma_format != IV_YUV_420SP_UV) &&
+ (ps_dec->u1_chroma_format != IV_YUV_420SP_VU))
+ {
+ ps_dec->u4_share_disp_buf = 0;
+ }
+
+ ps_dec->u1_enable_mb_info = ps_create_ip->u4_enable_frame_info;
+ ps_dec->pf_aligned_alloc = pf_aligned_alloc;
+ ps_dec->pf_aligned_free = pf_aligned_free;
+ ps_dec->pv_mem_ctxt = pv_mem_ctxt;
+
+ ps_dec->ps_sps = ps_svcd_ctxt->ps_sps;
+ ps_svc_lyr_dec->ps_subset_sps = ps_svcd_ctxt->ps_subset_sps;
+ ps_dec->ps_pps = ps_svcd_ctxt->ps_pps;
+ ps_dec->ps_sei = ps_svcd_ctxt->ps_sei;
+ ps_dec->ps_sei_parse = ps_svcd_ctxt->ps_sei_parse;
+
+ size = ithread_get_handle_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_dec_thread_handle = pv_buf;
+
+ size = ithread_get_handle_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_bs_deblk_thread_handle = pv_buf;
+
+#ifdef KEEP_THREADS_ACTIVE
+ {
+ UWORD32 i;
+ /* Request memory to hold mutex (start/done) for both threads */
+ size = ithread_get_mutex_lock_size() << 2;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ // init mutex variable for both the threads
+ // 1. ih264d_decode_picture_thread
+ // 2. ih264d_recon_deblk_thread
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 ret;
+ WORD32 mutex_size = ithread_get_mutex_lock_size();
+
+ ps_dec->apv_proc_start_mutex[i] = (UWORD8 *) pv_buf + (2 * i * mutex_size);
+ ps_dec->apv_proc_done_mutex[i] = (UWORD8 *) pv_buf + ((2 * i + 1) * mutex_size);
+
+ ret = ithread_mutex_init(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_init(ps_dec->apv_proc_done_mutex[i]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+
+ size = ithread_get_cond_struct_size() << 2;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ // init condition variable for both the threads
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 ret;
+ WORD32 cond_size = ithread_get_cond_struct_size();
+ ps_dec->apv_proc_start_condition[i] = (UWORD8 *) pv_buf + (2 * i * cond_size);
+ ps_dec->apv_proc_done_condition[i] = (UWORD8 *) pv_buf + ((2 * i + 1) * cond_size);
+
+ ret = ithread_cond_init(ps_dec->apv_proc_start_condition[i]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_cond_init(ps_dec->apv_proc_done_condition[i]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+ }
+#endif
+ size = sizeof(dpb_manager_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_dpb_mgr = pv_buf;
+
+ size = sizeof(pred_info_t) * 2 * 32;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_pred = pv_buf;
+
+ size = sizeof(disp_mgr_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_disp_buf_mgr = pv_buf;
+
+ size = ih264_buf_mgr_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_pic_buf_mgr = pv_buf;
+
+ size = sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_pic_buf_base = pv_buf;
+
+ size = sizeof(dec_err_status_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_dec_err_status = (dec_err_status_t *) pv_buf;
+
+ size = sizeof(dpb_commands_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_dpb_cmds = (dpb_commands_t *) pv_buf;
+
+ size = sizeof(dec_bit_stream_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_bitstrm = (dec_bit_stream_t *) pv_buf;
+
+ size = sizeof(dec_nal_unit_svc_ext_params_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svc_lyr_dec->ps_nal_svc_ext = (dec_nal_unit_svc_ext_params_t *) pv_buf;
+
+ size = sizeof(dec_slice_params_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_cur_slice = (dec_slice_params_t *) pv_buf;
+
+ size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_scratch_sps_pps = pv_buf;
+
+ size = sizeof(dec_svc_seq_params_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svc_lyr_dec->pv_scratch_subset_sps = pv_buf;
+
+ ps_dec->u4_static_bits_buf_size = 256000;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, ps_dec->u4_static_bits_buf_size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, ps_dec->u4_static_bits_buf_size);
+ ps_dec->pu1_bits_buf_static = pv_buf;
+
+ size = ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_dec->ppv_map_ref_idx_to_poc_base = pv_buf;
+ memset(ps_dec->ppv_map_ref_idx_to_poc_base, 0, size);
+
+ ps_dec->ppv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
+
+ size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS_SVC);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->p_cabac_ctxt_table_t = pv_buf;
+
+ size = sizeof(ctxt_inc_mb_info_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_left_mb_ctxt_info = pv_buf;
+
+ size = MAX_REF_BUF_SIZE * 2;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pu1_ref_buff_base = pv_buf;
+ ps_dec->pu1_ref_buff = ps_dec->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
+
+ size = ((sizeof(WORD16)) * PRED_BUFFER_WIDTH * PRED_BUFFER_HEIGHT * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pi2_pred1 = pv_buf;
+
+ size = sizeof(UWORD8) * (MB_LUM_SIZE);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pu1_temp_mc_buffer = pv_buf;
+
+ size = 8 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ ps_dec->pu1_init_dpb_base = pv_buf;
+ pu1_buf = pv_buf;
+ ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = (struct pic_buffer_t *) pu1_buf;
+
+ pu1_buf += size / 2;
+ ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = (struct pic_buffer_t *) pu1_buf;
+
+ size = (sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pu4_mbaff_wt_mat = pv_buf;
+
+ size = sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1));
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pu4_wts_ofsts_mat = pv_buf;
+
+ size = (sizeof(neighbouradd_t) << 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->ps_left_mvpred_addr = pv_buf;
+
+ size = ih264_buf_mgr_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_dec->pv_mv_buf_mgr = pv_buf;
+
+ size = sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_dec->ps_col_mv_base = pv_buf;
+ memset(ps_dec->ps_col_mv_base, 0, size);
+
+ size = ((MB_SIZE * MB_SIZE * 3) >> 1) + MB_SIZE;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma = pv_buf;
+ ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma =
+ ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma + (MB_SIZE * MB_SIZE);
+ memset(ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma, 0, size);
+
+ isvcd_init_decoder(ps_svc_lyr_dec);
+ }
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_create */
+/* */
+/* Description : creates decoder */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_create_ip_t *ps_create_ip;
+ isvcd_create_op_t *ps_create_op;
+ WORD32 ret;
+
+ ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
+ ps_create_op = (isvcd_create_op_t *) pv_api_op;
+
+ ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
+ dec_hdl = NULL;
+ ret = isvcd_allocate_static_bufs(&dec_hdl, pv_api_ip, pv_api_op);
+
+ /* If allocation of some buffer fails, then free buffers allocated till then */
+ if(IV_FAIL == ret)
+ {
+ if(dec_hdl)
+ {
+ if(dec_hdl->pv_codec_handle)
+ {
+ isvcd_free_static_bufs(dec_hdl);
+ }
+ else
+ {
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
+
+ pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
+ pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
+ pf_aligned_free(pv_mem_ctxt, dec_hdl);
+ }
+ }
+ ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED;
+ ps_create_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_FATALERROR;
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_update_dqid */
+/* */
+/* Description : Updates the DQID list based on reference layer DQID */
+/* */
+/* */
+/* Inputs : 1. Reference layer DQID */
+/* 2. current layer's vcl node structure */
+/* 3. pointer to store the bottom layer VCL node */
+/* Globals : None */
+/* Processing : 1. Searches for a layer with reference layer DQID */
+/* 2. Updates the bottom and top nodes of current layer and */
+/* reference layer vcl nodes respectively */
+/* */
+/* Outputs : Updates top and bottom node field of vcl nodes of current*/
+/* layer and reference layer respectively */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/*****************************************************************************/
+WORD32 isvcd_update_dqid(WORD32 i4_ref_lyr_dqid, vcl_node_t *ps_cur_lyr_node,
+ vcl_node_t **pps_bot_lyr_node)
+{
+ vcl_node_t *ps_vcl_node;
+
+ /* sanity checks */
+ if((NULL == ps_cur_lyr_node) || (NULL == pps_bot_lyr_node))
+ {
+ return NOT_OK;
+ }
+
+ ps_vcl_node = ps_cur_lyr_node->ps_bot_node;
+ while(NULL != ps_vcl_node)
+ {
+ WORD32 i4_dqid;
+
+ i4_dqid = (ps_vcl_node->i4_dependency_id << 4) + ps_vcl_node->i4_quality_id;
+
+ /* if reference layer DQ ID matches */
+ /* or reference layer is a layer below reference dq id layer */
+ if((i4_dqid == i4_ref_lyr_dqid) ||
+ (ps_vcl_node->i4_quality_id < (i4_ref_lyr_dqid & 0x0F)) ||
+ (ps_vcl_node->i4_dependency_id < (i4_ref_lyr_dqid >> 4)))
+ {
+ break;
+ }
+ ps_vcl_node = ps_vcl_node->ps_bot_node;
+ }
+
+ /* Update the top and bottom node of ref layer and current layer nodes */
+
+ if(NULL != ps_vcl_node)
+ {
+ ps_cur_lyr_node->ps_bot_node = ps_vcl_node;
+ ps_vcl_node->ps_top_node = ps_cur_lyr_node;
+ }
+
+ /* Update pointer to bottom VCL node */
+ *pps_bot_lyr_node = ps_vcl_node;
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_detect_res_change */
+/* */
+/* Description : This function detects the resolution change */
+/* */
+/* */
+/* Inputs : 1. Pointer to Current SPS */
+/* 2. Pointer to prevoius SPS */
+/* Globals : None */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : SVCD_TRUE if different resolution else SVCD_FALSE */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijayakumar Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_detect_res_change(dec_seq_params_t *ps_curr_sps, dec_seq_params_t *ps_prev_sps,
+ dec_svc_seq_params_t *ps_curr_subset_sps,
+ dec_svc_seq_params_t *ps_prev_subset_sps)
+{
+ UWORD16 u2_scaled_ref_width_sps;
+ UWORD16 u2_scaled_ref_ht_sps;
+ UNUSED(ps_prev_subset_sps);
+
+ if(NULL == ps_prev_sps)
+ {
+ /* indicates bottom most layer in Access unit */
+ return (SVCD_FALSE);
+ }
+ /* Check for the ESS idc */
+ if(2 == ps_curr_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc)
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* Calculate the scaled reference width and height */
+ u2_scaled_ref_width_sps = (ps_curr_sps->u2_frm_wd_in_mbs << 4);
+ u2_scaled_ref_width_sps -=
+ (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset +
+ ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset);
+
+ u2_scaled_ref_ht_sps = (ps_curr_sps->u2_frm_ht_in_mbs << 4);
+ u2_scaled_ref_ht_sps -=
+ (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset +
+ ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset);
+
+ /* Check for frame width being different */
+ if(u2_scaled_ref_width_sps != (ps_prev_sps->u2_frm_wd_in_mbs << 4))
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* Check for frame height being different */
+ if(u2_scaled_ref_ht_sps != (ps_prev_sps->u2_frm_ht_in_mbs << 4))
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* check for crop offset not MB aligned */
+ if((0 != (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset & 15)) ||
+ (0 != (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset & 15)))
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* check for chroma Phase Y being different */
+ if(ps_curr_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag !=
+ ps_curr_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag)
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* check for chroma Phase Y being different */
+ if(ps_curr_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1 !=
+ ps_curr_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1)
+ {
+ return (SVCD_TRUE);
+ }
+
+ /* If none of the above are true then there is no resolution change */
+ return (SVCD_FALSE);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_ref_pic_list_modify */
+/* */
+/* Description : Parses the reference picture modification related */
+/* syntax elements */
+/* */
+/* Inputs : 1. stream context structure */
+/* 2. slice prms structure */
+/* Globals : None */
+/* Processing : Parses the syntax elements */
+/* */
+/* Outputs : Updated stream buffer context */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_ref_pic_list_modify(dec_bit_stream_t *ps_bitstrm,
+ dec_slice_params_t *ps_slice_prms,
+ dec_seq_params_t *ps_curr_sps)
+{
+ WORD32 i4_mod_flag;
+ UWORD16 ui_nextUev;
+ WORD32 i4_num_sets_ctr = 0;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+
+ if(I_SLICE != ps_slice_prms->u1_slice_type)
+ {
+ /* ref_pic_list_modification_flag_l0 */
+ i4_mod_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(0 != i4_mod_flag)
+ {
+ WORD32 i4_mod_pic_num_idc;
+
+ i4_num_sets_ctr = 0;
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ i4_mod_pic_num_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((i4_mod_pic_num_idc > 3) || (i4_mod_pic_num_idc < 0))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ if(3 != i4_mod_pic_num_idc)
+ {
+ /* i4_mod_pic_num_idc = 0,1 ==> abs_diff_pic_num_minus1 */
+ /* i4_mod_pic_num_idc = 2 ==> long_term_pic_num */
+
+ ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ui_nextUev > (ps_curr_sps->u2_u4_max_pic_num_minus1 + 1))
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ i4_num_sets_ctr++;
+
+ /* if the number of commands recieved exceeds max limit */
+ if((H264_MAX_REF_PICS) == i4_num_sets_ctr) break;
+
+ } while(3 != i4_mod_pic_num_idc);
+ }
+
+ /*********** if (I_SLICE != u1_slice_type) ***************************/
+ }
+
+ if(B_SLICE != ps_slice_prms->u1_slice_type)
+ {
+ return (OK);
+ }
+
+ /* ref_pic_list_modification_flag_l1 */
+ i4_mod_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(0 != i4_mod_flag)
+ {
+ WORD32 i4_mod_pic_num_idc;
+
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ i4_mod_pic_num_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((i4_mod_pic_num_idc > 3) || (i4_mod_pic_num_idc < 0))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ if(3 != i4_mod_pic_num_idc)
+ {
+ /* i4_mod_pic_num_idc = 0,1 ==> abs_diff_pic_num_minus1 */
+ /* i4_mod_pic_num_idc = 2 ==> long_term_pic_num */
+
+ ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ui_nextUev > (ps_curr_sps->u2_u4_max_pic_num_minus1 + 1))
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ i4_num_sets_ctr++;
+
+ /* if the number of commands recieved exceeds max limit */
+ if((H264_MAX_REF_PICS) == i4_num_sets_ctr) break;
+
+ } while(3 != i4_mod_pic_num_idc);
+ }
+
+ return (OK);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_slice_hdr_refdq_id */
+/* */
+/* Description : this function decodes the slice until Inter layer deblk */
+/* parameters are parsed */
+/* */
+/* Inputs : 1. pointer to VCL node of given layer */
+/* 2. pointer toi slice params structure */
+/* 3. pointer to layer params strcuture */
+/* 4. pointer to stream context structure */
+/* 5. pointer to store the reference DQID */
+/* 6. pointer to array of SPS */
+/* 7. pointer to array of PPS */
+/* 8. no inter layer pred flag of current slice */
+/* Globals : none */
+/* Processing : prases syntax elements */
+/* */
+/* Outputs : reference layer DQ ID */
+/* Returns : Error code */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_slice_hdr_refdq_id(vcl_node_t *ps_vcl_node, dec_slice_params_t *ps_slice_prms,
+ dec_bit_stream_t *ps_bitstrm, WORD32 *pi4_ref_dq_id,
+ dec_seq_params_t *ps_sps, dec_pic_params_t *ps_pps,
+ WORD32 i4_no_int_lyr_pred, svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ UWORD8 u1_pps_id;
+ WORD32 i_temp;
+ UWORD32 u4_temp;
+ WORD32 i4_nal_unit_type;
+ WORD32 i4_nal_ref_idc, i4_quality_id;
+ WORD32 i4_use_ref_base, i4_idr_pic_flag;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ dec_svc_seq_params_t *ps_subset_sps = NULL;
+ WORD32 ret = OK;
+
+ i4_nal_unit_type = ps_vcl_node->i4_nal_unit_type;
+ i4_nal_ref_idc = ps_vcl_node->i4_nal_ref_idc;
+ i4_quality_id = ps_vcl_node->i4_quality_id;
+ i4_use_ref_base = ps_vcl_node->i4_use_ref_base;
+ i4_idr_pic_flag = ps_vcl_node->i4_idr_pic_flag;
+
+ /*-----------------------------------------------------------------------*/
+ /*--------------------- first mb in slice -------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ ps_slice_prms->u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ /*-----------------------------------------------------------------------*/
+ /*---------------------------- slice type -------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ ps_slice_prms->u1_slice_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ps_slice_prms->u1_slice_type > 4)
+ {
+ ps_slice_prms->u1_slice_type -= 5;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*----------------------------- PPS id ----------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ u1_pps_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ /* set correspoding sps and pps id also */
+ ps_pps += u1_pps_id;
+ if(FALSE == ps_pps->u1_is_valid)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_sps = ps_pps->ps_sps;
+ ps_subset_sps = &ps_svcd_ctxt->ps_subset_sps[ps_sps->u1_seq_parameter_set_id];
+ if(CODED_SLICE_EXTENSION_NAL == i4_nal_unit_type)
+ {
+ ps_sps += MAX_NUM_SEQ_PARAMS;
+ ps_subset_sps =
+ &ps_svcd_ctxt->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_sps->u1_seq_parameter_set_id];
+ }
+ /*-----------------------------------------------------------------------*/
+ /*--------------------------- frm num -----------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(!ps_sps) return ERROR_INV_SLICE_HDR_T;
+ if(FALSE == ps_sps->u1_is_valid) return ERROR_INV_SLICE_HDR_T;
+
+ ps_slice_prms->u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, ps_sps->u1_bits_in_frm_num);
+
+ /*-----------------------------------------------------------------------*/
+ /*------------------ field pic flag and bottom field flag ---------------*/
+ /*-----------------------------------------------------------------------*/
+ if(SVCD_TRUE != ps_sps->u1_frame_mbs_only_flag)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ /*-----------------------------------------------------------------------*/
+ /*--------------------------- IDR pic id --------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ UWORD32 u4_idr_pic_id = 0;
+ u4_idr_pic_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_idr_pic_id > 65535) return ERROR_INV_SLICE_HDR_T;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*----------------- poc lsb and delts_poc_bottom ------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(0 == ps_sps->u1_pic_order_cnt_type)
+ {
+ i_temp = ih264d_get_bits_h264(ps_bitstrm, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
+
+ if(i_temp < 0 || i_temp >= ps_sps->i4_max_pic_order_cntLsb) return ERROR_INV_SLICE_HDR_T;
+ if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*---------------- delta_poc_count[0] and [1] ---------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if((1 == ps_sps->u1_pic_order_cnt_type) && (!ps_sps->u1_delta_pic_order_always_zero_flag))
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_pps->u1_pic_order_present_flag)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*---------------------- redundant pic cnt ------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(ps_pps->u1_redundant_pic_cnt_present_flag)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_REDUNDANT_PIC_CNT) return ERROR_INV_SLICE_HDR_T;
+ }
+ /*-----------------------------------------------------------------------*/
+ /*-----------------Direct_spatial_mv_pred_flag --------------------------*/
+ /*-----------------num ref active override flag -------------------------*/
+ /*-----------------num_ref_idx_active_l0&1 ------------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(0 == i4_quality_id)
+ {
+ if(B_SLICE == ps_slice_prms->u1_slice_type)
+ {
+ ps_slice_prms->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+ }
+
+ if((P_SLICE == ps_slice_prms->u1_slice_type) || (B_SLICE == ps_slice_prms->u1_slice_type))
+ {
+ WORD8 i1_over_ride_flag;
+ i1_over_ride_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ ps_slice_prms->u1_num_ref_idx_active_override_flag = i1_over_ride_flag;
+
+ if(SVCD_TRUE == i1_over_ride_flag)
+ {
+ UWORD8 u8_ref_idx_l0;
+ u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_ref_idx_l0 > H264_MAX_REF_PICS)
+ {
+ return ERROR_NUM_REF;
+ }
+ if(B_SLICE == ps_slice_prms->u1_slice_type)
+ {
+ UWORD8 u8_ref_idx_l1;
+ u8_ref_idx_l1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_ref_idx_l1 > H264_MAX_REF_PICS)
+ {
+ return ERROR_NUM_REF;
+ }
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*---------------------- ref pic list modification ----------------------*/
+ /*-----------------------------------------------------------------------*/
+ {
+ ret = isvcd_parse_ref_pic_list_modify(ps_bitstrm, ps_slice_prms, ps_sps);
+ if(OK != ret) return ret;
+ }
+
+ if(((1 == ps_pps->u1_wted_pred_flag) && (P_SLICE == ps_slice_prms->u1_slice_type)) ||
+ ((B_SLICE == ps_slice_prms->u1_slice_type) && (1 == ps_pps->u1_wted_bipred_idc)))
+ {
+ if((ps_slice_prms->u1_num_ref_idx_lx_active[0] >= H264_MAX_REF_IDX) ||
+ (ps_slice_prms->u1_num_ref_idx_lx_active[1] >= H264_MAX_REF_IDX))
+ {
+ return ERROR_NUM_REF;
+ }
+ /*-------------------------------------------------------------------*/
+ /*------------------------- Pred weight table -----------------------*/
+ /*-------------------------------------------------------------------*/
+ if(CODED_SLICE_EXTENSION_NAL == i4_nal_unit_type)
+ {
+ WORD32 i4_base_pred_wt_tbl_flag = 1;
+
+ /* base_pred_weight_table_flag */
+ if(0 == i4_no_int_lyr_pred)
+ {
+ i4_base_pred_wt_tbl_flag = ih264d_get_bit_h264(ps_bitstrm);
+ }
+
+ if((1 == i4_no_int_lyr_pred) || (0 == i4_base_pred_wt_tbl_flag))
+ {
+ ret = ih264d_parse_pred_weight_table(ps_slice_prms, ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ {
+ ret = ih264d_parse_pred_weight_table(ps_slice_prms, ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*------------------------- ref pic marking -----------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if(0 != i4_nal_ref_idc)
+ {
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD8 u1_store_ref_base_pic;
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ {
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+
+ ps_dec->u1_nal_unit_type = i4_nal_unit_type;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag = i4_idr_pic_flag;
+ ps_dec->ps_cur_sps = ps_sps;
+ ps_dec->ps_cur_pps = ps_pps;
+ ps_pps->ps_sps = ps_sps;
+
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = i4_nal_unit_type;
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+
+ if(0 == ps_subset_sps->s_sps_svc_ext.u1_slice_header_restriction_flag)
+ {
+ /* store_ref_base_pic_flag */
+ u1_store_ref_base_pic = ih264d_get_bit_h264(ps_bitstrm);
+ if(0 != u1_store_ref_base_pic)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(((1 == i4_use_ref_base) || (1 == u1_store_ref_base_pic)) &&
+ (SVCD_FALSE == i4_idr_pic_flag))
+ {
+ i_temp = isvcd_dec_ref_base_pic_marking(
+ &ps_svc_lyr_dec->s_svc_slice_params.s_ref_base_pic_marking_svc_ext,
+ ps_bitstrm);
+ if(i_temp != OK)
+ {
+ return i_temp;
+ }
+ }
+ /******* End of if (SVC_VCL_NAL == i4_nal_unit_type) *********/
+ }
+ /******** End of if(0 != i4_nal_ref_idc) *************************/
+ }
+ /************* End of if(0 == i4_quality_id) *************************/
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*--------------------------- cabac int idc -----------------------------*/
+ /*-----------------------------------------------------------------------*/
+ if((ps_pps->u1_entropy_coding_mode == CABAC) && (I_SLICE != ps_slice_prms->u1_slice_type))
+ {
+ ps_slice_prms->u1_cabac_init_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ps_slice_prms->u1_cabac_init_idc > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*--------------------------- slice qp delta ----------------------------*/
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD8 i1_slice_qp_delta;
+ i1_slice_qp_delta = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ i1_slice_qp_delta += ps_pps->u1_pic_init_qp;
+ if((i1_slice_qp_delta < MIN_H264_QP) || (i1_slice_qp_delta > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_slice_prms->u1_slice_qp = (UWORD8) i1_slice_qp_delta;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*--------------------------- disable dblk filter idc -------------------*/
+ /*-----------------------------------------------------------------------*/
+ /* Set to default value */
+
+ ps_slice_prms->u1_disable_dblk_filter_idc = 0;
+ if(SVCD_TRUE == ps_pps->u1_deblocking_filter_parameters_present_flag)
+ {
+ ps_slice_prms->u1_disable_dblk_filter_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_slice_prms->u1_disable_dblk_filter_idc > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ /*-------------------------------------------------------------------*/
+ /*--------------------------- slice_alpha_c0_offset_div2 ------------*/
+ /*--------------------------- slice_beta_offset_div2 ----------------*/
+ /*-------------------------------------------------------------------*/
+ if(1 != ps_slice_prms->u1_disable_dblk_filter_idc)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ ps_slice_prms->i1_slice_alpha_c0_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((MIN_DBLK_FIL_OFF > ps_slice_prms->i1_slice_alpha_c0_offset) ||
+ (ps_slice_prms->i1_slice_alpha_c0_offset > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice_prms->i1_slice_beta_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((MIN_DBLK_FIL_OFF > ps_slice_prms->i1_slice_beta_offset) ||
+ (ps_slice_prms->i1_slice_beta_offset > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+ }
+
+ *pi4_ref_dq_id = -1;
+
+ if((0 == i4_no_int_lyr_pred) && (0 == i4_quality_id))
+ {
+ WORD32 i4_inter_lyr_dblk_idc;
+ WORD32 i4_inter_lyr_alpha_c0_offset;
+ WORD32 i4_inter_lyr_beta_offset;
+
+ /*-------------------------------------------------------------------*/
+ /*--------------------------- ref_layer_dq_id -----------------------*/
+ /*-------------------------------------------------------------------*/
+ *pi4_ref_dq_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(*pi4_ref_dq_id > MAX_REF_DEP_ID)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ /* ------------------------------------------- */
+ /* ---- Inter layer de-blocking parameters ---- */
+ /* ------------------------------------------- */
+ i4_inter_lyr_dblk_idc = 0;
+ i4_inter_lyr_alpha_c0_offset = 0;
+ i4_inter_lyr_beta_offset = 0;
+ if(SVCD_TRUE ==
+ ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag)
+ {
+ i4_inter_lyr_dblk_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(i4_inter_lyr_dblk_idc > 6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ if(1 != i4_inter_lyr_dblk_idc)
+ {
+ /* Alpha Offset */
+ i4_inter_lyr_alpha_c0_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(i4_inter_lyr_alpha_c0_offset > 6 || i4_inter_lyr_alpha_c0_offset < -6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ i4_inter_lyr_alpha_c0_offset <<= 1;
+
+ /* Beta Offset */
+ i4_inter_lyr_beta_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(i4_inter_lyr_beta_offset > 6 || i4_inter_lyr_beta_offset < -6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ i4_inter_lyr_beta_offset <<= 1;
+ }
+ }
+ ps_vcl_node->i4_inter_lyr_dblk_idc = i4_inter_lyr_dblk_idc;
+ ps_vcl_node->i4_inter_lyr_beta_offset = i4_inter_lyr_beta_offset;
+ ps_vcl_node->i4_inter_lyr_alpha_c0_offset = i4_inter_lyr_alpha_c0_offset;
+ }
+
+ return (0);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_ref_lyr_dqid */
+/* */
+/* Description : Parses the slice header till ref lyr dqid. */
+/* */
+/* */
+/* Inputs : 1. vcl node */
+/* 2. sequence prms set base buffer pointer */
+/* 3. picture prms set base buffer pointer */
+/* 4. Target layer flag */
+/* 5. DPB command context structure */
+/* 6. Reference layer DQID */
+/* Globals : None */
+/* Processing : 1. Parses the slice header till ref lyr DQID */
+/* 2. If current layer is target layer then it calculates */
+/* poc and gaps in frame number */
+/* */
+/* Outputs : Updates 1) ref dqid variable 2) dpb command context */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/*****************************************************************************/
+WORD32 isvcd_get_ref_lyr_dqid(vcl_node_t *ps_vcl_node, dec_seq_params_t *ps_sps,
+ dec_pic_params_t *ps_pps, WORD32 *pi4_ref_lyr_dqid,
+ WORD32 i4_prev_au_dqid, WORD32 *pi4_err_code,
+ svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ WORD32 i4_status;
+ WORD32 ai4_ref_dq_id[2] = {0};
+ WORD32 i4_num_slc_dec;
+
+ /* local structures */
+ dec_slice_params_t s_slice_prms = {0};
+
+ /* vcl buffer */
+ vcl_buf_hdr_t *ps_vcl_buf;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
+ UNUSED(i4_prev_au_dqid);
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* Sanity checks */
+ if((NULL == ps_vcl_node) || (NULL == ps_sps) || (NULL == ps_pps) || (NULL == pi4_ref_lyr_dqid))
+ {
+ return NOT_OK;
+ }
+
+ i4_num_slc_dec = 0;
+ ps_vcl_buf = ps_vcl_node->ps_first_vcl_nal;
+ i4_status = NOT_OK;
+
+ while(NULL != ps_vcl_buf)
+ {
+ WORD32 i4_error;
+
+ /* Fill the stream context structure */
+ ps_dec->ps_bitstrm->u4_ofst = 0;
+ ps_dec->ps_bitstrm->pu4_buffer =
+ (UWORD32 *) ((UWORD8 *) ps_vcl_buf + ps_vcl_buf->i4_buf_offset +
+ ps_vcl_buf->i4_slice_offset);
+ ps_dec->ps_bitstrm->u4_max_ofst = ps_vcl_buf->u4_max_bits;
+
+ /* call the function which decodes the slice header */
+ i4_error = isvcd_parse_slice_hdr_refdq_id(ps_vcl_node, &s_slice_prms, ps_dec->ps_bitstrm,
+ &ai4_ref_dq_id[i4_num_slc_dec], ps_sps, ps_pps,
+ ps_vcl_buf->i4_no_int_lyr_pred, ps_svcd_ctxt);
+
+ /* store the first error encountered */
+ if(0 == *pi4_err_code)
+ {
+ *pi4_err_code = i4_error;
+ }
+ if(i4_error != 0)
+ {
+ /* check on the Error returned */
+ return NOT_OK;
+ }
+
+ /* set the return status */
+ i4_status = OK;
+ break;
+
+ /* go to the next slice header */
+ ps_vcl_buf = ps_vcl_buf->ps_next;
+ }
+
+ /* set the appropriate reference dqid of the first slice */
+ *pi4_ref_lyr_dqid = ai4_ref_dq_id[0];
+
+ return (i4_status);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_conceal_node_params */
+/* */
+/* Description : This function detects the resolution change */
+/* */
+/* */
+/* Inputs : 1. Pointer to Current SPS */
+/* 2. Pointer to prevoius SPS */
+/* Globals : None */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : SVCD_TRUE if different resolution else SVCD_FALSE */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijayakumar Draft */
+/* */
+/*****************************************************************************/
+void isvcd_conceal_node_params(vcl_nal_t *ps_vcl_nal, prev_au_prms_t *ps_prev_au_prms)
+{
+ vcl_node_t *ps_node;
+ WORD32 i4_conceal_lyrs;
+ WORD32 i4_no_gaps_flag;
+
+ /* get the bottom node */
+ ps_node = ps_vcl_nal->ps_bot_node;
+ i4_conceal_lyrs = SVCD_FALSE;
+ i4_no_gaps_flag = SVCD_FALSE;
+
+ /* loop over all nodes present in the current AU */
+ while(NULL != ps_node)
+ {
+ WORD32 i4_dep_id = 0;
+ WORD32 i4_qua_id = 0;
+ UWORD16 u2_frm_num_dep = 0;
+ WORD32 i4_idr_pic_flag = 0;
+ WORD32 i4_idr_pic_num = 0;
+ WORD32 i4_nal_ref_idc = 0;
+ WORD32 i4_poc_syntax = 0;
+ WORD32 i4_qua_zero_lyr_sts = 0;
+
+ i4_dep_id = ps_node->i4_dependency_id;
+ i4_qua_id = ps_node->i4_quality_id;
+
+ /* reset the quality 0 layer updated status */
+ if(0 == i4_qua_id)
+ {
+ i4_qua_zero_lyr_sts = SVCD_FALSE;
+ }
+
+ /* process the quality id 0 layers */
+ if((0 == i4_qua_id) && (NULL != ps_node->ps_first_vcl_nal))
+ {
+ /* if current and previous are reference pictures */
+ if((0 != ps_prev_au_prms[i4_dep_id].i4_nal_ref_id) && (0 != ps_node->i4_nal_ref_idc))
+ {
+ if(ps_prev_au_prms[i4_dep_id].u2_frm_num == ps_node->u2_frm_num)
+ {
+ /* frame number is concealed */
+ ps_node->u2_frm_num++;
+ i4_conceal_lyrs = SVCD_TRUE;
+ }
+ else if((SVCD_TRUE == i4_conceal_lyrs) || (SVCD_TRUE == i4_no_gaps_flag))
+ {
+ /* if the current au frm_num is less than prev */
+ /* or the difference is greater than 1 */
+ if((ps_prev_au_prms[i4_dep_id].u2_frm_num > ps_node->u2_frm_num) ||
+ ((ps_node->u2_frm_num - ps_prev_au_prms[i4_dep_id].u2_frm_num) > 1))
+ {
+ /* frame number is concealed */
+ ps_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num + 1;
+ }
+ }
+
+ /* set the no gaps flag */
+ if(1 == (ps_node->u2_frm_num - ps_prev_au_prms[i4_dep_id].u2_frm_num))
+ {
+ i4_no_gaps_flag = SVCD_TRUE;
+ }
+ }
+
+ /* store the final frame number */
+ u2_frm_num_dep = ps_node->u2_frm_num;
+ i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
+ i4_idr_pic_num = ps_node->i4_idr_pic_num;
+ i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
+ i4_poc_syntax = ps_node->i4_poc_syntax;
+ i4_qua_zero_lyr_sts = SVCD_TRUE;
+ }
+ else
+ {
+ if(SVCD_TRUE == i4_qua_zero_lyr_sts)
+ {
+ /* for higher quality layers store the same value */
+ /* present in the quality id 0 layer */
+ ps_node->u2_frm_num = u2_frm_num_dep;
+ ps_node->i4_idr_pic_flag = i4_idr_pic_flag;
+ ps_node->i4_idr_pic_num = i4_idr_pic_num;
+ ps_node->i4_nal_ref_idc = i4_nal_ref_idc;
+ ps_node->i4_poc_syntax = i4_poc_syntax;
+ }
+ }
+
+ /* get the upper node pointer */
+ ps_node = ps_node->ps_top_node;
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_refine_dep_list */
+/* */
+/* Description : Refines the DQID list based on reference layer DQID */
+/* */
+/* */
+/* Inputs : 1. vcl nal structure (input and output) */
+/* 2. sps prms base buffer pointer */
+/* 3. pps prms base buffer pointer */
+/* 4. pointer to array in which the dep id should be stored */
+/* 5. pointer to array having prev AU ref dq id */
+/* 6. pointer to init params structure */
+/* 7. pointer to store the Error code */
+/* Globals : None */
+/* Processing : */
+/* */
+/* Outputs : Updates the vcl nal structure */
+/* Also determines frm_num and poc */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/*****************************************************************************/
+WORD32 isvcd_refine_dep_list(void *pv_out_vcl_ctxt, dec_seq_params_t *ps_sps,
+ dec_svc_seq_params_t *ps_subset_sps, dec_pic_params_t *ps_pps,
+ WORD32 *pi4_dep_id_map, prev_au_prms_t *ps_prev_au_prms,
+ prev_au_sps_pps_t *ps_pps_sps_prev, WORD32 *pi4_err_code,
+ svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ vcl_nal_t *ps_vcl_nal;
+ vcl_node_t *ps_vcl_node;
+ WORD32 i4_idr_pic_flag;
+ WORD32 i4_nal_ref_idc;
+ WORD32 i4_idr_pic_num;
+ WORD32 i4_num_res_lyrs_bup;
+ WORD32 i4_restore_prms_flag;
+ vcl_node_t *ps_node_bup;
+ WORD32 ai4_dep_id[MAX_NUM_RES_LYRS] = {0};
+
+ /* used for checking the init prms */
+ dec_seq_params_t *ps_sps_tgt_minus1_lyr = NULL;
+ dec_seq_params_t *ps_sps_tgt_minus2_lyr = NULL;
+ UNUSED(pi4_err_code);
+ /* sanity checks */
+ if((NULL == pv_out_vcl_ctxt) || (NULL == ps_sps) || (NULL == ps_pps))
+ {
+ return NOT_OK;
+ }
+
+ ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_ctxt;
+
+ /* no node is present */
+ if(NULL == ps_vcl_nal->ps_bot_node)
+ {
+ return (NOT_OK);
+ }
+
+ /* set the single layer flag if top node and bottom node are same */
+ if((ps_vcl_nal->ps_bot_node == ps_vcl_nal->ps_top_node) &&
+ (0 == ps_vcl_nal->ps_bot_node->i4_dependency_id))
+ {
+ }
+ else
+ {
+ /* call the function which corrects the frame number of each node */
+ /* based on previous access unit frame number */
+ isvcd_conceal_node_params(ps_vcl_nal, ps_prev_au_prms);
+ }
+ /* get the top most node */
+ ps_vcl_node = ps_vcl_nal->ps_top_node;
+
+ /* get the IDR picture flag for top most layer in current AU */
+ /* if not valid then set the value present in the first valid node */
+ {
+ vcl_node_t *ps_node;
+ WORD32 i4_node_present_flag;
+
+ ps_node = ps_vcl_node;
+ i4_node_present_flag = SVCD_FALSE;
+
+ /* store default values */
+ i4_idr_pic_flag = SVCD_FALSE;
+ i4_nal_ref_idc = 0;
+ i4_idr_pic_num = 0;
+
+ /* loop until valid node */
+ while(NULL != ps_node)
+ {
+ if(NULL != ps_node->ps_first_vcl_nal)
+ {
+ i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
+ i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
+ i4_idr_pic_num = ps_node->i4_idr_pic_num;
+ i4_node_present_flag = SVCD_TRUE;
+ break;
+ }
+ else if(SVCD_TRUE == ps_node->i4_idr_pic_flag)
+ {
+ i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
+ i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
+ i4_idr_pic_num = ps_node->i4_idr_pic_num;
+ i4_node_present_flag = SVCD_TRUE;
+ break;
+ }
+ /* point to next node */
+ ps_node = ps_node->ps_bot_node;
+ }
+
+ /* alteast one node should be present */
+ if(SVCD_FALSE == i4_node_present_flag)
+ {
+ return (NOT_OK);
+ }
+ }
+
+ /* initially the access unit is considered to have a single resolution */
+ ai4_dep_id[0] = 0;
+ ps_vcl_nal->i4_num_res_lyrs = 1;
+ i4_restore_prms_flag = SVCD_FALSE;
+
+ /*-----------------------------------------------------------------------*/
+ /* loop until all the nodes are processed */
+ /*-----------------------------------------------------------------------*/
+ while(NULL != ps_vcl_node)
+ {
+ WORD32 i4_ref_lyr_dqid, i4_status;
+ vcl_node_t *ps_bot_vcl_node;
+ WORD32 i4_res_chnge_flag = SVCD_FALSE;
+ WORD32 i4_dep_id, i4_qua_id;
+ WORD32 i4_prev_sps_pps_valid;
+ WORD32 i4_prev_au_prms_valid;
+
+ /* set the reference layer DQID to -1 */
+ i4_ref_lyr_dqid = -1;
+
+ /* get the current layer dependency and quality id */
+ i4_dep_id = ps_vcl_node->i4_dependency_id;
+ i4_qua_id = ps_vcl_node->i4_quality_id;
+
+ /* get the valid status of prev access unit params */
+ i4_prev_au_prms_valid = ps_prev_au_prms[i4_dep_id].i4_updated_sts;
+ i4_prev_sps_pps_valid = ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].i4_updated_sts;
+
+ /* missing layer handling */
+ if(NULL == ps_vcl_node->ps_first_vcl_nal)
+ {
+ /* store the params appropriately */
+ ps_vcl_node->i4_idr_pic_flag = i4_idr_pic_flag;
+ ps_vcl_node->i4_nal_ref_idc = i4_nal_ref_idc;
+ ps_vcl_node->i4_idr_pic_num = i4_idr_pic_num;
+ ps_vcl_node->i4_num_slices = 0;
+ ps_vcl_node->i4_use_ref_base = 0;
+ ps_vcl_node->i4_temporal_id = 0;
+
+ if((0 != i4_dep_id) || (0 != i4_qua_id))
+ {
+ ps_vcl_node->i4_nal_unit_type = CODED_SLICE_EXTENSION_NAL;
+ ps_vcl_node->u1_acc_no_int_pred = 0;
+ }
+ else if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ ps_vcl_node->i4_nal_unit_type = IDR_SLICE_NAL;
+ ps_vcl_node->u1_acc_no_int_pred = 1;
+ }
+ else
+ {
+ ps_vcl_node->i4_nal_unit_type = SLICE_NAL;
+ ps_vcl_node->u1_acc_no_int_pred = 1;
+ }
+
+ if(SVCD_FALSE == i4_idr_pic_flag)
+ {
+ /* pick the other params form previous access unit */
+ if(SVCD_TRUE == i4_prev_sps_pps_valid)
+ {
+ ps_vcl_node->u1_pps_id =
+ ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_pps_id;
+
+ ps_vcl_node->u1_sps_id =
+ ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id;
+ }
+
+ if(SVCD_TRUE == i4_prev_au_prms_valid)
+ {
+ if(0 == ps_vcl_node->i4_nal_ref_idc)
+ {
+ ps_vcl_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num;
+ }
+ else
+ {
+ ps_vcl_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num + 1;
+ }
+ }
+ }
+ }
+
+ /* SPS id cannot change unless its an IDR pic */
+ if(SVCD_FALSE == ps_vcl_node->i4_idr_pic_flag)
+ {
+ if(SVCD_TRUE == i4_prev_sps_pps_valid)
+ {
+ /* store the SPS id of the current layer */
+ ps_vcl_node->u1_sps_id = ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id;
+ }
+ }
+
+ /* store the PPS id and SPS id of the current layer */
+ ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_pps_id = ps_vcl_node->u1_pps_id;
+ ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id = ps_vcl_node->u1_sps_id;
+ ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].i4_updated_sts = SVCD_TRUE;
+
+ /* handling of no_inter_layer_pred_flag 1 cases */
+ if((1 == ps_vcl_node->u1_acc_no_int_pred) && (NULL != ps_vcl_node->ps_bot_node))
+ {
+ if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ /* take a back up of the parameters till the current node. */
+ /* these parameters will be restored at the end of loop */
+
+ if(SVCD_FALSE == i4_restore_prms_flag)
+ {
+ /* get the number of resolution detected so far */
+ i4_num_res_lyrs_bup = ps_vcl_nal->i4_num_res_lyrs;
+
+ ps_node_bup = ps_vcl_node;
+
+ /* set the restore params flag */
+ i4_restore_prms_flag = SVCD_TRUE;
+ }
+ }
+ else
+ {
+ ps_vcl_node->i4_ref_dq_id = -1;
+ ps_vcl_node->i4_res_change_flag = i4_res_chnge_flag;
+
+ /* store the reference DQID for current dependency */
+ ps_prev_au_prms[i4_dep_id].i4_ref_dq_id = -1;
+ ps_prev_au_prms[i4_dep_id].u2_frm_num = ps_vcl_node->u2_frm_num;
+ ps_prev_au_prms[i4_dep_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
+
+ /* the bottom node is set to NULL */
+ ps_vcl_node->ps_bot_node = NULL;
+ break;
+ }
+ }
+
+ /* derive the reference layer DQID for quality id equal to 0 */
+ if(0 == i4_qua_id)
+ {
+ dec_seq_params_t *ps_curr_sps;
+ dec_svc_seq_params_t *ps_curr_subset_sps;
+
+ /* derive current SPS */
+ ps_curr_sps = ps_sps + ps_vcl_node->u1_sps_id;
+ ps_curr_subset_sps = ps_subset_sps + ps_vcl_node->u1_sps_id;
+
+ {
+ WORD32 i4_max_frm_num;
+
+ /* get the maximum value of frame number */
+ i4_max_frm_num = (1 << (ps_curr_sps->u1_bits_in_frm_num + 1));
+ ps_vcl_node->u2_frm_num = ps_vcl_node->u2_frm_num % i4_max_frm_num;
+ if(SVCD_TRUE == ps_vcl_node->i4_idr_pic_flag)
+ {
+ /* if idr then frm num should be 0 */
+ ps_vcl_node->u2_frm_num = 0;
+ }
+ }
+
+ /* store default params to inter layer deblocking params */
+ ps_vcl_node->i4_inter_lyr_dblk_idc = 0;
+ ps_vcl_node->i4_inter_lyr_beta_offset = 0;
+ ps_vcl_node->i4_inter_lyr_alpha_c0_offset = 0;
+ /* No SEI support for scalability info*/
+ i4_status = NOT_OK;
+
+ /* if no inter layer pred flag is present set the */
+ /* status to fail since the slices will not contain */
+ /* reference layer Dqid */
+ if(1 == ps_vcl_node->u1_acc_no_int_pred)
+ {
+ i4_status = NOT_OK;
+ }
+ else
+ {
+ WORD32 *pi4_ref_dq_id;
+ WORD32 i4_ref_dq_id_temp;
+
+ /* check if the SEI message has given the ref_dq_id */
+ if(NOT_OK == i4_status)
+ {
+ pi4_ref_dq_id = &i4_ref_lyr_dqid;
+ }
+ else
+ {
+ pi4_ref_dq_id = &i4_ref_dq_id_temp;
+ }
+
+ i4_status = isvcd_get_ref_lyr_dqid(ps_vcl_node, ps_sps, ps_pps, pi4_ref_dq_id,
+ ps_prev_au_prms[i4_dep_id].i4_ref_dq_id,
+ &ps_svcd_ctxt->i4_error_code, ps_svcd_ctxt);
+ }
+
+ /* no slice in the layer has been successfully decoded */
+ if(NOT_OK == i4_status)
+ {
+ /* check for IDR picture */
+ if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ /* set the next lower layer as the reference layer */
+ if(NULL != ps_vcl_node->ps_bot_node)
+ {
+ i4_ref_lyr_dqid = ps_vcl_node->ps_bot_node->i4_dependency_id << 4;
+
+ i4_ref_lyr_dqid += ps_vcl_node->ps_bot_node->i4_quality_id;
+ }
+ else
+ {
+ i4_ref_lyr_dqid = -1;
+ }
+ }
+ else
+ {
+ /* take the reference dq id from previous access unit */
+ i4_ref_lyr_dqid = ps_prev_au_prms[i4_dep_id].i4_ref_dq_id;
+ }
+ }
+
+ /* Update the DQID list based on ref DQID. */
+ /* This routine also updates the ref_dq_id */
+ /* in case the actual layer is completely lost */
+ i4_status = isvcd_update_dqid(i4_ref_lyr_dqid, ps_vcl_node, &ps_bot_vcl_node);
+
+ if(!(OK == i4_status))
+ {
+ return i4_status;
+ }
+
+ /* store the reference DQID for current depedency and */
+ /* quality id 0 layer */
+ ps_prev_au_prms[i4_dep_id].i4_ref_dq_id = i4_ref_lyr_dqid;
+ ps_prev_au_prms[i4_dep_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
+ ps_prev_au_prms[i4_dep_id].u2_frm_num = ps_vcl_node->u2_frm_num;
+ ps_prev_au_prms[i4_dep_id].i4_updated_sts = SVCD_TRUE;
+
+ /* ------- Detect Resolution Change ---------------- */
+ {
+ dec_seq_params_t *ps_lower_sps = NULL;
+ dec_svc_seq_params_t *ps_lower_subset_sps = NULL;
+
+ if(NULL != ps_bot_vcl_node)
+ {
+ if((NULL != ps_bot_vcl_node->ps_first_vcl_nal) ||
+ (SVCD_TRUE == i4_idr_pic_flag))
+ {
+ /* get the SPS of layer */
+ ps_lower_sps = ps_sps + ps_bot_vcl_node->u1_sps_id;
+ ps_lower_subset_sps = ps_subset_sps + ps_bot_vcl_node->u1_sps_id;
+ }
+ else
+ {
+ /* if the bottom layer is completely missed */
+ WORD32 i4_bot_dep_id, i4_bot_qua_id;
+ UWORD8 u1_sps_id = 0;
+
+ /* sps id is picked from previous access unit */
+ i4_bot_dep_id = ps_bot_vcl_node->i4_dependency_id;
+ i4_bot_qua_id = ps_bot_vcl_node->i4_quality_id;
+
+ if(SVCD_TRUE ==
+ ps_pps_sps_prev[(i4_bot_dep_id << 4) + i4_bot_qua_id].i4_updated_sts)
+ {
+ u1_sps_id =
+ ps_pps_sps_prev[(i4_bot_dep_id << 4) + i4_bot_qua_id].u1_sps_id;
+ }
+ else
+ {
+ /* should not enter here */
+ return NOT_OK;
+ }
+
+ /* get the SPS of lower layer */
+ ps_lower_sps = ps_sps + u1_sps_id;
+ ps_lower_subset_sps = ps_subset_sps + u1_sps_id;
+ }
+ }
+
+ /* call the function which detects resolution change */
+ i4_res_chnge_flag = isvcd_detect_res_change(
+ ps_curr_sps, ps_lower_sps, ps_curr_subset_sps, ps_lower_subset_sps);
+
+ /* if a resolution exists below current resolution */
+ if(SVCD_TRUE == i4_res_chnge_flag)
+ {
+ /* if current picture id IDR */
+ if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ /* store the depedency id of bottom most layer in current resolution */
+ ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1] = i4_dep_id;
+ }
+
+ /* increment the num resolution layer counter */
+ ps_vcl_nal->i4_num_res_lyrs++;
+
+ /* store the SPS of target -1 and -2 resolution layers */
+ if(2 == ps_vcl_nal->i4_num_res_lyrs)
+ {
+ ps_sps_tgt_minus1_lyr = ps_curr_sps;
+ }
+ else if(3 == ps_vcl_nal->i4_num_res_lyrs)
+ {
+ ps_sps_tgt_minus2_lyr = ps_curr_sps;
+ }
+ else if(ps_vcl_nal->i4_num_res_lyrs > MAX_NUM_RES_LYRS)
+ {
+ return NOT_OK;
+ }
+ }
+ }
+
+ /* -------- end of resolution change detection -------- */
+ }
+ else
+ {
+ i4_ref_lyr_dqid = (i4_dep_id << 4);
+ i4_ref_lyr_dqid += (i4_qua_id - 1);
+
+ /* Update the DQID list based on ref DQID. */
+ /* This routine also updates the ref_dq_id */
+ /* in case the actual layer is completely lost */
+ i4_status = isvcd_update_dqid(i4_ref_lyr_dqid, ps_vcl_node, &ps_bot_vcl_node);
+
+ if(!(OK == i4_status))
+ {
+ return i4_status;
+ }
+ if(SVCD_TRUE == ps_vcl_node->i4_idr_pic_flag)
+ {
+ /* if idr then frm num should be 0 */
+ ps_vcl_node->u2_frm_num = 0;
+ }
+ }
+
+ /* Update resolution change flag inside VCL */
+ /* node structure. This parameter is later used*/
+ /* in detecting the top most layer in the */
+ /* resolution currently being decoded */
+ ps_vcl_node->i4_res_change_flag = i4_res_chnge_flag;
+ ps_vcl_node->i4_ref_dq_id = i4_ref_lyr_dqid;
+
+ /* go to the next node */
+ ps_vcl_node = ps_bot_vcl_node;
+ }
+
+ /* update the Dependency array for each resolution */
+ if(SVCD_TRUE == i4_idr_pic_flag)
+ {
+ WORD32 i4_idx;
+
+ ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1] = 0;
+
+ /* loop over number of resolutions detected */
+ for(i4_idx = 0; i4_idx < ps_vcl_nal->i4_num_res_lyrs; i4_idx++)
+ {
+ pi4_dep_id_map[i4_idx] = ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1 - i4_idx];
+ }
+ }
+
+ if(SVCD_TRUE == i4_restore_prms_flag)
+ {
+ /* restore the number of resolutions */
+ ps_vcl_nal->i4_num_res_lyrs = i4_num_res_lyrs_bup;
+
+ ps_vcl_node = ps_node_bup;
+
+ /* set the bottom node to NULL */
+ ps_vcl_node->ps_bot_node = NULL;
+
+ ps_vcl_node->i4_ref_dq_id = -1;
+ ps_vcl_node->i4_res_change_flag = SVCD_FALSE;
+
+ /* store the reference DQID for current dependency */
+ ps_prev_au_prms[ps_vcl_node->i4_dependency_id].i4_ref_dq_id = -1;
+
+ ps_prev_au_prms[ps_vcl_node->i4_dependency_id].u2_frm_num = ps_vcl_node->u2_frm_num;
+
+ ps_prev_au_prms[ps_vcl_node->i4_dependency_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
+ }
+
+ /* Finally update the bottom most node in the current access unit */
+ ps_vcl_node = ps_vcl_nal->ps_top_node;
+
+ while(NULL != ps_vcl_node->ps_bot_node)
+ {
+ ps_vcl_node = ps_vcl_node->ps_bot_node;
+ }
+
+ ps_vcl_nal->ps_bot_node = ps_vcl_node;
+
+ /* check on validity of Target Layer -1 and -2 dimensions */
+ if((NULL != ps_sps_tgt_minus1_lyr) && (0 == ps_sps_tgt_minus1_lyr->u1_is_valid))
+ {
+ if((H264_MAX_FRAME_WIDTH < (WORD32) (ps_sps_tgt_minus1_lyr->u2_frm_wd_in_mbs << 4)) ||
+ (H264_MAX_FRAME_HEIGHT < (WORD32) (ps_sps_tgt_minus1_lyr->u2_frm_ht_in_mbs << 4)))
+ {
+ return NOT_OK;
+ }
+ }
+
+ if((NULL != ps_sps_tgt_minus2_lyr) && (0 == ps_sps_tgt_minus2_lyr->u1_is_valid))
+ {
+ if((H264_MAX_FRAME_WIDTH < (WORD32) (ps_sps_tgt_minus2_lyr->u2_frm_wd_in_mbs << 4)) ||
+ (H264_MAX_FRAME_HEIGHT < (WORD32) (ps_sps_tgt_minus2_lyr->u2_frm_ht_in_mbs << 4)))
+ {
+ return NOT_OK;
+ }
+ }
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_dec_non_vcl */
+/* */
+/* Description : this function decodes the NON VCL NAL units */
+/* */
+/* */
+/* Inputs : pv_out_non_vcl : pointer to the structure containing */
+/* NON VCL NAL units */
+/* ps_seq_params : pointer to array of SPS structures */
+/* ps_pic_params : pointer to array of PPS structures */
+/* ps_sei_ctxt : pointer to array of SEI structures */
+/* Globals : none */
+/* Processing : it decodes the units unitl all the units are */
+/* decoded */
+/* Outputs : decoded parameters in appropriate structures */
+/* Returns : Success or Faliure */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_dec_non_vcl(void *pv_out_non_vcl, void *pv_seq_params, void *pv_pic_params,
+ svc_dec_ctxt_t *ps_svcd_ctxt)
+{
+ /* local varibles */
+ non_vcl_nal_t *ps_non_vcl;
+ WORD32 i4_unit_indx;
+ non_vcl_buf_hdr_t *ps_non_vcl_buf;
+ WORD32 i_status = OK;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ dec_bit_stream_t *ps_bitstrm;
+
+ if((NULL == pv_out_non_vcl) || (NULL == pv_seq_params) || (NULL == pv_pic_params))
+ {
+ return NOT_OK;
+ }
+ UNUSED(pv_seq_params);
+ UNUSED(pv_pic_params);
+
+ /* currently SEI decoding is not supported */
+ /* derive the local variables */
+ ps_non_vcl = (non_vcl_nal_t *) pv_out_non_vcl;
+ ps_non_vcl_buf = ps_non_vcl->ps_first_non_vcl_nal;
+ if(NULL == ps_non_vcl_buf) return (NOT_OK);
+
+ /* loop until all NON VCL NAL are decoded */
+ for(i4_unit_indx = 0; i4_unit_indx < ps_non_vcl->i4_num_non_vcl_nals; i4_unit_indx++)
+ {
+ UWORD32 u4_nal_unit_type;
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(NULL == ps_non_vcl_buf) return (NOT_OK);
+ /* get the current NAL unit type */
+ u4_nal_unit_type = (UWORD32) ps_non_vcl_buf->i4_nal_unit_type;
+ if(u4_nal_unit_type > MAX_SVC_NAL_UNIT_TYPE) return (NOT_OK);
+ ps_dec->u1_nal_unit_type = u4_nal_unit_type;
+
+ ps_dec->ps_bitstrm->pu4_buffer =
+ (UWORD32 *) ((UWORD8 *) ps_non_vcl_buf + ps_non_vcl_buf->i4_buf_offset);
+ ps_dec->ps_bitstrm->u4_ofst = 0;
+ ps_dec->ps_bitstrm->u4_max_ofst = isvcd_nal_rbsp_to_sodb(
+ (UWORD8 *) ps_dec->ps_bitstrm->pu4_buffer, ps_non_vcl_buf->i4_buf_size, 0);
+ if(ps_dec->ps_bitstrm->u4_max_ofst <= 0) return (NOT_OK);
+
+ ps_bitstrm = ps_dec->ps_bitstrm;
+
+ /* call the processing module based on nal unit type */
+ switch(u4_nal_unit_type)
+ {
+ case SEQ_PARAM_NAL:
+
+ i_status = isvcd_parse_sps(ps_svc_lyr_dec, ps_bitstrm);
+
+ if(!i_status)
+ {
+ ps_dec->i4_header_decoded |= 0x1;
+ ps_svcd_ctxt->u4_num_sps_ctr++;
+ }
+
+ if(i_status) return i_status;
+
+ break;
+ case SUBSET_SPS_NAL:
+
+ i_status = isvcd_parse_subset_sps(ps_svc_lyr_dec, ps_bitstrm);
+
+ if(!i_status)
+ {
+ ps_svcd_ctxt->u4_num_sps_ctr++;
+ ps_dec->i4_header_decoded |= 0x1;
+ }
+ if(i_status) return i_status;
+
+ break;
+
+ case PIC_PARAM_NAL:
+
+ i_status = isvcd_parse_pps(ps_svc_lyr_dec, ps_bitstrm);
+ if(i_status == ERROR_INV_SPS_PPS_T) return i_status;
+ if(!i_status)
+ {
+ ps_dec->i4_header_decoded |= 0x2;
+ ps_svcd_ctxt->u4_num_pps_ctr++;
+ }
+ break;
+ case SEI_NAL:
+ {
+ i_status = ih264d_parse_sei_message(ps_dec, ps_bitstrm);
+ ih264d_parse_sei(ps_dec, ps_bitstrm);
+ }
+ break;
+ default:
+ /* no other NON VCL UNIT is supported */
+ break;
+ }
+
+ /* get the next non vcl bufffer */
+ ps_non_vcl_buf = ps_non_vcl_buf->ps_next;
+
+ } /* end of loop over all NAL units */
+
+ return (OK);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_seq_hdr_dec */
+/* */
+/* Description : This function decodes sequence header, which includes */
+/* non VCL NAL before the first VCL unit */
+/* Inputs : Decoder context, inbufs, place holder for number of bytes*/
+/* consumed and number of packets consumed */
+/* Globals : None */
+/* Processing : 1. Parse non VCL units before first VCL unit */
+/* 2. Decode parsed non VCL units */
+/* Outputs : Decoded header */
+/* Returns : OK or NOT_OK */
+/* */
+/* Issues : no known issues */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_seq_hdr_dec(svc_dec_ctxt_t *ps_svcd_ctxt, ivd_video_decode_ip_t *ps_in_bufs,
+ UWORD32 *pu4_bytes_consumed)
+{
+ WORD32 i4_status;
+
+ /* Decode all non VCL NAL till first VCL NAL is encountered */
+ ps_svcd_ctxt->s_non_vcl_nal.i4_num_non_vcl_nals = 0;
+ i4_status = isvcd_nal_parse_non_vcl_nal(
+ ps_svcd_ctxt->pv_nal_parse_ctxt, ps_in_bufs->pv_stream_buffer, &ps_svcd_ctxt->s_non_vcl_nal,
+ pu4_bytes_consumed, &ps_in_bufs->u4_num_Bytes);
+
+ /* Note: The bitstream extraction module expects updated */
+ /* pointer whenever a new call to this module has been */
+ /* made. Hence the buffer pointer has to be incremented */
+ /* by bytes consumed */
+ ps_in_bufs->u4_num_Bytes -= *pu4_bytes_consumed;
+
+ /* ------------------------------------------------------ */
+ /* Decoding of non VCL data. As current implementation it */
+ /* decodes the followings: */
+ /* 1. Sequence parameter set */
+ /* 2. Picture parameter set */
+ /* 3. SEI message */
+ /* ------------------------------------------------------ */
+ isvcd_dec_non_vcl(&ps_svcd_ctxt->s_non_vcl_nal, ps_svcd_ctxt->ps_sps, ps_svcd_ctxt->ps_pps,
+ ps_svcd_ctxt);
+
+ return (i4_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pre_parse_refine_au */
+/* */
+/* Description : This function process a decode call */
+/* Inputs : ps_dec_ctxt : decoder context structure */
+/* ps_in_bufs : input buffer descriptor */
+/* pu4_bytes_consumed : pointer to store the bytes consumed */
+/* pi4_packets_consumed : pointer to store the packets */
+/* consumed */
+/* Globals : None */
+/* Processing : It calls the NAL parse module to parse the input stream */
+/* if a picture boundary is detected it calls the */
+/* Dependency list refiniment and Picture Decode routines */
+/* Outputs : Decoded picture */
+/* Returns : OK or NOT_OK */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_pre_parse_refine_au(svc_dec_ctxt_t *ps_svcd_ctxt, ivd_video_decode_ip_t *ps_in_bufs,
+ UWORD32 *pu4_bytes_consumed)
+{
+ WORD32 i4_status, i4_non_vcl_status;
+ UWORD32 u4_bytes_consumed = 0;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ /* Sequence header decode: */
+ /* If sequence header is not decoded then decode the seq */
+ /* uence header */
+
+ if(SVCD_FALSE == ps_dec->i4_header_decoded)
+ {
+ i4_status = isvcd_seq_hdr_dec(ps_svcd_ctxt, ps_in_bufs, &u4_bytes_consumed);
+
+ if((VCL_NAL_FOUND_TRUE == i4_status) && (ps_svcd_ctxt->u4_num_sps_ctr != 0) &&
+ (ps_svcd_ctxt->u4_num_pps_ctr != 0))
+ {
+ /* set the header decoded flag */
+ ps_dec->i4_header_decoded = 3;
+ }
+ }
+ *pu4_bytes_consumed = u4_bytes_consumed;
+ if(1 == ps_dec->i4_decode_header)
+ {
+ return OK;
+ }
+ /* Bit-stream Parsing. It performs following tasks: */
+ /* 1. NAL hader decoder */
+ /* 2. Emulation prevention and byte swap */
+ /* (During this process data to moved to output*/
+ /* buffer) */
+ /* 3. Dependency list creation based on NAL header*/
+ /* 4. Detection of picture boundary */
+ /* NOTE1: */
+ /* Output buffers for VCL and non VCL data are */
+ /* different. VCL data can be retrieved through */
+ /* dependency list. Whereas non VCL data is stored in*/
+ /* one single buffer, which is accessed through NON */
+ /* VCL structure */
+ /* NOTE2:Partial input case for nal parsing requires a */
+ /* flush API to be called when end of bitstream */
+ /* occurs */
+
+ if(SVCD_FALSE == ps_svcd_ctxt->i4_eos_flag)
+ {
+ if(ps_dec->i4_header_decoded == 3)
+ {
+ i4_status = isvcd_nal_parse_vcl_nal_partial(
+ ps_svcd_ctxt->pv_nal_parse_ctxt, ps_in_bufs->pv_stream_buffer,
+ &ps_svcd_ctxt->s_non_vcl_nal, &ps_svcd_ctxt->s_vcl_nal, &u4_bytes_consumed,
+ &ps_in_bufs->u4_num_Bytes);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ else
+ {
+ void *pv_nal_parse_ctxt;
+ pv_nal_parse_ctxt = ps_svcd_ctxt->pv_nal_parse_ctxt;
+
+ i4_status = isvcd_nal_parse_partial_signal_eos(pv_nal_parse_ctxt, &ps_svcd_ctxt->s_vcl_nal,
+ &ps_svcd_ctxt->s_non_vcl_nal);
+
+ u4_bytes_consumed = 0;
+ }
+
+ *pu4_bytes_consumed += u4_bytes_consumed;
+
+ /* Picture Boundary detected: Go ahead and do the decoding */
+ /* Picture boundary not detected: Otherwsie retrun from this*/
+ /* function and update the bytes consumed variable. This */
+ /* should be repeated till we get a picture boundary */
+
+ if(PIC_BOUNDARY_FALSE == i4_status)
+ {
+ return (NOT_OK);
+ }
+
+ else if(FLUSH_DECODED_PICTURE == i4_status)
+ {
+ /* No more data is expected to come. Pictures decoded */
+ /* so far needs to be sent for display */
+ return (FLUSH);
+ }
+
+ if(PIC_BOUNDARY_TRUE != i4_status)
+ {
+ return (NOT_OK);
+ }
+
+ /* check if the application has set any of the skip modes */
+ /* add the support for P and B skip modes */
+ /* if(ps_dec_ctxt->s_dyn_prms.u1_frame_skip_mode) */
+
+ /* Parse slice header to decode reference layer dQId and refine */
+ /* the dependency list */
+ /* NOTE: Yes, this processing could be moved into NAL parsing */
+ /* routine to avoid unneccessary emulation prevention and */
+ /* byte swapping over discardable data. This Optimization */
+ /* has been deferred for some time. In future if we found */
+ /* that there are many such streams which doesn't set */
+ /* 'discard_flag' correctly in NAL header, we will take a */
+ /* hit to optimize it. */
+
+ /* At present this routine also performs the following */
+ /* 1. Refine DQID list based on reference layer DQID */
+ /* 2. Calculates the POC for the target layer */
+
+ {
+ i4_status = isvcd_refine_dep_list(
+ &ps_svcd_ctxt->s_vcl_nal, ps_svcd_ctxt->ps_sps, ps_svcd_ctxt->ps_subset_sps,
+ ps_svcd_ctxt->ps_pps, &ps_svcd_ctxt->ai4_dq_id_map[0], &ps_svcd_ctxt->as_au_prms_dep[0],
+ &ps_svcd_ctxt->as_pps_sps_prev_au[0], &ps_svcd_ctxt->i4_error_code, ps_svcd_ctxt);
+ }
+
+ if(0 != ps_svcd_ctxt->s_non_vcl_nal.i4_num_non_vcl_nals)
+ {
+ /* Decoding of non VCL data. In current implementation it */
+ /* decodes the followings: */
+ /* 1. Sequence parameter set */
+ /* 2. Picture parameter set */
+ /* 3. SEI message */
+ i4_non_vcl_status = isvcd_dec_non_vcl(&ps_svcd_ctxt->s_non_vcl_nal, ps_svcd_ctxt->ps_sps,
+ ps_svcd_ctxt->ps_pps, ps_svcd_ctxt);
+
+ if(OK != i4_non_vcl_status) return i4_non_vcl_status;
+ }
+ if(OK != i4_status) return (i4_status);
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_video_decode */
+/* */
+/* Description : handle video decode API command */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ dec_struct_t *ps_dec;
+ dec_struct_t *ps_dec_zero_lyr;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_zero_dec;
+
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ WORD32 i4_err_status = 0;
+
+ UWORD32 bytes_consumed = 0;
+ WORD32 ret = 0, api_ret_value = IV_SUCCESS;
+ isvcd_video_decode_ip_t *ps_h264d_dec_ip;
+ isvcd_video_decode_op_t *ps_h264d_dec_op;
+ ivd_video_decode_ip_t *ps_dec_ip;
+ ivd_video_decode_op_t *ps_dec_op;
+ UWORD8 u1_res_id;
+
+ ithread_set_name((void *) "Parse_thread");
+
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) (dec_hdl->pv_codec_handle);
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_h264d_dec_ip = (isvcd_video_decode_ip_t *) pv_api_ip;
+ ps_h264d_dec_op = (isvcd_video_decode_op_t *) pv_api_op;
+ ps_dec_ip = &ps_h264d_dec_ip->s_ivd_video_decode_ip_t;
+ ps_dec_op = &ps_h264d_dec_op->s_ivd_video_decode_op_t;
+
+ {
+ UWORD32 u4_size;
+ u4_size = ps_dec_op->u4_size;
+ memset(ps_h264d_dec_op, 0, sizeof(isvcd_video_decode_op_t));
+ ps_dec_op->u4_size = u4_size;
+ }
+
+ ps_dec->pv_dec_out = ps_dec_op;
+ if(ps_dec->init_done != 1)
+ {
+ return IV_FAIL;
+ }
+
+ /*Data memory barries instruction,so that bitstream write by the application
+ * is complete*/
+ DATA_SYNC();
+
+ if(0 == ps_dec->u1_flushfrm)
+ {
+ if(ps_dec_ip->pv_stream_buffer == NULL)
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
+ return IV_FAIL;
+ }
+ if(ps_dec_ip->u4_num_Bytes <= 16)
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
+ return IV_FAIL;
+ }
+ }
+#ifdef KEEP_THREADS_ACTIVE
+ {
+ UWORD32 i;
+ ps_dec->i4_break_threads = 0;
+ for(i = 0; i < 2; i++)
+ {
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[i]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[i] = PROC_INIT;
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[i]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+ }
+#else
+ ps_dec->u4_dec_thread_created = 0;
+ ps_dec->u4_bs_deblk_thread_created = 0;
+#endif
+ ps_dec_op->u4_num_bytes_consumed = 0;
+ ps_dec_op->i4_reorder_depth = -1;
+ ps_dec_op->i4_display_index = DEFAULT_POC;
+
+ ps_dec->ps_out_buffer = NULL;
+ if(ps_dec_ip->u4_size >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
+ ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
+
+ if(0 == ps_dec->u4_share_disp_buf && ps_dec->i4_decode_header == 0)
+ {
+ UWORD32 i;
+ if((ps_dec->ps_out_buffer->u4_num_bufs == 0) ||
+ (ps_dec->ps_out_buffer->u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++)
+ {
+ if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL)
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0)
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+ return IV_FAIL;
+ }
+ }
+ }
+
+ if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT)
+ {
+ ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER;
+ return IV_FAIL;
+ }
+
+ ps_dec_op->u4_error_code = 0;
+ ps_dec_op->e_pic_type = IV_NA_FRAME;
+ ps_dec_op->u4_output_present = 0;
+ ps_dec_op->u4_frame_decoded_flag = 0;
+
+ /* In case the decoder is not in flush mode(in shared mode),
+ then decoder has to pick up a buffer to write current frame.
+ Check if a frame is available in such cases */
+ if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1 && ps_dec->u1_flushfrm == 0)
+ {
+ UWORD32 i;
+ WORD32 disp_avail = 0, free_id;
+
+ /* Check if at least one buffer is available with the codec */
+ /* If not then return to application with error */
+ for(i = 0; i < ps_dec->u1_pic_bufs; i++)
+ {
+ if(0 == ps_dec->u4_disp_buf_mapping[i] || 1 == ps_dec->u4_disp_buf_to_be_freed[i])
+ {
+ disp_avail = 1;
+ break;
+ }
+ }
+
+ if(0 == disp_avail)
+ {
+ /* If something is queued for display wait for that buffer to be returned
+ */
+
+ ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
+ ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
+ return (IV_FAIL);
+ }
+
+ while(1)
+ {
+ pic_buffer_t *ps_pic_buf;
+ ps_pic_buf = (pic_buffer_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_dec->pv_pic_buf_mgr, &free_id);
+
+ if(ps_pic_buf == NULL)
+ {
+ UWORD32 display_queued = 0;
+
+ /* check if any buffer was given for display which is not returned yet */
+ for(i = 0; i < (MAX_DISP_BUFS_NEW); i++)
+ {
+ if(0 != ps_dec->u4_disp_buf_mapping[i])
+ {
+ display_queued = 1;
+ break;
+ }
+ }
+ /* If some buffer is queued for display, then codec has to singal an
+ error and wait for that buffer to be returned. If nothing is queued for
+ display then codec has ownership of all display buffers and it can
+ reuse any of the existing buffers and continue decoding */
+
+ if(1 == display_queued)
+ {
+ /* If something is queued for display wait for that buffer to be
+ * returned */
+ ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
+ ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
+ return (IV_FAIL);
+ }
+ }
+ else
+ {
+ /* If the buffer is with display, then mark it as in use and then look
+ * for a buffer again */
+ if(1 == ps_dec->u4_disp_buf_mapping[free_id])
+ {
+ ih264_buf_mgr_set_status((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, free_id,
+ BUF_MGR_IO);
+ }
+ else
+ {
+ /**
+ * Found a free buffer for present call. Release it now.
+ * Will be again obtained later.
+ */
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, free_id,
+ BUF_MGR_IO);
+ break;
+ }
+ }
+ }
+ }
+
+ if(ps_dec->u1_enable_mb_info && (ps_dec->i4_header_decoded & DECODED_SPS_MASK))
+ {
+ UWORD32 blk_qp_map_size = ps_h264d_dec_ip->u4_8x8_blk_qp_map_size;
+ UWORD32 blk_type_map_size = ps_h264d_dec_ip->u4_8x8_blk_type_map_size;
+ UWORD32 blk_8x8_map_size = ps_dec->u4_total_mbs << 2;
+ if((ps_h264d_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
+ (ps_h264d_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
+ {
+ ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
+ ps_dec_op->u4_error_code |= IH264D_INSUFFICIENT_METADATA_BUFFER;
+ return IV_FAIL;
+ }
+ }
+
+ if(ps_dec->u1_flushfrm && (1 == ps_svcd_ctxt->u1_pre_parse_in_flush))
+ {
+ if(ps_dec->u1_init_dec_flag == 0)
+ {
+ ps_dec->u1_flushfrm = 0;
+ return (IV_FAIL);
+ }
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->s_vcl_nal.i4_num_res_lyrs - 1];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ ps_dec->u4_fmt_conv_cur_row = 0;
+ ps_dec->u4_output_present = 0;
+ ps_dec->s_disp_op.u4_error_code = 1;
+
+ ps_dec->ps_out_buffer = NULL;
+ if(ps_dec_ip->u4_size >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
+ {
+ ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
+ }
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
+ if(0 == ps_dec->s_disp_op.u4_error_code)
+ {
+ /* check output buffer size given by the application */
+ if(check_app_out_buf_size(ps_dec) != IV_SUCCESS)
+ {
+ ps_dec_op->u4_error_code = IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+ return (IV_FAIL);
+ }
+
+ ps_dec->u4_fmt_conv_cur_row = 0;
+ ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ ps_dec->u4_output_present = 1;
+ if(ps_dec->u1_enable_mb_info)
+ {
+ UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
+ if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
+ {
+ ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
+ ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
+ ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
+ ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
+ ps_dec->u4_total_mbs << 2);
+ }
+ if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
+ {
+ ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map;
+ ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
+ ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
+ ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
+ ps_dec->u4_total_mbs << 2);
+ }
+ }
+ }
+ ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
+
+ ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
+
+ ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
+ ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
+ ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
+ ps_dec_op->i4_display_index = ps_dec->i4_display_index;
+ ps_dec_op->u4_new_seq = 0;
+
+ ps_dec_op->u4_output_present = ps_dec->u4_output_present;
+ ps_dec_op->u4_progressive_frame_flag = ps_dec->s_disp_op.u4_progressive_frame_flag;
+ ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
+ ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
+ ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
+ ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
+ ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
+
+ /*In the case of flush ,since no frame is decoded set pic type as invalid*/
+ ps_dec_op->u4_is_ref_flag = UINT32_MAX;
+ ps_dec_op->e_pic_type = IV_NA_FRAME;
+ ps_dec_op->u4_frame_decoded_flag = 0;
+
+ if(0 == ps_dec->s_disp_op.u4_error_code)
+ {
+ return (IV_SUCCESS);
+ }
+ else
+ return (IV_FAIL);
+ }
+
+ if(ps_dec->u1_res_changed == 1)
+ {
+ /*if resolution has changed and all buffers have been flushed, reset
+ * decoder*/
+ if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
+ if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
+
+ isvcd_init_decoder(ps_svc_lyr_dec);
+ }
+
+ DEBUG_THREADS_PRINTF(" Starting process call\n");
+
+ {
+ vcl_node_t *ps_cur_node;
+ UWORD8 u1_num_res_lyrs;
+ vcl_buf_hdr_t *ps_vcl_buf;
+ UWORD8 flush_decode = 1;
+ ps_svcd_ctxt->u1_pre_parse_in_flush = 0;
+
+ ret = isvcd_pre_parse_refine_au(ps_svcd_ctxt, ps_dec_ip, &ps_dec_op->u4_num_bytes_consumed);
+ ps_svcd_ctxt->u1_pre_parse_in_flush = (ret == FLUSH);
+
+ if(ret != OK)
+ {
+ UWORD32 error = ih264d_map_error((UWORD32) ret);
+ if(ret != NOT_OK)
+ {
+ ps_dec_op->u4_error_code = error | ret;
+ }
+ if((ps_dec_op->u4_error_code >> IVD_FATALERROR) & 1)
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ }
+ api_ret_value = IV_FAIL;
+ if((ret == IVD_RES_CHANGED) || (ret == IVD_MEM_ALLOC_FAILED) ||
+ (ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T) ||
+ (ret == ERROR_INV_SPS_PPS_T) || (ret == ERROR_FEATURE_UNAVAIL) ||
+ (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED) ||
+ (ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE))
+ {
+ ps_dec->u4_slice_start_code_found = 0;
+ }
+ if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
+ {
+ api_ret_value = IV_FAIL;
+ }
+
+ if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
+ {
+ api_ret_value = IV_FAIL;
+ }
+ }
+
+ if(NOT_OK == ret)
+ {
+ if(ps_dec->u4_pic_buf_got == 0)
+ {
+ ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND;
+ ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
+
+ isvcd_fill_output_struct_from_context(ps_svc_lyr_dec, ps_dec_op);
+
+ ps_dec_op->u4_error_code = ps_dec->i4_error_code;
+ ps_dec_op->u4_frame_decoded_flag = 0;
+ return (IV_FAIL);
+ }
+ return (IV_SUCCESS);
+ }
+
+ u1_num_res_lyrs = ps_svcd_ctxt->s_vcl_nal.i4_num_res_lyrs;
+
+ /* error concelment: exit till next IDR if any of Non Target layers are
+ * corrupted */
+ {
+ ps_cur_node = ps_svcd_ctxt->s_vcl_nal.ps_bot_node;
+
+ if(NULL != ps_cur_node)
+ {
+ if(!ps_cur_node->i4_idr_pic_flag)
+ {
+ if(u1_num_res_lyrs != ps_svcd_ctxt->u1_prev_num_res_layers)
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
+ return IV_FAIL;
+ }
+ }
+ else
+ {
+ if(u1_num_res_lyrs != ps_svcd_ctxt->u1_prev_num_res_layers)
+ {
+ ps_svcd_ctxt->u1_prev_num_res_layers = u1_num_res_lyrs;
+ }
+ }
+ }
+ }
+ if(ps_svcd_ctxt->u1_prev_num_res_layers != u1_num_res_lyrs && (u1_num_res_lyrs != 0))
+ {
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_num_res_lyrs - 1;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ if(ps_dec->u1_init_dec_flag == 1)
+ {
+ ih264d_release_pics_in_dpb((void *) ps_dec, ps_dec->u1_pic_bufs);
+ ih264d_release_display_bufs(ps_dec);
+ ih264_disp_mgr_init((disp_mgr_t *) ps_dec->pv_disp_buf_mgr);
+
+ ih264_buf_mgr_reset(ps_dec->pv_pic_buf_mgr);
+ ih264_buf_mgr_reset(ps_dec->pv_mv_buf_mgr);
+ ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
+ }
+
+ // ps_svcd_ctxt->u1_prev_num_res_layers = u1_num_res_lyrs;
+ }
+ ps_svcd_ctxt->u1_parse_nal_unit_error = 0;
+
+ if((1 == ps_svcd_ctxt->u1_exit_till_next_IDR) &&
+ (ps_svcd_ctxt->s_vcl_nal.ps_bot_node != NULL))
+ {
+ if(1 == ps_svcd_ctxt->s_vcl_nal.ps_bot_node->i4_idr_pic_flag)
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 0;
+
+ for(u1_res_id = 0; u1_res_id < u1_num_res_lyrs; u1_res_id++)
+ {
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ ih264_buf_mgr_reset(ps_dec->pv_pic_buf_mgr);
+ ih264_buf_mgr_reset(ps_dec->pv_mv_buf_mgr);
+ }
+ }
+ else
+ {
+ ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
+ return IV_FAIL;
+ }
+ }
+
+ if((0 == ps_dec->i4_decode_header) && (OK == ret))
+ {
+ flush_decode = 0;
+ ps_cur_node = ps_svcd_ctxt->s_vcl_nal.ps_bot_node;
+ ps_svc_lyr_zero_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
+ ps_dec_zero_lyr = &ps_svc_lyr_zero_dec->s_dec;
+ /* master loop */
+
+ for(u1_res_id = 0; u1_res_id < u1_num_res_lyrs; u1_res_id++)
+ {
+ UWORD8 u1_layer_nal_data_present = 0;
+ ps_svcd_ctxt->u1_cur_layer_id = u1_res_id;
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_dec->i4_decode_header = ps_dec_zero_lyr->i4_decode_header;
+ ps_dec->i4_header_decoded = ps_dec_zero_lyr->i4_header_decoded;
+ ps_dec->u1_pic_decode_done = 0;
+ ps_dec->u4_fmt_conv_cur_row = 0;
+
+ ps_dec->u4_output_present = 0;
+ ps_dec->s_disp_op.u4_error_code = 1;
+ ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
+ ps_dec->u4_ts = ps_dec_ip->u4_ts;
+ ps_dec->i4_frametype = IV_NA_FRAME;
+ ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
+
+ ps_dec->u4_slice_start_code_found = 0;
+ ps_dec->u2_cur_mb_addr = 0;
+ ps_dec->u2_total_mbs_coded = 0;
+ ps_dec->u2_cur_slice_num = 0;
+ ps_dec->cur_dec_mb_num = 0;
+ ps_dec->cur_recon_mb_num = 0;
+ ps_dec->u4_first_slice_in_pic = 1;
+ ps_dec->u1_slice_header_done = 0;
+ ps_dec->u1_dangling_field = 0;
+
+ ps_dec->u4_dec_thread_created = 0;
+ ps_dec->u4_bs_deblk_thread_created = 0;
+ ps_dec->u4_cur_bs_mb_num = 0;
+ ps_dec->u4_cur_deblk_mb_num = 0;
+ ps_dec->u4_start_recon_deblk = 0;
+ ps_dec->u4_sps_cnt_in_process = 0;
+ ps_dec->u4_pic_buf_got = 0;
+ ps_dec->pv_dec_out = ps_dec_op;
+
+ if(ps_dec_ip->u4_size >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
+ ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
+
+ ps_dec->u1_nal_unit_type = ps_cur_node->i4_nal_unit_type;
+ ps_dec->u1_separate_parse = 0;
+ if(u1_res_id == (u1_num_res_lyrs - 1))
+ {
+ ps_svc_lyr_dec->u1_layer_identifier = TARGET_LAYER;
+ if(ps_dec->u4_num_cores >= 2)
+ {
+ ps_dec->u4_num_cores = 2;
+ ps_dec->u1_separate_parse = 1;
+ }
+ }
+ else if(u1_res_id == 0)
+ {
+ ps_svc_lyr_dec->u1_layer_identifier = BASE_LAYER;
+ ps_dec->u1_separate_parse = 0;
+ ps_dec->u4_num_cores = 1;
+ }
+ else if(u1_res_id != 0)
+ {
+ ps_svc_lyr_dec->u1_layer_identifier = MEDIAL_ENHANCEMENT_LAYER;
+ ps_dec->u1_separate_parse = 0;
+ ps_dec->u4_num_cores = 1;
+ }
+ else
+ {
+ return IV_FAIL;
+ }
+
+ ps_svc_lyr_dec->u1_base_res_flag = (0 == u1_res_id);
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag = ps_cur_node->i4_idr_pic_flag;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_dependency_id = ps_cur_node->i4_dependency_id;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_priority_id = ps_cur_node->i4_priority_id;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_no_inter_layer_pred_flag =
+ ps_cur_node->u1_acc_no_int_pred;
+
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id = ps_cur_node->i4_quality_id;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_temporal_id = ps_cur_node->i4_temporal_id;
+
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_use_ref_base_pic_flag =
+ ps_cur_node->i4_use_ref_base;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_discardable_flag = 0;
+ ps_svc_lyr_dec->ps_nal_svc_ext->u1_svc_ext_flag = (u1_res_id > 1);
+ ps_svc_lyr_dec->u4_pps_id_for_layer = UINT32_MAX;
+ ps_vcl_buf = ps_cur_node->ps_first_vcl_nal;
+ ps_svc_lyr_dec->u1_error_in_cur_frame = 0;
+
+ /* Only for Non target Layers*/
+ if(NULL != ps_cur_node->ps_top_node)
+ {
+ ps_svc_lyr_dec->u1_inter_lyr_disable_dblk_filter_idc =
+ ps_cur_node->ps_top_node->i4_inter_lyr_dblk_idc;
+ ps_svc_lyr_dec->i1_inter_lyr_slice_alpha_c0_offset =
+ ps_cur_node->ps_top_node->i4_inter_lyr_alpha_c0_offset;
+ ps_svc_lyr_dec->i1_inter_lyr_slice_beta_offset =
+ ps_cur_node->ps_top_node->i4_inter_lyr_beta_offset;
+ }
+
+ while(NULL != ps_vcl_buf)
+ {
+ u1_layer_nal_data_present = 1;
+ ps_dec->ps_bitstrm->u4_ofst = 0;
+ ps_dec->ps_bitstrm->pu4_buffer =
+ (UWORD32 *) ((UWORD8 *) ps_vcl_buf + ps_vcl_buf->i4_buf_offset +
+ ps_vcl_buf->i4_slice_offset);
+
+ ps_dec->ps_bitstrm->u4_max_ofst = ps_vcl_buf->u4_max_bits;
+
+ ps_dec_op->u4_frame_decoded_flag = 0;
+ ret = isvcd_parse_nal_unit(ps_svc_lyr_dec, ps_cur_node->i4_nal_ref_idc);
+ if(ret != OK)
+ {
+ ps_svcd_ctxt->u1_parse_nal_unit_error = 1;
+ break;
+ }
+
+ /* go to the next slice */
+ ps_vcl_buf = ps_vcl_buf->ps_next;
+ }
+ /* error concelment: exit till next IDR if a Layer data is missing */
+ if(0 == u1_layer_nal_data_present)
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
+ return IV_FAIL;
+ }
+ /* error concelment: exit till next IDR if any of Non Target layers are
+ * corrupted */
+ if((ret != OK) && (u1_res_id != (u1_num_res_lyrs - 1)))
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
+ return IV_FAIL;
+ }
+
+ if((ret != OK) && (u1_res_id == (u1_num_res_lyrs - 1)))
+ {
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_num_res_lyrs - 1;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ if((0 == ps_svcd_ctxt->u4_num_sps_ctr) || (0 == ps_svcd_ctxt->u4_num_pps_ctr) ||
+ (NULL == ps_dec->ps_cur_pps))
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
+ ih264d_signal_decode_thread(ps_dec);
+ return IV_FAIL;
+ }
+ }
+ ps_cur_node = ps_cur_node->ps_top_node;
+
+ if((ps_dec->u4_pic_buf_got == 1) && (ret != IVD_MEM_ALLOC_FAILED) &&
+ ps_dec->u2_total_mbs_coded < ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+ {
+ // last slice - missing/corruption
+ WORD32 num_mb_skipped;
+ WORD32 prev_slice_err;
+ pocstruct_t temp_poc;
+ WORD32 ret1;
+ WORD32 ht_in_mbs;
+ ht_in_mbs = ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag);
+ num_mb_skipped =
+ (ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
+
+ if(ps_dec->u4_first_slice_in_pic && (ps_dec->u4_pic_buf_got == 0))
+ prev_slice_err = 1;
+ else
+ prev_slice_err = 2;
+
+ if(ps_dec->u2_total_mbs_coded == 0)
+ {
+ prev_slice_err = 1;
+ }
+ ret1 = isvcd_mark_err_slice_skip(
+ ps_svc_lyr_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL,
+ ps_dec->ps_cur_slice->u2_frame_num, &temp_poc, prev_slice_err);
+
+ if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T) ||
+ (ret1 == ERROR_INV_SPS_PPS_T) || (ret1 == ERROR_CORRUPTED_SLICE) ||
+ (ret == NOT_OK))
+ {
+ ret = ret1;
+ }
+ }
+
+ if((ret == IVD_RES_CHANGED) || (ret == IVD_MEM_ALLOC_FAILED) ||
+ (ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T) ||
+ (ret == ERROR_INV_SPS_PPS_T) || (ret == ERROR_CORRUPTED_SLICE) ||
+ (ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE) || (ret == NOT_OK))
+ {
+ ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
+ /* signal the decode thread */
+ ih264d_signal_decode_thread(ps_dec);
+ /* dont consume bitstream for change in resolution case */
+ if(ret == IVD_RES_CHANGED)
+ {
+ ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
+ }
+ return IV_FAIL;
+ }
+
+ /* Multi thread - for target Layer decoding*/
+ if((ps_dec->u1_separate_parse) &&
+ (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
+ (0 == ps_svc_lyr_dec->u1_error_in_cur_frame))
+ {
+ /* If Format conversion is not complete,
+ complete it here */
+ if(ps_dec->u4_num_cores == 2)
+ {
+ /*do deblocking of all mbs*/
+ if((ps_dec->u4_nmb_deblk == 0) && (ps_dec->u4_start_recon_deblk == 1) &&
+ (ps_dec->ps_cur_sps->u1_mb_aff_flag == 0))
+ {
+ UWORD8 u1_end_of_row = 0;
+ UWORD32 u4_max_addr;
+ tfr_ctxt_t s_tfr_ctxt = {0};
+ tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
+ pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr;
+ UWORD32 u4_slice_end = 0;
+
+ /*BS is done for all mbs while parsing*/
+ u4_max_addr = (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs) - 1;
+ /* BS is moved post recon gen in SVC ext*/
+
+ ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt,
+ ps_dec->u2_frm_wd_in_mbs, 0);
+
+ {
+ while(u4_slice_end != 1)
+ {
+ dec_mb_info_t *p_cur_mb;
+ WORD32 i, bs_mb_grp;
+ bs_mb_grp = ps_dec->cur_dec_mb_num - ps_dec->u4_cur_bs_mb_num;
+
+ for(i = 0; i < bs_mb_grp; i++)
+ {
+ p_cur_mb =
+ &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_bs_mb_num];
+
+ DEBUG_THREADS_PRINTF("ps_dec->u4_cur_bs_mb_num = %d\n",
+ ps_dec->u4_cur_bs_mb_num);
+ isvcd_compute_bs_non_mbaff_thread(ps_svc_lyr_dec, p_cur_mb,
+ ps_dec->u4_cur_bs_mb_num);
+
+ ps_dec->u4_cur_bs_mb_num++;
+ ps_dec->u4_bs_cur_slice_num_mbs++;
+ }
+ if(ps_dec->u4_cur_bs_mb_num > u4_max_addr)
+ {
+ u4_slice_end = 1;
+ u1_end_of_row = 1;
+ }
+ /*deblock MB group*/
+ {
+ UWORD32 u4_num_mbs;
+
+ if(ps_dec->u4_cur_bs_mb_num > ps_dec->u4_cur_deblk_mb_num)
+ {
+ if(u1_end_of_row)
+ {
+ u4_num_mbs = ps_dec->u4_cur_bs_mb_num -
+ ps_dec->u4_cur_deblk_mb_num;
+ }
+ else
+ {
+ u4_num_mbs = ps_dec->u4_cur_bs_mb_num -
+ ps_dec->u4_cur_deblk_mb_num - 1;
+ }
+ }
+ else
+ u4_num_mbs = 0;
+
+ ih264d_check_mb_map_deblk(ps_dec, u4_num_mbs, ps_tfr_cxt,
+ 0);
+ }
+ }
+ }
+ }
+ }
+
+ /*signal the decode thread*/
+ ih264d_signal_decode_thread(ps_dec);
+ }
+ else if((ps_dec->u1_separate_parse) &&
+ (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER))
+ {
+ /*signal the decode thread*/
+ ih264d_signal_decode_thread(ps_dec);
+ }
+
+ DATA_SYNC();
+
+ if((ps_dec_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
+ {
+ ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
+ ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
+ ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
+ }
+
+ // Report if header (sps and pps) has not been decoded yet
+ if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3)
+ {
+ ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
+ api_ret_value = IV_FAIL;
+ }
+
+ if((ps_dec->u4_pic_buf_got == 1) && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status))
+ {
+ /* For field pictures, set bottom and top picture decoded u4_flag correctly */
+
+ if(ps_dec->ps_cur_slice->u1_field_pic_flag)
+ {
+ if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
+ {
+ ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY;
+ }
+ else
+ {
+ ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY;
+ }
+ }
+ else
+ {
+ ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
+ }
+
+ /* if new frame in not found (if we are still getting slices from
+ * previous frame) ih264d_deblock_display is not called. Such frames
+ * will not be added to reference /display
+ */
+ if((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
+ {
+ /* Calling Function to deblock Picture and Display */
+ ret = ih264d_deblock_display(ps_dec);
+ }
+
+ /*set to complete ,as we dont support partial frame decode*/
+ if(ps_dec->i4_header_decoded == 3)
+ {
+ ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
+ }
+
+ /*Update the i4_frametype at the end of picture*/
+ if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
+ {
+ ps_dec->i4_frametype = IV_IDR_FRAME;
+ }
+ else if(ps_dec->i4_pic_type == B_SLICE)
+ {
+ ps_dec->i4_frametype = IV_B_FRAME;
+ }
+ else if(ps_dec->i4_pic_type == P_SLICE)
+ {
+ ps_dec->i4_frametype = IV_P_FRAME;
+ }
+ else if(ps_dec->i4_pic_type == I_SLICE)
+ {
+ ps_dec->i4_frametype = IV_I_FRAME;
+ }
+ else
+ {
+ H264_DEC_DEBUG_PRINT("Shouldn't come here\n");
+ }
+
+ // Update the content type
+ ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag;
+
+ ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2;
+ ps_dec->u4_total_frames_decoded =
+ ps_dec->u4_total_frames_decoded - ps_dec->ps_cur_slice->u1_field_pic_flag;
+ }
+
+ /* In case the decoder is configured to run in low delay mode,
+ * then get display buffer and then format convert.
+ * Note in this mode, format conversion does not run paralelly in a
+ * thread and adds to the codec cycles
+ */
+ if((IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) && ps_dec->u1_init_dec_flag)
+ {
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
+ &(ps_dec->s_disp_op));
+
+ if(0 == ps_dec->s_disp_op.u4_error_code)
+ {
+ ps_dec->u4_fmt_conv_cur_row = 0;
+ ps_dec->u4_output_present = 1;
+ }
+ else
+ {
+ ps_dec->u4_output_present = 0;
+ }
+ }
+
+ isvcd_fill_output_struct_from_context(ps_svc_lyr_dec, ps_dec_op);
+
+ /* If Format conversion is not complete,
+ complete it here */
+ /* For Non -target Layers , Buffers are retrived but not displayed*/
+
+ if((ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
+ ps_dec->u4_output_present &&
+ (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
+ {
+ ps_dec->u4_fmt_conv_num_rows =
+ ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row;
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ }
+
+ ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
+
+ if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1)
+ {
+ ps_dec_op->u4_progressive_frame_flag = 1;
+ if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
+ {
+ if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag) &&
+ (0 == ps_dec->ps_sps->u1_mb_aff_flag))
+ ps_dec_op->u4_progressive_frame_flag = 0;
+ }
+ }
+
+ if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)
+ {
+ ps_dec->u1_top_bottom_decoded = 0;
+ }
+ /*--------------------------------------------------------------------*/
+ /* Do End of Pic processing. */
+ /* Should be called only if frame was decoded in previous process call*/
+ /*--------------------------------------------------------------------*/
+ if(ps_dec->u4_pic_buf_got == 1)
+ {
+ if(1 == ps_dec->u1_last_pic_not_decoded)
+ {
+ ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec);
+
+ if(ret != OK) return ret;
+
+ ret = ih264d_end_of_pic(ps_dec);
+ if(ret != OK) return ret;
+ }
+ else
+ {
+ ret = ih264d_end_of_pic(ps_dec);
+ if(ret != OK) return ret;
+ }
+ }
+
+ if(ps_dec->u1_enable_mb_info && ps_dec->u4_output_present)
+ {
+ UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
+ if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
+ {
+ ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
+ ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
+ ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
+ ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
+ ps_dec->u4_total_mbs << 2);
+ }
+ if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
+ {
+ ps_h264d_dec_op->pu1_8x8_blk_type_map =
+ ps_h264d_dec_ip->pu1_8x8_blk_type_map;
+ ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
+ ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
+ ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
+ ps_dec->u4_total_mbs << 2);
+ }
+ }
+ /*Data memory barrier instruction,so that yuv write by the library is
+ * complete*/
+ DATA_SYNC();
+
+ H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n",
+ ps_dec_op->u4_num_bytes_consumed);
+ }
+ }
+ /* highest layer for flush validation */
+
+ if((ps_dec->u1_flushfrm) && (1 == flush_decode))
+ {
+ u1_res_id = u1_num_res_lyrs - 1;
+ ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
+ if(0 == ps_dec->s_disp_op.u4_error_code)
+ {
+ /* check output buffer size given by the application */
+ if(check_app_out_buf_size(ps_dec) != IV_SUCCESS)
+ {
+ ps_dec_op->u4_error_code = IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+ return (IV_FAIL);
+ }
+
+ ps_dec->u4_fmt_conv_cur_row = 0;
+ ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ ps_dec->u4_output_present = 1;
+ }
+ else
+ {
+ ps_dec->u4_output_present = 0;
+ }
+ ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
+
+ ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
+
+ ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
+ ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
+ ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
+ ps_dec_op->i4_display_index = ps_dec->i4_display_index;
+
+ ps_dec_op->u4_new_seq = 0;
+ ps_dec_op->u4_output_present = (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ ? ps_dec->u4_output_present
+ : 0;
+ ps_dec_op->u4_progressive_frame_flag = ps_dec->s_disp_op.u4_progressive_frame_flag;
+ ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
+ ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
+ ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
+ ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
+ ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
+
+ /*In the case of flush ,since no frame is decoded set pic type as invalid*/
+ ps_dec_op->u4_is_ref_flag = UINT32_MAX;
+ ps_dec_op->e_pic_type = IV_NA_FRAME;
+ ps_dec_op->u4_frame_decoded_flag = 0;
+
+ if(0 == ps_dec->s_disp_op.u4_error_code)
+ {
+ return (IV_SUCCESS);
+ }
+ else
+ return (IV_FAIL);
+ }
+ }
+
+ if((ps_dec_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
+ {
+ ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
+ ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
+ ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
+ }
+ return api_ret_value;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_display_frame */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ UWORD32 u4_disp_buf_size[3] = {0};
+ UWORD32 u4_num_disp_bufs;
+ ivd_set_display_frame_ip_t *dec_disp_ip;
+ ivd_set_display_frame_op_t *dec_disp_op;
+ UWORD32 i;
+ dec_struct_t *ps_dec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ dec_disp_ip = (ivd_set_display_frame_ip_t *) pv_api_ip;
+ dec_disp_op = (ivd_set_display_frame_op_t *) pv_api_op;
+ dec_disp_op->u4_error_code = 0;
+
+ ps_dec->u4_num_disp_bufs = 0;
+ if(ps_dec->u4_share_disp_buf)
+ {
+ UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs;
+
+ u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW);
+ ps_dec->u4_num_disp_bufs = u4_num_bufs;
+
+ /* Get the number and sizes of the first buffer. Compare this with the
+ * rest to make sure all the buffers are of the same size.
+ */
+ u4_num_disp_bufs = dec_disp_ip->s_disp_buffer[0].u4_num_bufs;
+
+ u4_disp_buf_size[0] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[0];
+ u4_disp_buf_size[1] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1];
+ u4_disp_buf_size[2] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[2];
+
+ for(i = 0; i < u4_num_bufs; i++)
+ {
+ if(dec_disp_ip->s_disp_buffer[i].u4_num_bufs != u4_num_disp_bufs)
+ {
+ return IV_FAIL;
+ }
+
+ if((dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0] != u4_disp_buf_size[0]) ||
+ (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1] != u4_disp_buf_size[1]) ||
+ (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2] != u4_disp_buf_size[2]))
+ {
+ return IV_FAIL;
+ }
+
+ ps_dec->disp_bufs[i].u4_num_bufs = dec_disp_ip->s_disp_buffer[i].u4_num_bufs;
+
+ ps_dec->disp_bufs[i].buf[0] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
+ ps_dec->disp_bufs[i].buf[1] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
+ ps_dec->disp_bufs[i].buf[2] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[2];
+
+ ps_dec->disp_bufs[i].u4_bufsize[0] =
+ dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0];
+ ps_dec->disp_bufs[i].u4_bufsize[1] =
+ dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1];
+ ps_dec->disp_bufs[i].u4_bufsize[2] =
+ dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2];
+ }
+ }
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : ih264d_set_flush_mode_svt_ext */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ UWORD8 u1_layer_id;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *) pv_api_op;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ctl_op->u4_error_code = 0;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->i4_decode_header)
+ {
+ ps_svcd_ctxt->i4_eos_flag = 1;
+ }
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ UNUSED(pv_api_ip);
+
+ /* Signal flush frame control call */
+ ps_dec->u1_flushfrm = 1;
+
+ if(ps_dec->u1_init_dec_flag == 1)
+ {
+ ih264d_release_pics_in_dpb((void *) ps_dec, ps_dec->u1_pic_bufs);
+ ih264d_release_display_bufs(ps_dec);
+ }
+
+ ps_ctl_op->u4_error_code = 0;
+
+ /* Ignore dangling fields during flush */
+ ps_dec->u1_top_bottom_decoded = 0;
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_status */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ UWORD32 i;
+ dec_struct_t *ps_dec;
+ UWORD32 pic_wd, pic_ht;
+ ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *) pv_api_op;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ UNUSED(pv_api_ip);
+ ps_ctl_op->u4_error_code = 0;
+
+ if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
+ {
+ ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height;
+ ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width;
+
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ pic_wd = ps_dec->u2_disp_width;
+ pic_ht = ps_dec->u2_disp_height;
+ }
+ else
+ {
+ pic_wd = ps_dec->u2_frm_wd_y;
+ pic_ht = ps_dec->u2_frm_ht_y;
+ }
+ }
+ else
+ {
+ pic_wd = 0;
+ pic_ht = 0;
+ ps_ctl_op->u4_pic_ht = pic_wd;
+ ps_ctl_op->u4_pic_wd = pic_ht;
+
+ if(1 == ps_dec->u4_share_disp_buf)
+ {
+ pic_wd += (PAD_LEN_Y_H << 1);
+ pic_ht += (PAD_LEN_Y_V << 2);
+ }
+ }
+
+ if(ps_dec->u4_app_disp_width > pic_wd) pic_wd = ps_dec->u4_app_disp_width;
+ if(0 == ps_dec->u4_share_disp_buf)
+ ps_ctl_op->u4_num_disp_bufs = 1;
+ else
+ {
+ if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
+ {
+ if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
+ (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
+ {
+ ps_ctl_op->u4_num_disp_bufs = ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
+ }
+ else
+ {
+ /*if VUI is not present assume maximum possible refrence frames for the
+ * level, as max reorder frames*/
+ ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
+ }
+
+ ps_ctl_op->u4_num_disp_bufs += ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
+ }
+ else
+ {
+ ps_ctl_op->u4_num_disp_bufs = 32;
+ }
+ ps_ctl_op->u4_num_disp_bufs = MAX(ps_ctl_op->u4_num_disp_bufs, 6);
+ ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs, 32);
+ }
+
+ ps_ctl_op->u4_error_code = ps_dec->i4_error_code;
+ ps_ctl_op->u4_frame_rate = 0;
+ ps_ctl_op->u4_bit_rate = 0;
+ ps_ctl_op->e_content_type = ps_dec->i4_content_type;
+ ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format;
+ ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
+
+ if(ps_dec->u1_chroma_format == IV_YUV_420P)
+ {
+ ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
+ }
+ else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
+ {
+ ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
+ }
+ else if(ps_dec->u1_chroma_format == IV_RGB_565)
+ {
+ ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
+ }
+ else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
+ (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
+ {
+ ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
+ }
+ else
+ {
+ // Invalid chroma format; Error code may be updated, verify in testing if needed
+ ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
+ {
+ ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
+ }
+
+ if(ps_dec->u1_chroma_format == IV_YUV_420P)
+ {
+ ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
+ ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) >> 2;
+ ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht) >> 2;
+ }
+ else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
+ {
+ ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) * 2;
+ ps_ctl_op->u4_min_out_buf_size[1] = ps_ctl_op->u4_min_out_buf_size[2] = 0;
+ }
+ else if(ps_dec->u1_chroma_format == IV_RGB_565)
+ {
+ ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) * 2;
+ ps_ctl_op->u4_min_out_buf_size[1] = ps_ctl_op->u4_min_out_buf_size[2] = 0;
+ }
+ else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
+ (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
+ {
+ ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
+ ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) >> 1;
+ ps_ctl_op->u4_min_out_buf_size[2] = 0;
+ }
+
+ ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_buf_info */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD8 i = 0; // Default for 420P format
+ UWORD16 pic_wd, pic_ht;
+ ivd_ctl_getbufinfo_op_t *ps_ctl_op = (ivd_ctl_getbufinfo_op_t *) pv_api_op;
+ UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS] = {0};
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ UNUSED(pv_api_ip);
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ ps_ctl_op->u4_error_code = 0;
+
+ ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
+ ps_ctl_op->u4_num_disp_bufs = 1;
+ pic_wd = 0;
+ pic_ht = 0;
+
+ if(ps_dec->i4_header_decoded == 3)
+ {
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ pic_wd = ps_dec->u2_disp_width;
+ pic_ht = ps_dec->u2_disp_height;
+ }
+ else
+ {
+ pic_wd = ps_dec->u2_frm_wd_y;
+ pic_ht = ps_dec->u2_frm_ht_y;
+ }
+ }
+
+ for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
+ {
+ ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
+ }
+ if((WORD32) ps_dec->u4_app_disp_width > pic_wd) pic_wd = ps_dec->u4_app_disp_width;
+
+ if(0 == ps_dec->u4_share_disp_buf)
+ ps_ctl_op->u4_num_disp_bufs = 1;
+ else
+ {
+ if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
+ {
+ if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
+ (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
+ {
+ ps_ctl_op->u4_num_disp_bufs = ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
+ }
+ else
+ {
+ /*if VUI is not present assume maximum possible refrence frames for the
+ * level, as max reorder frames*/
+ ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
+ }
+
+ ps_ctl_op->u4_num_disp_bufs += ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
+ }
+ else
+ {
+ ps_ctl_op->u4_num_disp_bufs = 32;
+ }
+
+ ps_ctl_op->u4_num_disp_bufs = MAX(ps_ctl_op->u4_num_disp_bufs, 6);
+ ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs, 32);
+ }
+
+ ps_ctl_op->u4_min_num_out_bufs =
+ ih264d_get_outbuf_size(pic_wd, pic_ht, ps_dec->u1_chroma_format, &au4_min_out_buf_size[0]);
+
+ for(i = 0; i < ps_ctl_op->u4_min_num_out_bufs; i++)
+ {
+ ps_ctl_op->u4_min_out_buf_size[i] = au4_min_out_buf_size[i];
+ }
+
+ ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_params */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ WORD32 ret = IV_SUCCESS;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ WORD32 u1_layer_id;
+
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+ ps_svcd_ctxt->i4_eos_flag = 0;
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ isvcd_ctl_set_config_ip_t *ps_h264d_ctl_ip = (isvcd_ctl_set_config_ip_t *) pv_api_ip;
+ isvcd_ctl_set_config_op_t *ps_h264d_ctl_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_dec->u1_flushfrm = 0;
+ ps_dec->u4_skip_frm_mask = 0;
+ ps_ctl_op->u4_error_code = 0;
+
+ if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE)
+ {
+ ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+ ret = IV_FAIL;
+ }
+
+ if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width)
+ {
+ ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
+ }
+ else if(0 == ps_dec->i4_header_decoded)
+ {
+ ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
+ }
+ else if(ps_ctl_ip->u4_disp_wd == 0)
+ {
+ ps_dec->u4_app_disp_width = 0;
+ }
+ else
+ {
+ /*
+ * Set the display width to zero. This will ensure that the wrong value we
+ * had stored (0xFFFFFFFF) does not propogate.
+ */
+ ps_dec->u4_app_disp_width = 0;
+ ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
+ ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
+ ret = IV_FAIL;
+ }
+
+ if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
+ ps_dec->i4_decode_header = 0;
+ else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
+ ps_dec->i4_decode_header = 1;
+ else
+ {
+ ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+ ps_dec->i4_decode_header = 1;
+ ret = IV_FAIL;
+ }
+ ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+
+ if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
+ (ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
+ {
+ ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+ ret = IV_FAIL;
+ }
+ ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode;
+ }
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_target_layer */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 05 04 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_target_layer(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ WORD32 ret = IV_SUCCESS;
+
+ isvcd_set_target_layer_ip_t *ps_ip;
+ isvcd_set_target_layer_op_t *ps_op;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_set_target_layer_ip_t *) pv_api_ip;
+ ps_op = (isvcd_set_target_layer_op_t *) pv_api_op;
+
+ ps_svcd_ctxt->u1_tgt_dep_id = ps_ip->u1_tgt_dep_id;
+ ps_svcd_ctxt->u1_tgt_quality_id = ps_ip->u1_tgt_quality_id;
+ ps_svcd_ctxt->u1_tgt_temp_id = ps_ip->u1_tgt_temp_id;
+ ps_svcd_ctxt->u1_tgt_priority_id = ps_ip->u1_tgt_priority_id;
+
+ ret = isvcd_nal_parse_set_target_attr(ps_ip->u1_tgt_quality_id, ps_ip->u1_tgt_dep_id,
+ ps_ip->u1_tgt_temp_id, ps_ip->u1_tgt_priority_id,
+ ps_svcd_ctxt->pv_nal_parse_ctxt);
+ ps_op->u4_error_code = 0;
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_default_params */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Copied from set_params */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_default_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ WORD32 ret = IV_SUCCESS;
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ivd_ctl_set_config_op_t *ps_ctl_op = (ivd_ctl_set_config_op_t *) pv_api_op;
+
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+ UNUSED(pv_api_ip);
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_dec->u4_app_disp_width = 0;
+ ps_dec->u4_skip_frm_mask = 0;
+ ps_dec->i4_decode_header = 1;
+ }
+ ps_ctl_op->u4_error_code = 0;
+
+ return ret;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_delete */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ isvcd_delete_ip_t *ps_ip = (isvcd_delete_ip_t *) pv_api_ip;
+ isvcd_delete_op_t *ps_op = (isvcd_delete_op_t *) pv_api_op;
+
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+ UNUSED(ps_ip);
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
+ }
+ isvcd_free_static_bufs(dec_hdl);
+ ps_op->s_ivd_delete_op_t.u4_error_code = 0;
+
+ return IV_SUCCESS;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_reset */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *) pv_api_op;
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+ UNUSED(pv_api_ip);
+ ps_ctl_op->u4_error_code = 0;
+
+ ps_svcd_ctxt->i4_eos_flag = 0;
+ ps_svcd_ctxt->u4_num_sps_ctr = 0;
+ ps_svcd_ctxt->u4_num_pps_ctr = 0;
+ ps_svcd_ctxt->u1_pre_parse_in_flush = 1;
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(ps_dec != NULL)
+ {
+ if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
+ if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
+ ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
+
+ isvcd_init_decoder(ps_svc_lyr_dec);
+ ps_dec->u1_flushfrm = 0;
+ }
+ else
+ {
+ H264_DEC_DEBUG_PRINT("\nReset called without Initializing the decoder\n");
+ ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE;
+ }
+ }
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ctl */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ ivd_ctl_set_config_ip_t *ps_ctl_ip;
+ ivd_ctl_set_config_op_t *ps_ctl_op;
+ WORD32 ret = IV_SUCCESS;
+ UWORD32 subcommand;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(ps_dec->init_done != 1)
+ {
+ return IV_FAIL;
+ }
+ ps_ctl_ip = (ivd_ctl_set_config_ip_t *) pv_api_ip;
+ ps_ctl_op = (ivd_ctl_set_config_op_t *) pv_api_op;
+ ps_ctl_op->u4_error_code = 0;
+ subcommand = ps_ctl_ip->e_sub_cmd;
+
+ switch(subcommand)
+ {
+ case IVD_CMD_CTL_GETPARAMS:
+ ret = isvcd_get_status(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_SETPARAMS:
+ ret = isvcd_set_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_RESET:
+ ret = isvcd_reset(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_SETDEFAULT:
+ ret = isvcd_set_default_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_FLUSH:
+ ret = isvcd_set_flush_mode(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_GETBUFINFO:
+ ret = isvcd_get_buf_info(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_CTL_GETVERSION:
+ ret = ih264d_get_version(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_DEGRADE:
+ ret = isvcd_set_degrade(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
+ case IH264D_CMD_CTL_SET_NUM_CORES:
+ ret = isvcd_set_num_cores(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
+ ret = isvcd_get_frame_dimensions(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_VUI_PARAMS:
+ ret = isvcd_get_vui_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
+ ret = isvcd_get_sei_mdcv_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
+ ret = isvcd_get_sei_cll_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
+ ret = isvcd_get_sei_ave_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
+ ret = isvcd_get_sei_ccv_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IH264D_CMD_CTL_SET_PROCESSOR:
+ ret = isvcd_set_processor(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case ISVCD_CMD_CTL_SET_TGT_LAYER:
+ ret = isvcd_set_target_layer(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ default:
+ H264_DEC_DEBUG_PRINT("\ndo nothing\n");
+ break;
+ }
+
+ return ret;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_rel_display_frame */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_rel_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ ivd_rel_display_frame_ip_t *ps_rel_ip;
+ ivd_rel_display_frame_op_t *ps_rel_op;
+ UWORD32 buf_released = 0;
+
+ UWORD32 u4_ts = 0;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_rel_ip = (ivd_rel_display_frame_ip_t *) pv_api_ip;
+ ps_rel_op = (ivd_rel_display_frame_op_t *) pv_api_op;
+ ps_rel_op->u4_error_code = 0;
+ u4_ts = ps_rel_ip->u4_disp_buf_id;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
+ ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0;
+ return IV_SUCCESS;
+ }
+
+ if(ps_dec->pv_pic_buf_mgr != NULL)
+ {
+ if(1 == ps_dec->u4_disp_buf_mapping[u4_ts])
+ {
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr,
+ ps_rel_ip->u4_disp_buf_id, BUF_MGR_IO);
+ ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
+ buf_released = 1;
+ }
+ }
+
+ if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released))
+ ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1;
+ }
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets degrade params
+ *
+ * @par Description:
+ * Sets degrade params.
+ * Refer to ih264d_ctl_degrade_ip_t definition for details
+ *
+ * @param[in] ps_codec_obj
+ * Pointer to codec object at API level
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @returns Status
+ *
+ * @remarks
+ *
+ *
+ *******************************************************************************
+ */
+
+WORD32 isvcd_set_degrade(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_degrade_ip_t *ps_ip;
+ isvcd_ctl_degrade_op_t *ps_op;
+ dec_struct_t *ps_codec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD8 u1_layer_id;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) ps_codec_obj->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_degrade_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_degrade_op_t *) pv_api_op;
+
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_codec = &ps_svc_lyr_dec->s_dec;
+ ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
+ ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
+ ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
+
+ ps_codec->i4_degrade_pic_cnt = 0;
+ }
+ ps_op->u4_error_code = 0;
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_frame_dimensions */
+/* */
+/* Description : gets the frame wd and ht and the buffer sizes */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_frame_dimensions(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_frame_dimensions_ip_t *ps_ip;
+ isvcd_ctl_get_frame_dimensions_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_ip = (isvcd_ctl_get_frame_dimensions_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_frame_dimensions_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+ if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
+ {
+ disp_wd = ps_dec->u2_disp_width;
+ disp_ht = ps_dec->u2_disp_height;
+
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ buffer_wd = disp_wd;
+ buffer_ht = disp_ht;
+ }
+ else
+ {
+ buffer_wd = ps_dec->u2_frm_wd_y;
+ buffer_ht = ps_dec->u2_frm_ht_y;
+ }
+ }
+ else
+ {
+ disp_wd = 0;
+ disp_ht = 0;
+
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ buffer_wd = disp_wd;
+ buffer_ht = disp_ht;
+ }
+ else
+ {
+ buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1);
+ buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2);
+ }
+ }
+ if(ps_dec->u4_app_disp_width > buffer_wd) buffer_wd = ps_dec->u4_app_disp_width;
+
+ if(0 == ps_dec->u4_share_disp_buf)
+ {
+ x_offset = 0;
+ y_offset = 0;
+ }
+ else
+ {
+ y_offset = (PAD_LEN_Y_V << 1);
+ x_offset = PAD_LEN_Y_H;
+
+ if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid)) &&
+ (0 != ps_dec->u2_crop_offset_y))
+ {
+ y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y;
+ x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y;
+ }
+ }
+
+ ps_op->u4_disp_wd[0] = disp_wd;
+ ps_op->u4_disp_ht[0] = disp_ht;
+ ps_op->u4_buffer_wd[0] = buffer_wd;
+ ps_op->u4_buffer_ht[0] = buffer_ht;
+ ps_op->u4_x_offset[0] = x_offset;
+ ps_op->u4_y_offset[0] = y_offset;
+
+ ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) >> 1);
+ ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) >> 1);
+ ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] >> 1);
+ ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] >> 1);
+ ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0] >> 1);
+ ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0] >> 1);
+
+ if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
+ (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
+ {
+ ps_op->u4_disp_wd[2] = 0;
+ ps_op->u4_disp_ht[2] = 0;
+ ps_op->u4_buffer_wd[2] = 0;
+ ps_op->u4_buffer_ht[2] = 0;
+ ps_op->u4_x_offset[2] = 0;
+ ps_op->u4_y_offset[2] = 0;
+
+ ps_op->u4_disp_wd[1] <<= 1;
+ ps_op->u4_buffer_wd[1] <<= 1;
+ ps_op->u4_x_offset[1] <<= 1;
+ }
+
+ return IV_SUCCESS;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_vui_params */
+/* */
+/* Description : gets the VUI params */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : success or failure */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_get_vui_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_vui_params_ip_t *ps_ip;
+ isvcd_ctl_get_vui_params_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ dec_seq_params_t *ps_sps;
+ vui_t *ps_vui;
+ UWORD32 u4_size;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_get_vui_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_vui_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ u4_size = ps_op->u4_size;
+ memset(ps_op, 0, sizeof(isvcd_ctl_get_vui_params_op_t));
+ ps_op->u4_size = u4_size;
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(NULL == ps_dec->ps_cur_sps)
+ {
+ ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+ ps_sps = ps_dec->ps_cur_sps;
+
+ if((0 == ps_sps->u1_is_valid) || (0 == ps_sps->u1_vui_parameters_present_flag))
+ {
+ ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+
+ ps_vui = &ps_sps->s_vui;
+
+ ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc;
+ ps_op->u2_sar_width = ps_vui->u2_sar_width;
+ ps_op->u2_sar_height = ps_vui->u2_sar_height;
+ ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag;
+ ps_op->u1_video_format = ps_vui->u1_video_format;
+ ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag;
+ ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries;
+ ps_op->u1_tfr_chars = ps_vui->u1_tfr_chars;
+ ps_op->u1_matrix_coeffs = ps_vui->u1_matrix_coeffs;
+ ps_op->u1_cr_top_field = ps_vui->u1_cr_top_field;
+ ps_op->u1_cr_bottom_field = ps_vui->u1_cr_bottom_field;
+ ps_op->u4_num_units_in_tick = ps_vui->u4_num_units_in_tick;
+ ps_op->u4_time_scale = ps_vui->u4_time_scale;
+ ps_op->u1_fixed_frame_rate_flag = ps_vui->u1_fixed_frame_rate_flag;
+ ps_op->u1_nal_hrd_params_present = ps_vui->u1_nal_hrd_params_present;
+ ps_op->u1_vcl_hrd_params_present = ps_vui->u1_vcl_hrd_params_present;
+ ps_op->u1_low_delay_hrd_flag = ps_vui->u1_low_delay_hrd_flag;
+ ps_op->u1_pic_struct_present_flag = ps_vui->u1_pic_struct_present_flag;
+ ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag;
+ ps_op->u1_mv_over_pic_boundaries_flag = ps_vui->u1_mv_over_pic_boundaries_flag;
+ ps_op->u4_max_bytes_per_pic_denom = ps_vui->u4_max_bytes_per_pic_denom;
+ ps_op->u4_max_bits_per_mb_denom = ps_vui->u4_max_bits_per_mb_denom;
+ ps_op->u4_log2_max_mv_length_horz = ps_vui->u4_log2_max_mv_length_horz;
+ ps_op->u4_log2_max_mv_length_vert = ps_vui->u4_log2_max_mv_length_vert;
+ ps_op->u4_num_reorder_frames = ps_vui->u4_num_reorder_frames;
+ ps_op->u4_max_dec_frame_buffering = ps_vui->u4_max_dec_frame_buffering;
+
+ return IV_SUCCESS;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_sei_mdcv_params */
+/* */
+/* Description : This function populates SEI mdcv message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when MDCV is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_sei_mdcv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_sei_mdcv_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ sei_mdcv_params_t *ps_sei_mdcv;
+ WORD32 i4_count;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_get_sei_mdcv_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_mdcv_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->s_sei_export.u1_sei_mdcv_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_MDCV_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+ ps_sei_mdcv = &ps_dec->s_sei_export.s_sei_mdcv_params;
+
+ for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
+ {
+ ps_op->au2_display_primaries_x[i4_count] = ps_sei_mdcv->au2_display_primaries_x[i4_count];
+ ps_op->au2_display_primaries_y[i4_count] = ps_sei_mdcv->au2_display_primaries_y[i4_count];
+ }
+
+ ps_op->u2_white_point_x = ps_sei_mdcv->u2_white_point_x;
+ ps_op->u2_white_point_y = ps_sei_mdcv->u2_white_point_y;
+ ps_op->u4_max_display_mastering_luminance = ps_sei_mdcv->u4_max_display_mastering_luminance;
+ ps_op->u4_min_display_mastering_luminance = ps_sei_mdcv->u4_min_display_mastering_luminance;
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_sei_cll_params */
+/* */
+/* Description : This function populates SEI cll message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when CLL is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_sei_cll_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_sei_cll_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_cll_params_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ sei_cll_params_t *ps_sei_cll;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_get_sei_cll_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_cll_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->s_sei_export.u1_sei_cll_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_CLL_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+ ps_sei_cll = &ps_dec->s_sei_export.s_sei_cll_params;
+
+ ps_op->u2_max_content_light_level = ps_sei_cll->u2_max_content_light_level;
+ ps_op->u2_max_pic_average_light_level = ps_sei_cll->u2_max_pic_average_light_level;
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_sei_ave_params */
+/* */
+/* Description : This function populates SEI ave message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when AVE is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_sei_ave_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_sei_ave_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_ave_params_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ sei_ave_params_t *ps_sei_ave;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_get_sei_ave_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_ave_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->s_sei_export.u1_sei_ave_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_AVE_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+ ps_sei_ave = &ps_dec->s_sei_export.s_sei_ave_params;
+
+ ps_op->u4_ambient_illuminance = ps_sei_ave->u4_ambient_illuminance;
+ ps_op->u2_ambient_light_x = ps_sei_ave->u2_ambient_light_x;
+ ps_op->u2_ambient_light_y = ps_sei_ave->u2_ambient_light_y;
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_sei_ccv_params */
+/* */
+/* Description : This function populates SEI mdcv message in */
+/* output structure */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code when CCV is not present */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_sei_ccv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ isvcd_ctl_get_sei_ccv_params_ip_t *ps_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ sei_ccv_params_t *ps_sei_ccv;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ WORD32 i4_count;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_get_sei_ccv_params_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_get_sei_ccv_params_op_t *) pv_api_op;
+ UNUSED(ps_ip);
+
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if(0 == ps_dec->s_sei_export.u1_sei_ccv_params_present_flag)
+ {
+ ps_op->u4_error_code = ERROR_SEI_CCV_PARAMS_NOT_FOUND;
+ return IV_FAIL;
+ }
+ ps_sei_ccv = &ps_dec->s_sei_export.s_sei_ccv_params;
+ ps_op->u1_ccv_cancel_flag = ps_sei_ccv->u1_ccv_cancel_flag;
+
+ if(0 == ps_op->u1_ccv_cancel_flag)
+ {
+ ps_op->u1_ccv_persistence_flag = ps_sei_ccv->u1_ccv_persistence_flag;
+ ps_op->u1_ccv_primaries_present_flag = ps_sei_ccv->u1_ccv_primaries_present_flag;
+ ps_op->u1_ccv_min_luminance_value_present_flag =
+ ps_sei_ccv->u1_ccv_min_luminance_value_present_flag;
+ ps_op->u1_ccv_max_luminance_value_present_flag =
+ ps_sei_ccv->u1_ccv_max_luminance_value_present_flag;
+ ps_op->u1_ccv_avg_luminance_value_present_flag =
+ ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag;
+ ps_op->u1_ccv_reserved_zero_2bits = ps_sei_ccv->u1_ccv_reserved_zero_2bits;
+
+ if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag)
+ {
+ for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
+ {
+ ps_op->ai4_ccv_primaries_x[i4_count] = ps_sei_ccv->ai4_ccv_primaries_x[i4_count];
+ ps_op->ai4_ccv_primaries_y[i4_count] = ps_sei_ccv->ai4_ccv_primaries_y[i4_count];
+ }
+ }
+
+ if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag)
+ {
+ ps_op->u4_ccv_min_luminance_value = ps_sei_ccv->u4_ccv_min_luminance_value;
+ }
+ if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag)
+ {
+ ps_op->u4_ccv_max_luminance_value = ps_sei_ccv->u4_ccv_max_luminance_value;
+ }
+ if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag)
+ {
+ ps_op->u4_ccv_avg_luminance_value = ps_sei_ccv->u4_ccv_avg_luminance_value;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_num_cores */
+/* */
+/* Description : This function sets the no of cores which decoder */
+/* can use for decoding */
+/* Inputs : iv_obj_t decoder handle */
+/* : pv_api_ip pointer to input structure */
+/* : pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : returns 0; 1 with error code */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ UWORD8 u1_layer_id;
+ isvcd_ctl_set_num_cores_ip_t *ps_ip;
+ isvcd_ctl_set_num_cores_op_t *ps_op;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
+
+ ps_ip = (isvcd_ctl_set_num_cores_ip_t *) pv_api_ip;
+ ps_op = (isvcd_ctl_set_num_cores_op_t *) pv_api_op;
+ ps_op->u4_error_code = 0;
+ for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
+ {
+ ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ ps_dec->u4_num_cores = ps_ip->u4_num_cores;
+
+ if(ps_dec->u4_num_cores == 1)
+ {
+ ps_dec->u1_separate_parse = 0;
+ }
+ else
+ {
+ ps_dec->u1_separate_parse = 1;
+ }
+
+ /*using only upto three threads currently*/
+ if(ps_dec->u4_num_cores > 3) ps_dec->u4_num_cores = 3;
+ }
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_fill_output_struct_from_context */
+/* */
+/* Description : This function fills the output structure from the */
+/* svc layer context */
+/* Inputs : iv_obj_t decoder handle */
+/* : ps_svc_lyr_dec pointer to svc layer context */
+/* : ps_dec_op pointer to output structure */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* */
+/* */
+/*****************************************************************************/
+void isvcd_fill_output_struct_from_context(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ ivd_video_decode_op_t *ps_dec_op)
+{
+ dec_struct_t *ps_dec;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ if((ps_dec_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
+ {
+ ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
+ ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
+ }
+ ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
+ ps_dec_op->i4_display_index = ps_dec->i4_display_index;
+ ps_dec_op->e_pic_type = ps_dec->i4_frametype;
+
+ ps_dec_op->u4_new_seq = 0;
+ ps_dec_op->u4_output_present =
+ (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) ? ps_dec->u4_output_present : 0;
+ ps_dec_op->u4_progressive_frame_flag = ps_dec->s_disp_op.u4_progressive_frame_flag;
+
+ ps_dec_op->u4_is_ref_flag = 1;
+ if(ps_dec_op->u4_frame_decoded_flag)
+ {
+ if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0) ps_dec_op->u4_is_ref_flag = 0;
+ }
+
+ ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
+ ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
+ ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
+ ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
+ ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
+
+ ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_api_function */
+/* */
+/* Description : */
+/* */
+/* Inputs :iv_obj_t decoder handle */
+/* :pv_api_ip pointer to input structure */
+/* :pv_api_op pointer to output structure */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+IV_API_CALL_STATUS_T isvcd_api_function(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
+{
+ UWORD32 command;
+ UWORD32 *pu2_ptr_cmd;
+ UWORD32 u4_api_ret;
+ IV_API_CALL_STATUS_T e_status;
+ e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op);
+
+ if(e_status != IV_SUCCESS)
+ {
+ UWORD32 *ptr_err;
+
+ ptr_err = (UWORD32 *) pv_api_op;
+ UNUSED(ptr_err);
+ H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1));
+ return IV_FAIL;
+ }
+
+ pu2_ptr_cmd = (UWORD32 *) pv_api_ip;
+ pu2_ptr_cmd++;
+
+ command = *pu2_ptr_cmd;
+ switch(command)
+ {
+ case IVD_CMD_CREATE:
+ u4_api_ret = isvcd_create(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ case IVD_CMD_DELETE:
+ u4_api_ret = isvcd_delete(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
+ case IVD_CMD_VIDEO_DECODE:
+ u4_api_ret = isvcd_video_decode(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
+ case IVD_CMD_GET_DISPLAY_FRAME:
+ u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+
+ break;
+
+ case IVD_CMD_SET_DISPLAY_FRAME:
+ u4_api_ret = isvcd_set_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+
+ break;
+
+ case IVD_CMD_REL_DISPLAY_FRAME:
+ u4_api_ret = isvcd_rel_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+
+ case IVD_CMD_VIDEO_CTL:
+ u4_api_ret = isvcd_ctl(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
+ break;
+ default:
+ u4_api_ret = IV_FAIL;
+ break;
+ }
+
+ return u4_api_ret;
+}
diff --git a/decoder/svc/isvcd_api.h b/decoder/svc/isvcd_api.h
new file mode 100644
index 0000000..9ad636d
--- /dev/null
+++ b/decoder/svc/isvcd_api.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_api.h
+ *
+ * @brief
+ * This file contains all the necessary structure and enumeration definitions
+ * needed for the Application
+ * Program Interface(API) of the Ittiam H264 svc decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_API_H_
+#define _ISVCD_API_H_
+
+#include "iv.h"
+#include "ivd_ext.h"
+
+extern IV_API_CALL_STATUS_T isvcd_create(ivd_avc_ext_create_ip_t *ps_ip,
+ ivd_avc_ext_create_op_t *ps_op);
+
+extern IV_API_CALL_STATUS_T isvcd_delete(iv_obj_t *ps_dec_hdl);
+
+extern IV_API_CALL_STATUS_T isvcd_decode_au(iv_obj_t *ps_dec_hdl,
+ ivd_avc_ext_video_decode_ip_t *ps_ip,
+ ivd_avc_ext_video_decode_op_t *ps_op);
+
+extern IV_API_CALL_STATUS_T isvcd_ctl_cmd_handler(iv_obj_t *ps_dec_hdl, ivd_avc_ext_ctl_ip_t *ps_ip,
+ ivd_avc_ext_ctl_op_t *ps_op);
+
+#endif /*_ISVCD_API_H_*/ \ No newline at end of file
diff --git a/decoder/svc/isvcd_cabac.c b/decoder/svc/isvcd_cabac.c
new file mode 100644
index 0000000..977c2c6
--- /dev/null
+++ b/decoder/svc/isvcd_cabac.c
@@ -0,0 +1,148 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_cabac.c
+ *
+ * @brief
+ * This file contains Binary decoding routines.
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_init_cabac_contexts()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264d_cabac.h"
+#include "isvcd_cabac.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "isvcd_tables.h"
+#include "ih264d_parse_cabac.h"
+#include "ih264d_tables.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_init_cabac_contexts */
+/* */
+/* Description : This function initializes the cabac contexts */
+/* depending upon slice type and Init_Idc value. */
+/* Inputs : ps_dec, slice type */
+/* Globals : <Does it use any global variables?> */
+/* Outputs : */
+/* Returns : void */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+void isvcd_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec)
+{
+ bin_ctxt_model_t *p_cabac_ctxt_table_t = ps_dec->p_cabac_ctxt_table_t;
+ UWORD8 u1_qp_y = ps_dec->ps_cur_slice->u1_slice_qp;
+ UWORD8 u1_cabac_init_Idc = 0;
+
+ if(I_SLICE != u1_slice_type)
+ {
+ u1_cabac_init_Idc = ps_dec->ps_cur_slice->u1_cabac_init_idc;
+ }
+
+ {
+ /* MAKING ps_dec->p_ctxt_inc_mb_map a scratch buffer */
+ /* 0th entry of CtxtIncMbMap will be always be containing default values
+ for CABAC context representing MB not available */
+ ctxt_inc_mb_info_t *p_DefCtxt = ps_dec->p_ctxt_inc_mb_map - 1;
+ UWORD8 *pu1_temp;
+ WORD8 i;
+ p_DefCtxt->u1_mb_type = CAB_SKIP;
+ p_DefCtxt->u1_cbp = 0x0f;
+ p_DefCtxt->u1_intra_chroma_pred_mode = 0;
+ p_DefCtxt->u1_yuv_dc_csbp = 0x7;
+ p_DefCtxt->u1_transform8x8_ctxt = 0;
+
+ pu1_temp = (UWORD8 *) p_DefCtxt->i1_ref_idx;
+ for(i = 0; i < 4; i++, pu1_temp++) (*pu1_temp) = 0;
+ pu1_temp = (UWORD8 *) p_DefCtxt->u1_mv;
+ for(i = 0; i < 16; i++, pu1_temp++) (*pu1_temp) = 0;
+ ps_dec->ps_def_ctxt_mb_info = p_DefCtxt;
+ }
+
+ if(u1_slice_type == I_SLICE)
+ {
+ u1_cabac_init_Idc = 3;
+ ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_I_SLICE;
+ }
+ else if(u1_slice_type == P_SLICE)
+ {
+ ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_P_SLICE;
+ ps_dec->p_mb_skip_flag_t = p_cabac_ctxt_table_t + MB_SKIP_FLAG_P_SLICE;
+ ps_dec->p_sub_mb_type_t = p_cabac_ctxt_table_t + SUB_MB_TYPE_P_SLICE;
+ }
+ else if(u1_slice_type == B_SLICE)
+ {
+ ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_B_SLICE;
+ ps_dec->p_mb_skip_flag_t = p_cabac_ctxt_table_t + MB_SKIP_FLAG_B_SLICE;
+ ps_dec->p_sub_mb_type_t = p_cabac_ctxt_table_t + SUB_MB_TYPE_B_SLICE;
+ }
+ {
+ bin_ctxt_model_t *p_cabac_ctxt_table_t_tmp = p_cabac_ctxt_table_t;
+ if(ps_dec->ps_cur_slice->u1_field_pic_flag)
+ {
+ p_cabac_ctxt_table_t_tmp += SIGNIFICANT_COEFF_FLAG_FLD;
+ }
+ else
+ {
+ p_cabac_ctxt_table_t_tmp += SIGNIFICANT_COEFF_FLAG_FRAME;
+ }
+ {
+ bin_ctxt_model_t **p_significant_coeff_flag_t = ps_dec->p_significant_coeff_flag_t;
+ p_significant_coeff_flag_t[0] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_0_OFFSET;
+ p_significant_coeff_flag_t[1] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_1_OFFSET;
+ p_significant_coeff_flag_t[2] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_2_OFFSET;
+ p_significant_coeff_flag_t[3] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_3_OFFSET;
+ p_significant_coeff_flag_t[4] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_4_OFFSET;
+
+ p_significant_coeff_flag_t[5] = p_cabac_ctxt_table_t_tmp + SIG_COEFF_CTXT_CAT_5_OFFSET;
+ }
+ }
+
+ memcpy(p_cabac_ctxt_table_t, gau1_isvcd_cabac_ctxt_init_table[u1_cabac_init_Idc][u1_qp_y],
+ NUM_CABAC_CTXTS_SVC * sizeof(bin_ctxt_model_t));
+}
diff --git a/decoder/svc/isvcd_cabac.h b/decoder/svc/isvcd_cabac.h
new file mode 100644
index 0000000..6c8767a
--- /dev/null
+++ b/decoder/svc/isvcd_cabac.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_cabac.h
+ *
+ * @brief
+ * This file contains declarations of Binary decoding routines and tables.
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_CABAC_H_
+#define _ISVCD_CABAC_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+
+#define NUM_CABAC_CTXTS_SVC 467
+
+#endif /* _ISVCD_CABAC_H_ */
diff --git a/decoder/svc/isvcd_cabac_init_tables.c b/decoder/svc/isvcd_cabac_init_tables.c
new file mode 100644
index 0000000..15a2fd8
--- /dev/null
+++ b/decoder/svc/isvcd_cabac_init_tables.c
@@ -0,0 +1,6529 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_cabac_init_tables.c
+ *
+ * @brief
+ * This file contains the initialized cabac context structures for all
+ * possible values of Qp (0 - 51) Cabac_init Idc (0 - 2) and I slice.
+ * The contexts are initialized and stored as per tables 9-11 to 9 -23
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_CABAC_INIT_TABLES_H_
+#define _ISVCD_CABAC_INIT_TABLES_H_
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_cabac.h"
+#include "isvcd_cabac.h"
+#include "ih264d_tables.h"
+
+/*combined table :guc_RTAB,NextStateLPS,NextStateMPS
+ input(combined_state):
+ bits 0-5: state
+ bits 6:mps
+ output
+ bits 0-7:rangeTabLPS
+ bits 8-14 :combined_next_state_if_mps
+ bits 15 -21:combined_next_state_if_lps
+
+ */
+
+/*****************************************************************************/
+/* Global Variable Initialization */
+/*****************************************************************************/
+const UWORD8
+ gau1_isvcd_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_CABAC_CTXTS_SVC] =
+
+ {
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, 54, 14, 118,
+ 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, 67, 90, 104, 126, 104, 67, 78,
+ 65, 1, 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, 94, 9,
+ 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0, 83, 86, 97, 72,
+ 22, 1, 18, 78, 96, 126, 98, 101, 67, 82, 94, 83, 110, 91, 102, 93, 126,
+ 92, 89, 96, 108, 17, 65, 6, 93, 74, 92, 87, 126, 9, 3, 4, 69, 15,
+ 68, 69, 88, 85, 78, 75, 77, 9, 13, 68, 13, 21, 81, 0, 70, 67, 6,
+ 76, 28, 64, 2, 28, 38, 39, 34, 27, 93, 73, 73, 17, 14, 100, 10, 10,
+ 10, 2, 7, 7, 0, 3, 1, 6, 69, 6, 24, 12, 68, 64, 2, 0, 13,
+ 24, 19, 11, 15, 3, 4, 4, 30, 19, 20, 78, 3, 69, 35, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18,
+ 27, 10, 82, 8, 78, 17, 32, 84, 56, 62, 60, 59, 62, 62, 57, 57, 54,
+ 44, 36, 33, 43, 29, 70, 67, 4, 67, 33, 31, 28, 34, 32, 25, 20, 22,
+ 0, 4, 64, 94, 89, 108, 76, 19, 18, 11, 64, 4, 70, 75, 82, 102, 77,
+ 39, 21, 15, 8, 4, 71, 83, 87, 119, 5, 34, 27, 25, 20, 8, 5, 64,
+ 74, 90, 70, 34, 32, 21, 4, 5, 72, 81, 97, 5, 58, 49, 45, 36, 23,
+ 5, 70, 79, 85, 62, 106, 106, 87, 114, 110, 98, 110, 106, 103, 107, 108, 112,
+ 96, 95, 91, 93, 94, 86, 67, 80, 85, 70, 3, 5, 2, 13, 13, 14, 9,
+ 22, 17, 12, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, 64, 69, 4,
+ 70, 19, 32, 20, 10, 29, 25, 11, 23, 31, 19, 25, 13, 6, 20, 52, 49,
+ 52, 52, 54, 62, 62, 62, 62, 62, 62, 62, 62, 62, 34, 62, 62, 62, 62,
+ 62, 62, 54, 37, 36, 6, 82, 75, 97, 125, 62, 62, 62, 57, 55, 53, 41,
+ 44, 31, 32, 22, 19, 16, 65, 71, 3, 0, 65, 39, 43, 40, 31, 40, 39,
+ 23, 31, 34, 21, 6, 10, 2, 86, 23, 12, 4, 79, 71, 69, 70, 66, 68,
+ 73, 69, 70, 67, 1, 70, 66, 65, 0, 62, 62, 62, 62, 62, 60, 54, 36,
+ 4, 66, 28, 21, 18, 15, 7, 3, 1, 66, 76, 85, 81, 77, 81, 80, 73,
+ 74, 83, 71, 67, 2, 66, 66, 4, 4, 62, 62, 62, 62, 61, 57, 46, 29,
+ 1, 75, 65, 4, 67, 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, 62, 54, 14, 115,
+ 6, 77, 64, 1, 14, 72, 12, 65, 20, 62, 68, 91, 104, 124, 102, 67, 77,
+ 64, 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5, 75, 93, 9,
+ 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0, 82, 86, 97, 71,
+ 22, 1, 18, 77, 95, 124, 96, 99, 65, 80, 92, 82, 108, 89, 100, 92, 125,
+ 91, 88, 95, 107, 18, 64, 7, 92, 73, 91, 86, 124, 9, 3, 4, 69, 16,
+ 68, 68, 87, 84, 77, 74, 76, 9, 13, 67, 13, 21, 80, 0, 69, 67, 6,
+ 75, 28, 64, 2, 28, 37, 39, 34, 27, 92, 72, 72, 17, 14, 99, 10, 10,
+ 10, 3, 7, 7, 1, 4, 2, 6, 68, 6, 24, 12, 68, 64, 2, 0, 13,
+ 23, 19, 11, 15, 4, 5, 4, 29, 19, 20, 77, 3, 69, 35, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18,
+ 27, 10, 81, 8, 77, 17, 31, 83, 55, 62, 59, 58, 61, 62, 56, 56, 52,
+ 43, 35, 32, 41, 28, 71, 67, 4, 67, 32, 30, 27, 33, 31, 24, 19, 21,
+ 0, 4, 64, 93, 88, 107, 75, 20, 18, 11, 0, 5, 69, 74, 81, 100, 76,
+ 39, 21, 15, 8, 5, 70, 82, 86, 117, 5, 35, 28, 25, 20, 9, 5, 64,
+ 73, 89, 70, 35, 32, 21, 4, 6, 71, 80, 96, 5, 58, 49, 45, 36, 23,
+ 5, 69, 78, 84, 62, 105, 105, 86, 112, 108, 97, 108, 104, 101, 105, 106, 110,
+ 95, 94, 90, 92, 92, 85, 67, 79, 84, 69, 3, 5, 2, 13, 13, 13, 8,
+ 22, 17, 13, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, 64, 68, 5,
+ 70, 19, 32, 20, 10, 29, 25, 12, 23, 30, 19, 25, 13, 6, 19, 52, 49,
+ 52, 51, 53, 62, 62, 62, 62, 62, 62, 62, 62, 62, 33, 62, 62, 62, 62,
+ 62, 62, 53, 36, 35, 6, 81, 74, 95, 122, 62, 62, 62, 56, 53, 52, 40,
+ 42, 30, 31, 21, 18, 15, 66, 71, 3, 0, 66, 38, 42, 39, 30, 39, 38,
+ 22, 30, 33, 20, 5, 9, 1, 86, 23, 12, 4, 78, 70, 68, 69, 65, 67,
+ 71, 68, 69, 66, 3, 68, 65, 0, 2, 62, 62, 62, 62, 62, 58, 51, 34,
+ 2, 65, 29, 22, 19, 16, 8, 4, 2, 65, 75, 84, 80, 76, 80, 78, 71,
+ 73, 82, 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 58, 54, 43, 26,
+ 64, 75, 65, 4, 66, 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, 61, 54, 14, 113,
+ 6, 76, 0, 1, 13, 72, 11, 66, 19, 60, 70, 92, 105, 121, 101, 67, 76,
+ 0, 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5, 75, 92, 9,
+ 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0, 81, 86, 97, 71,
+ 21, 1, 18, 77, 95, 122, 94, 97, 64, 78, 91, 81, 107, 88, 99, 91, 123,
+ 91, 88, 95, 106, 18, 64, 7, 91, 73, 90, 86, 123, 9, 3, 4, 69, 16,
+ 68, 68, 87, 84, 77, 74, 76, 9, 13, 67, 13, 21, 80, 0, 69, 67, 6,
+ 75, 27, 64, 2, 27, 36, 38, 33, 26, 91, 72, 72, 16, 13, 99, 9, 10,
+ 10, 3, 7, 7, 2, 4, 2, 6, 68, 6, 23, 12, 69, 64, 2, 64, 13,
+ 22, 19, 11, 14, 4, 5, 4, 28, 19, 19, 77, 3, 70, 34, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 17,
+ 26, 9, 81, 8, 77, 16, 30, 83, 53, 62, 57, 56, 59, 60, 54, 54, 50,
+ 41, 33, 30, 39, 26, 72, 67, 4, 68, 31, 29, 26, 32, 29, 23, 18, 20,
+ 64, 3, 65, 93, 88, 106, 75, 20, 18, 11, 0, 5, 69, 74, 81, 99, 75,
+ 39, 21, 15, 8, 5, 70, 81, 85, 115, 5, 35, 28, 25, 20, 9, 5, 64,
+ 73, 88, 70, 35, 32, 21, 4, 6, 71, 80, 95, 5, 57, 48, 44, 35, 23,
+ 5, 69, 78, 84, 62, 104, 104, 85, 111, 107, 96, 107, 103, 100, 104, 105, 108,
+ 94, 93, 90, 91, 91, 85, 68, 79, 83, 69, 3, 4, 2, 12, 12, 12, 7,
+ 21, 17, 13, 14, 10, 21, 16, 8, 21, 18, 13, 10, 13, 0, 64, 68, 5,
+ 70, 18, 31, 19, 10, 28, 24, 12, 22, 29, 19, 25, 12, 5, 17, 51, 48,
+ 51, 50, 52, 62, 62, 62, 62, 62, 62, 62, 62, 62, 32, 62, 62, 62, 62,
+ 62, 62, 51, 35, 34, 6, 80, 74, 94, 120, 60, 60, 62, 54, 51, 50, 38,
+ 40, 29, 29, 20, 16, 14, 67, 72, 2, 0, 67, 37, 41, 37, 28, 37, 36,
+ 21, 28, 31, 19, 4, 8, 0, 87, 22, 11, 3, 78, 70, 68, 68, 65, 66,
+ 70, 67, 68, 65, 4, 67, 64, 1, 3, 62, 62, 62, 62, 60, 55, 48, 31,
+ 0, 65, 29, 22, 19, 16, 9, 4, 2, 65, 75, 84, 80, 75, 80, 77, 70,
+ 73, 81, 69, 65, 3, 65, 64, 4, 4, 62, 62, 62, 60, 55, 50, 39, 23,
+ 67, 75, 65, 4, 66, 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, 60, 54, 14, 111,
+ 6, 75, 1, 1, 12, 72, 10, 67, 19, 58, 71, 93, 105, 118, 100, 67, 75,
+ 1, 1, 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, 75, 92, 9,
+ 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, 0, 81, 86, 97, 70,
+ 20, 1, 18, 77, 95, 120, 92, 96, 1, 76, 90, 80, 105, 87, 98, 90, 121,
+ 90, 88, 94, 105, 18, 64, 7, 91, 73, 90, 85, 121, 9, 2, 3, 70, 16,
+ 68, 68, 86, 84, 76, 74, 75, 9, 13, 67, 13, 20, 80, 0, 69, 67, 6,
+ 75, 26, 64, 2, 26, 35, 37, 32, 25, 91, 71, 72, 15, 13, 98, 9, 10,
+ 10, 3, 7, 7, 3, 4, 2, 6, 67, 6, 22, 12, 70, 64, 2, 64, 12,
+ 21, 19, 11, 13, 4, 5, 4, 26, 19, 18, 77, 3, 70, 33, 23, 19, 14,
+ 17, 19, 12, 16, 24, 1, 16, 9, 9, 5, 0, 11, 5, 9, 10, 7, 16,
+ 25, 9, 81, 7, 77, 15, 28, 83, 52, 62, 55, 54, 57, 58, 52, 52, 48,
+ 39, 32, 29, 37, 24, 73, 67, 4, 68, 30, 28, 25, 30, 28, 21, 17, 19,
+ 65, 3, 65, 93, 88, 106, 74, 20, 18, 11, 0, 5, 69, 74, 80, 98, 75,
+ 39, 21, 15, 8, 6, 69, 80, 84, 113, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 88, 70, 35, 32, 20, 4, 6, 71, 80, 94, 5, 57, 48, 43, 34, 23,
+ 5, 69, 77, 83, 62, 103, 103, 85, 110, 106, 95, 105, 102, 99, 103, 103, 107,
+ 94, 92, 90, 91, 89, 85, 68, 79, 83, 69, 2, 4, 2, 11, 11, 11, 6,
+ 21, 16, 13, 13, 10, 21, 15, 8, 20, 18, 12, 10, 12, 0, 65, 68, 5,
+ 71, 18, 31, 18, 10, 27, 24, 12, 21, 28, 18, 24, 11, 5, 16, 50, 47,
+ 51, 49, 51, 61, 62, 62, 62, 62, 62, 62, 62, 62, 31, 62, 62, 62, 62,
+ 62, 62, 49, 34, 33, 6, 79, 74, 93, 118, 58, 58, 62, 52, 49, 48, 37,
+ 38, 27, 28, 19, 15, 12, 68, 73, 2, 64, 68, 36, 39, 36, 26, 35, 34,
+ 19, 27, 29, 17, 3, 6, 65, 88, 21, 10, 2, 78, 69, 68, 68, 64, 66,
+ 69, 66, 67, 64, 5, 66, 0, 3, 4, 62, 62, 62, 62, 58, 52, 45, 28,
+ 65, 64, 30, 23, 20, 16, 10, 5, 2, 64, 74, 84, 79, 75, 79, 76, 69,
+ 73, 81, 69, 65, 3, 64, 0, 4, 4, 62, 62, 62, 57, 52, 46, 35, 19,
+ 69, 75, 65, 4, 65, 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, 58, 54, 14, 108,
+ 5, 74, 1, 1, 11, 72, 9, 68, 18, 56, 73, 94, 106, 115, 99, 67, 74,
+ 1, 1, 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, 75, 91, 8,
+ 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0, 80, 87, 97, 70,
+ 19, 1, 18, 77, 95, 119, 91, 94, 2, 75, 89, 79, 104, 85, 97, 89, 119,
+ 90, 87, 94, 104, 18, 64, 7, 90, 73, 89, 85, 120, 8, 2, 3, 70, 16,
+ 68, 68, 86, 84, 76, 74, 75, 9, 12, 67, 13, 20, 80, 0, 69, 67, 6,
+ 75, 26, 65, 2, 26, 34, 36, 31, 24, 90, 71, 72, 14, 12, 98, 8, 10,
+ 9, 3, 7, 7, 4, 5, 2, 5, 67, 5, 21, 11, 71, 64, 2, 65, 12,
+ 20, 18, 10, 13, 5, 5, 4, 25, 18, 17, 77, 3, 71, 33, 23, 19, 14,
+ 17, 19, 12, 16, 23, 1, 16, 9, 9, 5, 64, 11, 5, 9, 10, 7, 16,
+ 24, 8, 81, 7, 77, 14, 27, 83, 50, 62, 53, 52, 55, 56, 50, 50, 46,
+ 37, 30, 27, 34, 22, 74, 67, 3, 69, 29, 27, 24, 29, 26, 20, 16, 17,
+ 65, 2, 66, 93, 88, 105, 74, 20, 18, 11, 0, 5, 69, 74, 80, 97, 74,
+ 39, 21, 15, 8, 6, 69, 80, 84, 111, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 87, 70, 35, 31, 20, 4, 6, 71, 80, 94, 5, 56, 47, 42, 33, 23,
+ 5, 69, 77, 83, 62, 102, 102, 84, 108, 105, 94, 104, 100, 98, 101, 102, 105,
+ 93, 92, 89, 90, 88, 84, 69, 79, 82, 69, 2, 3, 1, 10, 10, 10, 5,
+ 20, 16, 13, 13, 9, 20, 15, 8, 19, 17, 12, 9, 11, 64, 65, 68, 5,
+ 71, 17, 30, 17, 10, 26, 23, 12, 20, 27, 18, 24, 10, 4, 14, 49, 47,
+ 50, 48, 49, 60, 62, 62, 62, 62, 62, 62, 62, 62, 29, 62, 62, 62, 62,
+ 62, 62, 47, 33, 31, 6, 78, 73, 92, 116, 57, 56, 60, 51, 47, 46, 35,
+ 36, 26, 26, 17, 13, 11, 69, 74, 1, 64, 69, 34, 38, 34, 25, 33, 32,
+ 18, 25, 27, 16, 2, 5, 66, 88, 20, 10, 1, 78, 69, 67, 67, 64, 65,
+ 68, 66, 66, 0, 6, 65, 1, 4, 5, 62, 62, 62, 61, 55, 49, 42, 25,
+ 68, 64, 30, 23, 20, 17, 10, 5, 3, 64, 74, 83, 79, 74, 79, 75, 68,
+ 73, 80, 68, 64, 3, 64, 1, 4, 4, 62, 62, 61, 54, 49, 42, 31, 16,
+ 72, 75, 65, 4, 65, 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, 57, 54, 14, 106,
+ 5, 73, 2, 1, 11, 71, 8, 69, 18, 54, 75, 95, 106, 112, 97, 67, 73,
+ 2, 1, 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, 75, 90, 8,
+ 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, 80, 87, 97, 69,
+ 18, 1, 18, 76, 95, 117, 89, 93, 4, 73, 87, 78, 103, 84, 96, 88, 117,
+ 89, 87, 93, 103, 18, 64, 7, 90, 73, 89, 84, 118, 8, 2, 3, 70, 16,
+ 68, 67, 85, 84, 76, 74, 74, 9, 12, 67, 13, 20, 79, 0, 68, 67, 6,
+ 75, 25, 65, 2, 25, 33, 36, 30, 23, 89, 70, 72, 13, 12, 97, 8, 10,
+ 9, 3, 7, 7, 5, 5, 2, 5, 67, 5, 20, 11, 72, 64, 2, 65, 11,
+ 19, 18, 10, 12, 5, 5, 4, 24, 18, 16, 77, 3, 71, 32, 23, 19, 14,
+ 17, 19, 12, 16, 23, 1, 16, 9, 9, 5, 64, 11, 5, 8, 10, 7, 15,
+ 23, 8, 81, 6, 77, 13, 26, 83, 49, 61, 52, 51, 53, 54, 48, 48, 44,
+ 35, 28, 25, 32, 21, 75, 67, 3, 69, 28, 26, 23, 28, 25, 18, 15, 16,
+ 66, 2, 66, 93, 88, 105, 74, 20, 18, 11, 0, 5, 68, 73, 79, 96, 74,
+ 39, 21, 15, 8, 6, 68, 79, 83, 109, 5, 35, 28, 25, 20, 10, 5, 64,
+ 73, 86, 70, 36, 31, 19, 4, 6, 71, 80, 93, 5, 56, 46, 41, 32, 23,
+ 5, 69, 77, 82, 62, 101, 101, 83, 107, 104, 93, 103, 99, 97, 100, 100, 103,
+ 92, 91, 89, 90, 87, 84, 69, 78, 81, 69, 1, 3, 1, 10, 9, 9, 4,
+ 19, 15, 13, 12, 9, 20, 15, 8, 18, 16, 12, 9, 10, 64, 65, 68, 5,
+ 71, 16, 30, 17, 10, 25, 22, 12, 19, 26, 17, 23, 9, 3, 12, 48, 46,
+ 50, 47, 48, 58, 62, 62, 62, 62, 62, 62, 62, 62, 28, 62, 62, 62, 62,
+ 62, 61, 45, 32, 30, 6, 77, 73, 91, 114, 55, 55, 58, 49, 45, 44, 34,
+ 34, 25, 24, 16, 11, 9, 70, 75, 1, 64, 70, 33, 36, 32, 23, 32, 31,
+ 16, 24, 26, 14, 1, 4, 67, 89, 20, 9, 0, 77, 68, 67, 67, 0, 64,
+ 67, 65, 65, 1, 8, 64, 2, 5, 7, 62, 62, 62, 58, 53, 46, 39, 22,
+ 70, 64, 31, 24, 21, 17, 11, 5, 3, 0, 73, 83, 79, 73, 78, 74, 67,
+ 72, 79, 68, 64, 3, 0, 2, 4, 4, 62, 62, 58, 51, 46, 39, 27, 12,
+ 75, 75, 65, 4, 65, 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, 56, 54, 14, 104,
+ 5, 73, 3, 1, 10, 71, 7, 70, 17, 53, 76, 96, 107, 109, 96, 67, 73,
+ 3, 1, 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, 74, 90, 8,
+ 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, 79, 87, 97, 69,
+ 18, 0, 18, 76, 94, 115, 87, 91, 5, 71, 86, 77, 101, 83, 95, 88, 116,
+ 89, 87, 93, 103, 19, 64, 7, 89, 72, 88, 84, 117, 8, 1, 2, 71, 16,
+ 68, 67, 85, 84, 75, 74, 74, 9, 12, 66, 13, 19, 79, 0, 68, 67, 6,
+ 75, 24, 65, 2, 24, 32, 35, 30, 23, 89, 70, 72, 13, 11, 97, 7, 10,
+ 9, 3, 7, 7, 5, 5, 2, 5, 66, 5, 19, 11, 72, 65, 2, 66, 11,
+ 18, 18, 10, 11, 5, 5, 4, 22, 18, 15, 77, 3, 72, 31, 23, 18, 14,
+ 17, 19, 12, 16, 23, 1, 15, 9, 8, 5, 64, 10, 4, 8, 9, 6, 14,
+ 22, 7, 81, 6, 76, 12, 24, 83, 47, 59, 50, 49, 51, 52, 46, 46, 42,
+ 33, 27, 24, 30, 19, 76, 67, 3, 70, 27, 25, 22, 26, 23, 17, 14, 15,
+ 67, 1, 67, 93, 88, 104, 73, 20, 18, 11, 1, 5, 68, 73, 79, 95, 73,
+ 38, 21, 15, 8, 7, 68, 78, 82, 107, 5, 36, 28, 25, 20, 11, 5, 64,
+ 72, 86, 70, 36, 31, 19, 4, 6, 70, 79, 92, 5, 55, 46, 40, 32, 23,
+ 5, 68, 76, 82, 62, 101, 100, 83, 106, 103, 92, 101, 98, 96, 99, 99, 102,
+ 92, 90, 89, 89, 85, 84, 70, 78, 81, 69, 1, 2, 1, 9, 8, 8, 3,
+ 19, 15, 13, 12, 8, 19, 14, 8, 18, 16, 11, 9, 10, 64, 66, 68, 5,
+ 72, 16, 29, 16, 9, 24, 22, 13, 19, 25, 17, 23, 9, 3, 11, 47, 45,
+ 49, 46, 47, 57, 62, 62, 62, 62, 62, 62, 62, 61, 27, 62, 62, 62, 62,
+ 62, 59, 43, 31, 29, 6, 76, 73, 89, 111, 53, 53, 56, 47, 43, 42, 32,
+ 32, 23, 23, 15, 10, 8, 71, 76, 0, 65, 71, 32, 35, 31, 21, 30, 29,
+ 15, 22, 24, 13, 64, 2, 69, 90, 19, 8, 64, 77, 68, 67, 66, 0, 64,
+ 65, 64, 64, 2, 9, 1, 3, 7, 8, 62, 62, 60, 56, 50, 44, 36, 20,
+ 72, 0, 31, 24, 21, 17, 12, 6, 3, 0, 73, 83, 78, 73, 78, 73, 66,
+ 72, 79, 67, 0, 3, 0, 3, 4, 4, 62, 62, 56, 48, 42, 35, 24, 9,
+ 77, 75, 65, 4, 64, 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, 54, 54, 14, 101,
+ 4, 72, 3, 1, 9, 71, 6, 71, 17, 51, 78, 97, 107, 106, 95, 67, 72,
+ 3, 1, 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, 74, 89, 7,
+ 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, 79, 87, 97, 68,
+ 17, 0, 18, 76, 94, 114, 85, 90, 7, 69, 85, 76, 100, 81, 94, 87, 114,
+ 88, 86, 92, 102, 19, 64, 7, 89, 72, 88, 83, 115, 7, 1, 2, 71, 16,
+ 68, 67, 84, 84, 75, 74, 73, 9, 11, 66, 13, 19, 79, 0, 68, 67, 6,
+ 75, 24, 65, 2, 24, 31, 34, 29, 22, 88, 69, 72, 12, 11, 96, 7, 10,
+ 8, 3, 7, 7, 6, 6, 2, 5, 66, 5, 18, 11, 73, 65, 2, 66, 10,
+ 17, 17, 10, 11, 6, 5, 4, 21, 17, 14, 77, 3, 72, 31, 23, 18, 14,
+ 17, 19, 12, 16, 23, 1, 15, 9, 8, 5, 64, 10, 4, 7, 9, 6, 14,
+ 21, 7, 81, 5, 76, 11, 23, 83, 46, 57, 48, 47, 49, 50, 44, 44, 40,
+ 31, 25, 22, 27, 17, 77, 67, 2, 70, 26, 24, 21, 25, 22, 15, 13, 14,
+ 67, 1, 67, 93, 88, 104, 73, 20, 18, 11, 1, 5, 68, 73, 78, 94, 73,
+ 38, 21, 15, 8, 7, 67, 77, 82, 105, 5, 36, 28, 25, 20, 11, 5, 64,
+ 72, 85, 70, 36, 30, 18, 4, 6, 70, 79, 92, 5, 55, 45, 39, 31, 23,
+ 5, 68, 76, 81, 62, 100, 99, 82, 104, 102, 91, 100, 96, 95, 97, 97, 100,
+ 91, 89, 88, 89, 84, 83, 70, 78, 80, 69, 0, 2, 0, 8, 7, 7, 2,
+ 18, 14, 13, 11, 8, 19, 14, 8, 17, 15, 11, 8, 9, 64, 66, 68, 5,
+ 72, 15, 29, 15, 9, 23, 21, 13, 18, 24, 16, 22, 8, 2, 9, 46, 45,
+ 49, 45, 45, 55, 62, 62, 62, 62, 62, 62, 62, 59, 25, 62, 62, 62, 62,
+ 62, 56, 41, 30, 28, 6, 75, 72, 88, 109, 52, 51, 54, 46, 41, 40, 31,
+ 30, 22, 21, 13, 8, 6, 72, 77, 0, 65, 72, 30, 33, 29, 20, 28, 27,
+ 13, 21, 22, 11, 65, 1, 70, 90, 18, 8, 65, 77, 67, 66, 66, 1, 0,
+ 64, 0, 0, 3, 10, 2, 4, 8, 9, 62, 61, 58, 53, 48, 41, 33, 17,
+ 74, 0, 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, 77, 72, 65,
+ 72, 78, 67, 0, 3, 1, 4, 4, 4, 62, 62, 53, 45, 39, 31, 20, 5,
+ 80, 75, 65, 4, 64, 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, 53, 54, 14, 99, 4,
+ 71, 4, 1, 8, 71, 5, 73, 16, 49, 80, 98, 108, 104, 94, 67, 71, 4, 1,
+ 83, 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, 89, 7, 71, 79, 88,
+ 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, 78, 88, 97, 68, 16, 0, 18, 76,
+ 94, 112, 84, 88, 8, 68, 84, 75, 99, 80, 93, 86, 112, 88, 86, 92, 101, 19,
+ 64, 7, 88, 72, 87, 83, 114, 7, 0, 1, 72, 16, 68, 67, 84, 84, 75, 74,
+ 73, 8, 11, 66, 13, 18, 79, 0, 68, 67, 5, 75, 23, 66, 2, 23, 29, 33,
+ 28, 21, 88, 69, 72, 11, 10, 96, 6, 9, 8, 3, 7, 7, 7, 6, 2, 4,
+ 66, 4, 17, 10, 74, 65, 2, 67, 10, 16, 17, 9, 10, 6, 5, 4, 19, 17,
+ 13, 77, 3, 73, 30, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 7, 8, 5, 13, 20, 6, 81, 5, 76, 10, 21, 83, 44, 55, 46,
+ 45, 47, 47, 42, 42, 38, 29, 23, 20, 25, 15, 78, 67, 2, 71, 25, 22, 19,
+ 23, 20, 14, 11, 12, 68, 0, 68, 93, 88, 103, 73, 20, 18, 11, 1, 5, 68,
+ 73, 78, 93, 72, 38, 21, 15, 8, 7, 67, 77, 81, 104, 5, 36, 28, 25, 19,
+ 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, 79, 91, 5, 54, 44, 38,
+ 30, 22, 5, 68, 76, 81, 62, 99, 98, 82, 103, 101, 91, 99, 95, 94, 96, 96,
+ 99, 91, 89, 88, 88, 83, 83, 71, 78, 80, 69, 0, 1, 0, 7, 6, 5, 1,
+ 17, 14, 13, 11, 7, 18, 13, 7, 16, 14, 10, 8, 8, 65, 67, 68, 5, 73,
+ 14, 28, 14, 9, 22, 20, 13, 17, 23, 16, 22, 7, 1, 7, 45, 44, 48, 43,
+ 44, 54, 62, 62, 62, 62, 62, 62, 62, 56, 24, 62, 62, 62, 62, 61, 54, 39,
+ 28, 26, 6, 75, 72, 87, 107, 50, 49, 52, 44, 38, 38, 29, 28, 20, 19, 12,
+ 6, 5, 73, 78, 64, 66, 73, 29, 32, 27, 18, 26, 25, 12, 19, 20, 10, 66,
+ 64, 72, 91, 17, 7, 66, 77, 67, 66, 65, 1, 0, 0, 0, 1, 4, 11, 3,
+ 5, 9, 10, 61, 59, 56, 51, 45, 38, 30, 14, 77, 0, 32, 25, 22, 18, 13,
+ 6, 4, 1, 72, 82, 78, 72, 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4,
+ 3, 62, 61, 51, 42, 36, 27, 16, 2, 83, 75, 66, 3, 64, 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, 52, 54, 14, 97, 4,
+ 70, 5, 1, 8, 70, 4, 74, 15, 47, 81, 99, 109, 101, 92, 67, 70, 5, 1,
+ 82, 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, 88, 7, 71, 79, 88,
+ 0, 71, 71, 77, 68, 5, 22, 0, 0, 0, 77, 88, 97, 68, 15, 0, 18, 75,
+ 94, 110, 82, 86, 9, 66, 82, 74, 97, 79, 91, 85, 110, 88, 86, 92, 100, 19,
+ 64, 7, 87, 72, 86, 82, 113, 7, 0, 1, 72, 16, 68, 66, 83, 83, 74, 74,
+ 73, 8, 11, 66, 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 28, 33,
+ 27, 20, 87, 69, 71, 10, 9, 96, 5, 9, 8, 4, 7, 7, 8, 6, 2, 4,
+ 65, 4, 17, 10, 75, 65, 2, 68, 10, 15, 17, 9, 9, 6, 5, 4, 18, 17,
+ 13, 77, 3, 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 7, 8, 5, 12, 20, 6, 81, 5, 76, 9, 20, 83, 42, 54, 45,
+ 44, 45, 45, 41, 41, 36, 27, 22, 19, 23, 14, 79, 67, 2, 72, 24, 21, 18,
+ 22, 19, 13, 10, 11, 69, 64, 69, 93, 87, 102, 72, 21, 18, 11, 1, 6, 67,
+ 72, 77, 92, 71, 38, 21, 15, 8, 8, 67, 76, 80, 102, 5, 36, 28, 25, 19,
+ 12, 5, 64, 72, 84, 70, 37, 30, 18, 4, 7, 70, 79, 90, 5, 54, 44, 38,
+ 29, 22, 5, 68, 75, 80, 62, 98, 97, 81, 102, 99, 90, 97, 94, 92, 95, 95,
+ 97, 90, 88, 88, 87, 81, 83, 72, 77, 79, 69, 0, 0, 0, 7, 5, 4, 0,
+ 17, 14, 13, 11, 7, 17, 13, 7, 15, 14, 10, 8, 7, 65, 67, 67, 6, 73,
+ 14, 27, 14, 9, 22, 20, 13, 16, 22, 16, 22, 6, 1, 6, 45, 43, 47, 42,
+ 43, 53, 60, 60, 62, 62, 62, 62, 62, 54, 23, 62, 62, 62, 62, 58, 52, 38,
+ 27, 25, 6, 74, 72, 86, 105, 48, 48, 50, 42, 36, 37, 28, 26, 19, 18, 11,
+ 5, 4, 74, 78, 64, 66, 74, 28, 31, 26, 16, 25, 24, 11, 18, 19, 9, 67,
+ 65, 73, 92, 17, 6, 66, 76, 67, 66, 64, 2, 1, 1, 1, 2, 5, 13, 4,
+ 6, 11, 12, 60, 58, 54, 49, 42, 35, 27, 11, 79, 1, 32, 25, 23, 18, 14,
+ 7, 4, 2, 71, 82, 77, 71, 77, 70, 1, 71, 77, 65, 2, 3, 2, 5, 4,
+ 3, 62, 59, 49, 40, 33, 24, 12, 64, 85, 75, 66, 3, 0, 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, 50, 54, 14, 94, 3,
+ 69, 5, 1, 7, 70, 3, 75, 15, 45, 83, 100, 109, 98, 91, 67, 69, 5, 1,
+ 82, 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, 87, 6, 71, 79, 88,
+ 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, 77, 88, 97, 67, 14, 0, 18, 75,
+ 94, 109, 80, 85, 11, 64, 81, 73, 96, 77, 90, 84, 108, 87, 85, 91, 99, 19,
+ 64, 7, 87, 72, 86, 82, 111, 6, 0, 1, 72, 16, 68, 66, 83, 83, 74, 74,
+ 72, 8, 10, 66, 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 27, 32,
+ 26, 19, 86, 68, 71, 9, 9, 95, 5, 9, 7, 4, 7, 7, 9, 7, 2, 4,
+ 65, 4, 16, 10, 76, 65, 2, 68, 9, 14, 16, 9, 9, 7, 5, 4, 17, 16,
+ 12, 77, 3, 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4,
+ 65, 9, 3, 6, 8, 5, 12, 19, 5, 81, 4, 76, 8, 19, 83, 41, 52, 43,
+ 42, 43, 43, 39, 39, 34, 25, 20, 17, 20, 12, 80, 67, 1, 72, 23, 20, 17,
+ 21, 17, 11, 9, 10, 69, 64, 69, 93, 87, 102, 72, 21, 18, 11, 1, 6, 67,
+ 72, 77, 91, 71, 38, 21, 15, 8, 8, 66, 75, 80, 100, 5, 36, 28, 25, 19,
+ 12, 5, 64, 72, 83, 70, 37, 29, 17, 4, 7, 70, 79, 90, 5, 53, 43, 37,
+ 28, 22, 5, 68, 75, 80, 62, 97, 96, 80, 100, 98, 89, 96, 92, 91, 93, 93,
+ 95, 89, 87, 87, 87, 80, 82, 72, 77, 78, 69, 64, 0, 64, 6, 4, 3, 64,
+ 16, 13, 13, 10, 6, 17, 13, 7, 14, 13, 10, 7, 6, 65, 67, 67, 6, 73,
+ 13, 27, 13, 9, 21, 19, 13, 15, 21, 15, 21, 5, 0, 4, 44, 43, 47, 41,
+ 41, 51, 58, 58, 62, 62, 62, 62, 62, 52, 21, 59, 62, 59, 62, 56, 49, 36,
+ 26, 24, 6, 73, 71, 85, 103, 47, 46, 48, 41, 34, 35, 26, 24, 18, 16, 9,
+ 3, 2, 75, 79, 65, 66, 75, 26, 29, 24, 15, 23, 22, 9, 16, 17, 7, 68,
+ 66, 74, 92, 16, 6, 67, 76, 66, 65, 64, 2, 2, 2, 2, 3, 6, 14, 5,
+ 7, 12, 13, 60, 56, 52, 46, 40, 32, 24, 8, 81, 1, 33, 26, 23, 19, 15,
+ 7, 5, 2, 71, 81, 77, 70, 76, 69, 2, 71, 76, 65, 2, 3, 2, 6, 4,
+ 3, 62, 57, 46, 37, 30, 20, 8, 68, 88, 75, 66, 3, 0, 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, 49, 54, 14, 92, 3,
+ 69, 6, 1, 6, 70, 2, 76, 14, 44, 84, 101, 110, 95, 90, 67, 69, 6, 1,
+ 81, 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, 87, 6, 71, 78, 88,
+ 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 18, 75,
+ 93, 107, 78, 83, 12, 1, 80, 72, 94, 76, 89, 84, 107, 87, 85, 91, 99, 20,
+ 64, 7, 86, 71, 85, 81, 110, 6, 64, 0, 73, 16, 68, 66, 82, 83, 73, 74,
+ 72, 8, 10, 65, 13, 17, 78, 0, 67, 67, 5, 74, 21, 66, 2, 21, 26, 31,
+ 26, 19, 86, 68, 71, 9, 8, 95, 4, 9, 7, 4, 7, 7, 9, 7, 2, 4,
+ 64, 4, 15, 10, 76, 66, 2, 69, 9, 13, 16, 9, 8, 7, 5, 4, 15, 16,
+ 11, 77, 3, 75, 28, 22, 17, 14, 17, 18, 11, 16, 22, 0, 13, 9, 7, 4,
+ 65, 8, 2, 6, 7, 4, 11, 18, 5, 81, 4, 75, 7, 17, 83, 39, 50, 41,
+ 40, 41, 41, 37, 37, 32, 23, 19, 16, 18, 10, 81, 67, 1, 73, 22, 19, 16,
+ 19, 16, 10, 8, 9, 70, 65, 70, 93, 87, 101, 71, 21, 18, 11, 2, 6, 67,
+ 72, 76, 90, 70, 37, 21, 15, 8, 9, 66, 74, 79, 98, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 83, 70, 37, 29, 17, 4, 7, 69, 78, 89, 5, 53, 43, 36,
+ 28, 22, 5, 67, 74, 79, 62, 97, 95, 80, 99, 97, 88, 94, 91, 90, 92, 92,
+ 94, 89, 86, 87, 86, 78, 82, 73, 77, 78, 69, 64, 64, 64, 5, 3, 2, 65,
+ 16, 13, 13, 10, 6, 16, 12, 7, 14, 13, 9, 7, 6, 65, 68, 67, 6, 74,
+ 13, 26, 12, 8, 20, 19, 14, 15, 20, 15, 21, 5, 0, 3, 43, 42, 46, 40,
+ 40, 50, 56, 56, 61, 60, 62, 62, 60, 49, 20, 57, 62, 56, 62, 53, 47, 34,
+ 25, 23, 6, 72, 71, 83, 100, 45, 44, 46, 39, 32, 33, 25, 22, 16, 15, 8,
+ 2, 1, 76, 80, 65, 67, 76, 25, 28, 23, 13, 21, 20, 8, 15, 15, 6, 70,
+ 68, 76, 93, 15, 5, 68, 76, 66, 65, 0, 3, 2, 4, 3, 4, 7, 15, 7,
+ 8, 14, 14, 59, 55, 50, 44, 37, 30, 21, 6, 83, 2, 33, 26, 24, 19, 16,
+ 8, 5, 3, 70, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, 3, 7, 4,
+ 3, 62, 55, 44, 34, 26, 16, 5, 71, 90, 75, 66, 3, 1, 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, 48, 54, 14, 90, 3,
+ 68, 7, 1, 5, 70, 1, 77, 14, 42, 86, 102, 110, 92, 89, 67, 68, 7, 1,
+ 81, 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, 86, 6, 72, 78, 88,
+ 2, 70, 71, 76, 66, 5, 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 18, 75,
+ 93, 105, 77, 82, 14, 2, 79, 71, 93, 75, 88, 83, 105, 86, 85, 90, 98, 20,
+ 64, 7, 86, 71, 85, 81, 108, 6, 64, 0, 73, 16, 68, 66, 82, 83, 73, 74,
+ 71, 8, 10, 65, 13, 17, 78, 0, 67, 67, 5, 74, 20, 67, 2, 20, 25, 30,
+ 25, 18, 85, 67, 71, 8, 8, 94, 4, 9, 7, 4, 7, 7, 10, 7, 2, 3,
+ 64, 3, 14, 9, 77, 66, 2, 69, 8, 12, 16, 8, 7, 7, 5, 4, 14, 16,
+ 10, 77, 3, 75, 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4,
+ 66, 8, 2, 5, 7, 4, 10, 17, 4, 81, 3, 75, 6, 16, 83, 38, 48, 39,
+ 38, 39, 39, 35, 35, 30, 21, 17, 14, 16, 8, 82, 67, 1, 73, 21, 18, 15,
+ 18, 14, 8, 7, 7, 71, 65, 70, 93, 87, 101, 71, 21, 18, 11, 2, 6, 67,
+ 72, 76, 89, 70, 37, 21, 15, 8, 9, 65, 74, 78, 96, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 82, 70, 37, 29, 16, 4, 7, 69, 78, 88, 5, 52, 42, 35,
+ 27, 22, 5, 67, 74, 79, 62, 96, 94, 79, 98, 96, 87, 93, 90, 89, 91, 90,
+ 92, 88, 86, 87, 86, 77, 82, 73, 77, 77, 69, 65, 64, 64, 4, 2, 1, 66,
+ 15, 12, 13, 9, 5, 16, 12, 7, 13, 12, 9, 7, 5, 66, 68, 67, 6, 74,
+ 12, 26, 11, 8, 19, 18, 14, 14, 19, 14, 20, 4, 64, 1, 42, 41, 46, 39,
+ 39, 48, 54, 54, 59, 57, 62, 62, 57, 47, 19, 54, 62, 53, 58, 50, 44, 32,
+ 24, 21, 6, 71, 71, 82, 98, 43, 42, 44, 37, 30, 31, 23, 20, 15, 13, 7,
+ 0, 64, 77, 81, 66, 67, 77, 24, 26, 21, 11, 19, 18, 6, 13, 13, 4, 71,
+ 69, 77, 94, 14, 4, 69, 76, 65, 65, 0, 3, 3, 5, 3, 5, 8, 16, 8,
+ 9, 15, 15, 59, 53, 48, 41, 35, 27, 18, 3, 86, 2, 34, 27, 24, 19, 16,
+ 8, 5, 3, 70, 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3, 8, 4,
+ 3, 61, 53, 41, 31, 23, 12, 1, 75, 93, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, 46, 54, 14, 87, 2,
+ 67, 7, 1, 5, 69, 0, 78, 13, 40, 88, 103, 111, 89, 87, 67, 67, 7, 1,
+ 81, 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5, 72, 78, 88,
+ 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, 75, 89, 97, 66, 12, 64, 18, 74,
+ 93, 104, 75, 80, 15, 4, 77, 70, 92, 73, 87, 82, 103, 86, 84, 90, 97, 20,
+ 64, 7, 85, 71, 84, 80, 107, 5, 64, 0, 73, 16, 68, 65, 81, 83, 73, 74,
+ 71, 8, 9, 65, 13, 17, 77, 0, 66, 67, 5, 74, 20, 67, 2, 20, 24, 30,
+ 24, 17, 84, 67, 71, 7, 7, 94, 3, 9, 6, 4, 7, 7, 11, 8, 2, 3,
+ 64, 3, 13, 9, 78, 66, 2, 70, 8, 11, 15, 8, 7, 8, 5, 4, 13, 15,
+ 9, 77, 3, 76, 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4,
+ 66, 8, 2, 5, 7, 4, 10, 16, 4, 81, 3, 75, 5, 15, 83, 36, 46, 38,
+ 37, 37, 37, 33, 33, 28, 19, 15, 12, 13, 7, 83, 67, 0, 74, 20, 17, 14,
+ 17, 13, 7, 6, 6, 71, 66, 71, 93, 87, 100, 71, 21, 18, 11, 2, 6, 66,
+ 71, 75, 88, 69, 37, 21, 15, 8, 9, 65, 73, 78, 94, 5, 37, 28, 25, 19,
+ 13, 5, 64, 71, 81, 70, 38, 28, 16, 4, 7, 69, 78, 88, 5, 52, 41, 34,
+ 26, 22, 5, 67, 74, 78, 62, 95, 93, 78, 96, 95, 86, 92, 88, 88, 89, 89,
+ 90, 87, 85, 86, 85, 76, 81, 74, 76, 76, 69, 65, 65, 65, 4, 1, 0, 67,
+ 14, 12, 13, 9, 5, 15, 12, 7, 12, 11, 9, 6, 4, 66, 68, 67, 6, 74,
+ 11, 25, 11, 8, 18, 17, 14, 13, 18, 14, 20, 3, 65, 64, 41, 41, 45, 38,
+ 37, 47, 52, 52, 57, 55, 62, 61, 54, 45, 17, 51, 62, 50, 54, 48, 42, 30,
+ 23, 20, 6, 70, 70, 81, 96, 42, 41, 42, 36, 28, 29, 22, 18, 14, 11, 5,
+ 65, 65, 78, 82, 66, 67, 78, 22, 25, 19, 10, 18, 17, 5, 12, 12, 3, 72,
+ 70, 78, 94, 14, 4, 70, 75, 65, 64, 1, 4, 4, 6, 4, 6, 9, 18, 9,
+ 10, 16, 17, 58, 51, 46, 39, 32, 24, 15, 0, 88, 2, 34, 27, 25, 20, 17,
+ 8, 6, 4, 69, 80, 76, 68, 75, 66, 5, 70, 74, 0, 4, 3, 4, 9, 4,
+ 3, 59, 51, 39, 28, 20, 9, 66, 78, 96, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, 45, 54, 14, 85, 2,
+ 66, 8, 1, 4, 69, 64, 79, 13, 38, 89, 104, 111, 86, 86, 67, 66, 8, 1,
+ 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 18, 74,
+ 93, 102, 73, 79, 17, 6, 76, 69, 90, 72, 86, 81, 101, 85, 84, 89, 96, 20,
+ 64, 7, 85, 71, 84, 80, 105, 5, 65, 64, 74, 16, 68, 65, 81, 83, 72, 74,
+ 70, 8, 9, 65, 13, 16, 77, 0, 66, 67, 5, 74, 19, 67, 2, 19, 23, 29,
+ 23, 16, 84, 66, 71, 6, 7, 93, 3, 9, 6, 4, 7, 7, 12, 8, 2, 3,
+ 0, 3, 12, 9, 79, 66, 2, 70, 7, 10, 15, 8, 6, 8, 5, 4, 11, 15,
+ 8, 77, 3, 76, 26, 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4,
+ 66, 7, 1, 4, 6, 3, 9, 15, 3, 81, 2, 75, 4, 13, 83, 35, 44, 36,
+ 35, 35, 35, 31, 31, 26, 17, 14, 11, 11, 5, 84, 67, 0, 74, 19, 16, 13,
+ 15, 11, 5, 5, 5, 72, 66, 71, 93, 87, 100, 70, 21, 18, 11, 2, 6, 66,
+ 71, 75, 87, 69, 37, 21, 15, 8, 10, 64, 72, 77, 92, 5, 37, 28, 25, 19,
+ 14, 5, 64, 71, 81, 70, 38, 28, 15, 4, 7, 69, 78, 87, 5, 51, 41, 33,
+ 25, 22, 5, 67, 73, 78, 62, 94, 92, 78, 95, 94, 85, 90, 87, 87, 88, 87,
+ 89, 87, 84, 86, 85, 74, 81, 74, 76, 76, 69, 66, 65, 65, 3, 0, 64, 68,
+ 14, 11, 13, 8, 4, 15, 11, 7, 11, 11, 8, 6, 3, 66, 69, 67, 6, 75,
+ 11, 25, 10, 8, 17, 17, 14, 12, 17, 13, 19, 2, 65, 65, 40, 40, 45, 37,
+ 36, 45, 50, 50, 55, 52, 60, 59, 51, 42, 16, 48, 62, 47, 50, 45, 39, 28,
+ 22, 19, 6, 69, 70, 80, 94, 40, 39, 40, 34, 26, 27, 20, 16, 12, 10, 4,
+ 66, 67, 79, 83, 67, 68, 79, 21, 23, 18, 8, 16, 15, 3, 10, 10, 1, 73,
+ 72, 80, 95, 13, 3, 71, 75, 64, 64, 1, 4, 4, 7, 5, 7, 10, 19, 10,
+ 11, 18, 18, 58, 50, 44, 36, 30, 21, 12, 66, 90, 3, 35, 28, 25, 20, 18,
+ 9, 6, 4, 69, 80, 75, 68, 74, 65, 6, 70, 74, 0, 4, 3, 4, 10, 4,
+ 3, 58, 49, 36, 25, 17, 5, 70, 82, 98, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, 54, 14, 83, 2,
+ 65, 9, 1, 3, 69, 65, 80, 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1,
+ 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 18, 74,
+ 93, 100, 71, 77, 18, 8, 75, 68, 89, 71, 85, 80, 99, 85, 84, 89, 95, 20,
+ 64, 7, 84, 71, 83, 79, 104, 5, 65, 64, 74, 16, 68, 65, 80, 83, 72, 74,
+ 70, 8, 9, 65, 13, 16, 77, 0, 66, 67, 5, 74, 18, 67, 2, 18, 22, 28,
+ 22, 15, 83, 66, 71, 5, 6, 93, 2, 9, 6, 4, 7, 7, 13, 8, 2, 3,
+ 0, 3, 11, 9, 80, 66, 2, 71, 7, 9, 15, 8, 5, 8, 5, 4, 10, 15,
+ 7, 77, 3, 77, 25, 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4,
+ 66, 7, 1, 4, 6, 3, 8, 14, 3, 81, 2, 75, 3, 12, 83, 33, 42, 34,
+ 33, 33, 33, 29, 29, 24, 15, 12, 9, 9, 3, 85, 67, 0, 75, 18, 15, 12,
+ 14, 10, 4, 4, 4, 73, 67, 72, 93, 87, 99, 70, 21, 18, 11, 2, 6, 66,
+ 71, 74, 86, 68, 37, 21, 15, 8, 10, 64, 71, 76, 90, 5, 37, 28, 25, 19,
+ 14, 5, 64, 71, 80, 70, 38, 28, 15, 4, 7, 69, 78, 86, 5, 51, 40, 32,
+ 24, 22, 5, 67, 73, 77, 62, 93, 91, 77, 94, 93, 84, 89, 86, 86, 87, 86,
+ 87, 86, 83, 86, 84, 73, 81, 75, 76, 75, 69, 66, 66, 65, 2, 64, 65, 69,
+ 13, 11, 13, 8, 4, 14, 11, 7, 10, 10, 8, 6, 2, 66, 69, 67, 6, 75,
+ 10, 24, 9, 8, 16, 16, 14, 11, 16, 13, 19, 1, 66, 67, 39, 39, 44, 36,
+ 35, 44, 48, 48, 53, 50, 57, 56, 48, 40, 15, 45, 59, 44, 46, 42, 37, 26,
+ 21, 18, 6, 68, 70, 79, 92, 38, 37, 38, 32, 24, 25, 19, 14, 11, 8, 3,
+ 68, 68, 80, 84, 67, 68, 80, 20, 22, 16, 6, 14, 13, 2, 9, 8, 0, 74,
+ 73, 81, 96, 12, 2, 72, 75, 64, 64, 2, 5, 5, 8, 6, 8, 11, 20, 11,
+ 12, 19, 19, 57, 48, 42, 34, 27, 18, 9, 69, 92, 3, 35, 28, 26, 20, 19,
+ 9, 6, 5, 68, 80, 75, 67, 74, 64, 7, 70, 73, 1, 5, 3, 5, 11, 4,
+ 3, 57, 47, 34, 22, 14, 1, 74, 85, 101, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, 53, 14, 81, 1, 65,
+ 9, 0, 2, 69, 67, 82, 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0, 80, 78,
+ 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, 78, 88, 3, 69, 70,
+ 75, 65, 4, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 18, 74, 93, 99, 70, 76,
+ 19, 9, 74, 67, 88, 70, 84, 80, 98, 85, 84, 89, 95, 20, 64, 7, 84, 71, 83,
+ 79, 103, 4, 66, 65, 75, 16, 68, 65, 80, 83, 72, 74, 70, 7, 8, 65, 12, 15,
+ 77, 64, 66, 67, 4, 74, 17, 68, 1, 17, 20, 27, 21, 14, 83, 66, 71, 4, 5,
+ 93, 1, 8, 5, 4, 7, 7, 13, 8, 2, 2, 0, 2, 10, 8, 81, 67, 1, 72,
+ 6, 8, 14, 7, 4, 8, 5, 4, 8, 14, 6, 77, 3, 78, 24, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 7, 13, 2, 81,
+ 1, 75, 2, 10, 83, 31, 40, 32, 31, 31, 30, 27, 27, 22, 13, 10, 7, 6, 1,
+ 87, 68, 64, 76, 17, 13, 10, 12, 8, 2, 2, 2, 74, 68, 73, 93, 87, 99, 70,
+ 21, 18, 11, 2, 6, 66, 71, 74, 85, 68, 36, 21, 15, 8, 10, 64, 71, 76, 89,
+ 4, 37, 28, 24, 18, 14, 5, 64, 71, 80, 70, 38, 27, 14, 3, 7, 69, 78, 86,
+ 5, 50, 39, 31, 23, 21, 5, 67, 73, 77, 62, 93, 90, 77, 93, 92, 84, 88, 85,
+ 85, 86, 85, 86, 86, 83, 86, 84, 72, 81, 76, 76, 75, 69, 67, 67, 66, 1, 65,
+ 67, 71, 12, 10, 13, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, 70, 67, 6,
+ 76, 9, 23, 8, 7, 15, 15, 14, 10, 14, 12, 18, 0, 67, 69, 38, 38, 43, 34,
+ 33, 42, 46, 46, 50, 47, 54, 53, 45, 37, 13, 42, 55, 41, 41, 39, 34, 24, 19,
+ 16, 6, 68, 70, 78, 90, 36, 35, 36, 30, 21, 23, 17, 11, 9, 6, 1, 70, 70,
+ 81, 85, 68, 69, 82, 18, 20, 14, 4, 12, 11, 0, 7, 6, 65, 76, 75, 83, 97,
+ 11, 1, 73, 75, 64, 64, 2, 5, 5, 9, 6, 9, 11, 21, 12, 13, 20, 20, 56,
+ 46, 39, 31, 24, 15, 5, 72, 95, 3, 35, 28, 26, 20, 19, 9, 6, 5, 68, 80,
+ 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, 5, 11, 4, 2, 55, 44, 31, 19, 10,
+ 66, 78, 89, 104, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, 53, 14, 78, 1, 64,
+ 10, 0, 2, 68, 68, 83, 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0, 79, 76,
+ 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, 77, 88, 4, 68, 69,
+ 74, 64, 4, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 18, 73, 92, 97, 68, 74,
+ 21, 11, 72, 66, 86, 68, 82, 79, 96, 84, 83, 88, 94, 21, 0, 8, 83, 70, 82,
+ 78, 101, 4, 66, 65, 75, 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, 15,
+ 76, 64, 65, 67, 4, 73, 17, 68, 1, 17, 19, 27, 21, 14, 82, 65, 70, 4, 5,
+ 92, 1, 8, 5, 5, 7, 7, 14, 9, 3, 2, 1, 2, 10, 8, 81, 67, 1, 72,
+ 6, 7, 14, 7, 4, 9, 6, 4, 7, 14, 6, 76, 3, 78, 24, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 7, 13, 2, 80,
+ 1, 74, 2, 9, 82, 30, 39, 31, 30, 29, 28, 26, 26, 20, 12, 9, 6, 4, 0,
+ 88, 68, 64, 76, 16, 12, 9, 11, 7, 1, 1, 1, 74, 68, 73, 92, 86, 98, 69,
+ 22, 18, 11, 3, 7, 65, 70, 73, 83, 67, 36, 21, 15, 8, 11, 0, 70, 75, 87,
+ 4, 38, 29, 24, 18, 15, 5, 64, 70, 79, 70, 39, 27, 14, 3, 8, 68, 77, 85,
+ 5, 50, 39, 31, 23, 21, 5, 66, 72, 76, 62, 92, 89, 76, 91, 90, 83, 86, 83,
+ 83, 84, 83, 84, 85, 82, 85, 83, 70, 80, 76, 75, 74, 68, 67, 67, 66, 1, 65,
+ 68, 72, 12, 10, 14, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, 70, 66, 7,
+ 76, 9, 23, 8, 7, 15, 15, 15, 10, 13, 12, 18, 0, 67, 70, 38, 38, 43, 33,
+ 32, 41, 44, 44, 48, 45, 52, 51, 43, 35, 12, 40, 52, 38, 37, 37, 32, 23, 18,
+ 15, 6, 67, 69, 76, 87, 35, 34, 35, 29, 19, 22, 16, 9, 8, 5, 0, 71, 71,
+ 82, 85, 68, 69, 83, 17, 19, 13, 3, 11, 10, 64, 6, 5, 66, 77, 76, 84, 97,
+ 11, 1, 73, 74, 0, 0, 3, 6, 6, 11, 7, 10, 12, 23, 14, 14, 22, 22, 56,
+ 45, 37, 29, 22, 13, 2, 74, 97, 4, 36, 29, 27, 21, 20, 10, 7, 6, 67, 79,
+ 74, 66, 73, 2, 10, 69, 72, 2, 6, 4, 6, 12, 4, 2, 54, 42, 29, 17, 7,
+ 69, 81, 92, 106, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, 53, 14, 76, 1, 0,
+ 11, 0, 1, 68, 69, 84, 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0, 79, 75,
+ 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, 77, 88, 4, 68, 69,
+ 74, 64, 4, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 18, 73, 92, 95, 66, 72,
+ 22, 13, 71, 65, 85, 67, 81, 78, 94, 84, 83, 88, 93, 21, 0, 8, 82, 70, 81,
+ 78, 100, 4, 66, 65, 75, 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, 15,
+ 76, 64, 65, 67, 4, 73, 16, 68, 1, 16, 18, 26, 20, 13, 81, 65, 70, 3, 4,
+ 92, 0, 8, 5, 5, 7, 7, 15, 9, 3, 2, 1, 2, 9, 8, 82, 67, 1, 73,
+ 6, 6, 14, 7, 3, 9, 6, 4, 6, 14, 5, 76, 3, 79, 23, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, 6, 0, 3, 5, 2, 6, 12, 1, 80,
+ 1, 74, 1, 8, 82, 28, 37, 29, 28, 27, 26, 24, 24, 18, 10, 7, 4, 2, 65,
+ 89, 68, 64, 77, 15, 11, 8, 10, 5, 0, 0, 0, 75, 69, 74, 92, 86, 97, 69,
+ 22, 18, 11, 3, 7, 65, 70, 73, 82, 66, 36, 21, 15, 8, 11, 0, 69, 74, 85,
+ 4, 38, 29, 24, 18, 15, 5, 64, 70, 78, 70, 39, 27, 14, 3, 8, 68, 77, 84,
+ 5, 49, 38, 30, 22, 21, 5, 66, 72, 76, 62, 91, 88, 75, 90, 89, 82, 85, 82,
+ 82, 83, 82, 82, 84, 81, 85, 82, 69, 80, 77, 75, 73, 68, 67, 68, 66, 0, 66,
+ 69, 73, 11, 10, 14, 7, 2, 12, 10, 6, 8, 8, 7, 5, 0, 67, 70, 66, 7,
+ 76, 8, 22, 7, 7, 14, 14, 15, 9, 12, 12, 18, 64, 68, 72, 37, 37, 42, 32,
+ 31, 40, 42, 42, 46, 43, 49, 48, 40, 33, 11, 37, 49, 35, 33, 34, 30, 21, 17,
+ 14, 6, 66, 69, 75, 85, 33, 32, 33, 27, 17, 20, 14, 7, 7, 3, 64, 73, 72,
+ 83, 86, 69, 69, 84, 16, 18, 11, 1, 9, 8, 65, 4, 3, 67, 78, 77, 85, 98,
+ 10, 0, 74, 74, 0, 0, 4, 6, 7, 12, 8, 11, 13, 24, 15, 15, 23, 23, 55,
+ 43, 35, 27, 19, 10, 64, 77, 99, 4, 36, 29, 27, 21, 21, 10, 7, 6, 67, 79,
+ 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6, 13, 4, 2, 53, 40, 27, 14, 4,
+ 73, 85, 95, 109, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, 53, 14, 74, 1, 1,
+ 12, 0, 0, 68, 70, 85, 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0, 78, 74,
+ 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, 77, 88, 5, 68, 69,
+ 74, 0, 4, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 18, 73, 92, 93, 64, 71,
+ 24, 15, 70, 64, 83, 66, 80, 77, 92, 83, 83, 87, 92, 21, 0, 8, 82, 70, 81,
+ 77, 98, 4, 67, 66, 76, 17, 68, 64, 78, 82, 70, 73, 68, 7, 8, 64, 12, 14,
+ 76, 64, 65, 67, 4, 73, 15, 68, 1, 15, 17, 25, 19, 12, 81, 64, 70, 2, 4,
+ 91, 0, 8, 5, 5, 7, 7, 16, 9, 3, 2, 2, 2, 8, 8, 83, 67, 1, 73,
+ 5, 5, 14, 7, 2, 9, 6, 4, 4, 14, 4, 76, 3, 79, 22, 21, 16, 14, 17,
+ 17, 10, 16, 20, 64, 10, 9, 6, 3, 67, 5, 64, 2, 4, 1, 5, 11, 1, 80,
+ 0, 74, 0, 6, 82, 27, 35, 27, 26, 25, 24, 22, 22, 16, 8, 6, 3, 0, 67,
+ 90, 68, 64, 77, 14, 10, 7, 8, 4, 65, 64, 64, 76, 69, 74, 92, 86, 97, 68,
+ 22, 18, 11, 3, 7, 65, 70, 72, 81, 66, 36, 21, 15, 8, 12, 1, 68, 73, 83,
+ 4, 38, 29, 24, 18, 16, 5, 64, 70, 78, 70, 39, 27, 13, 3, 8, 68, 77, 83,
+ 5, 49, 38, 29, 21, 21, 5, 66, 71, 75, 62, 90, 87, 75, 89, 88, 81, 83, 81,
+ 81, 82, 80, 81, 84, 80, 85, 82, 67, 80, 77, 75, 73, 68, 68, 68, 66, 64, 67,
+ 70, 74, 11, 9, 14, 6, 2, 12, 9, 6, 7, 8, 6, 5, 64, 67, 71, 66, 7,
+ 77, 8, 22, 6, 7, 13, 14, 15, 8, 11, 11, 17, 65, 68, 73, 36, 36, 42, 31,
+ 30, 38, 40, 40, 44, 40, 47, 46, 37, 30, 10, 34, 46, 32, 29, 31, 27, 19, 16,
+ 13, 6, 65, 69, 74, 83, 31, 30, 31, 25, 15, 18, 13, 5, 5, 2, 65, 74, 74,
+ 84, 87, 69, 70, 85, 15, 16, 10, 64, 7, 6, 67, 3, 1, 69, 79, 79, 87, 99,
+ 9, 64, 75, 74, 1, 0, 4, 7, 7, 13, 9, 12, 14, 25, 16, 16, 25, 24, 55,
+ 42, 33, 24, 17, 7, 67, 80, 101, 5, 37, 30, 28, 21, 22, 11, 7, 7, 66, 79,
+ 73, 65, 72, 4, 12, 69, 71, 3, 7, 4, 7, 14, 4, 2, 52, 38, 24, 11, 1,
+ 77, 89, 99, 111, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, 53, 14, 71, 0, 2,
+ 12, 0, 64, 68, 71, 86, 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, 73,
+ 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, 77, 88, 5, 67, 69,
+ 73, 0, 4, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 18, 73, 92, 92, 0, 69,
+ 25, 16, 69, 0, 82, 64, 79, 76, 90, 83, 82, 87, 91, 21, 0, 8, 81, 70, 80,
+ 77, 97, 3, 67, 66, 76, 17, 68, 64, 78, 82, 70, 73, 68, 7, 7, 64, 12, 14,
+ 76, 64, 65, 67, 4, 73, 15, 69, 1, 15, 16, 24, 18, 11, 80, 64, 70, 1, 3,
+ 91, 64, 8, 4, 5, 7, 7, 17, 10, 3, 1, 2, 1, 7, 7, 84, 67, 1, 74,
+ 5, 4, 13, 6, 2, 10, 6, 4, 3, 13, 3, 76, 3, 80, 22, 21, 16, 14, 17,
+ 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, 64, 2, 4, 1, 5, 10, 0, 80,
+ 0, 74, 64, 5, 82, 25, 33, 25, 24, 23, 22, 20, 20, 14, 6, 4, 1, 66, 69,
+ 91, 68, 65, 78, 13, 9, 6, 7, 2, 66, 65, 66, 76, 70, 75, 92, 86, 96, 68,
+ 22, 18, 11, 3, 7, 65, 70, 72, 80, 65, 36, 21, 15, 8, 12, 1, 68, 73, 81,
+ 4, 38, 29, 24, 18, 16, 5, 64, 70, 77, 70, 39, 26, 13, 3, 8, 68, 77, 83,
+ 5, 48, 37, 28, 20, 21, 5, 66, 71, 75, 62, 89, 86, 74, 87, 87, 80, 82, 79,
+ 80, 80, 79, 79, 83, 80, 84, 81, 66, 79, 78, 75, 72, 68, 68, 69, 67, 65, 68,
+ 71, 75, 10, 9, 14, 6, 1, 11, 9, 6, 6, 7, 6, 4, 65, 68, 71, 66, 7,
+ 77, 7, 21, 5, 7, 12, 13, 15, 7, 10, 11, 17, 66, 69, 75, 35, 36, 41, 30,
+ 28, 37, 38, 38, 42, 38, 44, 43, 34, 28, 8, 31, 42, 29, 25, 29, 25, 17, 15,
+ 11, 6, 64, 68, 73, 81, 30, 28, 29, 24, 13, 16, 11, 3, 4, 0, 67, 76, 75,
+ 85, 88, 70, 70, 86, 13, 15, 8, 65, 5, 4, 68, 1, 64, 70, 80, 80, 88, 99,
+ 8, 64, 76, 74, 1, 1, 5, 7, 8, 14, 9, 13, 15, 26, 17, 17, 26, 25, 54,
+ 40, 31, 22, 14, 4, 70, 83, 104, 5, 37, 30, 28, 22, 22, 11, 8, 7, 66, 78,
+ 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7, 15, 4, 2, 50, 36, 22, 8, 65,
+ 81, 93, 102, 114, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, 53, 14, 69, 0,
+ 3, 13, 0, 64, 67, 72, 87, 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0,
+ 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, 77, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 18, 72,
+ 92, 90, 2, 68, 27, 18, 67, 1, 81, 0, 78, 75, 88, 82, 82, 86, 90, 21,
+ 0, 8, 81, 70, 80, 76, 95, 3, 67, 66, 76, 17, 68, 0, 77, 82, 70, 73,
+ 67, 7, 7, 64, 12, 14, 75, 64, 64, 67, 4, 73, 14, 69, 1, 14, 15, 24,
+ 17, 10, 79, 0, 70, 0, 3, 90, 64, 8, 4, 5, 7, 7, 18, 10, 3, 1,
+ 2, 1, 6, 7, 85, 67, 1, 74, 4, 3, 13, 6, 1, 10, 6, 4, 2, 13,
+ 2, 76, 3, 80, 21, 21, 16, 14, 17, 17, 10, 16, 19, 64, 10, 9, 6, 3,
+ 68, 5, 64, 1, 4, 1, 4, 9, 0, 80, 64, 74, 65, 4, 82, 24, 31, 24,
+ 23, 21, 20, 18, 18, 12, 4, 2, 64, 68, 70, 92, 68, 65, 78, 12, 8, 5,
+ 6, 1, 68, 66, 67, 77, 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 64,
+ 69, 71, 79, 65, 36, 21, 15, 8, 12, 2, 67, 72, 79, 4, 38, 29, 24, 18,
+ 16, 5, 64, 70, 76, 70, 40, 26, 12, 3, 8, 68, 77, 82, 5, 48, 36, 27,
+ 19, 21, 5, 66, 71, 74, 62, 88, 85, 73, 86, 86, 79, 81, 78, 79, 79, 77,
+ 77, 82, 79, 84, 81, 65, 79, 78, 74, 71, 68, 69, 69, 67, 65, 69, 72, 76,
+ 9, 8, 14, 5, 1, 11, 9, 6, 5, 6, 6, 4, 66, 68, 71, 66, 7, 77,
+ 6, 21, 5, 7, 11, 12, 15, 6, 9, 10, 16, 67, 70, 77, 34, 35, 41, 29,
+ 27, 35, 36, 36, 40, 35, 41, 41, 31, 26, 7, 28, 39, 26, 21, 26, 22, 15,
+ 14, 10, 6, 0, 68, 72, 79, 28, 27, 27, 22, 11, 14, 10, 1, 3, 65, 68,
+ 78, 77, 86, 89, 70, 70, 87, 12, 13, 6, 67, 4, 3, 70, 0, 65, 72, 81,
+ 81, 89, 100, 8, 65, 77, 73, 2, 1, 5, 8, 9, 15, 10, 14, 16, 28, 18,
+ 18, 27, 27, 54, 38, 29, 19, 12, 1, 73, 86, 106, 5, 38, 31, 29, 22, 23,
+ 11, 8, 8, 65, 78, 73, 0, 71, 6, 14, 68, 69, 4, 8, 4, 8, 16, 4,
+ 2, 49, 34, 19, 5, 68, 84, 97, 106, 117, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, 53, 14, 67, 0,
+ 3, 14, 0, 65, 67, 73, 88, 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0,
+ 77, 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, 76, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 18, 72,
+ 91, 88, 4, 66, 28, 20, 66, 2, 79, 1, 77, 75, 87, 82, 82, 86, 90, 22,
+ 0, 8, 80, 69, 79, 76, 94, 3, 68, 67, 77, 17, 68, 0, 77, 82, 69, 73,
+ 67, 7, 7, 0, 12, 13, 75, 64, 64, 67, 4, 73, 13, 69, 1, 13, 14, 23,
+ 17, 10, 79, 0, 70, 0, 2, 90, 65, 8, 4, 5, 7, 7, 18, 10, 3, 1,
+ 3, 1, 5, 7, 85, 68, 1, 75, 4, 2, 13, 6, 0, 10, 6, 4, 0, 13,
+ 1, 76, 3, 81, 20, 21, 15, 14, 17, 17, 10, 16, 19, 64, 9, 9, 5, 3,
+ 68, 4, 65, 1, 3, 0, 3, 8, 64, 80, 64, 73, 66, 2, 82, 22, 29, 22,
+ 21, 19, 18, 16, 16, 10, 2, 1, 65, 70, 72, 93, 68, 65, 79, 11, 7, 4,
+ 4, 64, 69, 67, 68, 78, 71, 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64,
+ 69, 71, 78, 64, 35, 21, 15, 8, 13, 2, 66, 71, 77, 4, 39, 29, 24, 18,
+ 17, 5, 64, 69, 76, 70, 40, 26, 12, 3, 8, 67, 76, 81, 5, 47, 36, 26,
+ 19, 21, 5, 65, 70, 74, 62, 88, 84, 73, 85, 85, 78, 79, 77, 78, 78, 76,
+ 76, 82, 78, 84, 80, 0, 79, 79, 74, 71, 68, 69, 70, 67, 66, 70, 73, 77,
+ 9, 8, 14, 5, 0, 10, 8, 6, 5, 6, 5, 4, 66, 68, 72, 66, 7, 78,
+ 6, 20, 4, 6, 10, 12, 16, 6, 8, 10, 16, 67, 70, 78, 33, 34, 40, 28,
+ 26, 34, 34, 34, 38, 33, 39, 38, 28, 23, 6, 26, 36, 23, 17, 23, 20, 13,
+ 13, 9, 6, 1, 68, 70, 76, 26, 25, 25, 20, 9, 12, 8, 64, 1, 66, 69,
+ 79, 78, 87, 90, 71, 71, 88, 11, 12, 5, 69, 2, 1, 71, 65, 67, 73, 83,
+ 83, 91, 101, 7, 66, 78, 73, 2, 1, 6, 8, 9, 17, 11, 15, 17, 29, 20,
+ 19, 29, 28, 53, 37, 27, 17, 9, 64, 76, 88, 108, 6, 38, 31, 29, 22, 24,
+ 12, 8, 8, 65, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8, 17, 4,
+ 2, 48, 32, 17, 2, 72, 88, 100, 109, 119, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, 53, 14, 64, 64,
+ 4, 14, 0, 66, 67, 74, 89, 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0,
+ 77, 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 18, 72,
+ 91, 87, 6, 65, 30, 22, 65, 3, 78, 3, 76, 74, 85, 81, 81, 85, 89, 22,
+ 0, 8, 80, 69, 79, 75, 92, 2, 68, 67, 77, 17, 68, 0, 76, 82, 69, 73,
+ 66, 7, 6, 0, 12, 13, 75, 64, 64, 67, 4, 73, 13, 69, 1, 13, 13, 22,
+ 16, 9, 78, 1, 70, 64, 2, 89, 65, 8, 3, 5, 7, 7, 19, 11, 3, 1,
+ 3, 1, 4, 7, 86, 68, 1, 75, 3, 1, 12, 6, 0, 11, 6, 4, 64, 12,
+ 0, 76, 3, 81, 20, 21, 15, 14, 17, 17, 10, 16, 19, 64, 9, 9, 5, 3,
+ 68, 4, 65, 0, 3, 0, 3, 7, 64, 80, 65, 73, 67, 1, 82, 21, 27, 20,
+ 19, 17, 16, 14, 14, 8, 0, 64, 67, 73, 74, 94, 68, 66, 79, 10, 6, 3,
+ 3, 65, 71, 68, 69, 78, 71, 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64,
+ 69, 70, 77, 64, 35, 21, 15, 8, 13, 3, 65, 71, 75, 4, 39, 29, 24, 18,
+ 17, 5, 64, 69, 75, 70, 40, 25, 11, 3, 8, 67, 76, 81, 5, 47, 35, 25,
+ 18, 21, 5, 65, 70, 73, 62, 87, 83, 72, 83, 84, 77, 78, 75, 77, 76, 74,
+ 74, 81, 77, 83, 80, 1, 78, 79, 74, 70, 68, 70, 70, 68, 67, 71, 74, 78,
+ 8, 7, 14, 4, 0, 10, 8, 6, 4, 5, 5, 3, 67, 68, 72, 66, 7, 78,
+ 5, 20, 3, 6, 9, 11, 16, 5, 7, 9, 15, 68, 71, 80, 32, 34, 40, 27,
+ 24, 32, 32, 32, 36, 30, 36, 36, 25, 21, 4, 23, 32, 20, 13, 21, 17, 11,
+ 12, 8, 6, 2, 67, 69, 74, 25, 23, 23, 19, 7, 10, 7, 66, 0, 68, 71,
+ 81, 80, 88, 91, 71, 71, 89, 9, 10, 3, 70, 0, 64, 73, 66, 69, 75, 84,
+ 84, 92, 101, 6, 66, 79, 73, 3, 2, 6, 9, 10, 18, 12, 16, 18, 30, 21,
+ 20, 30, 29, 53, 35, 25, 14, 7, 67, 79, 91, 110, 6, 39, 32, 30, 23, 25,
+ 12, 9, 9, 64, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9, 18, 4,
+ 2, 46, 30, 14, 64, 75, 92, 104, 113, 122, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, 53, 14, 1, 64,
+ 5, 15, 0, 67, 67, 75, 91, 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0,
+ 77, 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 18, 72,
+ 91, 85, 7, 0, 31, 23, 64, 4, 77, 4, 75, 73, 83, 81, 81, 85, 88, 22,
+ 0, 8, 79, 69, 78, 75, 91, 2, 69, 68, 78, 17, 68, 0, 76, 82, 69, 73,
+ 66, 6, 6, 0, 12, 12, 75, 64, 64, 67, 3, 73, 12, 70, 1, 12, 11, 21,
+ 15, 8, 78, 1, 70, 65, 1, 89, 66, 7, 3, 5, 7, 7, 20, 11, 3, 0,
+ 3, 0, 3, 6, 87, 68, 1, 76, 3, 0, 12, 5, 64, 11, 6, 4, 66, 12,
+ 64, 76, 3, 82, 19, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 0, 2, 64, 2, 6, 65, 80, 65, 73, 68, 64, 82, 19, 25, 18,
+ 17, 15, 13, 12, 12, 6, 65, 66, 69, 75, 76, 95, 68, 66, 80, 9, 4, 1,
+ 1, 67, 72, 70, 71, 79, 72, 77, 92, 86, 94, 67, 22, 18, 11, 4, 7, 64,
+ 69, 70, 76, 0, 35, 21, 15, 8, 13, 3, 65, 70, 74, 4, 39, 29, 24, 17,
+ 17, 5, 64, 69, 75, 70, 40, 25, 11, 3, 8, 67, 76, 80, 5, 46, 34, 24,
+ 17, 20, 5, 65, 70, 73, 62, 86, 82, 72, 82, 83, 77, 77, 74, 76, 75, 73,
+ 73, 81, 77, 83, 79, 2, 78, 80, 74, 70, 68, 70, 71, 68, 68, 72, 76, 79,
+ 7, 7, 14, 4, 64, 9, 7, 5, 3, 4, 4, 3, 68, 69, 73, 66, 7, 79,
+ 4, 19, 2, 6, 8, 10, 16, 4, 6, 9, 15, 69, 72, 82, 31, 33, 39, 25,
+ 23, 31, 30, 30, 33, 28, 33, 33, 22, 18, 3, 20, 29, 17, 9, 18, 15, 9,
+ 10, 6, 6, 2, 67, 68, 72, 23, 21, 21, 17, 4, 8, 5, 68, 65, 70, 72,
+ 83, 81, 89, 92, 72, 72, 90, 8, 9, 1, 72, 65, 66, 74, 68, 71, 76, 85,
+ 86, 94, 102, 5, 67, 80, 73, 3, 2, 7, 9, 10, 19, 12, 17, 19, 31, 22,
+ 21, 31, 30, 52, 33, 23, 12, 4, 70, 82, 94, 113, 6, 39, 32, 30, 23, 25,
+ 12, 9, 9, 64, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, 18, 4,
+ 1, 45, 28, 12, 67, 78, 96, 108, 116, 125, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, 53, 14, 3, 64,
+ 6, 16, 0, 67, 66, 76, 92, 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0,
+ 76, 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, 76, 88,
+ 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 18, 71,
+ 91, 83, 9, 2, 32, 25, 1, 5, 75, 5, 73, 72, 81, 81, 81, 85, 87, 22,
+ 0, 8, 78, 69, 77, 74, 90, 2, 69, 68, 78, 17, 68, 1, 75, 81, 68, 73,
+ 66, 6, 6, 0, 12, 12, 74, 64, 0, 67, 3, 72, 11, 70, 1, 11, 10, 21,
+ 14, 7, 77, 1, 69, 66, 0, 89, 67, 7, 3, 6, 7, 7, 21, 11, 3, 0,
+ 4, 0, 3, 6, 88, 68, 1, 77, 3, 64, 12, 5, 65, 11, 6, 4, 67, 12,
+ 64, 76, 3, 83, 18, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 0, 2, 64, 1, 6, 65, 80, 65, 73, 69, 65, 82, 17, 24, 17,
+ 16, 13, 11, 11, 11, 4, 67, 67, 70, 77, 77, 96, 68, 66, 81, 8, 3, 0,
+ 0, 68, 73, 71, 72, 80, 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0,
+ 68, 69, 75, 1, 35, 21, 15, 8, 14, 3, 64, 69, 72, 4, 39, 29, 24, 17,
+ 18, 5, 64, 69, 74, 70, 41, 25, 11, 3, 9, 67, 76, 79, 5, 46, 34, 24,
+ 16, 20, 5, 65, 69, 72, 62, 85, 81, 71, 81, 81, 76, 75, 73, 74, 74, 72,
+ 71, 80, 76, 83, 78, 4, 78, 81, 73, 69, 68, 70, 72, 68, 68, 73, 77, 80,
+ 7, 7, 14, 4, 64, 8, 7, 5, 2, 4, 4, 3, 69, 69, 73, 65, 8, 79,
+ 4, 18, 2, 6, 8, 10, 16, 3, 5, 9, 15, 70, 72, 83, 31, 32, 38, 24,
+ 22, 30, 28, 28, 31, 26, 31, 30, 20, 16, 2, 17, 26, 14, 5, 15, 13, 8,
+ 9, 5, 6, 3, 67, 67, 70, 21, 20, 19, 15, 2, 7, 4, 70, 66, 71, 73,
+ 84, 82, 90, 92, 72, 72, 91, 7, 8, 0, 74, 66, 67, 75, 69, 72, 77, 86,
+ 87, 95, 103, 5, 68, 80, 72, 3, 2, 8, 10, 11, 20, 13, 18, 20, 33, 23,
+ 22, 33, 32, 51, 32, 21, 10, 1, 73, 85, 97, 115, 7, 39, 32, 31, 23, 26,
+ 13, 9, 10, 0, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, 10, 19, 4,
+ 1, 44, 26, 10, 69, 81, 99, 112, 119, 126, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, 53, 14, 6, 65,
+ 7, 16, 0, 68, 66, 77, 93, 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0,
+ 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, 76, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 71,
+ 91, 82, 11, 3, 34, 27, 2, 6, 74, 7, 72, 71, 79, 80, 80, 84, 86, 22,
+ 0, 8, 78, 69, 77, 74, 88, 1, 69, 68, 78, 17, 68, 1, 75, 81, 68, 73,
+ 65, 6, 5, 0, 12, 12, 74, 64, 0, 67, 3, 72, 11, 70, 1, 11, 9, 20,
+ 13, 6, 76, 2, 69, 67, 0, 88, 67, 7, 2, 6, 7, 7, 22, 12, 3, 0,
+ 4, 0, 2, 6, 89, 68, 1, 77, 2, 65, 11, 5, 65, 12, 6, 4, 68, 11,
+ 65, 76, 3, 83, 18, 20, 15, 14, 17, 16, 9, 16, 18, 65, 8, 9, 5, 2,
+ 69, 3, 66, 64, 2, 64, 1, 5, 66, 80, 66, 73, 70, 66, 82, 16, 22, 15,
+ 14, 11, 9, 9, 9, 2, 69, 69, 72, 80, 79, 97, 68, 67, 81, 7, 2, 64,
+ 64, 70, 75, 72, 73, 80, 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0,
+ 68, 69, 74, 1, 35, 21, 15, 8, 14, 4, 0, 69, 70, 4, 39, 29, 24, 17,
+ 18, 5, 64, 69, 73, 70, 41, 24, 10, 3, 9, 67, 76, 79, 5, 45, 33, 23,
+ 15, 20, 5, 65, 69, 72, 62, 84, 80, 70, 79, 80, 75, 74, 71, 73, 72, 70,
+ 69, 79, 75, 82, 78, 5, 77, 81, 73, 68, 68, 71, 72, 69, 69, 74, 78, 81,
+ 6, 6, 14, 3, 65, 8, 7, 5, 1, 3, 4, 2, 70, 69, 73, 65, 8, 79,
+ 3, 18, 1, 6, 7, 9, 16, 2, 4, 8, 14, 71, 73, 85, 30, 32, 38, 23,
+ 20, 28, 26, 26, 29, 23, 28, 28, 17, 14, 0, 14, 22, 11, 1, 13, 10, 6,
+ 8, 4, 6, 4, 66, 66, 68, 20, 18, 17, 14, 0, 5, 2, 72, 67, 73, 75,
+ 86, 84, 91, 93, 73, 72, 92, 5, 6, 65, 75, 68, 69, 77, 71, 74, 79, 87,
+ 88, 96, 103, 4, 68, 81, 72, 4, 3, 8, 10, 12, 21, 14, 19, 21, 34, 24,
+ 23, 34, 33, 51, 30, 19, 7, 64, 76, 88, 100, 117, 7, 40, 33, 31, 24, 27,
+ 13, 10, 10, 0, 76, 71, 3, 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4,
+ 1, 42, 24, 7, 72, 84, 103, 116, 123, 126, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, 53, 14, 8, 65,
+ 7, 17, 0, 69, 66, 78, 94, 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0,
+ 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, 75, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 71,
+ 90, 80, 13, 5, 35, 29, 3, 7, 72, 8, 71, 71, 78, 80, 80, 84, 86, 23,
+ 0, 8, 77, 68, 76, 73, 87, 1, 70, 69, 79, 17, 68, 1, 74, 81, 67, 73,
+ 65, 6, 5, 1, 12, 11, 74, 64, 0, 67, 3, 72, 10, 70, 1, 10, 8, 19,
+ 13, 6, 76, 2, 69, 67, 64, 88, 68, 7, 2, 6, 7, 7, 22, 12, 3, 0,
+ 5, 0, 1, 6, 89, 69, 1, 78, 2, 66, 11, 5, 66, 12, 6, 4, 70, 11,
+ 66, 76, 3, 84, 17, 20, 14, 14, 17, 16, 9, 16, 18, 65, 7, 9, 4, 2,
+ 69, 2, 67, 64, 1, 65, 0, 4, 66, 80, 66, 72, 71, 68, 82, 14, 20, 13,
+ 12, 9, 7, 7, 7, 0, 71, 70, 73, 82, 81, 98, 68, 67, 82, 6, 1, 65,
+ 66, 71, 76, 73, 74, 81, 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0,
+ 68, 68, 73, 2, 34, 21, 15, 8, 15, 4, 1, 68, 68, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 73, 70, 41, 24, 10, 3, 9, 66, 75, 78, 5, 45, 33, 22,
+ 15, 20, 5, 64, 68, 71, 62, 84, 79, 70, 78, 79, 74, 72, 70, 72, 71, 69,
+ 68, 79, 74, 82, 77, 7, 77, 82, 73, 68, 68, 71, 73, 69, 70, 75, 79, 82,
+ 6, 6, 14, 3, 65, 7, 6, 5, 1, 3, 3, 2, 70, 69, 74, 65, 8, 80,
+ 3, 17, 0, 5, 6, 9, 17, 2, 3, 8, 14, 71, 73, 86, 29, 31, 37, 22,
+ 19, 27, 24, 24, 27, 21, 26, 25, 14, 11, 64, 12, 19, 8, 66, 10, 8, 4,
+ 7, 3, 6, 5, 66, 64, 65, 18, 16, 15, 12, 65, 3, 1, 74, 69, 74, 76,
+ 87, 85, 92, 94, 73, 73, 93, 4, 5, 66, 77, 70, 71, 78, 72, 76, 80, 89,
+ 90, 98, 104, 3, 69, 82, 72, 4, 3, 9, 11, 12, 23, 15, 20, 22, 35, 26,
+ 24, 36, 34, 50, 29, 17, 5, 67, 78, 91, 102, 119, 8, 40, 33, 32, 24, 28,
+ 14, 10, 11, 1, 76, 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4,
+ 1, 41, 22, 5, 75, 88, 107, 119, 126, 126, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, 53, 14, 10, 65,
+ 8, 18, 0, 70, 66, 79, 95, 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0,
+ 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, 75, 88,
+ 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 18, 71,
+ 90, 78, 14, 6, 37, 30, 4, 8, 71, 9, 70, 70, 76, 79, 80, 83, 85, 23,
+ 0, 8, 77, 68, 76, 73, 85, 1, 70, 69, 79, 17, 68, 1, 74, 81, 67, 73,
+ 64, 6, 5, 1, 12, 11, 74, 64, 0, 67, 3, 72, 9, 71, 1, 9, 7, 18,
+ 12, 5, 75, 3, 69, 68, 64, 87, 68, 7, 2, 6, 7, 7, 23, 12, 3, 64,
+ 5, 64, 0, 5, 90, 69, 1, 78, 1, 67, 11, 4, 67, 12, 6, 4, 71, 11,
+ 67, 76, 3, 84, 16, 20, 14, 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2,
+ 70, 2, 67, 65, 1, 65, 64, 3, 67, 80, 67, 72, 72, 69, 82, 13, 18, 11,
+ 10, 7, 5, 5, 5, 65, 73, 72, 75, 84, 83, 99, 68, 67, 82, 5, 0, 66,
+ 67, 73, 78, 74, 76, 82, 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0,
+ 68, 68, 72, 2, 34, 21, 15, 8, 15, 5, 1, 67, 66, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 72, 70, 41, 24, 9, 3, 9, 66, 75, 77, 5, 44, 32, 21,
+ 14, 20, 5, 64, 68, 71, 62, 83, 78, 69, 77, 78, 73, 71, 69, 71, 70, 67,
+ 66, 78, 74, 82, 77, 8, 77, 82, 73, 67, 68, 72, 73, 69, 71, 76, 80, 83,
+ 5, 5, 14, 2, 66, 7, 6, 5, 0, 2, 3, 2, 71, 70, 74, 65, 8, 80,
+ 2, 17, 64, 5, 5, 8, 17, 1, 2, 7, 13, 72, 74, 88, 28, 30, 37, 21,
+ 18, 25, 22, 22, 25, 18, 23, 23, 11, 9, 65, 9, 16, 5, 70, 7, 5, 2,
+ 6, 1, 6, 6, 66, 0, 0, 16, 14, 13, 10, 67, 1, 64, 76, 70, 76, 77,
+ 89, 87, 93, 95, 74, 73, 94, 3, 3, 68, 79, 72, 73, 80, 74, 78, 82, 90,
+ 91, 99, 105, 2, 70, 83, 72, 5, 3, 9, 11, 13, 24, 15, 21, 23, 36, 27,
+ 25, 37, 35, 50, 27, 15, 2, 69, 81, 94, 105, 122, 8, 41, 34, 32, 24, 28,
+ 14, 10, 11, 1, 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11, 22, 4,
+ 1, 40, 20, 2, 78, 91, 111, 123, 126, 126, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, 53, 14, 13, 66,
+ 9, 18, 0, 70, 65, 80, 96, 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0,
+ 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 18, 70,
+ 90, 77, 16, 8, 38, 32, 6, 9, 70, 11, 69, 69, 74, 79, 79, 83, 84, 23,
+ 0, 8, 76, 68, 75, 72, 84, 0, 70, 69, 79, 17, 68, 2, 73, 81, 67, 73,
+ 64, 6, 4, 1, 12, 11, 73, 64, 1, 67, 3, 72, 9, 71, 1, 9, 6, 18,
+ 11, 4, 74, 3, 69, 69, 65, 87, 69, 7, 1, 6, 7, 7, 24, 13, 3, 64,
+ 5, 64, 64, 5, 91, 69, 1, 79, 1, 68, 10, 4, 67, 13, 6, 4, 72, 10,
+ 68, 76, 3, 85, 16, 20, 14, 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2,
+ 70, 2, 67, 65, 1, 65, 64, 2, 67, 80, 67, 72, 73, 70, 82, 11, 16, 10,
+ 9, 5, 3, 3, 3, 67, 75, 74, 77, 87, 84, 100, 68, 68, 83, 4, 64, 67,
+ 68, 74, 79, 75, 77, 82, 75, 80, 92, 85, 91, 65, 23, 18, 11, 5, 8, 1,
+ 67, 67, 71, 3, 34, 21, 15, 8, 15, 5, 2, 67, 64, 4, 40, 29, 24, 17,
+ 19, 5, 64, 68, 71, 70, 42, 23, 9, 3, 9, 66, 75, 77, 5, 44, 31, 20,
+ 13, 20, 5, 64, 68, 70, 62, 82, 77, 68, 75, 77, 72, 70, 67, 70, 68, 66,
+ 64, 77, 73, 81, 76, 9, 76, 83, 72, 66, 68, 72, 74, 70, 71, 77, 81, 84,
+ 4, 5, 14, 2, 66, 6, 6, 5, 64, 1, 3, 1, 72, 70, 74, 65, 8, 80,
+ 1, 16, 64, 5, 4, 7, 17, 0, 1, 7, 13, 73, 75, 90, 27, 30, 36, 20,
+ 16, 24, 20, 20, 23, 16, 20, 20, 8, 7, 67, 6, 12, 2, 74, 5, 3, 0,
+ 5, 0, 6, 7, 65, 1, 2, 15, 13, 11, 9, 69, 64, 65, 78, 71, 78, 79,
+ 91, 88, 94, 96, 74, 73, 95, 1, 2, 70, 80, 73, 74, 81, 75, 79, 83, 91,
+ 92, 100, 105, 2, 70, 84, 71, 5, 4, 10, 12, 14, 25, 16, 22, 24, 38, 28,
+ 26, 38, 37, 49, 25, 13, 0, 72, 84, 97, 108, 124, 8, 41, 34, 33, 25, 29,
+ 14, 11, 12, 2, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, 12, 23, 4,
+ 1, 38, 18, 0, 81, 94, 114, 126, 126, 126, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, 53, 14, 15, 66,
+ 10, 19, 0, 71, 65, 81, 97, 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0,
+ 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 18, 70,
+ 90, 75, 18, 9, 40, 34, 7, 10, 68, 12, 68, 68, 72, 78, 79, 82, 83, 23,
+ 0, 8, 76, 68, 75, 72, 82, 0, 71, 70, 80, 17, 68, 2, 73, 81, 66, 73,
+ 0, 6, 4, 1, 12, 10, 73, 64, 1, 67, 3, 72, 8, 71, 1, 8, 5, 17,
+ 10, 3, 74, 4, 69, 70, 65, 86, 69, 7, 1, 6, 7, 7, 25, 13, 3, 64,
+ 6, 64, 65, 5, 92, 69, 1, 79, 0, 69, 10, 4, 68, 13, 6, 4, 74, 10,
+ 69, 76, 3, 85, 15, 20, 14, 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2,
+ 70, 1, 68, 66, 0, 66, 65, 1, 68, 80, 68, 72, 74, 72, 82, 10, 14, 8,
+ 7, 3, 1, 1, 1, 69, 77, 75, 78, 89, 86, 101, 68, 68, 83, 3, 65, 68,
+ 70, 76, 81, 76, 78, 83, 75, 80, 92, 85, 91, 64, 23, 18, 11, 5, 8, 1,
+ 67, 67, 70, 3, 34, 21, 15, 8, 16, 6, 3, 66, 1, 4, 40, 29, 24, 17,
+ 20, 5, 64, 68, 71, 70, 42, 23, 8, 3, 9, 66, 75, 76, 5, 43, 31, 19,
+ 12, 20, 5, 64, 67, 70, 62, 81, 76, 68, 74, 76, 71, 68, 66, 69, 67, 64,
+ 0, 77, 72, 81, 76, 11, 76, 83, 72, 66, 68, 73, 74, 70, 72, 78, 82, 85,
+ 4, 4, 14, 1, 67, 6, 5, 5, 65, 1, 2, 1, 73, 70, 75, 65, 8, 81,
+ 1, 16, 65, 5, 3, 7, 17, 64, 0, 6, 12, 74, 75, 91, 26, 29, 36, 19,
+ 15, 22, 18, 18, 21, 13, 18, 18, 5, 4, 68, 3, 9, 64, 78, 2, 0, 65,
+ 4, 64, 6, 8, 65, 2, 4, 13, 11, 9, 7, 71, 66, 67, 80, 73, 79, 80,
+ 92, 90, 95, 97, 75, 74, 96, 0, 0, 71, 82, 75, 76, 83, 77, 81, 85, 92,
+ 94, 102, 106, 1, 71, 85, 71, 6, 4, 10, 12, 14, 26, 17, 23, 25, 39, 29,
+ 27, 40, 38, 49, 24, 11, 66, 74, 87, 100, 111, 126, 9, 42, 35, 33, 25, 30,
+ 15, 11, 12, 2, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, 4, 12, 24, 4,
+ 1, 37, 16, 66, 84, 97, 118, 126, 126, 126, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, 53, 14, 17, 66,
+ 11, 20, 0, 72, 65, 82, 98, 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0,
+ 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 18, 70,
+ 90, 73, 20, 11, 41, 36, 8, 11, 67, 13, 67, 67, 70, 78, 79, 82, 82, 23,
+ 0, 8, 75, 68, 74, 71, 81, 0, 71, 70, 80, 17, 68, 2, 72, 81, 66, 73,
+ 0, 6, 4, 1, 12, 10, 73, 64, 1, 67, 3, 72, 7, 71, 1, 7, 4, 16,
+ 9, 2, 73, 4, 69, 71, 66, 86, 70, 7, 1, 6, 7, 7, 26, 13, 3, 64,
+ 6, 64, 66, 5, 93, 69, 1, 80, 0, 70, 10, 4, 69, 13, 6, 4, 75, 10,
+ 70, 76, 3, 86, 14, 20, 14, 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2,
+ 70, 1, 68, 66, 0, 66, 66, 0, 68, 80, 68, 72, 75, 73, 82, 8, 12, 6,
+ 5, 1, 64, 64, 64, 71, 79, 77, 80, 91, 88, 102, 68, 68, 84, 2, 66, 69,
+ 71, 77, 82, 77, 79, 84, 76, 81, 92, 85, 90, 64, 23, 18, 11, 5, 8, 1,
+ 67, 66, 69, 4, 34, 21, 15, 8, 16, 6, 4, 65, 3, 4, 40, 29, 24, 17,
+ 20, 5, 64, 68, 70, 70, 42, 23, 8, 3, 9, 66, 75, 75, 5, 43, 30, 18,
+ 11, 20, 5, 64, 67, 69, 62, 80, 75, 67, 73, 75, 70, 67, 65, 68, 66, 0,
+ 2, 76, 71, 81, 75, 12, 76, 84, 72, 65, 68, 73, 75, 70, 73, 79, 83, 86,
+ 3, 4, 14, 1, 67, 5, 5, 5, 66, 0, 2, 1, 74, 70, 75, 65, 8, 81,
+ 0, 15, 66, 5, 2, 6, 17, 65, 64, 6, 12, 75, 76, 93, 25, 28, 35, 18,
+ 14, 21, 16, 16, 19, 11, 15, 15, 2, 2, 69, 0, 6, 67, 82, 64, 65, 67,
+ 3, 65, 6, 9, 65, 3, 6, 11, 9, 7, 5, 73, 68, 68, 82, 74, 81, 81,
+ 94, 91, 96, 98, 75, 74, 97, 64, 64, 73, 84, 77, 78, 84, 78, 83, 86, 93,
+ 95, 103, 107, 0, 72, 86, 71, 6, 4, 11, 13, 15, 27, 18, 24, 26, 40, 30,
+ 28, 41, 39, 48, 22, 9, 68, 77, 90, 103, 114, 126, 9, 42, 35, 34, 25, 31,
+ 15, 11, 13, 3, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, 4, 13, 25, 4,
+ 1, 36, 14, 68, 87, 100, 122, 126, 126, 126, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, 52, 14, 19, 67,
+ 11, 20, 64, 73, 65, 84, 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, 64,
+ 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, 77, 75, 88,
+ 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 18, 70,
+ 90, 72, 21, 12, 42, 37, 9, 12, 66, 14, 66, 67, 69, 78, 79, 82, 82, 23,
+ 0, 8, 75, 68, 74, 71, 80, 64, 72, 71, 81, 17, 68, 2, 72, 81, 66, 73,
+ 0, 5, 3, 1, 11, 9, 73, 65, 1, 67, 2, 72, 6, 72, 0, 6, 2, 15,
+ 8, 1, 73, 4, 69, 72, 67, 86, 71, 6, 0, 6, 7, 7, 26, 13, 3, 65,
+ 6, 65, 67, 4, 94, 70, 0, 81, 64, 71, 9, 3, 70, 13, 6, 4, 77, 9,
+ 71, 76, 3, 87, 13, 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1,
+ 71, 0, 69, 67, 64, 67, 67, 64, 69, 80, 69, 72, 76, 75, 82, 6, 10, 4,
+ 3, 64, 67, 66, 66, 73, 81, 79, 82, 94, 90, 104, 69, 69, 85, 1, 68, 71,
+ 73, 79, 84, 79, 81, 85, 77, 82, 92, 85, 90, 64, 23, 18, 11, 5, 8, 1,
+ 67, 66, 68, 4, 33, 21, 15, 8, 16, 6, 4, 65, 4, 3, 40, 29, 23, 16,
+ 20, 5, 64, 68, 70, 70, 42, 22, 7, 2, 9, 66, 75, 75, 5, 42, 29, 17,
+ 10, 19, 5, 64, 67, 69, 62, 80, 74, 67, 72, 74, 70, 66, 64, 67, 65, 1,
+ 3, 76, 71, 81, 75, 13, 76, 85, 72, 65, 68, 74, 76, 71, 74, 80, 85, 88,
+ 2, 3, 14, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, 71, 76, 65, 8, 82,
+ 64, 14, 67, 4, 1, 5, 17, 66, 66, 5, 11, 76, 77, 95, 24, 27, 34, 16,
+ 12, 19, 14, 14, 16, 8, 12, 12, 64, 64, 71, 66, 2, 70, 87, 67, 68, 69,
+ 1, 67, 6, 9, 65, 4, 8, 9, 7, 5, 3, 76, 70, 70, 85, 76, 83, 83,
+ 96, 93, 97, 99, 76, 75, 99, 66, 66, 75, 86, 79, 80, 86, 80, 85, 88, 95,
+ 97, 105, 108, 64, 73, 87, 71, 6, 4, 11, 13, 15, 28, 18, 25, 26, 41, 31,
+ 29, 42, 40, 47, 20, 6, 71, 80, 93, 107, 117, 126, 9, 42, 35, 34, 25, 31,
+ 15, 11, 13, 3, 75, 69, 6, 67, 17, 26, 66, 0, 10, 14, 4, 13, 25, 4,
+ 0, 34, 11, 71, 90, 104, 126, 126, 126, 126, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, 52, 14, 22, 67,
+ 12, 21, 64, 73, 64, 85, 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, 64,
+ 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 18, 69,
+ 89, 70, 23, 14, 44, 39, 11, 13, 64, 16, 64, 66, 67, 77, 78, 81, 81, 24,
+ 1, 9, 74, 67, 73, 70, 78, 64, 72, 71, 81, 18, 68, 3, 71, 80, 65, 72,
+ 1, 5, 3, 2, 11, 9, 72, 65, 2, 67, 2, 71, 6, 72, 0, 6, 1, 15,
+ 8, 1, 72, 5, 68, 72, 67, 85, 71, 6, 0, 7, 7, 7, 27, 14, 4, 65,
+ 7, 65, 67, 4, 94, 70, 0, 81, 64, 72, 9, 3, 70, 14, 7, 4, 78, 9,
+ 71, 75, 3, 87, 13, 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1,
+ 71, 0, 69, 67, 64, 67, 67, 64, 69, 79, 69, 71, 76, 76, 81, 5, 9, 3,
+ 2, 66, 69, 67, 67, 75, 82, 80, 83, 96, 91, 105, 69, 69, 85, 0, 69, 72,
+ 74, 80, 85, 80, 82, 85, 77, 82, 91, 84, 89, 0, 24, 18, 11, 6, 9, 2,
+ 66, 65, 66, 5, 33, 21, 15, 8, 17, 7, 5, 64, 6, 3, 41, 30, 23, 16,
+ 21, 5, 64, 67, 69, 70, 43, 22, 7, 2, 10, 65, 74, 74, 5, 42, 29, 17,
+ 10, 19, 5, 0, 66, 68, 62, 79, 73, 66, 70, 72, 69, 64, 1, 65, 0, 3,
+ 5, 75, 70, 80, 74, 15, 75, 85, 71, 64, 67, 74, 76, 71, 74, 80, 86, 89,
+ 2, 3, 15, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, 71, 76, 64, 9, 82,
+ 64, 14, 67, 4, 1, 5, 18, 66, 67, 5, 11, 76, 77, 96, 24, 27, 34, 15,
+ 11, 18, 12, 12, 14, 6, 10, 10, 66, 66, 72, 68, 64, 73, 91, 69, 70, 70,
+ 0, 68, 6, 10, 64, 6, 11, 8, 6, 4, 2, 78, 71, 71, 87, 77, 84, 84,
+ 97, 94, 98, 99, 76, 75, 100, 67, 67, 76, 87, 80, 81, 87, 81, 86, 89, 96,
+ 98, 106, 108, 64, 73, 87, 70, 7, 5, 12, 14, 16, 30, 19, 26, 27, 43, 33,
+ 30, 44, 42, 47, 19, 4, 73, 82, 95, 110, 119, 126, 10, 43, 36, 35, 26, 32,
+ 16, 12, 14, 4, 74, 68, 7, 66, 19, 28, 65, 1, 11, 15, 5, 14, 26, 4,
+ 0, 33, 9, 73, 92, 107, 126, 126, 126, 126, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, 52, 14, 24,
+ 67, 13, 22, 64, 74, 64, 86, 102, 1, 2, 122, 124, 123, 34, 2, 69, 13,
+ 22, 64, 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, 64,
+ 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 18, 69, 89, 68, 25, 16, 45, 41, 12, 14, 0, 17, 0, 65, 65,
+ 77, 78, 81, 80, 24, 1, 9, 73, 67, 72, 70, 77, 64, 72, 71, 81, 18,
+ 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, 9, 72, 65, 2, 67, 2,
+ 71, 5, 72, 0, 5, 0, 14, 7, 0, 71, 5, 68, 73, 68, 85, 72, 6,
+ 0, 7, 7, 7, 28, 14, 4, 65, 7, 65, 68, 4, 95, 70, 0, 82, 64,
+ 73, 9, 3, 71, 14, 7, 4, 79, 9, 72, 75, 3, 88, 12, 19, 13, 14,
+ 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, 71, 0, 69, 67, 64, 67, 68,
+ 65, 70, 79, 69, 71, 77, 77, 81, 3, 7, 1, 0, 68, 71, 69, 69, 77,
+ 84, 82, 85, 98, 93, 106, 69, 69, 86, 64, 70, 73, 75, 82, 86, 81, 83,
+ 86, 78, 83, 91, 84, 88, 0, 24, 18, 11, 6, 9, 2, 66, 65, 65, 6,
+ 33, 21, 15, 8, 17, 7, 6, 0, 8, 3, 41, 30, 23, 16, 21, 5, 64,
+ 67, 68, 70, 43, 22, 7, 2, 10, 65, 74, 73, 5, 41, 28, 16, 9, 19,
+ 5, 0, 66, 68, 62, 78, 72, 65, 69, 71, 68, 0, 2, 64, 1, 4, 7,
+ 74, 69, 80, 73, 16, 75, 86, 71, 0, 67, 74, 77, 71, 75, 81, 87, 90,
+ 1, 3, 15, 0, 69, 3, 4, 4, 68, 65, 1, 0, 76, 71, 76, 64, 9,
+ 82, 65, 13, 68, 4, 0, 4, 18, 67, 68, 5, 11, 77, 78, 98, 23, 26,
+ 33, 14, 10, 17, 10, 10, 12, 4, 7, 7, 69, 68, 73, 71, 67, 76, 95,
+ 72, 72, 72, 64, 69, 6, 11, 64, 7, 13, 6, 4, 2, 0, 80, 73, 73,
+ 89, 78, 86, 85, 99, 95, 99, 100, 77, 75, 101, 68, 68, 78, 89, 82, 83,
+ 88, 83, 88, 90, 97, 99, 107, 109, 65, 74, 88, 70, 7, 5, 13, 14, 17,
+ 31, 20, 27, 28, 44, 34, 31, 45, 43, 46, 17, 2, 75, 85, 98, 113, 122,
+ 126, 10, 43, 36, 35, 26, 33, 16, 12, 14, 4, 74, 68, 8, 66, 20, 29,
+ 65, 2, 12, 16, 5, 14, 27, 4, 0, 32, 7, 75, 95, 110, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, 18, 52, 14, 26,
+ 67, 14, 23, 64, 75, 64, 87, 103, 1, 0, 123, 125, 123, 37, 3, 69, 14,
+ 23, 64, 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, 64,
+ 77, 74, 88, 12, 0, 65, 69, 7, 3, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 18, 69, 89, 66, 27, 17, 47, 43, 13, 15, 2, 18, 1, 64, 0,
+ 76, 78, 80, 79, 24, 1, 9, 73, 67, 72, 69, 75, 64, 73, 72, 82, 18,
+ 68, 3, 70, 80, 64, 72, 2, 5, 3, 2, 11, 8, 72, 65, 2, 67, 2,
+ 71, 4, 72, 0, 4, 64, 13, 6, 64, 71, 6, 68, 74, 68, 84, 72, 6,
+ 0, 7, 7, 7, 29, 14, 4, 65, 8, 65, 69, 4, 96, 70, 0, 82, 65,
+ 74, 9, 3, 72, 14, 7, 4, 81, 9, 73, 75, 3, 88, 11, 19, 13, 14,
+ 17, 15, 8, 16, 16, 66, 4, 9, 3, 1, 71, 64, 70, 68, 65, 68, 69,
+ 66, 70, 79, 70, 71, 78, 79, 81, 2, 5, 64, 65, 70, 73, 71, 71, 79,
+ 86, 83, 86, 100, 95, 107, 69, 69, 86, 65, 71, 74, 77, 83, 88, 82, 84,
+ 87, 78, 83, 91, 84, 88, 1, 24, 18, 11, 6, 9, 2, 66, 64, 64, 6,
+ 33, 21, 15, 8, 18, 8, 7, 1, 10, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 68, 70, 43, 22, 6, 2, 10, 65, 74, 72, 5, 41, 28, 15, 8, 19,
+ 5, 0, 65, 67, 62, 77, 71, 65, 68, 70, 67, 2, 3, 0, 2, 6, 8,
+ 74, 68, 80, 73, 18, 75, 86, 71, 0, 67, 75, 77, 71, 76, 82, 88, 91,
+ 1, 2, 15, 64, 69, 3, 3, 4, 69, 65, 0, 0, 77, 71, 77, 64, 9,
+ 83, 65, 13, 69, 4, 64, 4, 18, 68, 69, 4, 10, 78, 78, 99, 22, 25,
+ 33, 13, 9, 15, 8, 8, 10, 1, 5, 5, 72, 71, 74, 74, 70, 79, 99,
+ 75, 75, 74, 65, 70, 6, 12, 64, 8, 15, 4, 2, 0, 65, 82, 75, 74,
+ 91, 80, 87, 86, 100, 97, 100, 101, 77, 76, 102, 69, 70, 79, 91, 84, 85,
+ 90, 84, 90, 92, 98, 101, 109, 110, 66, 75, 89, 70, 8, 5, 13, 15, 17,
+ 32, 21, 28, 29, 45, 35, 32, 47, 44, 46, 16, 0, 78, 87, 101, 116, 125,
+ 126, 11, 44, 37, 36, 26, 34, 17, 12, 15, 5, 74, 67, 8, 65, 21, 30,
+ 65, 2, 12, 16, 5, 15, 28, 4, 0, 31, 5, 78, 98, 113, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, 16, 52, 14, 29,
+ 68, 15, 23, 64, 76, 64, 88, 104, 0, 65, 125, 126, 124, 40, 4, 69, 15,
+ 23, 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5, 69, 71, 65,
+ 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 18, 69, 89, 65, 28, 19, 48, 44, 14, 16, 3, 20, 2, 0, 2,
+ 76, 77, 80, 78, 24, 1, 9, 72, 67, 71, 69, 74, 65, 73, 72, 82, 18,
+ 68, 3, 70, 80, 64, 72, 2, 5, 2, 2, 11, 8, 72, 65, 2, 67, 2,
+ 71, 4, 73, 0, 4, 65, 12, 5, 65, 70, 6, 68, 75, 69, 84, 73, 6,
+ 64, 7, 7, 7, 30, 15, 4, 66, 8, 66, 70, 3, 97, 70, 0, 83, 65,
+ 75, 8, 2, 72, 15, 7, 4, 82, 8, 74, 75, 3, 89, 11, 19, 13, 14,
+ 17, 15, 8, 16, 15, 66, 4, 9, 3, 1, 72, 64, 70, 68, 65, 68, 69,
+ 67, 71, 79, 70, 71, 79, 80, 81, 0, 3, 66, 67, 72, 75, 73, 73, 81,
+ 88, 85, 88, 103, 97, 108, 69, 70, 87, 66, 72, 75, 78, 85, 89, 83, 86,
+ 87, 79, 84, 91, 84, 87, 1, 24, 18, 11, 6, 9, 2, 66, 64, 0, 7,
+ 33, 21, 15, 8, 18, 8, 7, 1, 12, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 67, 70, 43, 21, 6, 2, 10, 65, 74, 72, 5, 40, 27, 14, 7, 19,
+ 5, 0, 65, 67, 62, 76, 70, 64, 66, 69, 66, 3, 5, 1, 4, 7, 10,
+ 73, 68, 79, 72, 19, 74, 87, 71, 1, 67, 75, 78, 72, 77, 83, 89, 92,
+ 0, 2, 15, 64, 70, 2, 3, 4, 70, 66, 0, 64, 78, 72, 77, 64, 9,
+ 83, 66, 12, 70, 4, 65, 3, 18, 69, 70, 4, 10, 79, 79, 101, 21, 25,
+ 32, 12, 7, 14, 6, 6, 8, 64, 2, 2, 75, 73, 76, 77, 74, 82, 103,
+ 77, 77, 76, 66, 72, 6, 13, 0, 9, 17, 3, 0, 65, 66, 84, 77, 76,
+ 93, 81, 89, 88, 102, 98, 101, 102, 78, 76, 103, 71, 71, 81, 92, 86, 87,
+ 91, 86, 92, 93, 99, 102, 110, 110, 67, 75, 90, 70, 8, 6, 14, 15, 18,
+ 33, 21, 29, 30, 46, 36, 33, 48, 45, 45, 14, 65, 80, 90, 104, 119, 126,
+ 126, 11, 44, 37, 36, 27, 34, 17, 13, 15, 5, 73, 67, 9, 65, 22, 31,
+ 65, 3, 13, 17, 5, 15, 29, 4, 0, 29, 3, 80, 101, 116, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, 52, 14, 31,
+ 68, 16, 24, 64, 76, 0, 89, 105, 0, 67, 126, 126, 124, 43, 6, 69, 16,
+ 24, 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, 5, 69, 70, 65,
+ 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0, 1, 95, 97, 8,
+ 71, 68, 18, 68, 89, 0, 30, 20, 50, 46, 16, 17, 4, 21, 3, 1, 4,
+ 75, 77, 79, 77, 24, 1, 9, 72, 67, 71, 68, 72, 65, 73, 72, 82, 18,
+ 68, 4, 69, 80, 64, 72, 3, 5, 2, 2, 11, 8, 71, 65, 3, 67, 2,
+ 71, 3, 73, 0, 3, 66, 12, 4, 66, 69, 7, 68, 76, 69, 83, 73, 6,
+ 64, 7, 7, 7, 31, 15, 4, 66, 8, 66, 71, 3, 98, 70, 0, 83, 66,
+ 76, 8, 2, 73, 15, 7, 4, 83, 8, 75, 75, 3, 89, 10, 19, 13, 14,
+ 17, 15, 8, 16, 15, 66, 4, 9, 3, 1, 72, 64, 70, 69, 65, 68, 70,
+ 68, 71, 79, 71, 71, 80, 81, 81, 64, 1, 67, 68, 74, 77, 75, 75, 83,
+ 90, 87, 90, 105, 98, 109, 69, 70, 87, 67, 73, 76, 79, 86, 91, 84, 87,
+ 88, 79, 84, 91, 84, 87, 1, 24, 18, 11, 6, 9, 3, 65, 0, 1, 7,
+ 33, 21, 15, 8, 18, 9, 8, 2, 14, 3, 41, 30, 23, 16, 22, 5, 64,
+ 67, 66, 70, 44, 21, 5, 2, 10, 65, 74, 71, 5, 40, 26, 13, 6, 19,
+ 5, 0, 65, 66, 62, 75, 69, 0, 65, 68, 65, 4, 6, 2, 5, 9, 12,
+ 72, 67, 79, 72, 20, 74, 87, 70, 2, 67, 76, 78, 72, 77, 84, 90, 93,
+ 64, 1, 15, 65, 70, 2, 3, 4, 71, 67, 0, 64, 79, 72, 77, 64, 9,
+ 83, 67, 12, 70, 4, 66, 2, 18, 70, 71, 3, 9, 80, 80, 103, 20, 24,
+ 32, 11, 6, 12, 4, 4, 6, 67, 64, 0, 78, 75, 77, 80, 77, 85, 107,
+ 80, 80, 78, 67, 73, 6, 14, 0, 10, 19, 1, 64, 67, 68, 86, 79, 77,
+ 95, 82, 91, 89, 104, 100, 102, 103, 78, 76, 104, 72, 73, 83, 94, 87, 88,
+ 93, 87, 93, 95, 100, 103, 111, 111, 67, 76, 91, 69, 9, 6, 14, 16, 19,
+ 34, 22, 30, 31, 48, 37, 34, 49, 47, 45, 12, 67, 83, 92, 107, 122, 126,
+ 126, 11, 45, 38, 37, 27, 35, 17, 13, 16, 6, 73, 67, 10, 64, 23, 32,
+ 64, 4, 13, 17, 5, 16, 30, 4, 0, 28, 1, 83, 104, 119, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, 52, 14, 33,
+ 68, 16, 25, 64, 77, 0, 90, 106, 64, 68, 126, 126, 125, 46, 7, 69, 16,
+ 25, 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, 5, 68, 70, 65,
+ 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0, 2, 95, 97, 8,
+ 71, 69, 18, 68, 88, 2, 32, 22, 51, 48, 17, 18, 6, 22, 4, 1, 5,
+ 75, 77, 79, 77, 25, 1, 9, 71, 66, 70, 68, 71, 65, 74, 73, 83, 18,
+ 68, 4, 69, 80, 0, 72, 3, 5, 2, 3, 11, 7, 71, 65, 3, 67, 2,
+ 71, 2, 73, 0, 2, 67, 11, 4, 66, 69, 7, 68, 76, 70, 83, 74, 6,
+ 64, 7, 7, 7, 31, 15, 4, 66, 9, 66, 72, 3, 98, 71, 0, 84, 66,
+ 77, 8, 2, 74, 15, 7, 4, 85, 8, 76, 75, 3, 90, 9, 19, 12, 14,
+ 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, 65, 71, 69, 66, 69, 71,
+ 69, 72, 79, 71, 70, 81, 83, 81, 66, 64, 69, 70, 76, 79, 77, 77, 85,
+ 92, 88, 91, 107, 100, 110, 69, 70, 88, 68, 74, 77, 81, 88, 92, 85, 88,
+ 89, 80, 85, 91, 84, 86, 2, 24, 18, 11, 7, 9, 3, 65, 0, 2, 8,
+ 32, 21, 15, 8, 19, 9, 9, 3, 16, 3, 42, 30, 23, 16, 23, 5, 64,
+ 66, 66, 70, 44, 21, 5, 2, 10, 64, 73, 70, 5, 39, 26, 12, 6, 19,
+ 5, 1, 64, 66, 62, 75, 68, 0, 64, 67, 64, 6, 7, 3, 6, 10, 13,
+ 72, 66, 79, 71, 22, 74, 88, 70, 2, 67, 76, 79, 72, 78, 85, 91, 94,
+ 64, 1, 15, 65, 71, 1, 2, 4, 71, 67, 64, 64, 79, 72, 78, 64, 9,
+ 84, 67, 11, 71, 3, 67, 2, 19, 70, 72, 3, 9, 80, 80, 104, 19, 23,
+ 31, 10, 5, 11, 2, 2, 4, 69, 66, 66, 81, 78, 78, 82, 80, 88, 111,
+ 83, 82, 80, 68, 74, 6, 15, 0, 12, 22, 64, 66, 69, 70, 88, 81, 79,
+ 97, 84, 92, 90, 105, 101, 103, 104, 79, 77, 105, 73, 74, 84, 96, 89, 90,
+ 94, 89, 95, 96, 102, 105, 113, 112, 68, 77, 92, 69, 9, 6, 15, 16, 19,
+ 36, 23, 31, 32, 49, 39, 35, 51, 48, 44, 11, 69, 85, 95, 109, 125, 126,
+ 126, 12, 45, 38, 37, 27, 36, 18, 13, 16, 6, 73, 66, 10, 64, 24, 33,
+ 64, 4, 14, 18, 5, 16, 31, 4, 0, 27, 64, 85, 107, 123, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, 52, 14, 36,
+ 69, 17, 25, 64, 78, 0, 91, 107, 64, 70, 126, 126, 125, 49, 8, 69, 17,
+ 25, 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5, 68, 69, 66,
+ 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0, 2, 95, 97, 9,
+ 72, 69, 18, 68, 88, 3, 34, 23, 53, 50, 18, 19, 7, 24, 5, 2, 7,
+ 74, 76, 78, 76, 25, 1, 9, 71, 66, 70, 67, 69, 66, 74, 73, 83, 18,
+ 68, 4, 68, 80, 0, 72, 4, 5, 1, 3, 11, 7, 71, 65, 3, 67, 2,
+ 71, 2, 73, 0, 2, 68, 10, 3, 67, 68, 8, 68, 77, 70, 82, 74, 6,
+ 65, 7, 7, 7, 32, 16, 4, 66, 9, 66, 73, 3, 99, 71, 0, 84, 67,
+ 78, 7, 2, 74, 16, 7, 4, 86, 7, 77, 75, 3, 90, 9, 19, 12, 14,
+ 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, 65, 71, 70, 66, 69, 71,
+ 70, 72, 79, 72, 70, 82, 84, 81, 67, 66, 71, 72, 78, 81, 79, 79, 87,
+ 94, 90, 93, 110, 102, 111, 69, 71, 88, 69, 75, 78, 82, 89, 94, 86, 89,
+ 89, 80, 85, 91, 84, 86, 2, 24, 18, 11, 7, 9, 3, 65, 1, 3, 8,
+ 32, 21, 15, 8, 19, 10, 10, 3, 18, 3, 42, 30, 23, 16, 23, 5, 64,
+ 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 70, 5, 39, 25, 11, 5, 19,
+ 5, 1, 64, 65, 62, 74, 67, 1, 1, 66, 0, 7, 9, 4, 8, 12, 15,
+ 71, 65, 78, 71, 23, 73, 88, 70, 3, 67, 77, 79, 73, 79, 86, 92, 95,
+ 65, 0, 15, 66, 71, 1, 2, 4, 72, 68, 64, 65, 80, 72, 78, 64, 9,
+ 84, 68, 11, 72, 3, 68, 1, 19, 71, 73, 2, 8, 81, 81, 106, 18, 23,
+ 31, 9, 3, 9, 0, 0, 2, 72, 69, 68, 84, 80, 80, 85, 84, 91, 115,
+ 85, 85, 82, 69, 75, 6, 16, 1, 13, 24, 65, 68, 71, 71, 90, 83, 80,
+ 99, 85, 94, 92, 107, 103, 104, 105, 79, 77, 106, 75, 76, 86, 97, 91, 92,
+ 96, 90, 97, 98, 103, 106, 114, 112, 69, 77, 93, 69, 10, 7, 15, 17, 20,
+ 37, 24, 32, 33, 50, 40, 36, 52, 49, 44, 9, 71, 88, 97, 112, 126, 126,
+ 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, 66, 11, 0, 25, 34,
+ 64, 5, 14, 18, 5, 17, 32, 4, 0, 25, 66, 88, 110, 126, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, 52, 14, 38,
+ 69, 18, 26, 64, 79, 0, 92, 109, 65, 72, 126, 126, 126, 51, 9, 69, 18,
+ 26, 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5, 68, 69, 66,
+ 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0, 3, 96, 97, 9,
+ 73, 69, 18, 68, 88, 5, 35, 25, 54, 51, 19, 20, 8, 25, 6, 3, 9,
+ 74, 76, 78, 75, 25, 1, 9, 70, 66, 69, 67, 68, 66, 75, 74, 84, 18,
+ 68, 4, 68, 80, 0, 72, 4, 4, 1, 3, 11, 6, 71, 65, 3, 67, 1,
+ 71, 1, 74, 0, 1, 70, 9, 2, 68, 68, 8, 68, 78, 71, 82, 75, 5,
+ 65, 7, 7, 7, 33, 16, 4, 67, 9, 67, 74, 2, 100, 71, 0, 85, 67,
+ 79, 7, 1, 75, 16, 7, 4, 88, 7, 78, 75, 3, 91, 8, 18, 12, 14,
+ 17, 14, 7, 16, 14, 67, 2, 9, 2, 0, 73, 66, 72, 70, 67, 70, 72,
+ 71, 73, 79, 72, 70, 83, 86, 81, 69, 68, 73, 74, 80, 84, 81, 81, 89,
+ 96, 92, 95, 112, 104, 112, 69, 71, 89, 70, 77, 80, 84, 91, 95, 88, 91,
+ 90, 81, 86, 91, 84, 85, 2, 24, 18, 11, 7, 9, 3, 65, 1, 4, 9,
+ 32, 21, 15, 8, 19, 10, 10, 4, 19, 3, 42, 30, 23, 15, 23, 5, 64,
+ 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 69, 5, 38, 24, 10, 4, 18,
+ 5, 1, 64, 65, 62, 73, 66, 1, 2, 65, 0, 8, 10, 5, 9, 13, 16,
+ 71, 65, 78, 70, 24, 73, 89, 70, 3, 67, 77, 80, 73, 80, 87, 94, 96,
+ 66, 0, 15, 66, 72, 0, 1, 3, 73, 69, 65, 65, 81, 73, 79, 64, 9,
+ 85, 69, 10, 73, 3, 69, 0, 19, 72, 74, 2, 8, 82, 82, 108, 17, 22,
+ 30, 7, 2, 8, 65, 65, 64, 74, 72, 71, 87, 83, 81, 88, 87, 94, 119,
+ 88, 87, 84, 71, 77, 6, 16, 1, 14, 26, 67, 70, 73, 73, 93, 85, 82,
+ 101, 87, 96, 93, 109, 104, 105, 106, 80, 78, 107, 76, 77, 88, 99, 93, 94,
+ 97, 92, 99, 99, 104, 108, 116, 113, 70, 78, 94, 69, 10, 7, 16, 17, 20,
+ 38, 24, 33, 34, 51, 41, 37, 53, 50, 43, 7, 73, 90, 100, 115, 126, 126,
+ 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, 66, 11, 0, 26, 35,
+ 64, 5, 15, 19, 5, 17, 32, 4, 64, 24, 68, 90, 113, 126, 126, 126, 126,
+ 126, 75, 70, 64, 11, 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, 52, 14,
+ 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, 74, 126, 126, 126, 54, 11,
+ 69, 19, 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5,
+ 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 18, 67, 88, 7, 37, 27, 55, 53, 21, 21,
+ 10, 26, 8, 4, 11, 74, 76, 78, 74, 25, 1, 9, 69, 66, 68, 66,
+ 67, 66, 75, 74, 84, 18, 68, 5, 67, 79, 1, 72, 4, 4, 1, 3,
+ 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 71, 9, 1, 69,
+ 67, 8, 67, 79, 72, 82, 76, 5, 65, 8, 7, 7, 34, 16, 4, 67,
+ 10, 67, 74, 2, 101, 71, 0, 86, 67, 80, 7, 1, 76, 16, 7, 4,
+ 89, 7, 78, 75, 3, 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67,
+ 2, 9, 2, 0, 73, 66, 72, 70, 67, 70, 73, 71, 73, 79, 72, 70,
+ 84, 87, 81, 71, 69, 74, 75, 82, 86, 82, 82, 91, 98, 93, 96, 114,
+ 105, 113, 69, 71, 90, 71, 78, 81, 85, 92, 96, 89, 92, 91, 82, 87,
+ 91, 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 5, 10, 32, 21,
+ 15, 8, 20, 10, 11, 5, 21, 3, 42, 30, 23, 15, 24, 5, 64, 66,
+ 64, 70, 45, 20, 4, 2, 11, 64, 73, 68, 5, 38, 24, 10, 3, 18,
+ 5, 1, 0, 64, 62, 72, 65, 2, 3, 0, 1, 10, 11, 7, 10, 14,
+ 18, 70, 64, 78, 69, 26, 73, 90, 69, 4, 67, 77, 81, 73, 80, 88,
+ 95, 97, 66, 0, 15, 66, 72, 64, 1, 3, 74, 69, 65, 65, 82, 73,
+ 79, 0, 10, 85, 69, 9, 73, 3, 69, 0, 19, 73, 75, 2, 8, 83,
+ 82, 109, 17, 21, 29, 6, 1, 7, 67, 67, 66, 76, 74, 74, 89, 85,
+ 82, 91, 90, 97, 123, 91, 89, 85, 72, 78, 6, 17, 1, 15, 28, 69,
+ 71, 75, 75, 95, 86, 83, 103, 88, 97, 94, 110, 105, 106, 106, 80, 78,
+ 108, 77, 78, 89, 101, 94, 95, 98, 93, 100, 100, 105, 109, 117, 114, 70,
+ 79, 94, 68, 10, 7, 17, 18, 21, 39, 25, 34, 35, 53, 42, 38, 55,
+ 52, 42, 6, 75, 92, 103, 118, 126, 126, 126, 13, 46, 39, 39, 28, 38,
+ 19, 14, 18, 8, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, 5, 18,
+ 33, 4, 64, 23, 70, 92, 115, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, 52, 14,
+ 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, 76, 126, 126, 126, 57, 12,
+ 69, 20, 27, 64, 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5,
+ 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 18, 67, 88, 8, 39, 28, 57, 55, 22, 22,
+ 11, 28, 9, 5, 13, 73, 75, 77, 73, 25, 1, 9, 69, 66, 68, 66,
+ 65, 67, 75, 74, 84, 18, 68, 5, 67, 79, 1, 72, 5, 4, 0, 3,
+ 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 72, 8, 0, 70,
+ 66, 9, 67, 80, 72, 81, 76, 5, 66, 8, 7, 7, 35, 17, 4, 67,
+ 10, 67, 75, 2, 102, 71, 0, 86, 68, 81, 6, 1, 76, 17, 7, 4,
+ 90, 6, 79, 75, 3, 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67,
+ 2, 9, 2, 0, 73, 66, 72, 71, 67, 70, 73, 72, 74, 79, 73, 70,
+ 85, 88, 81, 72, 71, 76, 77, 84, 88, 84, 84, 93, 100, 95, 98, 117,
+ 107, 114, 69, 72, 90, 72, 79, 82, 86, 94, 98, 90, 93, 91, 82, 87,
+ 91, 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 6, 10, 32, 21,
+ 15, 8, 20, 11, 12, 5, 23, 3, 42, 30, 23, 15, 24, 5, 64, 66,
+ 0, 70, 45, 19, 3, 2, 11, 64, 73, 68, 5, 37, 23, 9, 2, 18,
+ 5, 1, 0, 64, 62, 71, 64, 3, 5, 1, 2, 11, 13, 8, 12, 16,
+ 20, 69, 0, 77, 69, 27, 72, 90, 69, 5, 67, 78, 81, 74, 81, 89,
+ 96, 98, 67, 64, 15, 67, 73, 64, 1, 3, 75, 70, 65, 66, 83, 73,
+ 79, 0, 10, 85, 70, 9, 74, 3, 70, 64, 19, 74, 76, 1, 7, 84,
+ 83, 111, 16, 21, 29, 5, 64, 5, 69, 69, 68, 79, 77, 76, 92, 87,
+ 84, 94, 94, 100, 126, 93, 92, 87, 73, 79, 6, 18, 2, 16, 30, 70,
+ 73, 77, 76, 97, 88, 85, 105, 89, 99, 96, 112, 107, 107, 107, 81, 78,
+ 109, 79, 80, 91, 102, 96, 97, 100, 95, 102, 102, 106, 110, 118, 114, 71,
+ 79, 95, 68, 11, 8, 17, 18, 22, 40, 26, 35, 36, 54, 43, 39, 56,
+ 53, 42, 4, 77, 95, 105, 121, 126, 126, 126, 13, 47, 40, 39, 29, 39,
+ 19, 15, 18, 8, 71, 65, 13, 1, 28, 38, 0, 7, 16, 20, 5, 18,
+ 34, 4, 64, 21, 72, 95, 118, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, 52, 14,
+ 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, 77, 126, 126, 126, 60, 13,
+ 69, 20, 28, 64, 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5,
+ 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 18, 67, 87, 10, 41, 30, 58, 57, 23, 23,
+ 13, 29, 10, 5, 14, 73, 75, 77, 73, 26, 1, 9, 68, 65, 67, 65,
+ 64, 67, 76, 75, 85, 18, 68, 5, 66, 79, 2, 72, 5, 4, 0, 4,
+ 11, 5, 70, 65, 4, 67, 1, 70, 64, 74, 0, 64, 73, 7, 0, 70,
+ 66, 9, 67, 80, 73, 81, 77, 5, 66, 8, 7, 7, 35, 17, 4, 67,
+ 11, 67, 76, 2, 102, 72, 0, 87, 68, 82, 6, 1, 77, 17, 7, 4,
+ 92, 6, 80, 75, 3, 93, 6, 18, 11, 14, 17, 14, 7, 16, 14, 67,
+ 1, 9, 1, 0, 73, 67, 73, 71, 68, 71, 74, 73, 74, 79, 73, 69,
+ 86, 90, 81, 74, 73, 78, 79, 86, 90, 86, 86, 95, 102, 96, 99, 119,
+ 109, 115, 69, 72, 91, 73, 80, 83, 88, 95, 99, 91, 94, 92, 83, 88,
+ 91, 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 7, 11, 31, 21,
+ 15, 8, 21, 11, 13, 6, 25, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 0, 70, 45, 19, 3, 2, 11, 0, 72, 67, 5, 37, 23, 8, 2, 18,
+ 5, 2, 1, 0, 62, 71, 0, 3, 6, 2, 3, 13, 14, 9, 13, 17,
+ 21, 69, 1, 77, 68, 29, 72, 91, 69, 5, 67, 78, 82, 74, 82, 90,
+ 97, 99, 67, 64, 15, 67, 73, 65, 0, 3, 75, 70, 66, 66, 83, 73,
+ 80, 0, 10, 86, 70, 8, 75, 2, 71, 64, 20, 74, 77, 1, 7, 84,
+ 83, 112, 15, 20, 28, 4, 65, 4, 71, 71, 70, 81, 79, 79, 95, 90,
+ 85, 96, 97, 103, 126, 96, 94, 89, 74, 80, 6, 19, 2, 18, 33, 72,
+ 75, 79, 78, 99, 90, 86, 107, 91, 100, 97, 113, 108, 108, 108, 81, 79,
+ 110, 80, 81, 92, 104, 98, 99, 101, 96, 104, 103, 108, 112, 120, 115, 72,
+ 80, 96, 68, 11, 8, 18, 19, 22, 42, 27, 36, 37, 55, 45, 40, 58,
+ 54, 41, 3, 79, 97, 108, 123, 126, 126, 126, 14, 47, 40, 40, 29, 40,
+ 20, 15, 19, 9, 71, 64, 13, 1, 29, 39, 0, 7, 17, 21, 5, 19,
+ 35, 4, 64, 20, 74, 97, 121, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, 52, 14,
+ 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, 79, 126, 126, 126, 62, 14,
+ 69, 21, 29, 64, 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5,
+ 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 18, 67, 87, 12, 42, 31, 60, 58, 24, 24,
+ 14, 30, 11, 6, 16, 72, 75, 76, 72, 26, 1, 9, 68, 65, 67, 65,
+ 1, 67, 76, 75, 85, 18, 68, 5, 66, 79, 2, 72, 6, 4, 0, 4,
+ 11, 5, 70, 65, 4, 67, 1, 70, 65, 75, 0, 65, 74, 6, 64, 71,
+ 65, 10, 67, 81, 73, 80, 77, 5, 66, 8, 7, 7, 36, 17, 4, 68,
+ 11, 68, 77, 1, 103, 72, 0, 87, 69, 83, 6, 0, 78, 17, 7, 4,
+ 93, 6, 81, 75, 3, 93, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 1, 9, 1, 0, 74, 67, 73, 72, 68, 71, 75, 74, 75, 79, 74, 69,
+ 87, 91, 81, 75, 75, 80, 81, 88, 92, 88, 88, 97, 104, 98, 101, 121,
+ 111, 116, 69, 72, 91, 74, 81, 84, 89, 97, 101, 92, 96, 93, 83, 88,
+ 91, 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 8, 11, 31, 21,
+ 15, 8, 21, 12, 13, 7, 27, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 1, 70, 45, 19, 2, 2, 11, 0, 72, 66, 5, 36, 22, 7, 1, 18,
+ 5, 2, 1, 0, 62, 70, 1, 4, 7, 3, 4, 14, 15, 10, 14, 19,
+ 23, 68, 1, 77, 68, 30, 72, 91, 69, 6, 67, 79, 82, 74, 83, 91,
+ 98, 100, 68, 65, 15, 68, 74, 65, 0, 3, 76, 71, 66, 66, 84, 74,
+ 80, 0, 10, 86, 71, 8, 76, 2, 72, 65, 20, 75, 78, 0, 6, 85,
+ 84, 114, 14, 19, 28, 3, 66, 2, 73, 73, 72, 84, 82, 81, 98, 92,
+ 86, 99, 100, 106, 126, 99, 97, 91, 75, 82, 6, 20, 2, 19, 35, 74,
+ 77, 81, 80, 101, 92, 88, 109, 92, 102, 98, 115, 110, 109, 109, 82, 79,
+ 111, 81, 83, 94, 106, 100, 101, 103, 98, 106, 105, 109, 113, 121, 116, 73,
+ 81, 97, 68, 12, 8, 18, 19, 23, 43, 27, 37, 38, 56, 46, 41, 59,
+ 55, 41, 1, 81, 100, 110, 126, 126, 126, 126, 14, 48, 41, 40, 29, 40,
+ 20, 15, 19, 9, 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19,
+ 36, 4, 64, 19, 76, 100, 124, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, 52, 14,
+ 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, 81, 126, 126, 126, 62, 16,
+ 69, 22, 29, 64, 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 18, 66, 87, 13, 44, 33, 61, 60, 26, 25,
+ 15, 32, 12, 7, 18, 72, 74, 76, 71, 26, 1, 9, 67, 65, 66, 64,
+ 2, 68, 76, 75, 85, 18, 68, 6, 65, 79, 2, 72, 6, 4, 64, 4,
+ 11, 5, 69, 65, 5, 67, 1, 70, 65, 75, 0, 65, 75, 6, 65, 72,
+ 64, 10, 67, 82, 74, 80, 78, 5, 67, 8, 7, 7, 37, 18, 4, 68,
+ 11, 68, 78, 1, 104, 72, 0, 88, 69, 84, 5, 0, 78, 18, 7, 4,
+ 94, 5, 82, 75, 3, 94, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 1, 9, 1, 0, 74, 67, 73, 72, 68, 71, 75, 75, 75, 79, 74, 69,
+ 88, 92, 81, 77, 77, 81, 82, 90, 94, 90, 90, 99, 106, 100, 103, 124,
+ 112, 117, 69, 73, 92, 75, 82, 85, 90, 98, 102, 93, 97, 93, 84, 89,
+ 91, 83, 82, 4, 25, 18, 11, 8, 10, 5, 0, 4, 9, 12, 31, 21,
+ 15, 8, 21, 12, 14, 7, 29, 3, 43, 30, 23, 15, 25, 5, 64, 65,
+ 2, 70, 46, 18, 2, 2, 11, 0, 72, 66, 5, 36, 21, 6, 0, 18,
+ 5, 2, 1, 1, 62, 69, 2, 5, 9, 4, 5, 15, 17, 11, 16, 20,
+ 25, 67, 2, 76, 67, 31, 71, 92, 68, 7, 67, 79, 83, 75, 83, 92,
+ 99, 101, 69, 65, 15, 68, 74, 66, 0, 3, 77, 72, 66, 67, 85, 74,
+ 80, 0, 10, 86, 72, 7, 76, 2, 73, 66, 20, 76, 79, 0, 6, 86,
+ 85, 116, 13, 19, 27, 2, 68, 1, 75, 75, 74, 86, 85, 84, 101, 94,
+ 88, 102, 104, 109, 126, 101, 99, 93, 76, 83, 6, 21, 3, 20, 37, 75,
+ 78, 83, 81, 103, 94, 89, 111, 93, 104, 100, 117, 111, 110, 110, 82, 79,
+ 112, 83, 84, 96, 107, 101, 102, 104, 99, 107, 106, 110, 114, 122, 116, 73,
+ 81, 98, 67, 12, 9, 19, 20, 24, 44, 28, 38, 39, 58, 47, 42, 60,
+ 57, 40, 64, 83, 102, 113, 126, 126, 126, 126, 14, 48, 41, 41, 30, 41,
+ 20, 16, 20, 10, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20,
+ 37, 4, 64, 17, 78, 102, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, 52, 14,
+ 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, 83, 126, 126, 126, 62, 17,
+ 69, 23, 30, 64, 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 18, 66, 87, 15, 46, 34, 62, 62, 27, 26,
+ 17, 33, 13, 8, 20, 71, 74, 75, 70, 26, 1, 9, 67, 65, 66, 64,
+ 4, 68, 77, 76, 86, 18, 68, 6, 65, 79, 3, 72, 7, 4, 64, 4,
+ 11, 4, 69, 65, 5, 67, 1, 70, 66, 75, 0, 66, 76, 5, 66, 73,
+ 64, 11, 67, 83, 74, 79, 78, 5, 67, 8, 7, 7, 38, 18, 4, 68,
+ 12, 68, 79, 1, 105, 72, 0, 88, 70, 85, 5, 0, 79, 18, 7, 4,
+ 96, 5, 83, 75, 3, 94, 4, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 0, 9, 1, 0, 74, 68, 74, 73, 69, 72, 76, 76, 76, 79, 75, 69,
+ 89, 94, 81, 78, 79, 83, 84, 92, 96, 92, 92, 101, 108, 101, 104, 126,
+ 114, 118, 69, 73, 92, 76, 83, 86, 92, 100, 104, 94, 98, 94, 84, 89,
+ 91, 83, 82, 5, 25, 18, 11, 8, 10, 5, 0, 4, 10, 12, 31, 21,
+ 15, 8, 22, 13, 15, 8, 31, 3, 43, 30, 23, 15, 26, 5, 64, 65,
+ 2, 70, 46, 18, 1, 2, 11, 0, 72, 65, 5, 35, 21, 5, 64, 18,
+ 5, 2, 2, 1, 62, 68, 3, 5, 10, 5, 6, 17, 18, 12, 17, 22,
+ 26, 67, 3, 76, 67, 33, 71, 92, 68, 7, 67, 80, 83, 75, 84, 93,
+ 100, 102, 69, 66, 15, 69, 75, 66, 64, 3, 78, 72, 67, 67, 86, 74,
+ 81, 0, 10, 87, 72, 7, 77, 2, 74, 66, 20, 77, 80, 64, 5, 87,
+ 85, 117, 12, 18, 27, 1, 69, 64, 77, 77, 76, 89, 87, 86, 104, 97,
+ 89, 105, 107, 112, 126, 104, 102, 95, 77, 84, 6, 22, 3, 21, 39, 77,
+ 80, 85, 83, 105, 96, 91, 113, 95, 105, 101, 118, 113, 111, 111, 83, 80,
+ 113, 84, 86, 97, 109, 103, 104, 106, 101, 109, 108, 111, 116, 124, 117, 74,
+ 82, 99, 67, 13, 9, 19, 20, 24, 45, 29, 39, 40, 59, 48, 43, 62,
+ 58, 40, 65, 85, 105, 115, 126, 126, 126, 126, 15, 49, 42, 41, 30, 42,
+ 21, 16, 20, 10, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20,
+ 38, 4, 64, 16, 80, 105, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, 2, 52, 14,
+ 54, 71, 24, 31, 64, 84, 2, 99, 116, 69, 85, 126, 126, 126, 62, 18,
+ 69, 24, 31, 64, 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5,
+ 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 18, 66, 87, 17, 48, 36, 62, 62, 28, 27,
+ 18, 34, 14, 9, 22, 71, 74, 75, 69, 26, 1, 9, 66, 65, 65, 0,
+ 5, 68, 77, 76, 86, 18, 68, 6, 64, 79, 3, 72, 7, 4, 64, 4,
+ 11, 4, 69, 65, 5, 67, 1, 70, 67, 75, 0, 67, 77, 4, 67, 74,
+ 0, 11, 67, 84, 75, 79, 79, 5, 67, 8, 7, 7, 39, 18, 4, 68,
+ 12, 68, 80, 1, 106, 72, 0, 89, 70, 86, 5, 0, 80, 18, 7, 4,
+ 97, 5, 84, 75, 3, 95, 3, 18, 11, 14, 17, 14, 7, 16, 13, 67,
+ 0, 9, 1, 0, 74, 68, 74, 73, 69, 72, 77, 77, 76, 79, 75, 69,
+ 90, 95, 81, 80, 81, 85, 86, 94, 98, 94, 94, 103, 110, 103, 106, 126,
+ 116, 119, 69, 73, 93, 77, 84, 87, 93, 101, 105, 95, 99, 95, 85, 90,
+ 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, 11, 13, 31, 21,
+ 15, 8, 22, 13, 16, 9, 33, 3, 43, 30, 23, 15, 26, 5, 64, 65,
+ 3, 70, 46, 18, 1, 2, 11, 0, 72, 64, 5, 35, 20, 4, 65, 18,
+ 5, 2, 2, 2, 62, 67, 4, 6, 11, 6, 7, 18, 19, 13, 18, 23,
+ 28, 66, 4, 76, 66, 34, 71, 93, 68, 8, 67, 80, 84, 75, 85, 94,
+ 101, 103, 70, 66, 15, 69, 75, 67, 64, 3, 79, 73, 67, 67, 87, 74,
+ 81, 0, 10, 87, 73, 6, 78, 2, 75, 67, 20, 78, 81, 64, 5, 88,
+ 86, 119, 11, 17, 26, 0, 70, 65, 79, 79, 78, 91, 90, 89, 107, 99,
+ 90, 108, 110, 115, 126, 107, 104, 97, 78, 85, 6, 23, 3, 22, 41, 79,
+ 82, 87, 85, 107, 98, 92, 115, 96, 107, 102, 120, 114, 112, 112, 83, 80,
+ 114, 85, 87, 99, 111, 105, 106, 107, 102, 111, 109, 112, 117, 125, 118, 75,
+ 83, 100, 67, 13, 9, 20, 21, 25, 46, 30, 40, 41, 60, 49, 44, 62,
+ 59, 39, 67, 87, 107, 118, 126, 126, 126, 126, 15, 49, 42, 42, 30, 43,
+ 21, 16, 21, 11, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21,
+ 39, 4, 64, 15, 82, 107, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, 0, 51, 14,
+ 56, 72, 24, 31, 65, 85, 2, 101, 118, 70, 87, 126, 126, 126, 62, 19,
+ 70, 24, 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5,
+ 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 18, 66, 87, 18, 49, 37, 62, 62, 29, 28,
+ 19, 35, 15, 9, 23, 71, 74, 75, 69, 26, 1, 9, 66, 65, 65, 0,
+ 6, 69, 78, 77, 87, 18, 68, 6, 64, 79, 3, 72, 7, 3, 65, 4,
+ 10, 3, 69, 66, 5, 67, 0, 70, 68, 76, 64, 68, 79, 3, 68, 75,
+ 0, 11, 67, 85, 76, 79, 80, 4, 68, 8, 7, 7, 39, 18, 4, 69,
+ 12, 69, 81, 0, 107, 73, 64, 90, 71, 87, 4, 64, 81, 18, 7, 4,
+ 99, 4, 85, 75, 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 79, 76, 69,
+ 91, 97, 81, 82, 83, 87, 88, 96, 101, 96, 96, 105, 112, 105, 108, 126,
+ 118, 121, 70, 74, 94, 78, 86, 89, 95, 103, 107, 97, 101, 96, 86, 91,
+ 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, 12, 13, 30, 21,
+ 15, 8, 22, 13, 16, 9, 34, 2, 43, 30, 22, 14, 26, 5, 64, 65,
+ 3, 70, 46, 17, 0, 1, 11, 0, 72, 64, 5, 34, 19, 3, 66, 17,
+ 5, 2, 2, 2, 62, 67, 5, 6, 12, 7, 7, 19, 20, 14, 19, 24,
+ 29, 66, 4, 76, 66, 35, 71, 94, 68, 8, 67, 81, 85, 76, 86, 95,
+ 103, 105, 71, 67, 15, 70, 76, 68, 65, 2, 80, 74, 68, 68, 88, 75,
+ 82, 0, 10, 88, 74, 5, 79, 1, 76, 68, 20, 79, 83, 65, 4, 89,
+ 87, 121, 10, 16, 25, 65, 72, 67, 81, 81, 81, 94, 93, 92, 110, 102,
+ 92, 111, 114, 118, 126, 110, 107, 99, 80, 87, 6, 23, 3, 23, 43, 81,
+ 84, 89, 87, 110, 100, 94, 118, 98, 109, 104, 122, 116, 113, 113, 84, 81,
+ 116, 87, 89, 101, 113, 107, 108, 109, 104, 113, 111, 114, 119, 126, 119, 76,
+ 84, 101, 67, 13, 9, 20, 21, 25, 47, 30, 41, 41, 61, 50, 45, 62,
+ 60, 38, 69, 90, 110, 121, 126, 126, 126, 126, 15, 49, 42, 42, 30, 43,
+ 21, 16, 21, 11, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, 21,
+ 39, 4, 65, 13, 85, 110, 126, 126, 126, 126, 126, 126, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, 64, 51, 14,
+ 59, 72, 25, 32, 65, 85, 3, 102, 119, 70, 88, 126, 126, 126, 62, 21,
+ 70, 25, 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5,
+ 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 18, 65, 86, 20, 51, 39, 62, 62, 31, 29,
+ 21, 37, 17, 10, 25, 70, 73, 74, 68, 27, 2, 10, 65, 64, 64, 1,
+ 8, 69, 78, 77, 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5,
+ 10, 3, 68, 66, 6, 67, 0, 69, 68, 76, 64, 68, 80, 3, 68, 75,
+ 1, 12, 66, 85, 76, 78, 80, 4, 68, 9, 7, 7, 40, 19, 5, 69,
+ 13, 69, 81, 0, 107, 73, 64, 90, 71, 88, 4, 64, 81, 19, 8, 4,
+ 100, 4, 85, 74, 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 78, 76, 68,
+ 91, 98, 80, 83, 84, 88, 89, 98, 103, 97, 97, 107, 113, 106, 109, 126,
+ 119, 122, 70, 74, 94, 79, 87, 90, 96, 104, 108, 98, 102, 96, 86, 91,
+ 90, 82, 80, 6, 26, 18, 11, 9, 11, 6, 1, 6, 14, 14, 30, 21,
+ 15, 8, 23, 14, 17, 10, 36, 2, 44, 31, 22, 14, 27, 5, 64, 64,
+ 4, 70, 47, 17, 0, 1, 12, 1, 71, 0, 5, 34, 19, 3, 66, 17,
+ 5, 3, 3, 3, 62, 66, 6, 7, 14, 9, 8, 21, 22, 16, 21, 26,
+ 31, 65, 5, 75, 65, 37, 70, 94, 67, 9, 66, 81, 85, 76, 86, 95,
+ 104, 106, 71, 67, 16, 70, 76, 68, 65, 2, 80, 74, 68, 68, 88, 75,
+ 82, 1, 11, 88, 74, 5, 79, 1, 76, 68, 21, 79, 84, 65, 4, 89,
+ 87, 122, 10, 16, 25, 66, 73, 68, 83, 83, 83, 96, 95, 94, 112, 104,
+ 93, 113, 117, 121, 126, 112, 109, 100, 81, 88, 6, 24, 4, 25, 46, 82,
+ 85, 90, 88, 112, 101, 95, 120, 99, 110, 105, 123, 117, 114, 113, 84, 81,
+ 117, 88, 90, 102, 114, 108, 109, 110, 105, 114, 112, 115, 120, 126, 119, 76,
+ 84, 101, 66, 14, 10, 21, 22, 26, 49, 31, 42, 42, 62, 52, 46, 62,
+ 62, 38, 70, 92, 112, 123, 126, 126, 126, 126, 16, 50, 43, 43, 31, 44,
+ 22, 17, 22, 12, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, 22,
+ 40, 4, 65, 12, 87, 112, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, 65, 51, 14,
+ 61, 72, 26, 33, 65, 86, 3, 103, 120, 71, 90, 126, 126, 126, 62, 22,
+ 70, 26, 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 18, 65, 86, 22, 53, 41, 62, 62, 32, 30,
+ 22, 38, 18, 11, 27, 70, 73, 74, 67, 27, 2, 10, 64, 64, 0, 1,
+ 9, 69, 78, 77, 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5,
+ 10, 3, 68, 66, 6, 67, 0, 69, 69, 76, 64, 69, 81, 2, 69, 76,
+ 2, 12, 66, 86, 77, 78, 81, 4, 68, 9, 7, 7, 41, 19, 5, 69,
+ 13, 69, 82, 0, 108, 73, 64, 91, 71, 89, 4, 64, 82, 19, 8, 4,
+ 101, 4, 86, 74, 3, 97, 1, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 64, 9, 0, 64, 75, 69, 75, 74, 70, 73, 79, 79, 78, 78, 76, 68,
+ 92, 99, 80, 85, 86, 90, 91, 100, 105, 99, 99, 109, 115, 108, 111, 126,
+ 121, 123, 70, 74, 95, 80, 88, 91, 97, 106, 109, 99, 103, 97, 87, 92,
+ 90, 82, 79, 6, 26, 18, 11, 9, 11, 6, 1, 6, 15, 15, 30, 21,
+ 15, 8, 23, 14, 18, 11, 38, 2, 44, 31, 22, 14, 27, 5, 64, 64,
+ 5, 70, 47, 17, 0, 1, 12, 1, 71, 1, 5, 33, 18, 2, 67, 17,
+ 5, 3, 3, 3, 62, 65, 7, 8, 15, 10, 9, 22, 23, 17, 22, 27,
+ 33, 64, 6, 75, 64, 38, 70, 95, 67, 10, 66, 81, 86, 76, 87, 96,
+ 105, 107, 72, 67, 16, 70, 77, 69, 65, 2, 81, 75, 68, 68, 89, 75,
+ 82, 1, 11, 88, 75, 4, 80, 1, 77, 69, 21, 80, 85, 65, 4, 90,
+ 88, 124, 9, 15, 24, 67, 74, 69, 85, 85, 85, 98, 98, 97, 115, 106,
+ 94, 116, 120, 124, 126, 115, 111, 102, 82, 89, 6, 25, 4, 26, 48, 84,
+ 87, 92, 90, 114, 103, 97, 122, 100, 112, 106, 125, 118, 115, 114, 85, 81,
+ 118, 89, 91, 104, 116, 110, 111, 111, 107, 116, 113, 116, 121, 126, 120, 77,
+ 85, 102, 66, 14, 10, 22, 22, 27, 50, 32, 43, 43, 62, 53, 47, 62,
+ 62, 37, 72, 94, 114, 126, 126, 126, 126, 126, 16, 50, 43, 43, 31, 45,
+ 22, 17, 22, 12, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, 22,
+ 41, 4, 65, 11, 89, 114, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, 66, 51, 14,
+ 62, 72, 27, 34, 65, 87, 3, 104, 121, 71, 92, 126, 126, 126, 62, 23,
+ 70, 27, 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 18, 65, 86, 24, 55, 42, 62, 62, 33, 31,
+ 24, 39, 19, 12, 29, 69, 73, 73, 66, 27, 2, 10, 64, 64, 0, 2,
+ 11, 69, 79, 78, 88, 19, 68, 7, 1, 78, 5, 71, 9, 3, 65, 5,
+ 10, 2, 68, 66, 6, 67, 0, 69, 70, 76, 64, 70, 82, 1, 70, 77,
+ 2, 13, 66, 87, 77, 77, 81, 4, 68, 9, 7, 7, 42, 19, 5, 69,
+ 14, 69, 83, 0, 109, 73, 64, 91, 72, 90, 4, 64, 83, 19, 8, 4,
+ 103, 4, 87, 74, 3, 97, 0, 17, 10, 14, 17, 13, 6, 16, 12, 68,
+ 65, 9, 0, 64, 75, 70, 76, 75, 71, 74, 80, 80, 78, 78, 77, 68,
+ 93, 101, 80, 86, 88, 92, 93, 102, 107, 101, 101, 111, 117, 109, 112, 126,
+ 123, 124, 70, 74, 95, 81, 89, 92, 99, 107, 111, 100, 104, 98, 87, 92,
+ 90, 82, 79, 7, 26, 18, 11, 9, 11, 6, 1, 7, 16, 15, 30, 21,
+ 15, 8, 24, 15, 19, 12, 40, 2, 44, 31, 22, 14, 28, 5, 64, 64,
+ 5, 70, 47, 17, 64, 1, 12, 1, 71, 2, 5, 33, 18, 1, 68, 17,
+ 5, 3, 4, 4, 62, 64, 8, 8, 16, 11, 10, 24, 24, 18, 23, 29,
+ 34, 64, 7, 75, 64, 40, 70, 95, 67, 10, 66, 82, 86, 76, 88, 97,
+ 106, 108, 72, 68, 16, 71, 77, 69, 66, 2, 82, 75, 69, 68, 90, 75,
+ 83, 1, 11, 89, 75, 4, 81, 1, 78, 69, 21, 81, 86, 66, 3, 91,
+ 88, 125, 8, 14, 24, 68, 75, 71, 87, 87, 87, 101, 100, 99, 118, 109,
+ 95, 119, 123, 126, 126, 118, 114, 104, 83, 90, 6, 26, 4, 27, 50, 86,
+ 89, 94, 92, 116, 105, 98, 124, 102, 113, 107, 126, 120, 116, 115, 85, 82,
+ 119, 90, 93, 105, 118, 112, 113, 113, 108, 118, 115, 117, 123, 126, 121, 78,
+ 86, 103, 66, 15, 10, 22, 23, 27, 51, 33, 44, 44, 62, 54, 48, 62,
+ 62, 37, 73, 96, 117, 126, 126, 126, 126, 126, 17, 51, 44, 44, 31, 46,
+ 23, 17, 23, 13, 69, 2, 18, 5, 38, 48, 2, 12, 21, 25, 6, 23,
+ 42, 4, 65, 10, 91, 117, 126, 126, 126, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 38, 62, 62, 54, 22,
+ 118, 65, 71, 79, 11, 13, 70, 9, 29, 41, 62, 61, 27, 69, 126, 101,
+ 76, 71, 79, 11, 69, 90, 11, 20, 69, 82, 96, 4, 75, 87, 100, 7,
+ 74, 85, 4, 81, 86, 95, 66, 77, 70, 86, 72, 2, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 48, 12, 80, 126, 91, 96, 81, 98, 102, 97,
+ 119, 99, 110, 102, 126, 80, 89, 94, 92, 24, 65, 84, 126, 73, 104, 91,
+ 126, 8, 7, 8, 2, 10, 68, 74, 88, 103, 91, 89, 92, 76, 87, 110,
+ 105, 78, 112, 99, 126, 126, 126, 126, 66, 78, 71, 72, 4, 8, 70, 75,
+ 89, 119, 75, 43, 41, 126, 9, 2, 5, 3, 2, 67, 84, 74, 65, 11,
+ 6, 2, 69, 70, 8, 71, 5, 2, 22, 38, 31, 20, 16, 19, 12, 17,
+ 25, 66, 25, 21, 29, 89, 18, 35, 32, 62, 62, 48, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 62, 53, 62, 62, 62, 62, 62, 62, 62, 56, 62,
+ 62, 62, 27, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 53, 45,
+ 38, 22, 75, 72, 77, 28, 32, 28, 33, 18, 21, 18, 37, 9, 66, 7,
+ 73, 67, 116, 112, 71, 2, 10, 66, 77, 80, 84, 87, 126, 101, 24, 10,
+ 2, 75, 77, 91, 107, 111, 122, 76, 19, 11, 6, 5, 72, 69, 69, 74,
+ 86, 66, 29, 31, 32, 11, 8, 67, 73, 89, 11, 59, 55, 55, 44, 26,
+ 2, 73, 70, 78, 62, 126, 124, 110, 126, 124, 105, 121, 117, 102, 117, 116,
+ 122, 95, 100, 95, 111, 114, 89, 80, 82, 85, 81, 72, 64, 67, 7, 69,
+ 69, 69, 69, 67, 77, 64, 2, 67, 64, 6, 65, 66, 1, 12, 66, 71,
+ 75, 70, 72, 3, 26, 16, 28, 26, 22, 22, 15, 22, 22, 4, 13, 23,
+ 66, 13, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 54, 62, 62, 62, 62, 62, 62, 62, 62, 62, 49, 37, 26, 8, 65, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 43, 33, 19, 15, 14,
+ 18, 41, 41, 42, 43, 35, 39, 29, 21, 24, 13, 70, 9, 71, 83, 31,
+ 14, 9, 85, 81, 77, 81, 80, 73, 74, 83, 71, 67, 2, 66, 66, 4,
+ 4, 62, 62, 62, 62, 62, 60, 53, 36, 6, 71, 39, 27, 21, 11, 6,
+ 0, 65, 67, 82, 81, 76, 72, 78, 72, 68, 70, 76, 66, 1, 6, 2,
+ 3, 9, 5, 62, 62, 62, 62, 62, 60, 53, 36, 6, 75, 65, 4, 67,
+ 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 37, 61, 62, 55, 22,
+ 116, 65, 70, 78, 11, 13, 69, 9, 28, 40, 61, 58, 25, 70, 124, 100,
+ 75, 70, 78, 11, 69, 89, 11, 20, 68, 81, 95, 4, 75, 86, 99, 7,
+ 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 48, 12, 80, 124, 89, 94, 79, 95, 100, 95,
+ 117, 97, 108, 100, 124, 80, 88, 93, 91, 24, 65, 83, 124, 72, 103, 90,
+ 125, 8, 7, 8, 2, 11, 68, 73, 87, 102, 90, 88, 91, 75, 86, 108,
+ 103, 77, 110, 97, 122, 122, 123, 124, 65, 77, 70, 71, 4, 9, 69, 74,
+ 88, 116, 74, 41, 40, 124, 9, 3, 5, 4, 3, 66, 82, 73, 64, 11,
+ 6, 2, 68, 69, 7, 70, 5, 2, 22, 37, 31, 20, 16, 19, 12, 17,
+ 24, 65, 25, 21, 29, 89, 18, 35, 32, 62, 62, 47, 62, 62, 62, 61,
+ 62, 62, 62, 62, 62, 62, 52, 62, 62, 62, 62, 62, 62, 62, 54, 62,
+ 60, 62, 26, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 52, 44,
+ 37, 21, 75, 72, 77, 28, 31, 27, 32, 17, 20, 17, 36, 8, 66, 6,
+ 73, 67, 115, 110, 70, 3, 10, 65, 76, 79, 83, 86, 124, 99, 25, 11,
+ 3, 74, 76, 89, 105, 109, 120, 75, 20, 12, 7, 6, 71, 68, 68, 73,
+ 85, 66, 30, 31, 32, 11, 9, 66, 73, 88, 11, 59, 55, 54, 43, 26,
+ 3, 72, 69, 77, 62, 124, 122, 108, 124, 122, 103, 119, 115, 100, 115, 114,
+ 119, 94, 99, 94, 109, 112, 88, 79, 81, 84, 80, 71, 64, 67, 7, 69,
+ 69, 69, 68, 66, 76, 0, 2, 66, 0, 6, 64, 65, 1, 12, 65, 70,
+ 74, 69, 71, 3, 25, 16, 27, 26, 22, 22, 15, 22, 22, 4, 13, 22,
+ 66, 12, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 52, 62, 62, 62, 62, 62, 62, 62, 61, 62, 48, 36, 25, 8, 65, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 42, 32, 18, 15, 14,
+ 17, 40, 40, 41, 41, 34, 38, 28, 20, 23, 12, 70, 8, 71, 83, 30,
+ 13, 8, 84, 80, 76, 80, 78, 71, 73, 82, 70, 66, 3, 65, 65, 4,
+ 4, 62, 62, 62, 62, 60, 56, 49, 32, 4, 70, 39, 28, 22, 12, 7,
+ 1, 64, 66, 81, 80, 75, 71, 77, 71, 67, 69, 75, 65, 2, 6, 3,
+ 4, 9, 5, 62, 62, 62, 62, 60, 56, 49, 32, 4, 75, 65, 4, 66,
+ 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 36, 59, 61, 55, 22,
+ 114, 65, 70, 77, 11, 12, 69, 8, 26, 39, 58, 54, 22, 72, 121, 99,
+ 75, 70, 77, 11, 69, 88, 11, 19, 68, 81, 94, 4, 75, 86, 99, 7,
+ 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 47, 12, 80, 122, 88, 93, 77, 93, 99, 94,
+ 115, 96, 107, 99, 122, 80, 88, 93, 91, 24, 65, 82, 122, 72, 102, 89,
+ 123, 8, 7, 8, 1, 11, 68, 73, 86, 101, 89, 87, 90, 75, 85, 107,
+ 102, 76, 109, 96, 117, 118, 120, 121, 65, 77, 70, 71, 4, 9, 69, 74,
+ 88, 114, 74, 39, 38, 121, 9, 3, 5, 4, 3, 66, 80, 72, 64, 11,
+ 6, 2, 67, 68, 6, 70, 5, 2, 21, 36, 30, 20, 15, 19, 12, 17,
+ 23, 65, 24, 20, 28, 89, 18, 34, 31, 62, 62, 46, 60, 62, 62, 59,
+ 62, 62, 62, 62, 62, 62, 50, 62, 62, 62, 62, 62, 62, 62, 52, 62,
+ 58, 62, 24, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 50, 42,
+ 35, 19, 75, 72, 78, 27, 30, 26, 31, 16, 19, 16, 34, 7, 66, 5,
+ 74, 68, 114, 109, 69, 3, 10, 65, 75, 78, 82, 85, 122, 98, 25, 11,
+ 3, 73, 75, 88, 103, 107, 118, 74, 21, 13, 8, 7, 70, 68, 68, 73,
+ 84, 66, 31, 31, 31, 11, 9, 66, 73, 88, 11, 59, 54, 53, 42, 26,
+ 3, 72, 69, 77, 62, 123, 121, 107, 122, 120, 102, 117, 113, 99, 113, 112,
+ 117, 93, 98, 94, 108, 110, 88, 79, 81, 83, 80, 71, 64, 67, 6, 69,
+ 69, 69, 68, 66, 75, 0, 2, 66, 0, 6, 64, 65, 1, 11, 65, 70,
+ 74, 69, 70, 2, 24, 16, 26, 25, 21, 21, 15, 21, 21, 4, 13, 21,
+ 66, 11, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 50, 62, 62, 62, 62, 62, 62, 62, 59, 59, 46, 34, 24, 7, 66, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 40, 30, 16, 14, 13,
+ 15, 39, 39, 39, 39, 32, 36, 26, 19, 21, 11, 71, 7, 72, 84, 28,
+ 12, 7, 84, 80, 75, 80, 77, 70, 73, 81, 69, 65, 3, 65, 64, 4,
+ 4, 62, 62, 62, 62, 57, 52, 45, 28, 1, 70, 39, 28, 22, 12, 8,
+ 1, 64, 66, 81, 80, 75, 71, 77, 70, 66, 69, 75, 65, 2, 6, 3,
+ 5, 9, 5, 62, 62, 62, 62, 57, 52, 45, 28, 1, 75, 65, 4, 66,
+ 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 34, 57, 60, 55, 22,
+ 112, 65, 69, 76, 11, 12, 69, 8, 25, 38, 56, 51, 20, 73, 118, 98,
+ 75, 69, 76, 11, 70, 87, 11, 19, 68, 81, 94, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 84, 94, 65, 76, 70, 85, 71, 2, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 46, 11, 80, 119, 87, 92, 76, 91, 97, 92,
+ 113, 94, 106, 98, 120, 80, 88, 92, 91, 24, 65, 81, 120, 72, 101, 89,
+ 121, 8, 6, 7, 1, 11, 68, 72, 86, 100, 88, 87, 89, 74, 84, 105,
+ 100, 76, 108, 95, 112, 113, 117, 118, 65, 77, 70, 70, 4, 9, 68, 73,
+ 87, 112, 74, 37, 36, 118, 9, 3, 5, 4, 3, 65, 79, 71, 64, 11,
+ 6, 2, 67, 67, 5, 70, 5, 1, 21, 35, 30, 20, 15, 19, 12, 17,
+ 22, 65, 23, 19, 28, 89, 18, 34, 31, 62, 62, 45, 58, 62, 62, 57,
+ 62, 62, 62, 62, 62, 61, 48, 62, 62, 62, 62, 62, 62, 60, 50, 62,
+ 56, 62, 22, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 48, 40,
+ 34, 17, 75, 72, 78, 26, 29, 25, 30, 15, 18, 15, 32, 6, 67, 4,
+ 75, 68, 114, 107, 68, 4, 10, 65, 74, 78, 82, 85, 120, 97, 25, 11,
+ 4, 72, 74, 87, 102, 106, 116, 73, 21, 13, 8, 7, 69, 67, 68, 73,
+ 84, 66, 31, 31, 30, 11, 9, 66, 73, 87, 11, 58, 54, 52, 41, 26,
+ 3, 72, 69, 77, 62, 122, 119, 106, 121, 119, 101, 115, 111, 98, 112, 110,
+ 115, 93, 97, 93, 107, 108, 87, 79, 81, 83, 79, 71, 64, 67, 6, 69,
+ 69, 70, 67, 65, 74, 0, 2, 65, 0, 6, 64, 65, 1, 11, 65, 70,
+ 74, 69, 70, 1, 23, 16, 25, 24, 20, 21, 15, 20, 20, 4, 13, 20,
+ 66, 10, 62, 62, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 48, 62, 62, 62, 62, 62, 62, 62, 57, 57, 44, 32, 22, 6, 67, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 60, 38, 28, 15, 13, 12,
+ 14, 37, 37, 37, 37, 31, 34, 24, 18, 20, 10, 72, 6, 73, 85, 27,
+ 11, 6, 84, 79, 75, 79, 76, 69, 73, 81, 69, 65, 3, 64, 0, 4,
+ 4, 62, 62, 62, 59, 54, 48, 41, 24, 65, 70, 39, 28, 22, 12, 8,
+ 2, 64, 66, 80, 80, 75, 70, 76, 69, 65, 69, 74, 65, 2, 6, 3,
+ 5, 9, 5, 62, 62, 62, 59, 54, 48, 41, 24, 65, 75, 65, 4, 65,
+ 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 33, 55, 59, 55, 21,
+ 110, 65, 69, 75, 10, 11, 69, 7, 23, 37, 53, 47, 17, 75, 115, 97,
+ 75, 69, 75, 10, 70, 86, 11, 18, 68, 80, 93, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 84, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 45, 11, 80, 117, 86, 91, 74, 89, 96, 91,
+ 112, 93, 104, 97, 118, 80, 87, 92, 91, 24, 65, 80, 118, 72, 101, 88,
+ 119, 8, 6, 7, 0, 11, 68, 72, 85, 99, 87, 86, 88, 74, 84, 104,
+ 99, 75, 107, 94, 107, 109, 114, 115, 65, 76, 70, 70, 4, 9, 68, 73,
+ 87, 110, 74, 35, 34, 116, 9, 4, 5, 4, 3, 65, 77, 70, 0, 10,
+ 6, 2, 66, 67, 4, 70, 5, 1, 20, 34, 29, 19, 14, 19, 12, 17,
+ 21, 65, 22, 18, 27, 89, 17, 33, 30, 62, 62, 44, 56, 62, 62, 55,
+ 62, 62, 62, 62, 62, 59, 46, 59, 62, 62, 62, 62, 62, 57, 48, 62,
+ 54, 62, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 55, 46, 38,
+ 32, 15, 75, 72, 79, 25, 28, 24, 28, 14, 16, 14, 31, 5, 67, 3,
+ 75, 69, 113, 106, 67, 4, 10, 64, 74, 77, 81, 84, 118, 95, 25, 12,
+ 4, 72, 73, 86, 100, 104, 115, 73, 22, 14, 9, 8, 68, 67, 68, 72,
+ 83, 66, 32, 31, 30, 10, 9, 66, 73, 87, 11, 58, 53, 51, 40, 26,
+ 3, 71, 69, 77, 62, 120, 118, 105, 119, 117, 100, 114, 110, 97, 110, 109,
+ 113, 92, 96, 93, 106, 107, 87, 79, 81, 82, 79, 71, 65, 67, 5, 69,
+ 69, 70, 67, 65, 73, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70,
+ 74, 69, 69, 0, 22, 16, 24, 24, 19, 20, 15, 19, 19, 4, 13, 19,
+ 66, 9, 62, 62, 60, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 46, 62, 62, 62, 62, 62, 62, 62, 54, 54, 42, 30, 21, 5, 67, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 57, 36, 26, 13, 12, 12,
+ 12, 36, 36, 36, 35, 29, 32, 23, 17, 18, 9, 73, 4, 74, 85, 25,
+ 9, 4, 83, 79, 74, 79, 75, 68, 73, 80, 68, 64, 3, 64, 1, 4,
+ 4, 62, 62, 62, 56, 50, 44, 36, 20, 68, 69, 39, 28, 22, 12, 9,
+ 2, 64, 66, 80, 80, 75, 70, 76, 69, 64, 69, 74, 64, 3, 6, 3,
+ 6, 9, 5, 62, 62, 62, 56, 50, 44, 36, 20, 68, 75, 65, 4, 65,
+ 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 32, 53, 58, 55, 21,
+ 108, 65, 69, 74, 10, 11, 69, 6, 21, 36, 51, 44, 15, 77, 112, 96,
+ 74, 69, 74, 10, 70, 85, 11, 18, 68, 80, 92, 4, 75, 86, 99, 7,
+ 73, 83, 4, 80, 83, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 44, 10, 80, 114, 85, 90, 72, 87, 94, 89,
+ 110, 91, 103, 96, 115, 80, 87, 91, 90, 24, 65, 79, 116, 72, 100, 88,
+ 117, 8, 5, 6, 0, 11, 68, 71, 85, 98, 86, 86, 87, 73, 83, 102,
+ 97, 74, 105, 93, 102, 105, 111, 112, 64, 76, 69, 69, 4, 9, 67, 73,
+ 86, 108, 74, 33, 32, 113, 9, 4, 5, 4, 3, 64, 76, 69, 0, 10,
+ 6, 2, 66, 66, 3, 69, 5, 0, 20, 33, 29, 19, 14, 19, 12, 17,
+ 20, 64, 21, 18, 27, 89, 17, 32, 29, 62, 62, 43, 55, 62, 62, 53,
+ 62, 62, 62, 62, 61, 57, 44, 57, 62, 60, 62, 62, 62, 55, 46, 62,
+ 52, 62, 19, 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 53, 44, 37,
+ 30, 13, 75, 72, 79, 24, 27, 23, 27, 13, 15, 13, 29, 4, 68, 2,
+ 76, 70, 112, 104, 66, 5, 10, 64, 73, 77, 81, 83, 116, 94, 25, 12,
+ 5, 71, 72, 85, 99, 103, 113, 72, 23, 15, 10, 8, 67, 66, 67, 72,
+ 83, 66, 32, 31, 29, 10, 9, 66, 73, 86, 11, 57, 52, 50, 39, 26,
+ 3, 71, 69, 76, 62, 119, 116, 103, 117, 116, 99, 112, 108, 96, 108, 107,
+ 111, 91, 95, 92, 105, 105, 87, 79, 80, 82, 78, 71, 65, 67, 5, 69,
+ 69, 71, 66, 65, 72, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70,
+ 74, 69, 69, 64, 21, 16, 23, 23, 19, 19, 15, 19, 18, 4, 13, 18,
+ 66, 8, 62, 62, 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 44, 62, 62, 62, 62, 62, 62, 61, 52, 52, 40, 29, 19, 5, 68, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 61, 55, 54, 34, 24, 12, 12, 11,
+ 10, 35, 34, 34, 33, 27, 30, 21, 16, 17, 8, 73, 3, 75, 86, 24,
+ 8, 3, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, 0, 2, 4,
+ 4, 62, 62, 59, 53, 47, 40, 32, 16, 71, 69, 39, 28, 22, 12, 9,
+ 2, 0, 65, 79, 80, 75, 69, 76, 68, 0, 69, 74, 64, 3, 6, 4,
+ 6, 9, 5, 62, 62, 59, 53, 47, 40, 32, 16, 71, 75, 65, 4, 65,
+ 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 30, 51, 57, 55, 21,
+ 107, 65, 68, 74, 10, 10, 68, 6, 20, 34, 48, 40, 12, 78, 110, 95,
+ 74, 68, 74, 10, 71, 85, 11, 17, 68, 80, 92, 4, 75, 85, 98, 7,
+ 72, 82, 4, 79, 83, 93, 65, 76, 70, 85, 70, 2, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 44, 10, 80, 112, 84, 89, 71, 84, 93, 88,
+ 108, 90, 102, 95, 113, 80, 87, 91, 90, 24, 65, 78, 113, 72, 99, 87,
+ 115, 7, 5, 6, 64, 12, 68, 71, 84, 98, 86, 85, 86, 73, 82, 101,
+ 96, 74, 104, 92, 97, 100, 108, 109, 64, 76, 69, 69, 4, 9, 67, 72,
+ 86, 106, 73, 31, 30, 110, 9, 4, 5, 4, 4, 64, 74, 68, 0, 10,
+ 6, 2, 65, 65, 2, 69, 5, 0, 19, 32, 28, 19, 13, 19, 12, 17,
+ 18, 64, 20, 17, 26, 89, 17, 32, 29, 62, 62, 42, 53, 62, 62, 51,
+ 62, 62, 62, 62, 57, 55, 43, 55, 62, 58, 62, 62, 62, 52, 44, 62,
+ 50, 62, 17, 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, 42, 35,
+ 29, 12, 75, 72, 80, 23, 26, 22, 26, 12, 14, 12, 27, 3, 68, 1,
+ 77, 70, 112, 103, 65, 5, 10, 64, 72, 76, 80, 83, 114, 93, 26, 12,
+ 5, 70, 71, 84, 97, 101, 111, 71, 23, 15, 10, 9, 66, 66, 67, 72,
+ 82, 66, 33, 31, 28, 10, 9, 66, 73, 86, 10, 57, 52, 49, 38, 25,
+ 3, 71, 69, 76, 62, 118, 115, 102, 116, 114, 98, 110, 106, 95, 107, 105,
+ 109, 91, 94, 92, 104, 103, 86, 79, 80, 81, 78, 71, 65, 67, 4, 69,
+ 69, 71, 66, 64, 71, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70,
+ 74, 69, 68, 65, 20, 16, 22, 22, 18, 19, 15, 18, 18, 4, 12, 16,
+ 67, 7, 62, 62, 58, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 42, 62, 62, 62, 62, 62, 62, 58, 50, 49, 38, 27, 18, 4, 69, 62,
+ 62, 62, 62, 62, 62, 62, 62, 61, 58, 52, 51, 32, 23, 10, 11, 10,
+ 9, 33, 33, 32, 31, 26, 28, 19, 15, 15, 7, 74, 2, 76, 87, 22,
+ 7, 2, 83, 78, 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, 3, 4,
+ 4, 62, 62, 57, 50, 44, 36, 28, 12, 74, 69, 39, 28, 22, 12, 10,
+ 3, 0, 65, 79, 79, 74, 69, 75, 67, 1, 68, 73, 64, 3, 6, 4,
+ 7, 9, 5, 62, 62, 57, 50, 44, 36, 28, 12, 74, 75, 65, 4, 64,
+ 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 29, 49, 56, 55, 21,
+ 105, 65, 68, 73, 9, 10, 68, 5, 18, 33, 46, 37, 10, 80, 107, 94,
+ 74, 68, 73, 9, 71, 84, 11, 17, 68, 79, 91, 4, 75, 85, 98, 7,
+ 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 43, 9, 80, 109, 83, 88, 69, 82, 91, 86,
+ 107, 88, 100, 94, 111, 80, 86, 90, 90, 24, 65, 77, 111, 72, 98, 87,
+ 113, 7, 4, 5, 64, 12, 68, 70, 84, 97, 85, 85, 85, 72, 81, 99,
+ 94, 73, 103, 91, 92, 96, 105, 106, 64, 75, 69, 68, 4, 9, 66, 72,
+ 85, 104, 73, 29, 28, 107, 9, 5, 5, 4, 4, 0, 73, 67, 1, 9,
+ 6, 2, 65, 65, 1, 69, 5, 64, 19, 31, 28, 18, 13, 19, 12, 17,
+ 17, 64, 19, 16, 26, 89, 17, 31, 28, 60, 62, 41, 51, 62, 62, 49,
+ 62, 61, 62, 62, 54, 53, 41, 52, 62, 55, 62, 62, 62, 49, 42, 62,
+ 48, 62, 16, 62, 62, 62, 62, 62, 62, 62, 62, 57, 53, 48, 40, 33,
+ 27, 10, 75, 72, 80, 22, 25, 21, 24, 11, 13, 11, 26, 2, 69, 0,
+ 77, 71, 111, 101, 64, 6, 10, 0, 72, 76, 80, 82, 112, 91, 26, 13,
+ 6, 70, 70, 83, 96, 100, 109, 71, 24, 16, 11, 9, 65, 65, 67, 71,
+ 82, 66, 33, 31, 28, 9, 9, 66, 73, 85, 10, 56, 51, 48, 37, 25,
+ 3, 70, 69, 76, 62, 116, 113, 101, 114, 113, 97, 109, 105, 94, 105, 104,
+ 107, 90, 93, 91, 103, 101, 86, 79, 80, 81, 77, 71, 66, 67, 4, 69,
+ 69, 72, 65, 64, 70, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70,
+ 74, 69, 68, 66, 19, 16, 21, 22, 17, 18, 15, 17, 17, 4, 12, 15,
+ 67, 6, 61, 62, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 40, 62, 62, 62, 62, 62, 62, 56, 48, 47, 36, 25, 16, 3, 69, 62,
+ 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, 48, 30, 21, 9, 10, 10,
+ 7, 32, 31, 31, 29, 24, 26, 18, 14, 14, 6, 75, 0, 77, 87, 21,
+ 5, 0, 82, 78, 72, 77, 72, 65, 72, 78, 67, 0, 3, 1, 4, 4,
+ 4, 62, 62, 54, 47, 40, 32, 24, 8, 77, 68, 39, 28, 22, 12, 10,
+ 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, 0, 4, 6, 4,
+ 7, 9, 5, 62, 62, 54, 47, 40, 32, 24, 8, 77, 75, 65, 4, 64,
+ 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 27, 46, 55, 55, 20,
+ 103, 66, 68, 72, 9, 9, 68, 4, 16, 32, 43, 33, 7, 82, 104, 93,
+ 74, 68, 72, 9, 72, 83, 11, 16, 68, 79, 91, 3, 76, 85, 98, 7,
+ 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 42, 9, 81, 107, 82, 87, 68, 80, 90, 85,
+ 105, 87, 99, 93, 109, 80, 86, 90, 90, 24, 65, 76, 109, 72, 98, 86,
+ 111, 7, 4, 5, 65, 12, 68, 70, 83, 96, 84, 84, 85, 72, 81, 98,
+ 93, 73, 102, 90, 88, 92, 102, 104, 64, 75, 69, 68, 3, 9, 66, 72,
+ 85, 102, 73, 27, 26, 105, 9, 5, 5, 4, 4, 0, 71, 67, 1, 9,
+ 5, 2, 64, 64, 64, 69, 5, 64, 18, 29, 27, 18, 12, 19, 12, 16,
+ 16, 64, 18, 15, 25, 89, 16, 30, 27, 58, 62, 39, 49, 62, 62, 46,
+ 62, 59, 62, 62, 50, 51, 39, 50, 62, 53, 62, 62, 62, 46, 40, 62,
+ 46, 62, 14, 62, 62, 62, 62, 62, 62, 62, 60, 55, 51, 46, 38, 31,
+ 25, 8, 75, 73, 81, 21, 23, 20, 23, 10, 11, 9, 24, 1, 69, 64,
+ 78, 72, 111, 100, 0, 6, 10, 0, 71, 75, 79, 82, 110, 90, 26, 13,
+ 6, 69, 69, 82, 94, 98, 108, 70, 24, 16, 11, 10, 64, 65, 67, 71,
+ 81, 67, 34, 31, 27, 9, 9, 66, 73, 85, 10, 56, 50, 47, 36, 25,
+ 3, 70, 69, 76, 62, 115, 112, 100, 113, 111, 96, 107, 103, 93, 104, 102,
+ 105, 90, 93, 91, 102, 100, 86, 79, 80, 80, 77, 71, 66, 67, 3, 69,
+ 69, 72, 65, 64, 69, 0, 1, 64, 1, 5, 0, 64, 1, 8, 65, 70,
+ 74, 69, 67, 67, 18, 16, 19, 21, 16, 17, 14, 16, 16, 4, 12, 14,
+ 67, 4, 60, 60, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60,
+ 38, 62, 62, 62, 62, 62, 62, 53, 45, 44, 34, 23, 15, 2, 70, 62,
+ 62, 62, 62, 62, 62, 62, 62, 56, 53, 47, 45, 28, 19, 7, 9, 9,
+ 5, 30, 30, 29, 27, 22, 24, 16, 12, 12, 4, 76, 64, 78, 88, 19,
+ 4, 64, 82, 78, 72, 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4,
+ 3, 62, 60, 51, 44, 37, 28, 19, 3, 80, 68, 39, 28, 22, 12, 11,
+ 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, 0, 4, 6, 4,
+ 8, 9, 4, 62, 60, 51, 44, 37, 28, 19, 3, 80, 75, 66, 3, 64,
+ 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 26, 44, 54, 56, 20, 101,
+ 66, 67, 71, 9, 8, 68, 4, 15, 31, 41, 29, 4, 83, 101, 92, 73, 67,
+ 71, 9, 72, 82, 11, 16, 67, 79, 90, 3, 76, 85, 98, 7, 72, 81, 4,
+ 79, 82, 92, 65, 76, 70, 84, 69, 2, 22, 0, 0, 0, 77, 88, 97, 68,
+ 15, 0, 41, 9, 81, 105, 80, 86, 66, 78, 88, 84, 103, 85, 98, 91, 106,
+ 80, 86, 90, 89, 24, 65, 75, 107, 71, 97, 85, 109, 7, 4, 5, 65, 12,
+ 68, 70, 82, 95, 83, 83, 84, 71, 80, 97, 91, 72, 100, 89, 83, 87, 98,
+ 101, 0, 75, 68, 67, 3, 9, 66, 71, 84, 99, 73, 25, 25, 102, 9, 5,
+ 5, 4, 4, 1, 69, 66, 1, 9, 5, 2, 0, 0, 65, 68, 5, 64, 17,
+ 28, 26, 18, 11, 19, 12, 16, 15, 0, 17, 15, 24, 89, 16, 30, 27, 56,
+ 62, 38, 48, 62, 62, 44, 60, 57, 62, 62, 47, 49, 37, 48, 62, 51, 62,
+ 62, 62, 44, 38, 62, 44, 62, 12, 62, 62, 62, 62, 62, 62, 60, 58, 53,
+ 49, 44, 37, 30, 24, 6, 75, 73, 81, 21, 22, 19, 22, 9, 10, 8, 22,
+ 0, 69, 65, 79, 72, 110, 99, 1, 6, 10, 0, 70, 74, 78, 81, 107, 89,
+ 26, 13, 6, 68, 68, 81, 92, 96, 106, 69, 25, 17, 12, 11, 0, 65, 66,
+ 71, 80, 67, 35, 31, 26, 9, 10, 65, 73, 84, 10, 56, 50, 46, 35, 25,
+ 3, 70, 69, 75, 62, 114, 111, 98, 111, 109, 95, 105, 101, 92, 102, 100, 103,
+ 89, 92, 90, 101, 98, 85, 78, 79, 79, 76, 71, 66, 67, 2, 69, 69, 72,
+ 65, 0, 68, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, 69, 73, 69, 66,
+ 67, 17, 16, 18, 20, 16, 17, 14, 16, 15, 4, 12, 13, 67, 3, 59, 59,
+ 56, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 36, 62, 62, 62, 62,
+ 62, 62, 50, 43, 42, 33, 22, 14, 2, 71, 62, 62, 62, 62, 62, 62, 62,
+ 62, 54, 51, 45, 43, 26, 17, 5, 9, 8, 4, 29, 29, 27, 25, 21, 23,
+ 14, 11, 10, 3, 76, 65, 78, 89, 17, 3, 65, 82, 77, 71, 77, 70, 1,
+ 71, 77, 65, 2, 3, 2, 5, 4, 3, 62, 58, 49, 41, 34, 24, 15, 64,
+ 83, 68, 39, 28, 23, 13, 12, 4, 1, 64, 78, 79, 74, 68, 74, 65, 3,
+ 68, 72, 0, 4, 6, 5, 9, 9, 4, 62, 58, 49, 41, 34, 24, 15, 64,
+ 83, 75, 66, 3, 0, 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 25, 42, 53, 56, 20, 99,
+ 66, 67, 70, 8, 8, 68, 3, 13, 30, 38, 26, 2, 85, 98, 91, 73, 67,
+ 70, 8, 72, 81, 11, 15, 67, 78, 89, 3, 76, 85, 98, 7, 72, 81, 4,
+ 79, 81, 91, 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 77, 88, 97, 67,
+ 14, 0, 40, 8, 81, 102, 79, 85, 64, 76, 87, 82, 102, 84, 96, 90, 104,
+ 80, 85, 89, 89, 24, 65, 74, 105, 71, 96, 85, 107, 7, 3, 4, 66, 12,
+ 68, 69, 82, 94, 82, 83, 83, 71, 79, 95, 90, 71, 99, 88, 78, 83, 95,
+ 98, 0, 74, 68, 67, 3, 9, 65, 71, 84, 97, 73, 23, 23, 99, 9, 6,
+ 5, 4, 4, 1, 68, 65, 2, 8, 5, 2, 0, 0, 66, 68, 5, 65, 17,
+ 27, 26, 17, 11, 19, 12, 16, 14, 0, 16, 14, 24, 89, 16, 29, 26, 54,
+ 62, 37, 46, 62, 62, 42, 57, 55, 62, 62, 43, 47, 35, 45, 61, 48, 62,
+ 62, 62, 41, 36, 58, 42, 62, 11, 62, 62, 62, 62, 62, 60, 58, 56, 51,
+ 46, 42, 35, 28, 22, 4, 75, 73, 82, 20, 21, 18, 20, 8, 9, 7, 21,
+ 64, 70, 66, 79, 73, 109, 97, 2, 7, 10, 1, 70, 74, 78, 80, 105, 87,
+ 26, 14, 7, 68, 67, 80, 91, 95, 104, 69, 26, 18, 13, 11, 1, 64, 66,
+ 70, 80, 67, 35, 31, 26, 8, 10, 65, 73, 84, 10, 55, 49, 45, 34, 25,
+ 3, 69, 69, 75, 62, 112, 109, 97, 109, 108, 94, 104, 100, 91, 100, 99, 101,
+ 88, 91, 90, 100, 96, 85, 78, 79, 79, 76, 71, 67, 67, 2, 69, 69, 73,
+ 64, 0, 67, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, 69, 73, 69, 66,
+ 68, 16, 16, 17, 20, 15, 16, 14, 15, 14, 4, 12, 12, 67, 2, 58, 58,
+ 55, 59, 60, 62, 62, 62, 62, 62, 62, 62, 62, 55, 34, 62, 62, 62, 62,
+ 62, 62, 48, 41, 39, 31, 20, 12, 1, 71, 62, 62, 62, 62, 62, 62, 62,
+ 62, 52, 48, 43, 40, 24, 15, 4, 8, 8, 2, 28, 27, 26, 23, 19, 21,
+ 13, 10, 9, 2, 77, 67, 79, 89, 16, 1, 67, 81, 77, 70, 76, 69, 2,
+ 71, 76, 65, 2, 3, 2, 6, 4, 3, 62, 56, 46, 38, 30, 20, 11, 68,
+ 86, 67, 39, 28, 23, 13, 12, 4, 1, 64, 77, 79, 74, 67, 74, 64, 4,
+ 68, 72, 1, 5, 6, 5, 9, 9, 4, 62, 56, 46, 38, 30, 20, 11, 68,
+ 86, 75, 66, 3, 0, 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 23, 40, 52, 56, 20, 98, 66,
+ 66, 70, 8, 7, 67, 3, 12, 28, 36, 22, 64, 86, 96, 90, 73, 66, 70, 8,
+ 73, 81, 11, 15, 67, 78, 89, 3, 76, 84, 97, 7, 71, 80, 4, 78, 81, 91,
+ 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 40, 8,
+ 81, 100, 78, 84, 0, 73, 85, 81, 100, 82, 95, 89, 102, 80, 85, 89, 89, 24,
+ 65, 73, 102, 71, 95, 84, 105, 6, 3, 4, 66, 13, 68, 69, 81, 94, 82, 82,
+ 82, 70, 78, 94, 88, 71, 98, 87, 73, 78, 92, 95, 0, 74, 68, 66, 3, 9,
+ 65, 70, 83, 95, 72, 21, 21, 96, 9, 6, 5, 4, 5, 2, 66, 64, 2, 8,
+ 5, 2, 1, 1, 67, 68, 5, 65, 16, 26, 25, 17, 10, 19, 12, 16, 12, 0,
+ 15, 13, 23, 89, 16, 29, 26, 52, 62, 36, 44, 61, 62, 40, 55, 53, 62, 62,
+ 40, 45, 34, 43, 57, 46, 62, 62, 62, 38, 34, 55, 40, 62, 9, 62, 62, 62,
+ 62, 62, 58, 55, 54, 49, 44, 39, 33, 26, 21, 3, 75, 73, 82, 19, 20, 17,
+ 19, 7, 8, 6, 19, 65, 70, 67, 80, 73, 109, 96, 3, 7, 10, 1, 69, 73,
+ 77, 80, 103, 86, 27, 14, 7, 67, 66, 79, 89, 93, 102, 68, 26, 18, 13, 12,
+ 2, 64, 66, 70, 79, 67, 36, 31, 25, 8, 10, 65, 73, 83, 9, 55, 49, 44,
+ 33, 24, 3, 69, 69, 75, 62, 111, 108, 96, 108, 106, 93, 102, 98, 90, 99, 97,
+ 99, 88, 90, 89, 99, 94, 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 73,
+ 64, 1, 66, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, 69, 65, 69,
+ 15, 16, 16, 19, 14, 16, 14, 14, 14, 4, 11, 10, 68, 1, 56, 57, 54, 58,
+ 58, 62, 62, 62, 62, 62, 62, 62, 62, 52, 32, 62, 62, 62, 62, 62, 62, 45,
+ 39, 37, 29, 18, 11, 0, 72, 62, 62, 62, 62, 62, 62, 60, 59, 49, 46, 40,
+ 37, 22, 14, 2, 7, 7, 1, 26, 26, 24, 21, 18, 19, 11, 9, 7, 1, 78,
+ 68, 80, 90, 14, 0, 68, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, 3,
+ 7, 4, 3, 62, 54, 44, 35, 27, 16, 7, 72, 89, 67, 39, 28, 23, 13, 13,
+ 5, 1, 64, 77, 78, 73, 67, 73, 0, 5, 67, 71, 1, 5, 6, 5, 10, 9,
+ 4, 62, 54, 44, 35, 27, 16, 7, 72, 89, 75, 66, 3, 1, 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 22, 38, 51, 56, 19, 96, 66,
+ 66, 69, 8, 7, 67, 2, 10, 27, 33, 19, 66, 88, 93, 89, 73, 66, 69, 8,
+ 73, 80, 11, 14, 67, 78, 88, 3, 76, 84, 97, 7, 71, 80, 4, 78, 80, 91,
+ 65, 76, 70, 84, 68, 2, 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 39, 7,
+ 81, 97, 77, 83, 2, 71, 84, 79, 98, 81, 94, 88, 100, 80, 85, 88, 89, 24,
+ 65, 72, 100, 71, 95, 84, 103, 6, 2, 3, 67, 13, 68, 68, 81, 93, 81, 82,
+ 81, 70, 78, 92, 87, 70, 97, 86, 68, 74, 89, 92, 0, 74, 68, 66, 3, 9,
+ 64, 70, 83, 93, 72, 19, 19, 94, 9, 6, 5, 4, 5, 2, 65, 0, 2, 8,
+ 5, 2, 1, 2, 68, 68, 5, 66, 16, 25, 25, 17, 10, 19, 12, 16, 11, 0,
+ 14, 12, 23, 89, 15, 28, 25, 50, 62, 35, 42, 59, 60, 38, 52, 51, 62, 62,
+ 36, 43, 32, 41, 54, 43, 58, 62, 62, 35, 32, 51, 38, 62, 7, 62, 62, 62,
+ 62, 62, 56, 53, 52, 47, 42, 37, 31, 24, 19, 1, 75, 73, 83, 18, 19, 16,
+ 18, 6, 6, 5, 17, 66, 71, 68, 81, 74, 108, 94, 4, 8, 10, 1, 68, 73,
+ 77, 79, 101, 85, 27, 14, 8, 66, 65, 78, 88, 92, 101, 67, 27, 19, 14, 12,
+ 3, 0, 66, 70, 79, 67, 36, 31, 24, 8, 10, 65, 73, 83, 9, 54, 48, 43,
+ 32, 24, 3, 69, 69, 75, 62, 110, 106, 95, 106, 105, 92, 100, 96, 89, 97, 95,
+ 97, 87, 89, 89, 98, 93, 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 74,
+ 0, 1, 65, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, 69, 65, 70,
+ 14, 16, 15, 18, 13, 15, 14, 13, 13, 4, 11, 9, 68, 0, 55, 56, 53, 56,
+ 56, 62, 61, 62, 62, 62, 62, 62, 61, 50, 30, 62, 62, 62, 62, 62, 59, 43,
+ 36, 34, 27, 16, 9, 64, 73, 62, 62, 62, 62, 62, 62, 57, 56, 47, 43, 38,
+ 34, 20, 12, 1, 6, 6, 64, 25, 24, 22, 19, 16, 17, 9, 8, 6, 0, 79,
+ 69, 81, 91, 13, 64, 69, 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3,
+ 8, 4, 3, 61, 52, 41, 32, 24, 12, 2, 76, 92, 67, 39, 28, 23, 13, 13,
+ 5, 1, 64, 76, 78, 73, 66, 73, 0, 6, 67, 71, 1, 5, 6, 5, 10, 9,
+ 4, 61, 52, 41, 32, 24, 12, 2, 76, 92, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 21, 36, 50, 56, 19, 94, 66,
+ 66, 68, 7, 6, 67, 1, 8, 26, 31, 15, 69, 90, 90, 88, 72, 66, 68, 7,
+ 73, 79, 11, 14, 67, 77, 87, 3, 76, 84, 97, 7, 71, 80, 4, 78, 80, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 75, 89, 97, 66, 12, 64, 38, 7,
+ 81, 95, 76, 82, 4, 69, 82, 78, 97, 79, 92, 87, 97, 80, 84, 88, 88, 24,
+ 65, 71, 98, 71, 94, 83, 101, 6, 2, 3, 67, 13, 68, 68, 80, 92, 80, 81,
+ 80, 69, 77, 91, 85, 69, 95, 85, 0, 70, 86, 89, 1, 73, 67, 65, 3, 9,
+ 64, 70, 82, 91, 72, 17, 17, 91, 9, 7, 5, 4, 5, 3, 0, 1, 3, 7,
+ 5, 2, 2, 2, 69, 67, 5, 66, 15, 24, 24, 16, 9, 19, 12, 16, 10, 1,
+ 13, 12, 22, 89, 15, 27, 24, 48, 62, 34, 41, 57, 58, 36, 50, 49, 62, 62,
+ 33, 41, 30, 38, 51, 41, 55, 62, 62, 33, 30, 48, 36, 62, 6, 62, 62, 62,
+ 61, 60, 54, 51, 50, 45, 39, 35, 29, 23, 17, 64, 75, 73, 83, 17, 18, 15,
+ 16, 5, 5, 4, 16, 67, 71, 69, 81, 75, 107, 93, 5, 8, 10, 2, 68, 72,
+ 76, 78, 99, 83, 27, 15, 8, 66, 64, 77, 86, 90, 99, 67, 28, 20, 15, 13,
+ 4, 0, 65, 69, 78, 67, 37, 31, 24, 7, 10, 65, 73, 82, 9, 54, 47, 42,
+ 31, 24, 3, 68, 69, 74, 62, 108, 105, 93, 104, 103, 91, 99, 95, 88, 95, 94,
+ 95, 86, 88, 88, 97, 91, 84, 78, 78, 77, 74, 71, 68, 67, 0, 69, 69, 74,
+ 0, 1, 64, 1, 1, 1, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, 71,
+ 13, 16, 14, 18, 13, 14, 14, 13, 12, 4, 11, 8, 68, 64, 54, 55, 52, 54,
+ 54, 62, 59, 61, 62, 59, 62, 62, 58, 47, 28, 62, 62, 62, 62, 59, 56, 40,
+ 34, 32, 25, 15, 8, 64, 73, 62, 62, 62, 62, 59, 59, 55, 53, 45, 41, 36,
+ 31, 18, 10, 64, 6, 6, 66, 24, 23, 21, 17, 14, 15, 8, 7, 4, 64, 79,
+ 71, 82, 91, 11, 66, 71, 80, 76, 68, 75, 66, 5, 70, 74, 0, 4, 3, 4,
+ 9, 4, 3, 60, 50, 38, 29, 20, 8, 65, 80, 95, 66, 39, 28, 23, 13, 14,
+ 5, 2, 0, 76, 78, 73, 66, 73, 1, 7, 67, 71, 2, 6, 6, 6, 11, 9,
+ 4, 60, 50, 38, 29, 20, 8, 65, 80, 95, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 19, 34, 49, 56, 19, 92, 66,
+ 65, 67, 7, 6, 67, 1, 7, 25, 28, 12, 71, 91, 87, 87, 72, 65, 67, 7,
+ 74, 78, 11, 13, 67, 77, 87, 3, 76, 84, 97, 7, 71, 79, 4, 78, 79, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 37, 6,
+ 81, 92, 75, 81, 5, 67, 81, 76, 95, 78, 91, 86, 95, 80, 84, 87, 88, 24,
+ 65, 70, 96, 71, 93, 83, 99, 6, 1, 2, 68, 13, 68, 67, 80, 91, 79, 81,
+ 79, 69, 76, 89, 84, 69, 94, 84, 5, 65, 83, 86, 1, 73, 67, 65, 3, 9,
+ 0, 69, 82, 89, 72, 15, 15, 88, 9, 7, 5, 4, 5, 3, 1, 2, 3, 7,
+ 5, 2, 2, 3, 70, 67, 5, 67, 15, 23, 24, 16, 9, 19, 12, 16, 9, 1,
+ 12, 11, 22, 89, 15, 27, 24, 46, 61, 33, 39, 55, 55, 34, 47, 47, 62, 62,
+ 29, 39, 28, 36, 48, 38, 52, 61, 62, 30, 28, 44, 34, 62, 4, 60, 62, 60,
+ 58, 57, 52, 49, 48, 43, 37, 33, 27, 21, 16, 66, 75, 73, 84, 16, 17, 14,
+ 15, 4, 4, 3, 14, 68, 72, 70, 82, 75, 107, 91, 6, 9, 10, 2, 67, 72,
+ 76, 78, 97, 82, 27, 15, 9, 65, 0, 76, 85, 89, 97, 66, 28, 20, 15, 13,
+ 5, 1, 65, 69, 78, 67, 37, 31, 23, 7, 10, 65, 73, 82, 9, 53, 47, 41,
+ 30, 24, 3, 68, 69, 74, 62, 107, 103, 92, 103, 102, 90, 97, 93, 87, 94, 92,
+ 93, 86, 87, 88, 96, 89, 83, 78, 78, 77, 74, 71, 68, 67, 0, 69, 69, 75,
+ 1, 2, 0, 1, 1, 2, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, 72,
+ 12, 16, 13, 17, 12, 14, 14, 12, 11, 4, 11, 7, 68, 65, 53, 54, 51, 53,
+ 52, 60, 57, 59, 59, 57, 62, 60, 55, 45, 26, 62, 62, 62, 62, 55, 53, 38,
+ 32, 29, 23, 13, 6, 65, 74, 62, 62, 62, 60, 56, 57, 52, 50, 42, 38, 33,
+ 28, 16, 8, 65, 5, 5, 67, 22, 21, 19, 15, 13, 13, 6, 6, 3, 65, 80,
+ 72, 83, 92, 10, 67, 72, 80, 75, 68, 74, 65, 6, 70, 74, 0, 4, 3, 4,
+ 10, 4, 3, 59, 48, 36, 26, 17, 4, 69, 84, 98, 66, 39, 28, 23, 13, 14,
+ 6, 2, 0, 75, 78, 73, 65, 72, 2, 8, 67, 70, 2, 6, 6, 6, 11, 9,
+ 4, 59, 48, 36, 26, 17, 4, 69, 84, 98, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 18, 32, 48, 56, 19, 90, 66,
+ 65, 66, 7, 5, 67, 0, 5, 24, 26, 8, 74, 93, 84, 86, 72, 65, 66, 7,
+ 74, 77, 11, 13, 67, 77, 86, 3, 76, 84, 97, 7, 71, 79, 4, 78, 79, 90,
+ 65, 76, 70, 84, 67, 2, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 36, 6,
+ 81, 90, 74, 80, 7, 65, 79, 75, 93, 76, 90, 85, 93, 80, 84, 87, 88, 24,
+ 65, 69, 94, 71, 92, 82, 97, 6, 1, 2, 68, 13, 68, 67, 79, 90, 78, 80,
+ 78, 68, 75, 88, 82, 68, 93, 83, 10, 2, 80, 83, 1, 73, 67, 64, 3, 9,
+ 0, 69, 81, 87, 72, 13, 13, 85, 9, 7, 5, 4, 5, 4, 3, 3, 3, 7,
+ 5, 2, 3, 4, 71, 67, 5, 67, 14, 22, 23, 16, 8, 19, 12, 16, 8, 1,
+ 11, 10, 21, 89, 15, 26, 23, 44, 58, 32, 37, 53, 53, 32, 45, 45, 62, 62,
+ 26, 37, 26, 34, 45, 36, 49, 57, 62, 27, 26, 41, 32, 62, 2, 58, 62, 58,
+ 56, 55, 50, 47, 46, 41, 35, 31, 25, 19, 14, 68, 75, 73, 84, 15, 16, 13,
+ 14, 3, 3, 2, 12, 69, 72, 71, 83, 76, 106, 90, 7, 9, 10, 2, 66, 71,
+ 75, 77, 95, 81, 27, 15, 9, 64, 1, 75, 83, 87, 95, 65, 29, 21, 16, 14,
+ 6, 1, 65, 69, 77, 67, 38, 31, 22, 7, 10, 65, 73, 81, 9, 53, 46, 40,
+ 29, 24, 3, 68, 69, 74, 62, 106, 102, 91, 101, 100, 89, 95, 91, 86, 92, 90,
+ 91, 85, 86, 87, 95, 87, 83, 78, 78, 76, 73, 71, 68, 67, 64, 69, 69, 75,
+ 1, 2, 1, 1, 1, 2, 2, 5, 1, 0, 1, 4, 65, 69, 73, 69, 0, 73,
+ 11, 16, 12, 16, 11, 13, 14, 11, 10, 4, 11, 6, 68, 66, 52, 53, 50, 51,
+ 50, 58, 55, 57, 57, 54, 61, 57, 52, 42, 24, 62, 62, 62, 62, 52, 50, 35,
+ 30, 27, 21, 11, 5, 66, 75, 62, 62, 62, 58, 53, 54, 50, 47, 40, 36, 31,
+ 25, 14, 6, 67, 4, 4, 69, 21, 20, 17, 13, 11, 11, 4, 5, 1, 66, 81,
+ 73, 84, 93, 8, 68, 73, 80, 75, 67, 74, 64, 7, 70, 73, 1, 5, 3, 5,
+ 11, 4, 3, 58, 46, 33, 23, 14, 0, 73, 88, 101, 66, 39, 28, 23, 13, 15,
+ 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, 6, 6, 6, 12, 9,
+ 4, 58, 46, 33, 23, 14, 0, 73, 88, 101, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 16, 29, 47, 56, 18, 89, 67,
+ 65, 66, 6, 4, 67, 64, 3, 22, 23, 4, 77, 95, 82, 86, 72, 65, 66, 6,
+ 75, 77, 11, 12, 67, 77, 86, 2, 77, 84, 97, 6, 71, 79, 4, 78, 79, 90,
+ 65, 76, 71, 84, 67, 2, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 35, 5,
+ 82, 88, 73, 79, 8, 0, 78, 74, 92, 75, 89, 84, 91, 80, 84, 87, 88, 24,
+ 65, 69, 92, 71, 92, 82, 96, 5, 0, 1, 69, 13, 68, 67, 79, 90, 78, 80,
+ 78, 68, 75, 87, 81, 68, 92, 82, 14, 6, 77, 81, 1, 73, 67, 64, 2, 9,
+ 0, 69, 81, 85, 72, 11, 11, 83, 9, 7, 5, 4, 5, 4, 4, 3, 3, 6,
+ 4, 2, 3, 4, 73, 67, 5, 68, 13, 20, 22, 15, 7, 19, 12, 15, 6, 1,
+ 10, 9, 20, 89, 14, 25, 22, 41, 54, 30, 35, 50, 50, 29, 42, 43, 55, 62,
+ 22, 34, 24, 31, 41, 33, 45, 52, 59, 24, 24, 37, 30, 62, 0, 55, 59, 55,
+ 53, 52, 47, 44, 43, 39, 32, 28, 23, 17, 12, 70, 75, 74, 85, 14, 14, 11,
+ 12, 1, 1, 0, 10, 70, 73, 72, 84, 77, 106, 89, 7, 9, 10, 2, 66, 71,
+ 75, 77, 93, 80, 27, 15, 9, 64, 1, 74, 82, 86, 94, 65, 29, 21, 16, 14,
+ 7, 1, 65, 69, 77, 68, 38, 30, 21, 6, 10, 65, 73, 81, 8, 52, 45, 38,
+ 28, 23, 3, 68, 69, 74, 62, 105, 101, 90, 100, 99, 88, 94, 90, 85, 91, 89,
+ 89, 85, 86, 87, 94, 86, 83, 78, 78, 76, 73, 71, 69, 68, 65, 69, 70, 76,
+ 1, 2, 2, 1, 0, 2, 2, 4, 1, 0, 1, 3, 65, 69, 73, 69, 0, 74,
+ 10, 16, 10, 15, 10, 12, 13, 10, 9, 4, 10, 4, 69, 68, 50, 51, 49, 49,
+ 48, 55, 52, 54, 54, 51, 58, 54, 48, 39, 22, 62, 62, 61, 60, 48, 46, 32,
+ 27, 24, 19, 9, 3, 67, 76, 59, 60, 60, 55, 50, 51, 47, 43, 37, 33, 28,
+ 22, 12, 4, 69, 3, 3, 71, 19, 18, 15, 10, 9, 9, 2, 3, 64, 68, 82,
+ 75, 85, 94, 6, 70, 75, 80, 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, 5,
+ 11, 4, 2, 56, 44, 30, 19, 10, 67, 78, 93, 104, 66, 39, 28, 23, 13, 15,
+ 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, 6, 6, 6, 12, 8,
+ 3, 56, 44, 30, 19, 10, 67, 78, 93, 104, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 15, 27, 46, 57, 18, 87, 67, 64,
+ 65, 6, 4, 66, 64, 2, 21, 21, 1, 79, 96, 79, 85, 71, 64, 65, 6, 75, 76,
+ 11, 12, 66, 76, 85, 2, 77, 83, 96, 6, 70, 78, 4, 77, 78, 89, 64, 75, 71,
+ 83, 66, 2, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 35, 5, 82, 85, 71, 77,
+ 10, 3, 76, 72, 90, 73, 87, 82, 88, 80, 83, 86, 87, 24, 65, 68, 89, 70, 91,
+ 81, 94, 5, 0, 1, 69, 14, 68, 66, 78, 89, 77, 79, 77, 67, 74, 85, 79, 67,
+ 90, 80, 19, 11, 73, 78, 2, 72, 66, 0, 2, 10, 1, 68, 80, 82, 71, 9, 10,
+ 80, 9, 8, 5, 5, 6, 5, 6, 4, 4, 6, 4, 2, 4, 5, 74, 66, 5, 68,
+ 13, 19, 22, 15, 7, 19, 12, 15, 5, 2, 10, 9, 20, 89, 14, 25, 22, 39, 51,
+ 29, 34, 48, 48, 27, 40, 41, 49, 62, 19, 32, 23, 29, 38, 31, 42, 48, 55, 22,
+ 22, 34, 28, 62, 64, 53, 57, 53, 51, 50, 45, 42, 41, 37, 30, 26, 22, 16, 11,
+ 71, 75, 74, 85, 14, 13, 10, 11, 0, 0, 64, 9, 71, 73, 73, 84, 77, 105, 87,
+ 8, 10, 10, 3, 65, 70, 74, 76, 90, 78, 28, 16, 10, 0, 2, 72, 80, 84, 92,
+ 64, 30, 22, 17, 15, 8, 2, 64, 68, 76, 68, 39, 30, 21, 6, 11, 64, 73, 80,
+ 8, 52, 45, 37, 27, 23, 4, 67, 68, 73, 62, 103, 99, 88, 98, 97, 86, 92, 88,
+ 83, 89, 87, 86, 84, 85, 86, 92, 84, 82, 77, 77, 75, 72, 70, 69, 68, 65, 69,
+ 70, 76, 2, 3, 3, 2, 0, 3, 3, 4, 2, 1, 1, 3, 64, 68, 72, 68, 1,
+ 74, 9, 16, 9, 15, 10, 12, 13, 10, 9, 4, 10, 3, 69, 69, 49, 50, 49, 48,
+ 47, 53, 50, 52, 52, 49, 56, 52, 45, 37, 20, 61, 60, 57, 56, 45, 43, 30, 25,
+ 22, 18, 8, 2, 67, 76, 57, 58, 58, 53, 48, 49, 45, 40, 35, 31, 26, 20, 11,
+ 3, 70, 3, 3, 72, 18, 17, 14, 8, 8, 8, 1, 2, 65, 69, 82, 76, 85, 94,
+ 5, 71, 76, 79, 74, 66, 73, 2, 10, 69, 72, 2, 6, 4, 6, 12, 4, 2, 55,
+ 42, 28, 16, 7, 71, 82, 97, 106, 65, 39, 29, 24, 14, 16, 7, 3, 1, 74, 77,
+ 72, 64, 71, 4, 10, 66, 69, 3, 7, 6, 7, 13, 8, 3, 55, 42, 28, 16, 7,
+ 71, 82, 97, 106, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 14, 25, 45, 57, 18, 85, 67,
+ 64, 64, 6, 3, 66, 65, 0, 20, 18, 66, 82, 98, 76, 84, 71, 64, 64, 6,
+ 75, 75, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, 78, 4, 77, 78, 89,
+ 64, 75, 71, 83, 66, 2, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 34, 5,
+ 82, 83, 70, 76, 12, 5, 75, 71, 88, 72, 86, 81, 86, 80, 83, 86, 87, 24,
+ 65, 67, 87, 70, 90, 80, 92, 5, 0, 1, 70, 14, 68, 66, 77, 88, 76, 78,
+ 76, 67, 73, 84, 78, 66, 89, 79, 24, 15, 70, 75, 2, 72, 66, 0, 2, 10,
+ 1, 68, 80, 80, 71, 7, 8, 77, 9, 8, 5, 5, 6, 5, 8, 5, 4, 6,
+ 4, 2, 5, 6, 75, 66, 5, 68, 12, 18, 21, 15, 6, 19, 12, 15, 4, 2,
+ 9, 8, 19, 89, 14, 24, 21, 37, 48, 28, 32, 46, 46, 25, 38, 39, 43, 62,
+ 15, 30, 21, 27, 35, 29, 39, 44, 51, 19, 20, 31, 26, 62, 66, 51, 55, 51,
+ 49, 48, 43, 40, 39, 35, 28, 24, 20, 14, 9, 73, 75, 74, 86, 13, 12, 9,
+ 10, 64, 64, 65, 7, 72, 73, 74, 85, 78, 104, 86, 9, 10, 10, 3, 64, 69,
+ 73, 75, 88, 77, 28, 16, 10, 1, 3, 71, 78, 82, 90, 0, 31, 23, 18, 16,
+ 9, 2, 64, 68, 75, 68, 40, 30, 20, 6, 11, 64, 73, 80, 8, 52, 44, 36,
+ 26, 23, 4, 67, 68, 73, 62, 102, 98, 87, 96, 95, 85, 90, 86, 82, 87, 85,
+ 84, 83, 84, 86, 91, 82, 82, 77, 77, 74, 72, 70, 69, 68, 66, 69, 70, 76,
+ 2, 3, 4, 2, 0, 3, 3, 4, 2, 1, 1, 2, 64, 68, 72, 68, 2, 75,
+ 8, 16, 8, 14, 9, 11, 13, 9, 8, 4, 10, 2, 69, 70, 48, 49, 48, 46,
+ 45, 51, 48, 50, 50, 46, 53, 49, 42, 34, 18, 57, 56, 53, 51, 42, 40, 27,
+ 23, 19, 16, 6, 1, 68, 77, 55, 56, 55, 51, 45, 46, 42, 37, 33, 28, 24,
+ 17, 9, 1, 72, 2, 2, 74, 17, 16, 12, 6, 6, 6, 64, 1, 67, 70, 83,
+ 77, 86, 95, 3, 72, 77, 79, 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6,
+ 13, 4, 2, 54, 40, 25, 13, 4, 75, 86, 101, 109, 65, 39, 29, 24, 14, 17,
+ 7, 3, 1, 74, 77, 72, 64, 71, 5, 11, 66, 69, 3, 7, 6, 7, 14, 8,
+ 3, 54, 40, 25, 13, 4, 75, 86, 101, 109, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 12, 23, 44, 57, 18, 83, 67,
+ 0, 0, 6, 3, 66, 65, 64, 19, 16, 69, 84, 99, 73, 83, 71, 0, 0, 6,
+ 76, 74, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, 77, 4, 77, 77, 89,
+ 64, 75, 71, 83, 66, 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 33, 4,
+ 82, 80, 69, 75, 13, 7, 73, 69, 86, 70, 85, 80, 84, 80, 83, 85, 87, 24,
+ 65, 66, 85, 70, 89, 80, 90, 5, 64, 0, 70, 14, 68, 65, 77, 87, 75, 78,
+ 75, 66, 72, 82, 76, 66, 88, 78, 29, 20, 67, 72, 2, 72, 66, 1, 2, 10,
+ 2, 67, 79, 78, 71, 5, 6, 74, 9, 8, 5, 5, 6, 6, 9, 6, 4, 6,
+ 4, 2, 5, 7, 76, 66, 5, 69, 12, 17, 21, 15, 6, 19, 12, 15, 3, 2,
+ 8, 7, 19, 89, 14, 24, 21, 35, 45, 27, 30, 44, 43, 23, 35, 37, 36, 62,
+ 12, 28, 19, 25, 32, 26, 36, 40, 47, 16, 18, 27, 24, 62, 68, 49, 53, 49,
+ 46, 45, 41, 38, 37, 33, 26, 22, 18, 12, 8, 75, 75, 74, 86, 12, 11, 8,
+ 9, 65, 65, 66, 5, 73, 74, 75, 86, 78, 104, 84, 10, 11, 10, 3, 0, 69,
+ 73, 75, 86, 76, 28, 16, 11, 2, 4, 70, 77, 81, 88, 1, 31, 23, 18, 16,
+ 10, 3, 64, 68, 75, 68, 40, 30, 19, 6, 11, 64, 73, 79, 8, 51, 44, 35,
+ 25, 23, 4, 67, 68, 73, 62, 101, 96, 86, 95, 94, 84, 88, 84, 81, 86, 83,
+ 82, 83, 83, 85, 90, 80, 81, 77, 77, 74, 71, 70, 69, 68, 66, 69, 70, 77,
+ 3, 4, 5, 2, 0, 4, 3, 4, 2, 1, 1, 2, 64, 68, 72, 68, 2, 76,
+ 7, 16, 7, 13, 8, 11, 13, 8, 7, 4, 10, 1, 69, 71, 47, 48, 47, 45,
+ 43, 49, 46, 48, 47, 44, 50, 46, 39, 32, 16, 53, 52, 49, 46, 38, 37, 25,
+ 21, 17, 14, 4, 64, 69, 78, 53, 53, 53, 48, 42, 44, 40, 34, 30, 26, 21,
+ 14, 7, 64, 73, 1, 1, 75, 15, 14, 10, 4, 5, 4, 66, 0, 68, 71, 84,
+ 78, 87, 96, 2, 73, 78, 79, 73, 65, 72, 4, 12, 69, 71, 3, 7, 4, 7,
+ 14, 4, 2, 53, 38, 23, 10, 1, 79, 90, 105, 112, 65, 39, 29, 24, 14, 17,
+ 8, 3, 1, 73, 77, 72, 0, 70, 6, 12, 66, 68, 3, 7, 6, 7, 14, 8,
+ 3, 53, 38, 23, 10, 1, 79, 90, 105, 112, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 21, 43, 57, 17, 81, 67,
+ 0, 1, 5, 2, 66, 66, 66, 18, 13, 73, 87, 101, 70, 82, 71, 0, 1, 5,
+ 76, 73, 11, 10, 66, 75, 83, 2, 77, 83, 96, 6, 70, 77, 4, 77, 77, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 32, 4,
+ 82, 78, 68, 74, 15, 9, 72, 68, 85, 69, 83, 79, 82, 80, 82, 85, 87, 24,
+ 65, 65, 83, 70, 89, 79, 88, 5, 64, 0, 71, 14, 68, 65, 76, 86, 74, 77,
+ 74, 66, 72, 81, 75, 65, 87, 77, 34, 24, 64, 69, 2, 71, 66, 1, 2, 10,
+ 2, 67, 79, 76, 71, 3, 4, 72, 9, 9, 5, 5, 6, 6, 11, 7, 5, 5,
+ 4, 2, 6, 7, 77, 66, 5, 69, 11, 16, 20, 14, 5, 19, 12, 15, 2, 2,
+ 7, 6, 18, 89, 13, 23, 20, 33, 41, 26, 28, 42, 41, 21, 33, 35, 30, 62,
+ 8, 26, 17, 22, 29, 24, 32, 35, 43, 13, 16, 24, 22, 62, 69, 47, 51, 46,
+ 44, 43, 39, 36, 35, 31, 23, 20, 16, 10, 6, 77, 75, 74, 87, 11, 10, 7,
+ 7, 66, 67, 67, 4, 74, 74, 76, 86, 79, 103, 83, 11, 11, 10, 4, 0, 68,
+ 72, 74, 84, 74, 28, 17, 11, 2, 5, 69, 75, 79, 87, 1, 32, 24, 19, 17,
+ 11, 3, 64, 67, 74, 68, 41, 30, 19, 5, 11, 64, 73, 79, 8, 51, 43, 34,
+ 24, 23, 4, 66, 68, 73, 62, 99, 95, 85, 93, 92, 83, 87, 83, 80, 84, 82,
+ 80, 82, 82, 85, 89, 79, 81, 77, 77, 73, 71, 70, 70, 68, 67, 69, 70, 77,
+ 3, 4, 6, 2, 0, 4, 3, 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 77,
+ 6, 16, 6, 13, 7, 10, 13, 7, 6, 4, 10, 0, 69, 72, 46, 47, 46, 43,
+ 41, 47, 44, 45, 45, 41, 47, 43, 36, 29, 14, 48, 48, 45, 41, 35, 33, 22,
+ 18, 14, 12, 2, 65, 70, 78, 50, 51, 50, 46, 39, 41, 37, 31, 28, 23, 19,
+ 11, 5, 66, 75, 0, 1, 77, 14, 13, 9, 2, 3, 2, 67, 64, 70, 72, 85,
+ 80, 88, 96, 0, 75, 80, 78, 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7,
+ 15, 4, 2, 52, 36, 20, 7, 66, 83, 95, 109, 115, 64, 39, 29, 24, 14, 18,
+ 8, 3, 1, 73, 77, 72, 0, 70, 6, 13, 66, 68, 4, 8, 6, 7, 15, 8,
+ 3, 52, 36, 20, 7, 66, 83, 95, 109, 115, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 10, 19, 42, 57, 17, 79, 67,
+ 0, 2, 5, 2, 66, 67, 68, 17, 11, 76, 89, 103, 67, 81, 70, 0, 2, 5,
+ 76, 72, 11, 10, 66, 75, 82, 2, 77, 83, 96, 6, 70, 77, 4, 77, 76, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 31, 3,
+ 82, 75, 67, 73, 17, 11, 70, 66, 83, 67, 82, 78, 79, 80, 82, 84, 86, 24,
+ 65, 64, 81, 70, 88, 79, 86, 5, 65, 64, 71, 14, 68, 64, 76, 85, 73, 77,
+ 73, 65, 71, 79, 73, 64, 85, 76, 39, 28, 2, 66, 3, 71, 65, 2, 2, 10,
+ 3, 67, 78, 74, 71, 1, 2, 69, 9, 9, 5, 5, 6, 7, 12, 8, 5, 5,
+ 4, 2, 6, 8, 78, 65, 5, 70, 11, 15, 20, 14, 5, 19, 12, 15, 1, 3,
+ 6, 6, 18, 89, 13, 22, 19, 31, 38, 25, 27, 40, 39, 19, 30, 33, 24, 62,
+ 5, 24, 15, 20, 26, 21, 29, 31, 39, 11, 14, 20, 20, 62, 71, 45, 49, 44,
+ 42, 41, 37, 34, 33, 29, 21, 18, 14, 9, 4, 79, 75, 74, 87, 10, 9, 6,
+ 6, 67, 68, 68, 2, 75, 75, 77, 87, 80, 102, 81, 12, 12, 10, 4, 1, 68,
+ 72, 73, 82, 73, 28, 17, 12, 3, 6, 68, 74, 78, 85, 2, 33, 25, 20, 17,
+ 12, 4, 0, 67, 74, 68, 41, 30, 18, 5, 11, 64, 73, 78, 8, 50, 42, 33,
+ 23, 23, 4, 66, 68, 72, 62, 98, 93, 83, 91, 91, 82, 85, 81, 79, 82, 80,
+ 78, 81, 81, 84, 88, 77, 81, 77, 76, 73, 70, 70, 70, 68, 67, 69, 70, 78,
+ 4, 4, 7, 2, 0, 4, 3, 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 78,
+ 5, 16, 5, 12, 7, 9, 13, 7, 5, 4, 10, 64, 69, 73, 45, 46, 45, 41,
+ 39, 45, 42, 43, 42, 38, 44, 40, 33, 27, 12, 44, 44, 41, 36, 32, 30, 20,
+ 16, 12, 10, 1, 67, 70, 79, 48, 48, 48, 44, 36, 38, 35, 28, 26, 21, 17,
+ 8, 3, 68, 76, 0, 0, 79, 13, 11, 7, 0, 1, 0, 69, 65, 71, 73, 85,
+ 81, 89, 97, 64, 76, 81, 78, 73, 0, 71, 6, 14, 68, 69, 4, 8, 4, 8,
+ 16, 4, 2, 51, 34, 17, 4, 69, 87, 99, 113, 118, 64, 39, 29, 24, 14, 18,
+ 8, 4, 2, 72, 77, 72, 1, 70, 7, 14, 66, 68, 4, 8, 6, 8, 15, 8,
+ 3, 51, 34, 17, 4, 69, 87, 99, 113, 118, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 17, 41, 57, 17, 78, 67,
+ 1, 2, 5, 1, 65, 67, 69, 15, 8, 80, 92, 104, 65, 80, 70, 1, 2, 5,
+ 77, 72, 11, 9, 66, 75, 82, 2, 77, 82, 95, 6, 69, 76, 4, 76, 76, 88,
+ 64, 75, 71, 83, 65, 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 31, 3,
+ 82, 73, 66, 72, 18, 14, 69, 65, 81, 66, 81, 77, 77, 80, 82, 84, 86, 24,
+ 65, 0, 78, 70, 87, 78, 84, 4, 65, 64, 72, 15, 68, 64, 75, 85, 73, 76,
+ 72, 65, 70, 78, 72, 64, 84, 75, 44, 33, 5, 0, 3, 71, 65, 2, 2, 10,
+ 3, 66, 78, 72, 70, 64, 0, 66, 9, 9, 5, 5, 7, 7, 14, 9, 5, 5,
+ 4, 2, 7, 9, 79, 65, 5, 70, 10, 14, 19, 14, 4, 19, 12, 15, 64, 3,
+ 5, 5, 17, 89, 13, 22, 19, 29, 35, 24, 25, 37, 36, 17, 28, 31, 17, 62,
+ 1, 22, 14, 18, 22, 19, 26, 27, 34, 8, 12, 17, 18, 62, 73, 43, 47, 42,
+ 39, 38, 35, 31, 31, 27, 19, 15, 12, 7, 3, 80, 75, 74, 88, 9, 8, 5,
+ 5, 68, 69, 69, 0, 76, 75, 78, 88, 80, 102, 80, 13, 12, 10, 4, 2, 67,
+ 71, 73, 80, 72, 29, 17, 12, 4, 7, 67, 72, 76, 83, 3, 33, 25, 20, 18,
+ 13, 4, 0, 67, 73, 68, 42, 30, 17, 5, 11, 64, 73, 78, 7, 50, 42, 32,
+ 22, 22, 4, 66, 68, 72, 62, 97, 92, 82, 90, 89, 81, 83, 79, 78, 81, 78,
+ 76, 81, 80, 84, 87, 75, 80, 77, 76, 72, 70, 70, 70, 68, 68, 69, 70, 78,
+ 4, 5, 8, 2, 0, 5, 4, 4, 3, 2, 1, 0, 64, 68, 72, 68, 4, 79,
+ 4, 16, 4, 11, 6, 9, 13, 6, 5, 4, 9, 66, 70, 74, 43, 45, 44, 40,
+ 37, 43, 40, 41, 40, 36, 41, 38, 30, 24, 10, 40, 40, 37, 32, 28, 27, 17,
+ 14, 9, 8, 64, 68, 71, 80, 46, 46, 45, 41, 33, 36, 32, 25, 23, 18, 14,
+ 5, 1, 69, 78, 64, 64, 80, 11, 10, 5, 65, 0, 65, 71, 66, 73, 74, 86,
+ 82, 90, 98, 66, 77, 82, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8,
+ 17, 4, 2, 50, 32, 15, 1, 72, 91, 103, 117, 121, 64, 39, 29, 24, 14, 19,
+ 9, 4, 2, 72, 76, 71, 1, 69, 8, 15, 65, 67, 4, 8, 6, 8, 16, 8,
+ 3, 50, 32, 15, 1, 72, 91, 103, 117, 121, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 7, 15, 40, 57, 17, 76, 67,
+ 1, 3, 4, 1, 65, 68, 71, 14, 6, 83, 94, 106, 1, 79, 70, 1, 3, 4,
+ 77, 71, 11, 9, 66, 74, 81, 2, 77, 82, 95, 6, 69, 76, 4, 76, 75, 87,
+ 64, 75, 71, 83, 64, 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 30, 2,
+ 82, 70, 65, 71, 20, 16, 67, 0, 80, 64, 79, 76, 75, 80, 81, 83, 86, 24,
+ 65, 1, 76, 70, 86, 78, 82, 4, 66, 65, 72, 15, 68, 0, 75, 84, 72, 76,
+ 71, 64, 69, 76, 70, 0, 83, 74, 49, 37, 8, 3, 3, 70, 65, 3, 2, 10,
+ 4, 66, 77, 70, 70, 66, 65, 0, 9, 10, 5, 5, 7, 8, 15, 10, 6, 4,
+ 4, 2, 7, 9, 80, 65, 5, 71, 10, 13, 19, 13, 4, 19, 12, 15, 65, 3,
+ 4, 4, 17, 89, 13, 21, 18, 27, 32, 23, 23, 35, 34, 15, 25, 29, 11, 62,
+ 65, 20, 12, 15, 19, 16, 23, 22, 30, 5, 10, 13, 16, 62, 74, 41, 45, 40,
+ 37, 36, 33, 29, 29, 25, 16, 13, 10, 5, 1, 82, 75, 74, 88, 8, 7, 4,
+ 3, 69, 70, 70, 64, 77, 76, 79, 88, 81, 101, 78, 14, 13, 10, 5, 2, 67,
+ 71, 72, 78, 70, 29, 18, 13, 4, 8, 66, 71, 75, 81, 3, 34, 26, 21, 18,
+ 14, 5, 0, 66, 73, 68, 42, 30, 17, 4, 11, 64, 73, 77, 7, 49, 41, 31,
+ 21, 22, 4, 65, 68, 72, 62, 95, 90, 81, 88, 88, 80, 82, 78, 77, 79, 77,
+ 74, 80, 79, 83, 86, 73, 80, 77, 76, 72, 69, 70, 71, 68, 68, 69, 70, 79,
+ 5, 5, 9, 2, 0, 5, 4, 4, 3, 2, 1, 0, 64, 68, 72, 68, 4, 80,
+ 3, 16, 3, 11, 5, 8, 13, 5, 4, 4, 9, 67, 70, 75, 42, 44, 43, 38,
+ 35, 41, 38, 38, 37, 33, 38, 35, 27, 22, 8, 35, 36, 33, 27, 25, 24, 15,
+ 12, 7, 6, 66, 70, 72, 80, 43, 43, 43, 39, 30, 33, 30, 22, 21, 16, 12,
+ 2, 64, 71, 79, 65, 64, 82, 10, 8, 4, 67, 65, 67, 72, 67, 74, 75, 87,
+ 84, 91, 98, 67, 79, 84, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9,
+ 18, 4, 2, 49, 30, 12, 65, 76, 95, 107, 121, 124, 0, 39, 29, 24, 14, 19,
+ 9, 4, 2, 71, 76, 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 16, 8,
+ 3, 49, 30, 12, 65, 76, 95, 107, 121, 124, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 5, 12, 39, 57, 16, 74, 68,
+ 1, 4, 4, 0, 65, 69, 73, 13, 3, 87, 97, 108, 4, 78, 70, 1, 4, 4,
+ 78, 70, 11, 8, 66, 74, 81, 1, 78, 82, 95, 6, 69, 76, 4, 76, 75, 87,
+ 64, 75, 71, 83, 64, 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 29, 2,
+ 83, 68, 64, 70, 21, 18, 66, 1, 78, 0, 78, 75, 73, 80, 81, 83, 86, 24,
+ 65, 2, 74, 70, 86, 77, 80, 4, 66, 65, 73, 15, 68, 0, 74, 83, 71, 75,
+ 71, 64, 69, 75, 69, 0, 82, 73, 53, 41, 11, 5, 3, 70, 65, 3, 1, 10,
+ 4, 66, 77, 68, 70, 68, 67, 2, 9, 10, 5, 5, 7, 8, 17, 10, 6, 4,
+ 3, 2, 8, 10, 82, 65, 5, 71, 9, 11, 18, 13, 3, 19, 12, 14, 66, 3,
+ 3, 3, 16, 89, 12, 20, 17, 25, 28, 21, 21, 33, 31, 12, 23, 27, 4, 62,
+ 69, 18, 10, 13, 16, 14, 19, 18, 26, 2, 8, 10, 14, 62, 76, 39, 42, 37,
+ 34, 33, 30, 27, 26, 23, 14, 11, 8, 3, 64, 84, 75, 75, 89, 7, 5, 3,
+ 2, 70, 72, 72, 66, 78, 76, 80, 89, 82, 101, 77, 15, 13, 10, 5, 3, 66,
+ 70, 72, 76, 69, 29, 18, 13, 5, 9, 65, 69, 73, 80, 4, 34, 26, 21, 19,
+ 15, 5, 0, 66, 72, 69, 43, 30, 16, 4, 11, 64, 73, 77, 7, 49, 40, 30,
+ 20, 22, 4, 65, 68, 72, 62, 94, 89, 80, 87, 86, 79, 80, 76, 76, 78, 75,
+ 72, 80, 79, 83, 85, 72, 80, 77, 76, 71, 69, 70, 71, 68, 69, 69, 70, 79,
+ 5, 5, 10, 2, 64, 5, 4, 3, 3, 2, 1, 64, 64, 68, 72, 68, 5, 81,
+ 2, 16, 1, 10, 4, 7, 12, 4, 3, 4, 9, 68, 70, 77, 41, 42, 42, 36,
+ 33, 39, 36, 36, 35, 30, 35, 32, 24, 19, 6, 31, 32, 28, 22, 21, 20, 12,
+ 9, 4, 4, 68, 71, 73, 81, 41, 41, 40, 36, 27, 30, 27, 19, 18, 13, 9,
+ 64, 66, 73, 81, 66, 65, 84, 8, 7, 2, 69, 67, 69, 74, 69, 76, 77, 88,
+ 85, 92, 99, 69, 80, 85, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9,
+ 18, 4, 1, 48, 28, 9, 68, 79, 99, 112, 126, 126, 0, 39, 29, 24, 14, 20,
+ 9, 4, 2, 71, 76, 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 17, 8,
+ 2, 48, 28, 9, 68, 79, 99, 112, 126, 126, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 4, 10, 38, 58, 16, 72, 68,
+ 2, 5, 4, 64, 65, 69, 74, 12, 1, 91, 100, 109, 7, 77, 69, 2, 5, 4,
+ 78, 69, 11, 8, 65, 74, 80, 1, 78, 82, 95, 6, 69, 75, 4, 76, 75, 87,
+ 64, 75, 71, 82, 64, 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 28, 2,
+ 83, 66, 1, 69, 23, 20, 64, 2, 76, 2, 77, 73, 70, 80, 81, 83, 85, 24,
+ 65, 3, 72, 69, 85, 76, 78, 4, 66, 65, 73, 15, 68, 0, 73, 82, 70, 74,
+ 70, 0, 68, 74, 67, 1, 80, 72, 58, 46, 15, 8, 4, 70, 64, 4, 1, 10,
+ 4, 65, 76, 65, 70, 70, 68, 5, 9, 10, 5, 5, 7, 9, 19, 11, 6, 4,
+ 3, 2, 9, 11, 83, 64, 5, 71, 8, 10, 17, 13, 2, 19, 12, 14, 67, 4,
+ 2, 3, 15, 89, 12, 20, 17, 23, 25, 20, 20, 31, 29, 10, 21, 25, 65, 62,
+ 72, 16, 8, 11, 13, 12, 16, 14, 22, 0, 6, 7, 12, 62, 78, 37, 40, 35,
+ 32, 31, 28, 25, 24, 21, 12, 9, 7, 2, 65, 86, 75, 75, 89, 7, 4, 2,
+ 1, 71, 73, 73, 68, 79, 76, 81, 90, 82, 100, 76, 16, 13, 10, 5, 4, 65,
+ 69, 71, 73, 68, 29, 18, 13, 6, 10, 64, 67, 71, 78, 5, 35, 27, 22, 20,
+ 16, 5, 1, 66, 71, 69, 44, 30, 15, 4, 12, 0, 73, 76, 7, 49, 40, 29,
+ 19, 22, 4, 65, 68, 71, 62, 93, 88, 78, 85, 84, 78, 78, 74, 75, 76, 73,
+ 70, 79, 78, 82, 84, 70, 79, 76, 75, 70, 68, 70, 71, 68, 70, 69, 70, 79,
+ 5, 6, 11, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, 71, 68, 6, 81,
+ 1, 16, 0, 9, 4, 7, 12, 4, 2, 4, 9, 69, 70, 78, 40, 41, 42, 35,
+ 31, 37, 34, 34, 33, 28, 32, 29, 21, 16, 4, 27, 28, 24, 17, 18, 17, 9,
+ 7, 2, 3, 69, 72, 73, 82, 39, 39, 38, 34, 25, 28, 25, 16, 16, 11, 7,
+ 66, 68, 75, 83, 66, 66, 85, 7, 6, 0, 71, 68, 70, 76, 70, 78, 78, 88,
+ 86, 92, 100, 71, 81, 86, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, 10,
+ 19, 4, 1, 47, 26, 7, 71, 82, 103, 116, 126, 126, 0, 39, 29, 25, 15, 21,
+ 10, 5, 3, 71, 76, 71, 2, 68, 10, 17, 65, 66, 5, 9, 6, 9, 18, 8,
+ 2, 47, 26, 7, 71, 82, 103, 116, 126, 126, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 3, 8, 37, 58, 16, 70, 68,
+ 2, 6, 3, 64, 65, 70, 76, 11, 65, 94, 102, 111, 10, 76, 69, 2, 6, 3,
+ 78, 68, 11, 7, 65, 73, 79, 1, 78, 82, 95, 6, 69, 75, 4, 76, 74, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 27, 1,
+ 83, 0, 2, 68, 25, 22, 0, 4, 75, 3, 75, 72, 68, 80, 80, 82, 85, 24,
+ 65, 4, 70, 69, 84, 76, 76, 4, 67, 66, 74, 15, 68, 1, 73, 81, 69, 74,
+ 69, 0, 67, 72, 66, 2, 79, 71, 62, 50, 18, 11, 4, 69, 64, 4, 1, 10,
+ 5, 65, 76, 0, 70, 72, 70, 8, 9, 11, 5, 5, 7, 9, 20, 12, 7, 3,
+ 3, 2, 9, 11, 84, 64, 5, 72, 8, 9, 17, 12, 2, 19, 12, 14, 68, 4,
+ 1, 2, 15, 89, 12, 19, 16, 21, 22, 19, 18, 29, 27, 8, 18, 23, 71, 62,
+ 76, 14, 6, 8, 10, 9, 13, 9, 18, 66, 4, 3, 10, 62, 79, 35, 38, 33,
+ 30, 29, 26, 23, 22, 19, 9, 7, 5, 0, 67, 88, 75, 75, 90, 6, 3, 1,
+ 64, 72, 74, 74, 69, 80, 77, 82, 90, 83, 99, 74, 17, 14, 10, 6, 4, 65,
+ 69, 70, 71, 66, 29, 19, 14, 6, 11, 0, 66, 70, 76, 5, 36, 28, 23, 20,
+ 17, 6, 1, 65, 71, 69, 44, 30, 15, 3, 12, 0, 73, 76, 7, 48, 39, 28,
+ 18, 22, 4, 64, 68, 71, 62, 91, 86, 77, 83, 83, 77, 77, 73, 74, 74, 72,
+ 68, 78, 77, 82, 83, 68, 79, 76, 75, 70, 68, 70, 72, 68, 70, 69, 70, 80,
+ 6, 6, 12, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, 71, 68, 6, 82,
+ 0, 16, 64, 9, 3, 6, 12, 3, 1, 4, 9, 70, 70, 79, 39, 40, 41, 33,
+ 29, 35, 32, 31, 30, 25, 29, 26, 18, 14, 2, 22, 24, 20, 12, 15, 14, 7,
+ 5, 64, 1, 71, 74, 74, 82, 36, 36, 35, 32, 22, 25, 22, 13, 14, 8, 5,
+ 69, 70, 77, 84, 67, 66, 87, 6, 4, 64, 73, 70, 72, 77, 71, 79, 79, 89,
+ 88, 93, 100, 72, 83, 88, 76, 71, 3, 69, 11, 20, 67, 66, 7, 11, 4, 10,
+ 20, 4, 1, 46, 24, 4, 74, 86, 107, 120, 126, 126, 1, 39, 29, 25, 15, 21,
+ 10, 5, 3, 70, 76, 71, 3, 68, 11, 18, 65, 66, 6, 10, 6, 9, 18, 8,
+ 2, 46, 24, 4, 74, 86, 107, 120, 126, 126, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 1, 6, 36, 58, 16, 69, 68,
+ 3, 6, 3, 65, 64, 70, 77, 9, 67, 98, 105, 112, 12, 75, 69, 3, 6, 3,
+ 79, 68, 11, 7, 65, 73, 79, 1, 78, 81, 94, 6, 68, 74, 4, 75, 74, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 27, 1,
+ 83, 2, 3, 67, 26, 25, 2, 5, 73, 5, 74, 71, 66, 80, 80, 82, 85, 24,
+ 65, 5, 67, 69, 83, 75, 74, 3, 67, 66, 74, 16, 68, 1, 72, 81, 69, 73,
+ 68, 1, 66, 71, 64, 2, 78, 70, 62, 55, 21, 14, 4, 69, 64, 5, 1, 10,
+ 5, 64, 75, 2, 69, 74, 72, 11, 9, 11, 5, 5, 8, 10, 22, 13, 7, 3,
+ 3, 2, 10, 12, 85, 64, 5, 72, 7, 8, 16, 12, 1, 19, 12, 14, 70, 4,
+ 0, 1, 14, 89, 12, 19, 16, 19, 19, 18, 16, 26, 24, 6, 16, 21, 78, 62,
+ 79, 12, 5, 6, 6, 7, 10, 5, 13, 69, 2, 0, 8, 62, 81, 33, 36, 31,
+ 27, 26, 24, 20, 20, 17, 7, 4, 3, 65, 68, 89, 75, 75, 90, 5, 2, 0,
+ 65, 73, 75, 75, 71, 81, 77, 83, 91, 83, 99, 73, 18, 14, 10, 6, 5, 64,
+ 68, 70, 69, 65, 30, 19, 14, 7, 12, 1, 64, 68, 74, 6, 36, 28, 23, 21,
+ 18, 6, 1, 65, 70, 69, 45, 30, 14, 3, 12, 0, 73, 75, 6, 48, 39, 27,
+ 17, 21, 4, 64, 68, 71, 62, 90, 85, 76, 82, 81, 76, 75, 71, 73, 73, 70,
+ 66, 78, 76, 81, 82, 66, 78, 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 80,
+ 6, 7, 13, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, 71, 68, 7, 83,
+ 64, 16, 65, 8, 2, 6, 12, 2, 1, 4, 8, 72, 71, 80, 37, 39, 40, 32,
+ 27, 33, 30, 29, 28, 23, 26, 24, 15, 11, 0, 18, 20, 16, 8, 11, 11, 4,
+ 3, 66, 64, 73, 75, 75, 83, 34, 34, 33, 29, 19, 23, 20, 10, 11, 6, 2,
+ 72, 72, 78, 86, 68, 67, 88, 4, 3, 66, 75, 71, 74, 79, 72, 81, 80, 90,
+ 89, 94, 101, 74, 84, 89, 76, 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11,
+ 21, 4, 1, 45, 22, 2, 77, 89, 111, 124, 126, 126, 1, 39, 29, 25, 15, 22,
+ 11, 5, 3, 70, 75, 70, 3, 67, 12, 19, 64, 65, 6, 10, 6, 9, 19, 8,
+ 2, 45, 22, 2, 77, 89, 111, 124, 126, 126, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 0, 4, 35, 58, 15, 67, 68,
+ 3, 7, 3, 65, 64, 71, 79, 8, 70, 101, 107, 114, 15, 74, 69, 3, 7, 3,
+ 79, 67, 11, 6, 65, 73, 78, 1, 78, 81, 94, 6, 68, 74, 4, 75, 73, 86,
+ 64, 75, 71, 82, 0, 2, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 26, 0,
+ 83, 5, 4, 66, 28, 27, 3, 7, 71, 6, 73, 70, 64, 80, 80, 81, 85, 24,
+ 65, 6, 65, 69, 83, 75, 72, 3, 68, 67, 75, 16, 68, 2, 72, 80, 68, 73,
+ 67, 1, 66, 69, 0, 3, 77, 69, 62, 59, 24, 17, 4, 69, 64, 5, 1, 10,
+ 6, 64, 75, 4, 69, 76, 74, 13, 9, 11, 5, 5, 8, 10, 23, 14, 7, 3,
+ 3, 2, 10, 13, 86, 64, 5, 73, 7, 7, 16, 12, 1, 19, 12, 14, 71, 4,
+ 64, 0, 14, 89, 11, 18, 15, 17, 15, 17, 14, 24, 22, 4, 13, 19, 84, 62,
+ 83, 10, 3, 4, 3, 4, 6, 1, 9, 72, 0, 67, 6, 62, 83, 31, 34, 28,
+ 25, 24, 22, 18, 18, 15, 5, 2, 1, 67, 70, 91, 75, 75, 91, 4, 1, 64,
+ 66, 74, 77, 76, 73, 82, 78, 84, 92, 84, 98, 71, 19, 15, 10, 6, 6, 64,
+ 68, 69, 67, 64, 30, 19, 15, 8, 13, 2, 0, 67, 73, 7, 37, 29, 24, 21,
+ 19, 7, 1, 65, 70, 69, 45, 30, 13, 3, 12, 0, 73, 75, 6, 47, 38, 26,
+ 16, 21, 4, 64, 68, 71, 62, 89, 83, 75, 80, 80, 75, 73, 69, 72, 71, 68,
+ 64, 77, 75, 81, 81, 65, 78, 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 81,
+ 7, 7, 14, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, 71, 68, 7, 84,
+ 65, 16, 66, 7, 1, 5, 12, 1, 0, 4, 8, 73, 71, 81, 36, 38, 39, 30,
+ 25, 31, 28, 27, 25, 20, 23, 21, 12, 9, 65, 14, 16, 12, 3, 8, 7, 2,
+ 0, 69, 66, 75, 77, 76, 84, 32, 31, 30, 27, 16, 20, 17, 7, 9, 3, 0,
+ 75, 74, 80, 87, 69, 68, 90, 3, 1, 68, 77, 73, 76, 81, 73, 82, 81, 91,
+ 90, 95, 102, 75, 85, 90, 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11,
+ 22, 4, 1, 44, 20, 64, 80, 92, 115, 126, 126, 126, 1, 39, 29, 25, 15, 22,
+ 11, 5, 3, 69, 75, 70, 4, 67, 12, 20, 64, 65, 6, 10, 6, 9, 19, 8,
+ 2, 44, 20, 64, 80, 92, 115, 126, 126, 126, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 64, 2, 34, 58, 15, 65, 68,
+ 3, 8, 2, 66, 64, 72, 81, 7, 72, 105, 110, 116, 18, 73, 68, 3, 8, 2,
+ 79, 66, 11, 6, 65, 72, 77, 1, 78, 81, 94, 6, 68, 74, 4, 75, 73, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 25, 0,
+ 83, 7, 5, 65, 30, 29, 5, 8, 70, 8, 71, 69, 2, 80, 79, 81, 84, 24,
+ 65, 7, 0, 69, 82, 74, 70, 3, 68, 67, 75, 16, 68, 2, 71, 79, 67, 72,
+ 66, 2, 65, 68, 2, 4, 75, 68, 62, 62, 27, 20, 5, 68, 0, 6, 1, 10,
+ 6, 64, 74, 6, 69, 78, 76, 16, 9, 12, 5, 5, 8, 11, 25, 15, 8, 2,
+ 3, 2, 11, 13, 87, 0, 5, 73, 6, 6, 15, 11, 0, 19, 12, 14, 72, 5,
+ 65, 0, 13, 89, 11, 17, 14, 15, 12, 16, 13, 22, 20, 2, 11, 17, 90, 62,
+ 86, 8, 1, 1, 0, 2, 3, 67, 5, 74, 65, 70, 4, 62, 84, 29, 32, 26,
+ 23, 22, 20, 16, 16, 13, 2, 0, 64, 68, 72, 93, 75, 75, 91, 3, 0, 65,
+ 68, 75, 78, 77, 74, 83, 78, 85, 92, 85, 97, 70, 20, 15, 10, 7, 6, 0,
+ 67, 68, 65, 1, 30, 20, 15, 8, 14, 3, 2, 65, 71, 7, 38, 30, 25, 22,
+ 20, 7, 2, 64, 69, 69, 46, 30, 13, 2, 12, 0, 73, 74, 6, 47, 37, 25,
+ 15, 21, 4, 0, 68, 70, 62, 87, 82, 73, 78, 78, 74, 72, 68, 71, 69, 67,
+ 1, 76, 74, 80, 80, 0, 78, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, 81,
+ 7, 7, 15, 3, 64, 7, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, 8, 85,
+ 66, 16, 67, 7, 1, 4, 12, 1, 64, 4, 8, 74, 71, 82, 35, 37, 38, 28,
+ 23, 29, 26, 24, 23, 17, 20, 18, 9, 6, 67, 9, 12, 8, 65, 5, 4, 64,
+ 65, 71, 68, 76, 78, 76, 84, 29, 29, 28, 25, 13, 17, 15, 4, 7, 1, 65,
+ 78, 76, 82, 89, 69, 68, 92, 2, 0, 69, 79, 75, 78, 82, 74, 84, 82, 91,
+ 92, 96, 102, 77, 87, 92, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, 12,
+ 23, 4, 1, 43, 18, 67, 83, 96, 119, 126, 126, 126, 2, 39, 29, 25, 15, 23,
+ 11, 6, 4, 69, 75, 70, 4, 67, 13, 21, 64, 65, 7, 11, 6, 10, 20, 8,
+ 2, 43, 18, 67, 83, 96, 119, 126, 126, 126, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 66, 0, 33, 58, 15, 0, 68,
+ 4, 9, 2, 66, 64, 72, 82, 6, 75, 108, 112, 117, 21, 72, 68, 4, 9, 2,
+ 80, 65, 11, 5, 65, 72, 77, 1, 78, 81, 94, 6, 68, 73, 4, 75, 72, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 24, 64,
+ 83, 10, 6, 64, 31, 31, 6, 10, 68, 9, 70, 68, 4, 80, 79, 80, 84, 24,
+ 65, 8, 2, 69, 81, 74, 68, 3, 69, 68, 76, 16, 68, 3, 71, 78, 66, 72,
+ 65, 2, 64, 66, 3, 4, 74, 67, 62, 62, 30, 23, 5, 68, 0, 6, 1, 10,
+ 7, 0, 74, 8, 69, 80, 78, 19, 9, 12, 5, 5, 8, 11, 26, 16, 8, 2,
+ 3, 2, 11, 14, 88, 0, 5, 74, 6, 5, 15, 11, 0, 19, 12, 14, 73, 5,
+ 66, 64, 13, 89, 11, 17, 14, 13, 9, 15, 11, 20, 17, 0, 8, 15, 97, 62,
+ 90, 6, 64, 64, 66, 64, 0, 71, 1, 77, 67, 74, 2, 62, 86, 27, 30, 24,
+ 20, 19, 18, 14, 14, 11, 0, 65, 66, 70, 73, 95, 75, 75, 92, 2, 64, 66,
+ 69, 76, 79, 78, 76, 84, 79, 86, 93, 85, 97, 68, 21, 16, 10, 7, 7, 0,
+ 67, 68, 0, 2, 30, 20, 16, 9, 15, 4, 3, 64, 69, 8, 38, 30, 25, 22,
+ 21, 8, 2, 64, 69, 69, 46, 30, 12, 2, 12, 0, 73, 74, 6, 46, 37, 24,
+ 14, 21, 4, 0, 68, 70, 62, 86, 80, 72, 77, 77, 73, 70, 66, 70, 68, 65,
+ 3, 76, 73, 80, 79, 2, 77, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, 82,
+ 8, 8, 16, 3, 64, 8, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, 8, 86,
+ 67, 16, 68, 6, 0, 4, 12, 0, 65, 4, 8, 75, 71, 83, 34, 36, 37, 27,
+ 21, 27, 24, 22, 20, 15, 17, 15, 6, 4, 69, 5, 8, 4, 70, 1, 1, 66,
+ 67, 74, 70, 78, 80, 77, 85, 27, 26, 25, 22, 10, 15, 12, 1, 4, 65, 68,
+ 81, 78, 84, 90, 70, 69, 93, 0, 65, 71, 81, 76, 80, 84, 75, 85, 83, 92,
+ 93, 97, 103, 78, 88, 93, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, 4, 12,
+ 24, 4, 1, 42, 16, 69, 86, 99, 123, 126, 126, 126, 2, 39, 29, 25, 15, 23,
+ 12, 6, 4, 68, 75, 70, 5, 66, 14, 22, 64, 64, 7, 11, 6, 10, 20, 8,
+ 2, 42, 16, 69, 86, 99, 123, 126, 126, 126, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 67, 65, 32, 58, 15, 2, 68,
+ 4, 10, 2, 67, 64, 73, 84, 5, 77, 112, 115, 119, 24, 71, 68, 4, 10, 2,
+ 80, 64, 11, 5, 65, 72, 76, 1, 78, 81, 94, 6, 68, 73, 4, 75, 72, 85,
+ 64, 75, 71, 82, 1, 2, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 23, 64,
+ 83, 12, 7, 0, 33, 33, 8, 11, 66, 11, 69, 67, 6, 80, 79, 80, 84, 24,
+ 65, 9, 4, 69, 80, 73, 66, 3, 69, 68, 76, 16, 68, 3, 70, 77, 65, 71,
+ 64, 3, 0, 65, 5, 5, 73, 66, 62, 62, 33, 26, 5, 68, 0, 7, 1, 10,
+ 7, 0, 73, 10, 69, 82, 80, 22, 9, 12, 5, 5, 8, 12, 28, 17, 8, 2,
+ 3, 2, 12, 15, 89, 0, 5, 74, 5, 4, 14, 11, 64, 19, 12, 14, 74, 5,
+ 67, 65, 12, 89, 11, 16, 13, 11, 6, 14, 9, 18, 15, 65, 6, 13, 103, 62,
+ 93, 4, 66, 66, 69, 66, 66, 75, 66, 80, 69, 77, 0, 62, 88, 25, 28, 22,
+ 18, 17, 16, 12, 12, 9, 65, 67, 68, 72, 75, 97, 75, 75, 92, 1, 65, 67,
+ 70, 77, 80, 79, 78, 85, 79, 87, 94, 86, 96, 67, 22, 16, 10, 7, 8, 1,
+ 66, 67, 2, 3, 30, 20, 16, 10, 16, 5, 5, 1, 67, 9, 39, 31, 26, 23,
+ 22, 8, 2, 64, 68, 69, 47, 30, 11, 2, 12, 0, 73, 73, 6, 46, 36, 23,
+ 13, 21, 4, 0, 68, 70, 62, 85, 79, 71, 75, 75, 72, 68, 64, 69, 66, 0,
+ 5, 75, 72, 79, 78, 4, 77, 76, 74, 67, 65, 70, 73, 68, 73, 69, 70, 82,
+ 8, 8, 17, 3, 64, 8, 5, 3, 4, 3, 1, 68, 64, 67, 71, 68, 9, 87,
+ 68, 16, 69, 5, 64, 3, 12, 64, 66, 4, 8, 76, 71, 84, 33, 35, 36, 25,
+ 19, 25, 22, 20, 18, 12, 14, 12, 3, 1, 71, 1, 4, 0, 75, 65, 65, 69,
+ 69, 76, 72, 80, 81, 78, 86, 25, 24, 23, 20, 7, 12, 10, 65, 2, 67, 70,
+ 84, 80, 86, 92, 71, 70, 95, 64, 66, 73, 83, 78, 82, 86, 76, 87, 84, 93,
+ 94, 98, 104, 80, 89, 94, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, 4, 13,
+ 25, 4, 1, 41, 14, 72, 89, 102, 126, 126, 126, 126, 2, 39, 29, 25, 15, 24,
+ 12, 6, 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, 6, 10, 21, 8,
+ 2, 41, 14, 72, 89, 102, 126, 126, 126, 126, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 69, 68, 31, 58, 14, 3, 69,
+ 4, 10, 1, 68, 64, 74, 86, 3, 80, 116, 118, 121, 26, 71, 68, 4, 10, 1,
+ 81, 64, 11, 4, 65, 72, 76, 0, 79, 81, 94, 5, 68, 73, 4, 75, 72, 85,
+ 64, 75, 72, 82, 1, 2, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 22, 65,
+ 84, 14, 8, 1, 34, 35, 9, 12, 65, 12, 68, 66, 8, 80, 79, 80, 84, 24,
+ 65, 9, 6, 69, 80, 73, 65, 2, 70, 69, 77, 16, 68, 3, 70, 77, 65, 71,
+ 64, 3, 0, 64, 6, 5, 72, 65, 62, 62, 36, 28, 5, 68, 0, 7, 0, 10,
+ 7, 0, 73, 12, 69, 84, 82, 24, 9, 12, 5, 5, 8, 12, 29, 17, 8, 1,
+ 2, 2, 12, 15, 91, 0, 5, 75, 4, 2, 13, 10, 65, 19, 12, 13, 76, 5,
+ 68, 66, 11, 89, 10, 15, 12, 8, 2, 12, 7, 15, 12, 68, 3, 11, 110, 62,
+ 97, 1, 68, 69, 73, 69, 70, 80, 71, 83, 71, 81, 65, 62, 90, 22, 25, 19,
+ 15, 14, 13, 9, 9, 7, 68, 70, 70, 74, 77, 99, 75, 76, 93, 0, 67, 69,
+ 72, 79, 82, 81, 80, 86, 80, 88, 95, 87, 96, 66, 22, 16, 10, 7, 8, 1,
+ 66, 67, 4, 4, 30, 20, 16, 10, 16, 6, 6, 2, 66, 9, 39, 31, 26, 23,
+ 23, 8, 2, 64, 68, 70, 47, 29, 10, 1, 12, 0, 73, 73, 5, 45, 35, 21,
+ 12, 20, 4, 0, 68, 70, 62, 84, 78, 70, 74, 74, 71, 67, 0, 68, 65, 1,
+ 7, 75, 72, 79, 77, 5, 77, 76, 74, 67, 65, 70, 74, 69, 74, 69, 71, 83,
+ 8, 8, 18, 3, 65, 8, 5, 2, 4, 3, 1, 69, 64, 67, 71, 68, 9, 88,
+ 69, 16, 71, 4, 65, 2, 11, 65, 67, 4, 7, 78, 72, 86, 31, 33, 35, 23,
+ 17, 22, 19, 17, 15, 9, 11, 9, 64, 65, 73, 67, 0, 68, 80, 69, 69, 72,
+ 72, 79, 74, 82, 83, 79, 87, 22, 21, 20, 17, 4, 9, 7, 69, 64, 70, 73,
+ 87, 82, 88, 94, 72, 71, 97, 66, 68, 75, 86, 80, 84, 88, 78, 89, 86, 94,
+ 96, 99, 105, 82, 91, 96, 75, 69, 6, 67, 17, 26, 66, 0, 10, 14, 4, 13,
+ 25, 4, 0, 39, 12, 75, 93, 106, 126, 126, 126, 126, 2, 39, 29, 25, 15, 24,
+ 12, 6, 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, 6, 10, 21, 7,
+ 1, 39, 12, 75, 93, 106, 126, 126, 126, 126, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 70, 70, 30, 59, 14, 5,
+ 69, 5, 11, 1, 68, 0, 74, 87, 2, 82, 119, 120, 122, 29, 70, 67, 5,
+ 11, 1, 81, 0, 11, 4, 64, 71, 75, 0, 79, 80, 93, 5, 67, 72, 4,
+ 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 64, 94, 97, 6,
+ 67, 68, 22, 65, 84, 17, 10, 3, 36, 38, 11, 14, 0, 14, 66, 64, 11,
+ 80, 78, 79, 83, 24, 65, 10, 9, 68, 79, 72, 0, 2, 70, 69, 77, 17,
+ 68, 4, 69, 76, 64, 70, 0, 4, 1, 1, 8, 6, 70, 0, 62, 62, 40,
+ 31, 6, 67, 1, 8, 0, 11, 8, 1, 72, 15, 68, 86, 83, 27, 9, 13,
+ 5, 6, 9, 13, 31, 18, 9, 1, 2, 2, 13, 16, 92, 1, 5, 75, 4,
+ 1, 13, 10, 65, 19, 12, 13, 77, 6, 68, 66, 11, 89, 10, 15, 12, 6,
+ 64, 11, 6, 13, 10, 70, 1, 9, 116, 62, 100, 64, 69, 71, 76, 71, 73,
+ 84, 75, 85, 73, 84, 67, 62, 91, 20, 23, 17, 13, 12, 11, 7, 7, 5,
+ 70, 72, 71, 75, 78, 100, 75, 76, 93, 0, 68, 70, 73, 80, 83, 82, 81,
+ 87, 80, 89, 95, 87, 95, 64, 23, 17, 10, 8, 9, 2, 65, 66, 7, 6,
+ 31, 21, 17, 11, 17, 8, 8, 4, 64, 10, 40, 32, 27, 24, 24, 9, 3,
+ 0, 67, 70, 48, 29, 10, 1, 13, 1, 73, 72, 5, 45, 35, 20, 11, 20,
+ 5, 1, 67, 69, 62, 82, 76, 68, 72, 72, 69, 65, 2, 66, 0, 3, 10,
+ 74, 71, 78, 75, 7, 76, 75, 73, 66, 64, 69, 74, 69, 74, 69, 71, 83,
+ 9, 9, 19, 4, 65, 9, 6, 2, 5, 4, 1, 69, 0, 66, 70, 67, 10,
+ 88, 70, 16, 72, 4, 65, 2, 11, 65, 67, 4, 7, 79, 72, 87, 30, 32,
+ 35, 22, 16, 20, 17, 15, 13, 7, 9, 7, 67, 67, 75, 71, 66, 72, 84,
+ 72, 72, 74, 74, 81, 75, 83, 84, 79, 87, 20, 19, 18, 15, 2, 7, 5,
+ 72, 66, 72, 75, 89, 83, 89, 95, 72, 71, 98, 67, 69, 76, 88, 81, 85,
+ 89, 79, 90, 87, 94, 97, 99, 105, 83, 92, 97, 74, 68, 7, 66, 19, 28,
+ 65, 1, 11, 15, 5, 14, 26, 4, 0, 38, 10, 77, 96, 109, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 25, 13, 7, 5, 67, 74, 69, 6, 65, 16, 24,
+ 0, 0, 8, 12, 6, 11, 22, 7, 1, 38, 10, 77, 96, 109, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 71, 72, 29, 59, 14, 7,
+ 69, 5, 12, 1, 69, 0, 75, 89, 1, 85, 123, 123, 124, 32, 69, 67, 5,
+ 12, 1, 81, 1, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, 72, 4,
+ 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 21, 65, 84, 19, 11, 4, 38, 40, 12, 15, 2, 15, 65, 0, 13,
+ 80, 78, 79, 83, 24, 65, 11, 11, 68, 78, 71, 2, 2, 70, 69, 78, 17,
+ 68, 4, 68, 75, 0, 69, 1, 4, 2, 2, 9, 7, 69, 1, 62, 62, 43,
+ 34, 6, 67, 1, 8, 0, 11, 8, 1, 72, 17, 68, 88, 85, 30, 9, 13,
+ 5, 6, 9, 13, 33, 19, 9, 1, 2, 2, 14, 17, 93, 1, 5, 75, 3,
+ 0, 12, 10, 66, 19, 12, 13, 78, 6, 69, 67, 10, 89, 10, 14, 11, 4,
+ 67, 10, 4, 11, 8, 72, 64, 7, 122, 62, 104, 66, 71, 73, 79, 73, 76,
+ 88, 79, 88, 75, 87, 69, 62, 93, 18, 21, 15, 11, 10, 9, 5, 5, 3,
+ 72, 74, 73, 77, 80, 102, 75, 76, 94, 64, 69, 71, 74, 81, 84, 83, 83,
+ 88, 80, 90, 96, 88, 94, 0, 24, 17, 10, 8, 10, 3, 64, 65, 9, 7,
+ 31, 21, 17, 12, 18, 9, 10, 6, 1, 11, 41, 33, 28, 25, 25, 9, 3,
+ 0, 66, 70, 49, 29, 9, 1, 13, 1, 73, 72, 5, 45, 34, 19, 10, 20,
+ 5, 1, 67, 69, 62, 81, 75, 67, 70, 70, 68, 0, 4, 65, 2, 5, 12,
+ 73, 70, 78, 74, 9, 76, 75, 73, 65, 64, 69, 74, 69, 75, 69, 71, 83,
+ 9, 9, 20, 4, 65, 9, 6, 2, 5, 4, 1, 70, 0, 66, 70, 67, 11,
+ 89, 71, 16, 73, 3, 66, 1, 11, 66, 68, 4, 7, 80, 72, 88, 29, 31,
+ 34, 20, 14, 18, 15, 13, 11, 4, 6, 4, 70, 70, 77, 75, 70, 76, 89,
+ 75, 75, 77, 76, 84, 77, 85, 85, 80, 88, 18, 17, 15, 13, 64, 4, 2,
+ 75, 68, 75, 77, 92, 85, 91, 97, 73, 72, 100, 68, 70, 78, 90, 83, 87,
+ 91, 80, 92, 88, 95, 98, 100, 106, 85, 93, 98, 74, 68, 8, 66, 20, 29,
+ 65, 2, 12, 16, 5, 14, 27, 4, 0, 37, 8, 80, 99, 112, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 26, 13, 7, 5, 67, 74, 69, 6, 65, 17, 25,
+ 0, 0, 8, 12, 6, 11, 23, 7, 1, 37, 8, 80, 99, 112, 126, 126, 126,
+ 126, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 73, 74, 28, 59, 14, 9,
+ 69, 6, 13, 1, 69, 0, 75, 90, 0, 87, 126, 125, 125, 35, 68, 67, 6,
+ 13, 1, 82, 2, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 70, 84, 0, 74, 72, 81, 2, 2, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 20, 66, 84, 22, 12, 5, 39, 42, 14, 17, 4, 17, 64, 1, 15,
+ 80, 78, 78, 83, 24, 65, 12, 13, 68, 77, 71, 4, 2, 71, 70, 78, 17,
+ 68, 5, 68, 74, 1, 69, 2, 5, 3, 4, 11, 7, 68, 2, 62, 62, 46,
+ 37, 6, 67, 1, 9, 0, 11, 9, 2, 71, 19, 68, 90, 87, 33, 9, 13,
+ 5, 6, 9, 14, 34, 20, 9, 1, 2, 2, 14, 18, 94, 1, 5, 76, 3,
+ 64, 12, 10, 66, 19, 12, 13, 79, 6, 70, 68, 10, 89, 10, 14, 11, 2,
+ 70, 9, 2, 9, 5, 74, 67, 5, 126, 62, 107, 68, 73, 75, 82, 76, 79,
+ 92, 83, 91, 77, 91, 71, 62, 95, 16, 19, 13, 8, 7, 7, 3, 3, 1,
+ 74, 76, 75, 79, 81, 104, 75, 76, 94, 65, 70, 72, 75, 82, 85, 84, 85,
+ 89, 81, 91, 97, 88, 94, 2, 25, 18, 10, 8, 11, 3, 64, 65, 11, 8,
+ 31, 21, 18, 13, 19, 10, 11, 7, 3, 12, 41, 33, 28, 25, 26, 10, 3,
+ 0, 66, 70, 49, 29, 8, 1, 13, 1, 73, 71, 5, 44, 34, 18, 9, 20,
+ 5, 1, 67, 69, 62, 80, 73, 66, 69, 69, 67, 2, 6, 64, 3, 7, 14,
+ 73, 69, 77, 73, 11, 75, 75, 73, 65, 0, 69, 74, 69, 75, 69, 71, 84,
+ 10, 10, 21, 4, 65, 10, 6, 2, 5, 4, 1, 70, 0, 66, 70, 67, 11,
+ 90, 72, 16, 74, 2, 67, 1, 11, 67, 69, 4, 7, 81, 72, 89, 28, 30,
+ 33, 19, 12, 16, 13, 11, 8, 2, 3, 1, 73, 72, 79, 79, 74, 80, 94,
+ 79, 78, 79, 78, 86, 79, 87, 87, 81, 89, 16, 14, 13, 10, 67, 2, 0,
+ 78, 71, 77, 80, 95, 87, 93, 98, 74, 73, 101, 70, 72, 80, 92, 84, 89,
+ 93, 81, 93, 89, 96, 99, 101, 107, 86, 94, 99, 74, 67, 8, 65, 21, 30,
+ 65, 2, 12, 16, 5, 15, 28, 4, 0, 36, 6, 82, 102, 115, 126, 126, 126,
+ 126, 3, 39, 30, 26, 16, 26, 14, 7, 5, 66, 74, 69, 7, 64, 18, 26,
+ 0, 1, 8, 12, 6, 11, 23, 7, 1, 36, 6, 82, 102, 115, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 74, 76, 27, 59, 13, 11,
+ 69, 6, 14, 0, 70, 0, 76, 92, 64, 90, 126, 126, 126, 38, 67, 67, 6,
+ 14, 0, 82, 3, 11, 2, 64, 70, 73, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 70, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 19, 66, 84, 24, 13, 6, 41, 44, 15, 18, 5, 18, 1, 2, 17,
+ 80, 77, 78, 83, 24, 65, 13, 15, 68, 77, 70, 6, 2, 71, 70, 79, 17,
+ 68, 5, 67, 73, 2, 68, 3, 5, 3, 5, 12, 8, 67, 3, 62, 62, 49,
+ 40, 6, 66, 1, 9, 0, 11, 9, 2, 71, 21, 68, 92, 89, 35, 9, 14,
+ 5, 6, 9, 14, 36, 21, 10, 0, 2, 2, 15, 18, 95, 1, 5, 76, 2,
+ 65, 11, 9, 67, 19, 12, 13, 80, 6, 71, 69, 9, 89, 9, 13, 10, 0,
+ 74, 8, 0, 7, 3, 76, 69, 3, 126, 62, 111, 70, 75, 78, 85, 78, 83,
+ 97, 87, 94, 79, 94, 73, 62, 96, 14, 17, 10, 6, 5, 5, 1, 1, 64,
+ 77, 78, 77, 81, 83, 106, 75, 76, 95, 66, 71, 73, 77, 83, 87, 85, 86,
+ 90, 81, 92, 97, 89, 93, 3, 26, 18, 10, 9, 11, 4, 0, 64, 13, 10,
+ 31, 22, 18, 13, 20, 11, 13, 9, 4, 12, 42, 34, 29, 26, 27, 10, 3,
+ 1, 65, 70, 50, 29, 8, 0, 13, 1, 73, 71, 5, 44, 33, 17, 8, 20,
+ 5, 2, 67, 69, 62, 78, 72, 65, 67, 67, 66, 3, 7, 0, 5, 8, 16,
+ 72, 68, 77, 72, 12, 75, 75, 73, 64, 0, 69, 75, 69, 76, 69, 71, 84,
+ 10, 10, 22, 4, 65, 10, 6, 2, 5, 4, 1, 71, 0, 66, 70, 67, 12,
+ 91, 73, 16, 75, 2, 68, 0, 11, 68, 70, 4, 7, 82, 72, 90, 27, 29,
+ 32, 17, 10, 14, 11, 8, 6, 64, 0, 65, 76, 75, 81, 84, 78, 84, 99,
+ 82, 82, 82, 81, 89, 81, 89, 88, 82, 89, 13, 12, 10, 8, 70, 64, 66,
+ 81, 73, 80, 82, 98, 89, 95, 100, 75, 73, 103, 71, 73, 81, 94, 86, 91,
+ 94, 82, 95, 90, 97, 101, 102, 107, 88, 96, 101, 73, 67, 9, 65, 22, 31,
+ 65, 3, 13, 17, 5, 15, 29, 4, 0, 35, 4, 85, 105, 119, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 27, 14, 7, 5, 66, 74, 69, 7, 64, 18, 27,
+ 0, 1, 9, 13, 6, 11, 24, 7, 1, 35, 4, 85, 105, 119, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 75, 78, 26, 59, 13, 13,
+ 69, 6, 15, 0, 70, 0, 77, 94, 65, 92, 126, 126, 126, 41, 66, 66, 6,
+ 15, 0, 82, 4, 11, 2, 64, 70, 72, 0, 79, 80, 93, 5, 67, 71, 4,
+ 74, 69, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 1, 95, 97, 8,
+ 71, 68, 18, 67, 84, 27, 14, 7, 43, 46, 17, 20, 7, 20, 2, 3, 20,
+ 80, 77, 77, 82, 24, 65, 14, 17, 68, 76, 70, 8, 2, 72, 71, 79, 17,
+ 68, 6, 67, 72, 3, 68, 4, 6, 4, 7, 14, 9, 65, 4, 62, 62, 52,
+ 43, 7, 66, 2, 10, 0, 11, 10, 2, 70, 23, 68, 94, 91, 38, 9, 14,
+ 5, 6, 9, 15, 37, 22, 10, 0, 2, 2, 15, 19, 96, 2, 5, 77, 2,
+ 66, 11, 9, 67, 19, 12, 13, 81, 7, 72, 69, 9, 89, 9, 12, 9, 65,
+ 77, 7, 64, 5, 1, 78, 72, 1, 126, 62, 114, 72, 77, 80, 88, 81, 86,
+ 101, 91, 96, 81, 98, 75, 62, 98, 12, 15, 8, 4, 3, 3, 64, 64, 66,
+ 79, 80, 79, 82, 85, 108, 75, 76, 95, 67, 72, 74, 78, 84, 88, 86, 88,
+ 91, 82, 93, 98, 90, 92, 5, 27, 19, 10, 9, 12, 4, 0, 0, 15, 11,
+ 31, 22, 19, 14, 21, 12, 14, 10, 6, 13, 43, 35, 30, 26, 28, 11, 4,
+ 1, 65, 70, 50, 29, 7, 0, 13, 1, 73, 70, 5, 43, 32, 16, 7, 20,
+ 5, 2, 67, 68, 62, 77, 70, 0, 65, 66, 65, 5, 9, 1, 7, 10, 18,
+ 71, 67, 76, 71, 14, 75, 75, 72, 64, 1, 69, 75, 69, 76, 69, 71, 85,
+ 11, 10, 23, 4, 65, 10, 6, 2, 5, 4, 1, 71, 0, 66, 70, 67, 12,
+ 92, 74, 16, 76, 1, 68, 64, 11, 68, 71, 4, 7, 83, 72, 91, 26, 28,
+ 31, 15, 8, 12, 9, 6, 3, 67, 66, 68, 79, 77, 83, 88, 82, 88, 104,
+ 85, 85, 84, 83, 91, 83, 90, 90, 82, 90, 11, 9, 8, 6, 73, 67, 68,
+ 84, 75, 82, 84, 101, 91, 97, 101, 75, 74, 105, 72, 75, 83, 96, 88, 93,
+ 96, 83, 96, 91, 97, 102, 103, 108, 89, 97, 102, 73, 67, 10, 64, 23, 32,
+ 64, 4, 13, 17, 5, 16, 30, 4, 0, 34, 2, 88, 108, 122, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 27, 14, 8, 6, 65, 74, 69, 8, 64, 19, 28,
+ 0, 1, 9, 13, 6, 12, 24, 7, 1, 34, 2, 88, 108, 122, 126, 126, 126,
+ 126, 75, 69, 0, 10, 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 77, 80, 25, 59, 13, 14,
+ 69, 7, 15, 0, 71, 1, 77, 95, 67, 95, 126, 126, 126, 43, 65, 66, 7,
+ 15, 0, 83, 4, 11, 1, 64, 70, 72, 0, 79, 79, 92, 5, 66, 70, 4,
+ 73, 69, 83, 0, 74, 72, 81, 3, 2, 22, 0, 0, 0, 2, 95, 97, 8,
+ 71, 69, 18, 67, 84, 29, 15, 8, 44, 49, 18, 21, 9, 21, 3, 4, 22,
+ 80, 77, 77, 82, 24, 65, 15, 20, 68, 75, 69, 10, 1, 72, 71, 80, 18,
+ 68, 6, 66, 72, 3, 67, 5, 6, 5, 8, 15, 9, 64, 5, 62, 62, 55,
+ 46, 7, 66, 2, 10, 0, 11, 10, 3, 70, 25, 67, 96, 93, 41, 9, 14,
+ 5, 6, 10, 15, 39, 23, 10, 0, 2, 2, 16, 20, 97, 2, 5, 77, 1,
+ 67, 10, 9, 68, 19, 12, 13, 83, 7, 73, 70, 8, 89, 9, 12, 9, 67,
+ 80, 6, 66, 2, 65, 80, 74, 64, 126, 62, 118, 74, 78, 82, 92, 83, 89,
+ 105, 96, 99, 83, 101, 77, 62, 100, 10, 13, 6, 1, 0, 1, 67, 66, 68,
+ 81, 83, 81, 84, 86, 109, 75, 76, 96, 68, 73, 75, 79, 85, 89, 87, 90,
+ 92, 82, 94, 99, 90, 92, 6, 28, 19, 10, 9, 13, 5, 1, 0, 17, 12,
+ 32, 22, 19, 15, 22, 13, 16, 12, 8, 14, 43, 35, 30, 27, 29, 11, 4,
+ 1, 64, 70, 51, 29, 6, 0, 13, 1, 73, 70, 4, 43, 32, 15, 6, 19,
+ 5, 2, 67, 68, 62, 76, 69, 1, 64, 64, 64, 7, 11, 2, 8, 12, 20,
+ 71, 66, 76, 70, 16, 74, 75, 72, 0, 1, 69, 75, 69, 77, 69, 71, 85,
+ 11, 11, 24, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66, 70, 67, 13,
+ 93, 75, 16, 77, 0, 69, 64, 11, 69, 71, 4, 6, 85, 73, 92, 24, 27,
+ 30, 14, 6, 10, 7, 4, 1, 69, 69, 70, 82, 80, 85, 92, 86, 92, 108,
+ 89, 88, 87, 85, 94, 85, 92, 91, 83, 91, 9, 7, 5, 3, 76, 69, 71,
+ 87, 78, 85, 87, 104, 93, 98, 103, 76, 75, 106, 74, 76, 85, 98, 89, 95,
+ 98, 84, 98, 92, 98, 103, 104, 109, 91, 98, 103, 73, 66, 10, 64, 24, 33,
+ 64, 4, 14, 18, 5, 16, 31, 4, 0, 33, 0, 90, 111, 125, 126, 126, 126,
+ 126, 4, 39, 30, 26, 16, 28, 15, 8, 6, 65, 73, 68, 8, 0, 20, 29,
+ 1, 2, 9, 13, 6, 12, 25, 7, 1, 33, 0, 90, 111, 125, 126, 126, 126,
+ 126, 75, 69, 0, 11, 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 78, 82, 24, 59, 13,
+ 16, 69, 7, 16, 64, 71, 1, 78, 97, 68, 97, 126, 126, 126, 46, 64,
+ 66, 7, 16, 64, 83, 5, 11, 1, 64, 69, 71, 0, 79, 79, 92, 5,
+ 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 17, 68, 84, 32, 16, 9, 46, 51, 20, 23,
+ 10, 23, 5, 5, 24, 80, 76, 76, 82, 24, 65, 16, 22, 68, 74, 69,
+ 12, 1, 73, 72, 80, 18, 68, 7, 66, 71, 4, 67, 6, 7, 6, 10,
+ 17, 10, 0, 6, 62, 62, 58, 49, 7, 65, 2, 11, 0, 11, 11, 3,
+ 69, 27, 67, 98, 95, 44, 9, 15, 5, 6, 10, 16, 40, 24, 11, 64,
+ 2, 2, 16, 20, 98, 2, 5, 78, 1, 68, 10, 8, 68, 19, 12, 13,
+ 84, 7, 74, 71, 8, 89, 9, 11, 8, 69, 83, 5, 68, 0, 67, 82,
+ 77, 66, 126, 62, 121, 76, 80, 85, 95, 86, 92, 110, 100, 102, 85, 105,
+ 79, 62, 101, 8, 11, 4, 64, 65, 64, 69, 68, 70, 84, 85, 83, 86,
+ 88, 111, 75, 76, 96, 69, 74, 76, 81, 86, 90, 88, 91, 93, 83, 95,
+ 99, 91, 91, 8, 29, 20, 10, 10, 13, 5, 1, 1, 19, 14, 32, 23,
+ 20, 15, 23, 14, 17, 13, 10, 14, 44, 36, 31, 27, 30, 12, 4, 2,
+ 64, 70, 51, 29, 6, 64, 13, 1, 73, 69, 4, 42, 31, 14, 5, 19,
+ 5, 3, 67, 68, 62, 74, 67, 2, 1, 0, 0, 8, 12, 3, 10, 13,
+ 22, 70, 65, 75, 69, 18, 74, 75, 72, 0, 2, 69, 76, 69, 77, 69,
+ 71, 86, 12, 11, 25, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66,
+ 70, 67, 13, 94, 76, 16, 78, 0, 70, 65, 11, 70, 72, 4, 6, 86,
+ 73, 93, 23, 26, 29, 12, 4, 8, 5, 1, 65, 72, 72, 73, 85, 82,
+ 87, 97, 90, 96, 113, 92, 91, 89, 87, 96, 87, 94, 93, 84, 91, 6,
+ 4, 3, 1, 79, 72, 73, 90, 80, 87, 89, 107, 95, 100, 104, 77, 75,
+ 108, 75, 78, 86, 100, 91, 97, 99, 85, 99, 93, 99, 105, 105, 109, 92,
+ 100, 105, 72, 66, 11, 0, 25, 34, 64, 5, 14, 18, 5, 17, 32, 4,
+ 0, 32, 65, 93, 114, 126, 126, 126, 126, 126, 5, 39, 30, 26, 16, 28,
+ 15, 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12,
+ 25, 7, 1, 32, 65, 93, 114, 126, 126, 126, 126, 126, 75, 69, 0, 11,
+ 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 80, 85, 23, 59, 12,
+ 18, 70, 7, 17, 64, 72, 1, 79, 99, 69, 100, 126, 126, 126, 49, 0,
+ 66, 7, 17, 64, 84, 6, 11, 0, 64, 69, 71, 64, 80, 79, 92, 5,
+ 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 16, 68, 85, 34, 17, 10, 47, 53, 21, 24,
+ 12, 24, 6, 6, 26, 80, 76, 76, 82, 24, 65, 17, 24, 68, 74, 68,
+ 14, 1, 73, 72, 81, 18, 68, 7, 65, 70, 5, 66, 6, 7, 6, 11,
+ 18, 10, 1, 7, 62, 62, 61, 51, 7, 65, 2, 11, 64, 11, 11, 3,
+ 69, 29, 67, 100, 97, 46, 9, 15, 5, 6, 10, 16, 42, 24, 11, 64,
+ 1, 2, 17, 21, 100, 2, 5, 78, 0, 70, 9, 8, 69, 19, 12, 12,
+ 85, 7, 75, 72, 7, 89, 8, 10, 7, 71, 87, 3, 70, 65, 70, 85,
+ 79, 68, 126, 62, 125, 78, 82, 87, 98, 88, 96, 114, 104, 105, 87, 108,
+ 81, 62, 103, 6, 8, 1, 67, 68, 67, 71, 71, 72, 86, 87, 85, 88,
+ 90, 113, 75, 77, 97, 70, 76, 77, 82, 87, 92, 90, 93, 94, 83, 96,
+ 100, 92, 91, 9, 30, 20, 10, 10, 14, 6, 2, 1, 21, 15, 32, 23,
+ 20, 16, 24, 15, 19, 15, 11, 15, 44, 36, 31, 28, 31, 12, 4, 2,
+ 0, 71, 52, 29, 5, 64, 13, 1, 73, 69, 4, 42, 30, 13, 4, 19,
+ 5, 3, 67, 68, 62, 73, 66, 3, 2, 2, 1, 10, 14, 4, 11, 15,
+ 24, 70, 65, 75, 68, 19, 74, 75, 72, 1, 2, 69, 76, 69, 78, 69,
+ 71, 86, 12, 11, 26, 4, 66, 11, 7, 1, 6, 5, 1, 73, 0, 66,
+ 70, 67, 14, 95, 77, 16, 80, 64, 71, 66, 10, 71, 73, 4, 6, 87,
+ 73, 95, 22, 24, 28, 10, 2, 6, 3, 64, 67, 75, 75, 76, 88, 85,
+ 89, 101, 94, 101, 118, 96, 95, 92, 90, 99, 89, 96, 94, 85, 92, 4,
+ 2, 0, 65, 82, 75, 76, 93, 83, 90, 92, 110, 97, 102, 106, 78, 76,
+ 110, 77, 79, 88, 102, 93, 99, 101, 87, 101, 95, 100, 106, 106, 110, 94,
+ 101, 106, 72, 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, 17, 32, 4,
+ 64, 31, 67, 96, 117, 126, 126, 126, 126, 126, 5, 39, 30, 26, 16, 29,
+ 15, 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12,
+ 26, 7, 0, 31, 67, 96, 117, 126, 126, 126, 126, 126, 75, 70, 64, 11,
+ 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 81, 87, 22, 60, 12,
+ 20, 70, 8, 18, 64, 73, 1, 79, 100, 70, 102, 126, 126, 126, 52, 1,
+ 65, 8, 18, 64, 84, 7, 11, 0, 0, 69, 70, 64, 80, 79, 92, 5,
+ 66, 69, 4, 73, 68, 82, 0, 74, 72, 80, 4, 2, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 15, 68, 85, 36, 19, 11, 49, 55, 23, 25,
+ 14, 26, 7, 8, 29, 80, 76, 76, 81, 24, 65, 18, 26, 67, 73, 67,
+ 16, 1, 73, 72, 81, 18, 68, 7, 64, 69, 6, 65, 7, 8, 7, 12,
+ 20, 11, 3, 8, 62, 62, 62, 54, 8, 65, 3, 12, 64, 11, 11, 4,
+ 68, 32, 67, 102, 98, 49, 9, 15, 5, 6, 10, 17, 44, 25, 11, 64,
+ 1, 2, 18, 22, 101, 3, 5, 78, 64, 71, 8, 8, 70, 19, 12, 12,
+ 86, 8, 76, 72, 6, 89, 8, 10, 7, 73, 90, 2, 71, 67, 72, 87,
+ 81, 70, 126, 62, 126, 80, 84, 89, 101, 90, 99, 118, 108, 107, 89, 111,
+ 83, 62, 105, 4, 6, 64, 69, 70, 69, 73, 73, 74, 88, 89, 86, 89,
+ 91, 115, 75, 77, 97, 70, 77, 78, 83, 88, 93, 91, 95, 95, 83, 97,
+ 101, 92, 90, 10, 31, 20, 10, 10, 15, 7, 3, 2, 24, 16, 32, 23,
+ 20, 17, 25, 16, 21, 17, 13, 16, 45, 37, 32, 29, 32, 12, 5, 2,
+ 1, 71, 53, 29, 4, 64, 14, 2, 73, 68, 4, 42, 30, 12, 3, 19,
+ 5, 3, 67, 67, 62, 72, 65, 5, 4, 4, 2, 12, 16, 5, 13, 17,
+ 26, 69, 64, 74, 67, 21, 73, 74, 71, 2, 3, 69, 76, 69, 79, 69,
+ 71, 86, 12, 12, 27, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65,
+ 69, 67, 15, 95, 78, 16, 81, 65, 71, 66, 10, 71, 74, 4, 6, 88,
+ 73, 96, 21, 23, 28, 9, 0, 4, 1, 66, 69, 77, 78, 79, 91, 88,
+ 91, 105, 98, 105, 123, 99, 98, 95, 92, 101, 90, 97, 95, 85, 93, 2,
+ 0, 65, 67, 84, 77, 78, 96, 85, 92, 94, 112, 99, 104, 108, 78, 77,
+ 111, 78, 80, 90, 104, 94, 100, 103, 88, 103, 96, 100, 107, 106, 111, 96,
+ 102, 107, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, 5, 18, 33, 4,
+ 64, 30, 69, 98, 120, 126, 126, 126, 126, 126, 5, 39, 30, 27, 17, 30,
+ 16, 9, 7, 64, 73, 68, 9, 1, 22, 31, 1, 3, 10, 14, 6, 13,
+ 27, 7, 0, 30, 69, 98, 120, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 82, 89, 21, 60, 12,
+ 22, 70, 8, 19, 65, 73, 1, 80, 102, 71, 105, 126, 126, 126, 55, 2,
+ 65, 8, 19, 65, 84, 8, 11, 64, 0, 68, 69, 64, 80, 79, 92, 5,
+ 66, 69, 4, 73, 67, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 14, 69, 85, 39, 20, 12, 51, 57, 24, 27,
+ 15, 27, 9, 9, 31, 80, 75, 75, 81, 24, 65, 19, 28, 67, 72, 67,
+ 18, 1, 74, 73, 82, 18, 68, 8, 64, 68, 7, 65, 8, 8, 8, 14,
+ 21, 12, 4, 9, 62, 62, 62, 57, 8, 64, 3, 12, 64, 11, 12, 4,
+ 68, 34, 67, 104, 100, 52, 9, 16, 5, 6, 10, 17, 45, 26, 12, 65,
+ 1, 2, 18, 22, 102, 3, 5, 79, 64, 72, 8, 7, 70, 19, 12, 12,
+ 87, 8, 77, 73, 6, 89, 8, 9, 6, 75, 93, 1, 73, 69, 74, 89,
+ 84, 72, 126, 62, 126, 82, 86, 92, 104, 93, 102, 123, 112, 110, 91, 115,
+ 85, 62, 106, 2, 4, 66, 71, 72, 71, 75, 75, 76, 91, 91, 88, 91,
+ 93, 117, 75, 77, 98, 71, 78, 79, 85, 89, 94, 92, 96, 96, 84, 98,
+ 101, 93, 89, 12, 32, 21, 10, 11, 15, 7, 3, 3, 26, 18, 32, 24,
+ 21, 17, 26, 17, 22, 18, 15, 16, 46, 38, 33, 29, 33, 13, 5, 3,
+ 1, 71, 53, 29, 4, 65, 14, 2, 73, 68, 4, 41, 29, 11, 2, 19,
+ 5, 4, 67, 67, 62, 70, 0, 6, 6, 5, 3, 13, 17, 6, 15, 18,
+ 28, 68, 0, 74, 66, 23, 73, 74, 71, 2, 3, 69, 77, 69, 79, 69,
+ 71, 87, 13, 12, 28, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65,
+ 69, 67, 15, 96, 79, 16, 82, 65, 72, 67, 10, 72, 75, 4, 6, 89,
+ 73, 97, 20, 22, 27, 7, 65, 2, 64, 69, 72, 80, 81, 82, 94, 90,
+ 93, 110, 102, 109, 126, 102, 101, 97, 94, 104, 92, 99, 97, 86, 93, 64,
+ 66, 68, 69, 87, 80, 81, 99, 87, 95, 96, 115, 101, 106, 109, 79, 77,
+ 113, 79, 82, 91, 106, 96, 102, 104, 89, 104, 97, 101, 109, 107, 111, 97,
+ 104, 109, 71, 65, 13, 1, 28, 38, 0, 7, 16, 20, 5, 18, 34, 4,
+ 64, 29, 71, 101, 123, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 30,
+ 16, 9, 7, 0, 73, 68, 10, 1, 23, 32, 1, 3, 11, 15, 6, 13,
+ 27, 7, 0, 29, 71, 101, 123, 126, 126, 126, 126, 126, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 84, 91, 20, 60, 12,
+ 23, 70, 9, 19, 65, 74, 2, 80, 103, 73, 107, 126, 126, 126, 57, 3,
+ 65, 9, 19, 65, 85, 8, 11, 64, 0, 68, 69, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 67, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 14, 69, 85, 41, 21, 13, 52, 60, 26, 28,
+ 17, 29, 10, 10, 33, 80, 75, 75, 81, 24, 65, 20, 31, 67, 71, 66,
+ 20, 0, 74, 73, 82, 19, 68, 8, 0, 68, 7, 64, 9, 9, 9, 15,
+ 23, 12, 5, 10, 62, 62, 62, 60, 8, 64, 3, 13, 64, 11, 12, 5,
+ 67, 36, 66, 106, 102, 55, 9, 16, 5, 6, 11, 18, 47, 27, 12, 65,
+ 1, 2, 19, 23, 103, 3, 5, 79, 65, 73, 7, 7, 71, 19, 12, 12,
+ 89, 8, 78, 74, 5, 89, 8, 9, 6, 77, 96, 0, 75, 72, 77, 91,
+ 86, 74, 126, 62, 126, 84, 87, 94, 108, 95, 105, 126, 117, 113, 93, 118,
+ 87, 62, 108, 0, 2, 68, 74, 75, 73, 78, 77, 78, 93, 94, 90, 93,
+ 94, 118, 75, 77, 98, 72, 79, 80, 86, 90, 95, 93, 98, 97, 84, 99,
+ 102, 93, 89, 13, 33, 21, 10, 11, 16, 8, 4, 3, 28, 19, 33, 24,
+ 21, 18, 27, 18, 24, 20, 17, 17, 46, 38, 33, 30, 34, 13, 5, 3,
+ 2, 71, 54, 29, 3, 65, 14, 2, 73, 67, 3, 41, 29, 10, 1, 18,
+ 5, 4, 67, 67, 62, 69, 1, 7, 7, 7, 4, 15, 19, 7, 16, 20,
+ 30, 68, 1, 73, 65, 25, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69,
+ 71, 87, 13, 13, 29, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65,
+ 69, 67, 16, 97, 80, 16, 83, 66, 73, 67, 10, 73, 75, 4, 5, 91,
+ 74, 98, 18, 21, 26, 6, 67, 0, 66, 71, 74, 82, 84, 84, 97, 93,
+ 95, 114, 106, 113, 126, 106, 104, 100, 96, 106, 94, 101, 98, 87, 94, 66,
+ 68, 70, 72, 90, 82, 83, 102, 90, 97, 99, 118, 103, 107, 111, 80, 78,
+ 114, 81, 83, 93, 108, 97, 104, 106, 90, 106, 98, 102, 110, 108, 112, 99,
+ 105, 110, 71, 64, 13, 1, 29, 39, 0, 7, 17, 21, 5, 19, 35, 4,
+ 64, 28, 73, 103, 126, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 31,
+ 17, 9, 7, 0, 72, 67, 10, 2, 24, 33, 2, 4, 11, 15, 6, 13,
+ 28, 7, 0, 28, 73, 103, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 85, 93, 19, 60, 11,
+ 25, 70, 9, 20, 65, 74, 2, 81, 105, 74, 110, 126, 126, 126, 60, 4,
+ 65, 9, 20, 65, 85, 9, 11, 65, 0, 68, 68, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 66, 81, 0, 74, 72, 80, 5, 2, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 13, 70, 85, 44, 22, 14, 54, 62, 27, 30,
+ 19, 30, 11, 11, 35, 80, 75, 74, 81, 24, 65, 21, 33, 67, 71, 66,
+ 22, 0, 75, 74, 83, 19, 68, 9, 0, 67, 8, 64, 10, 9, 9, 17,
+ 24, 13, 6, 11, 62, 62, 62, 62, 8, 64, 3, 13, 64, 11, 13, 5,
+ 67, 38, 66, 108, 104, 57, 9, 16, 5, 6, 11, 18, 48, 28, 12, 65,
+ 1, 2, 19, 24, 104, 3, 5, 80, 65, 74, 7, 7, 71, 19, 12, 12,
+ 90, 8, 79, 75, 5, 89, 7, 8, 5, 79, 100, 64, 77, 74, 79, 93,
+ 89, 76, 126, 62, 126, 86, 89, 96, 111, 98, 109, 126, 121, 116, 95, 122,
+ 89, 62, 110, 65, 0, 71, 76, 77, 75, 80, 79, 80, 95, 96, 92, 95,
+ 96, 120, 75, 77, 99, 73, 80, 81, 87, 91, 97, 94, 100, 98, 85, 100,
+ 103, 94, 88, 15, 34, 22, 10, 11, 17, 8, 4, 4, 30, 20, 33, 24,
+ 22, 19, 28, 19, 25, 21, 18, 18, 47, 39, 34, 30, 35, 14, 5, 3,
+ 2, 71, 54, 29, 2, 65, 14, 2, 73, 67, 3, 40, 28, 9, 0, 18,
+ 5, 4, 67, 67, 62, 68, 3, 8, 9, 8, 5, 17, 21, 8, 18, 22,
+ 32, 67, 2, 73, 64, 26, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69,
+ 71, 88, 14, 13, 30, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65,
+ 69, 67, 16, 98, 81, 16, 84, 67, 74, 68, 10, 74, 76, 4, 5, 92,
+ 74, 99, 17, 20, 25, 4, 69, 65, 68, 73, 77, 85, 87, 87, 100, 95,
+ 97, 118, 110, 117, 126, 109, 108, 102, 99, 109, 96, 103, 100, 88, 95, 68,
+ 71, 73, 74, 93, 85, 86, 105, 92, 100, 101, 121, 105, 109, 112, 81, 79,
+ 116, 82, 85, 95, 110, 99, 106, 108, 91, 107, 99, 103, 111, 109, 113, 100,
+ 106, 111, 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19, 36, 4,
+ 64, 27, 75, 106, 126, 126, 126, 126, 126, 126, 6, 39, 30, 27, 17, 31,
+ 17, 9, 7, 1, 72, 67, 11, 2, 24, 34, 2, 4, 11, 15, 6, 13,
+ 28, 7, 0, 27, 75, 106, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 86, 95, 18, 60, 11,
+ 27, 70, 9, 21, 66, 75, 2, 82, 107, 75, 112, 126, 126, 126, 62, 5,
+ 64, 9, 21, 66, 85, 10, 11, 65, 0, 67, 67, 64, 80, 78, 91, 5,
+ 65, 68, 4, 72, 66, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 12, 70, 85, 46, 23, 15, 56, 62, 29, 31,
+ 20, 32, 13, 12, 38, 80, 74, 74, 80, 24, 65, 22, 35, 67, 70, 65,
+ 24, 0, 75, 74, 83, 19, 68, 9, 1, 66, 9, 0, 11, 10, 10, 18,
+ 26, 14, 8, 12, 62, 62, 62, 62, 9, 0, 4, 14, 64, 11, 13, 5,
+ 66, 40, 66, 110, 106, 60, 9, 17, 5, 6, 11, 19, 50, 29, 13, 66,
+ 1, 2, 20, 24, 105, 4, 5, 80, 66, 75, 6, 6, 72, 19, 12, 12,
+ 91, 9, 80, 75, 4, 89, 7, 7, 4, 81, 103, 65, 78, 76, 81, 95,
+ 91, 78, 126, 62, 126, 88, 91, 99, 114, 100, 112, 126, 125, 118, 97, 125,
+ 91, 62, 111, 67, 65, 73, 78, 79, 77, 82, 81, 82, 98, 98, 94, 96,
+ 98, 122, 75, 77, 99, 74, 81, 82, 89, 92, 98, 95, 101, 99, 85, 101,
+ 103, 95, 87, 16, 35, 22, 10, 12, 17, 9, 5, 5, 32, 22, 33, 25,
+ 22, 19, 29, 20, 27, 23, 20, 18, 48, 40, 35, 31, 36, 14, 6, 4,
+ 3, 71, 55, 29, 2, 66, 14, 2, 73, 66, 3, 40, 27, 8, 64, 18,
+ 5, 5, 67, 66, 62, 66, 4, 10, 11, 10, 6, 18, 22, 9, 20, 23,
+ 34, 66, 3, 72, 0, 28, 72, 74, 70, 4, 5, 69, 78, 69, 81, 69,
+ 71, 88, 14, 13, 31, 5, 66, 13, 8, 1, 7, 6, 1, 76, 0, 65,
+ 69, 67, 17, 99, 82, 16, 85, 67, 74, 69, 10, 74, 77, 4, 5, 93,
+ 74, 100, 16, 19, 24, 2, 71, 67, 70, 76, 79, 88, 90, 90, 103, 98,
+ 99, 123, 114, 121, 126, 112, 111, 105, 101, 111, 98, 104, 101, 88, 95, 71,
+ 73, 75, 76, 96, 88, 88, 108, 94, 102, 103, 124, 107, 111, 114, 81, 79,
+ 118, 83, 86, 96, 112, 101, 108, 109, 92, 109, 100, 103, 113, 110, 113, 102,
+ 108, 113, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20, 37, 4,
+ 64, 26, 77, 109, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 32,
+ 17, 10, 8, 1, 72, 67, 11, 2, 25, 35, 2, 4, 12, 16, 6, 14,
+ 29, 7, 0, 26, 77, 109, 126, 126, 126, 126, 126, 126, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 88, 97, 17, 60, 11,
+ 29, 70, 10, 22, 66, 75, 2, 82, 108, 76, 115, 126, 126, 126, 62, 6,
+ 64, 10, 22, 66, 86, 11, 11, 66, 0, 67, 67, 64, 80, 78, 91, 5,
+ 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 11, 71, 85, 49, 24, 16, 57, 62, 30, 33,
+ 22, 33, 14, 13, 40, 80, 74, 73, 80, 24, 65, 23, 37, 67, 69, 65,
+ 26, 0, 76, 75, 84, 19, 68, 10, 1, 65, 10, 0, 12, 10, 11, 20,
+ 27, 14, 9, 13, 62, 62, 62, 62, 9, 0, 4, 14, 64, 11, 14, 6,
+ 66, 42, 66, 112, 108, 62, 9, 17, 5, 6, 11, 19, 51, 30, 13, 66,
+ 1, 2, 20, 25, 106, 4, 5, 81, 66, 76, 6, 6, 72, 19, 12, 12,
+ 92, 9, 81, 76, 4, 89, 7, 7, 4, 83, 106, 66, 80, 78, 84, 97,
+ 94, 80, 126, 62, 126, 90, 93, 101, 117, 103, 115, 126, 126, 121, 99, 126,
+ 93, 62, 113, 69, 67, 75, 81, 82, 79, 84, 83, 84, 100, 100, 96, 98,
+ 99, 124, 75, 77, 100, 75, 82, 83, 90, 93, 99, 96, 103, 100, 86, 102,
+ 104, 95, 87, 18, 36, 23, 10, 12, 18, 9, 5, 5, 34, 23, 33, 25,
+ 23, 20, 30, 21, 28, 24, 22, 19, 48, 40, 35, 31, 37, 15, 6, 4,
+ 3, 71, 55, 29, 1, 66, 14, 2, 73, 66, 3, 39, 27, 7, 65, 18,
+ 5, 5, 67, 66, 62, 65, 6, 11, 12, 11, 7, 20, 24, 10, 21, 25,
+ 36, 66, 4, 72, 1, 30, 71, 74, 70, 4, 5, 69, 78, 69, 81, 69,
+ 71, 89, 15, 14, 32, 5, 66, 14, 8, 1, 7, 6, 1, 76, 0, 65,
+ 69, 67, 17, 100, 83, 16, 86, 68, 75, 69, 10, 75, 78, 4, 5, 94,
+ 74, 101, 15, 18, 23, 1, 73, 69, 72, 78, 82, 90, 93, 93, 106, 100,
+ 101, 126, 118, 125, 126, 116, 114, 107, 103, 114, 100, 106, 103, 89, 96, 73,
+ 76, 78, 79, 99, 90, 91, 111, 97, 105, 106, 126, 109, 113, 115, 82, 80,
+ 119, 85, 88, 98, 114, 102, 110, 111, 93, 110, 101, 104, 114, 111, 114, 103,
+ 109, 114, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20, 38, 4,
+ 64, 25, 79, 111, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 32,
+ 18, 10, 8, 2, 72, 67, 12, 3, 26, 36, 2, 5, 12, 16, 6, 14,
+ 29, 7, 0, 25, 79, 111, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 89, 99, 16, 60, 11,
+ 31, 70, 10, 23, 66, 76, 2, 83, 110, 77, 117, 126, 126, 126, 62, 7,
+ 64, 10, 23, 66, 86, 12, 11, 66, 0, 67, 66, 64, 80, 78, 91, 5,
+ 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, 6, 2, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 10, 71, 85, 51, 25, 17, 59, 62, 32, 34,
+ 24, 35, 15, 14, 42, 80, 74, 73, 80, 24, 65, 24, 39, 67, 68, 64,
+ 28, 0, 76, 75, 84, 19, 68, 10, 2, 64, 11, 1, 13, 11, 12, 21,
+ 29, 15, 10, 14, 62, 62, 62, 62, 9, 0, 4, 15, 64, 11, 14, 6,
+ 65, 44, 66, 114, 110, 62, 9, 17, 5, 6, 11, 20, 53, 31, 13, 66,
+ 1, 2, 21, 26, 107, 4, 5, 81, 67, 77, 5, 6, 73, 19, 12, 12,
+ 93, 9, 82, 77, 3, 89, 7, 6, 3, 85, 109, 67, 82, 80, 86, 99,
+ 96, 82, 126, 62, 126, 92, 95, 103, 120, 105, 118, 126, 126, 124, 101, 126,
+ 95, 62, 115, 71, 69, 77, 83, 84, 81, 86, 85, 86, 102, 102, 98, 100,
+ 101, 126, 75, 77, 100, 76, 83, 84, 91, 94, 100, 97, 105, 101, 86, 103,
+ 105, 96, 86, 19, 37, 23, 10, 12, 19, 10, 6, 6, 36, 24, 33, 25,
+ 23, 21, 31, 22, 30, 26, 24, 20, 49, 41, 36, 32, 38, 15, 6, 4,
+ 4, 71, 56, 29, 0, 66, 14, 2, 73, 65, 3, 39, 26, 6, 66, 18,
+ 5, 5, 67, 66, 62, 64, 7, 12, 14, 13, 8, 22, 26, 11, 23, 27,
+ 38, 65, 5, 71, 2, 32, 71, 74, 70, 5, 6, 69, 78, 69, 82, 69,
+ 71, 89, 15, 14, 33, 5, 66, 14, 8, 1, 7, 6, 1, 77, 0, 65,
+ 69, 67, 18, 101, 84, 16, 87, 69, 76, 70, 10, 76, 79, 4, 5, 95,
+ 74, 102, 14, 17, 22, 64, 75, 71, 74, 80, 84, 93, 96, 96, 109, 103,
+ 103, 126, 122, 126, 126, 119, 117, 110, 105, 116, 102, 108, 104, 90, 97, 75,
+ 78, 80, 81, 102, 93, 93, 114, 99, 107, 108, 126, 111, 115, 117, 83, 81,
+ 121, 86, 89, 100, 116, 104, 112, 113, 94, 112, 102, 105, 115, 112, 115, 105,
+ 110, 115, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21, 39, 4,
+ 64, 24, 81, 114, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 33,
+ 18, 10, 8, 2, 72, 67, 12, 3, 27, 37, 2, 5, 12, 16, 6, 14,
+ 30, 7, 0, 24, 81, 114, 126, 126, 126, 126, 126, 126, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 91, 102, 15, 60, 10,
+ 32, 71, 10, 23, 67, 77, 2, 84, 112, 79, 120, 126, 126, 126, 62, 7,
+ 64, 10, 23, 67, 87, 12, 11, 67, 0, 67, 66, 65, 81, 78, 91, 4,
+ 65, 67, 4, 72, 65, 80, 0, 74, 73, 80, 6, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 9, 72, 86, 53, 26, 18, 60, 62, 33, 35,
+ 25, 36, 16, 15, 44, 80, 74, 73, 80, 24, 65, 24, 41, 67, 68, 64,
+ 29, 64, 77, 76, 85, 19, 68, 10, 2, 64, 11, 1, 13, 11, 12, 22,
+ 30, 15, 11, 15, 62, 62, 62, 62, 9, 0, 4, 15, 65, 11, 14, 6,
+ 65, 46, 66, 116, 112, 62, 9, 17, 5, 6, 11, 20, 54, 31, 13, 67,
+ 0, 2, 21, 26, 109, 4, 5, 82, 68, 79, 4, 5, 74, 19, 12, 11,
+ 95, 9, 83, 78, 2, 89, 6, 5, 2, 88, 113, 69, 84, 83, 89, 102,
+ 99, 84, 126, 62, 126, 95, 97, 106, 124, 108, 122, 126, 126, 126, 103, 126,
+ 97, 62, 117, 74, 72, 80, 86, 87, 84, 89, 88, 88, 105, 105, 100, 102,
+ 103, 126, 75, 78, 101, 77, 85, 86, 93, 96, 102, 99, 107, 102, 87, 104,
+ 106, 97, 86, 20, 37, 23, 10, 12, 19, 10, 6, 6, 38, 25, 33, 25,
+ 23, 21, 31, 23, 31, 27, 25, 20, 49, 41, 36, 32, 39, 15, 6, 4,
+ 4, 72, 56, 28, 64, 67, 14, 2, 73, 65, 2, 38, 25, 4, 67, 17,
+ 5, 5, 67, 66, 62, 0, 8, 13, 15, 14, 9, 23, 27, 12, 24, 28,
+ 40, 65, 5, 71, 3, 33, 71, 74, 70, 5, 6, 69, 79, 70, 83, 69,
+ 72, 90, 15, 14, 34, 5, 67, 14, 8, 0, 7, 6, 1, 78, 0, 65,
+ 69, 67, 18, 102, 85, 16, 89, 70, 77, 71, 9, 77, 80, 4, 4, 97,
+ 75, 104, 12, 15, 21, 66, 77, 74, 77, 83, 87, 96, 99, 99, 113, 106,
+ 105, 126, 126, 126, 126, 123, 121, 113, 108, 119, 104, 110, 106, 91, 98, 78,
+ 81, 83, 84, 105, 96, 96, 118, 102, 110, 111, 126, 113, 117, 119, 84, 82,
+ 123, 88, 91, 102, 119, 106, 114, 115, 96, 114, 104, 106, 117, 113, 116, 107,
+ 112, 117, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, 21, 39, 4,
+ 65, 22, 83, 117, 126, 126, 126, 126, 126, 126, 7, 39, 30, 27, 17, 33,
+ 18, 10, 8, 2, 72, 67, 12, 3, 27, 37, 2, 5, 12, 16, 6, 14,
+ 30, 6, 64, 22, 83, 117, 126, 126, 126, 126, 126, 126, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 92, 104, 14, 61, 10,
+ 34, 71, 11, 24, 67, 77, 3, 84, 113, 80, 122, 126, 126, 126, 62, 8,
+ 0, 11, 24, 67, 87, 13, 11, 67, 1, 66, 65, 65, 81, 77, 90, 4,
+ 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 9, 72, 86, 56, 28, 20, 62, 62, 35, 37,
+ 27, 38, 18, 17, 47, 80, 73, 72, 79, 24, 65, 25, 44, 66, 67, 0,
+ 31, 64, 77, 76, 85, 20, 68, 11, 3, 0, 12, 2, 14, 12, 13, 24,
+ 32, 16, 13, 17, 62, 62, 62, 62, 10, 1, 5, 16, 65, 12, 15, 7,
+ 64, 49, 65, 118, 113, 62, 9, 18, 5, 7, 12, 21, 56, 32, 14, 67,
+ 0, 2, 22, 27, 110, 5, 5, 82, 68, 80, 4, 5, 74, 19, 12, 11,
+ 96, 10, 83, 78, 2, 89, 6, 5, 2, 90, 116, 70, 85, 85, 91, 104,
+ 101, 86, 126, 62, 126, 97, 98, 108, 126, 110, 125, 126, 126, 126, 105, 126,
+ 99, 62, 118, 76, 74, 82, 88, 89, 86, 91, 90, 90, 107, 107, 101, 103,
+ 104, 126, 75, 78, 101, 77, 86, 87, 94, 97, 103, 100, 108, 103, 87, 105,
+ 106, 97, 85, 22, 38, 24, 10, 13, 20, 11, 7, 7, 41, 27, 34, 26,
+ 24, 22, 32, 25, 33, 29, 27, 21, 50, 42, 37, 33, 40, 16, 7, 5,
+ 5, 72, 57, 28, 64, 67, 15, 3, 73, 64, 2, 38, 25, 3, 68, 17,
+ 6, 6, 66, 65, 62, 2, 10, 15, 17, 16, 11, 25, 29, 14, 26, 30,
+ 43, 64, 6, 70, 5, 35, 70, 73, 69, 6, 7, 68, 79, 70, 83, 69,
+ 72, 90, 16, 15, 35, 6, 67, 15, 9, 0, 8, 7, 1, 78, 1, 64,
+ 68, 66, 19, 102, 86, 16, 90, 70, 77, 71, 9, 77, 80, 4, 4, 98,
+ 75, 105, 11, 14, 21, 67, 78, 76, 79, 85, 89, 98, 101, 101, 116, 108,
+ 107, 126, 126, 126, 126, 126, 124, 115, 110, 121, 105, 111, 107, 91, 98, 80,
+ 83, 85, 86, 107, 98, 98, 121, 104, 112, 113, 126, 114, 118, 120, 84, 82,
+ 124, 89, 92, 103, 121, 107, 115, 116, 97, 115, 105, 106, 118, 113, 116, 108,
+ 113, 118, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, 22, 40, 4,
+ 65, 21, 85, 119, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 34,
+ 19, 11, 9, 3, 71, 66, 13, 4, 28, 38, 3, 6, 13, 17, 6, 15,
+ 31, 6, 64, 21, 85, 119, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 93, 106, 13, 61, 10,
+ 36, 71, 11, 25, 67, 78, 3, 85, 115, 81, 125, 126, 126, 126, 62, 9,
+ 0, 11, 25, 67, 87, 14, 11, 68, 1, 66, 64, 65, 81, 77, 90, 4,
+ 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 8, 72, 86, 58, 29, 21, 62, 62, 36, 38,
+ 29, 39, 19, 18, 49, 80, 73, 72, 79, 24, 65, 26, 46, 66, 66, 1,
+ 33, 64, 77, 76, 86, 20, 68, 11, 4, 1, 13, 3, 15, 12, 14, 25,
+ 33, 17, 14, 18, 62, 62, 62, 62, 10, 1, 5, 16, 65, 12, 15, 7,
+ 64, 51, 65, 120, 115, 62, 9, 18, 5, 7, 12, 21, 58, 33, 14, 67,
+ 0, 2, 23, 28, 111, 5, 5, 82, 69, 81, 3, 5, 75, 19, 12, 11,
+ 97, 10, 84, 79, 1, 89, 6, 4, 1, 92, 119, 71, 87, 87, 93, 106,
+ 103, 88, 126, 62, 126, 99, 100, 110, 126, 112, 126, 126, 126, 126, 107, 126,
+ 101, 62, 120, 78, 76, 84, 90, 91, 88, 93, 92, 92, 109, 109, 103, 105,
+ 106, 126, 75, 78, 102, 78, 87, 88, 95, 98, 104, 101, 110, 104, 87, 106,
+ 107, 98, 84, 23, 39, 24, 10, 13, 21, 12, 8, 8, 43, 28, 34, 26,
+ 24, 23, 33, 26, 35, 31, 29, 22, 51, 43, 38, 34, 41, 16, 7, 5,
+ 6, 72, 58, 28, 65, 67, 15, 3, 73, 64, 2, 38, 24, 2, 69, 17,
+ 6, 6, 66, 65, 62, 3, 11, 16, 19, 18, 12, 27, 31, 15, 28, 32,
+ 45, 0, 7, 70, 6, 37, 70, 73, 69, 7, 7, 68, 79, 70, 84, 69,
+ 72, 90, 16, 15, 36, 6, 67, 15, 9, 0, 8, 7, 1, 79, 1, 64,
+ 68, 66, 20, 103, 87, 16, 91, 71, 78, 72, 9, 78, 81, 4, 4, 99,
+ 75, 106, 10, 13, 20, 69, 80, 78, 81, 87, 91, 101, 104, 104, 119, 111,
+ 109, 126, 126, 126, 126, 126, 126, 118, 112, 124, 107, 113, 108, 92, 99, 82,
+ 85, 88, 88, 110, 101, 101, 124, 106, 115, 115, 126, 116, 120, 122, 85, 83,
+ 126, 90, 93, 105, 123, 109, 117, 118, 98, 117, 106, 107, 119, 114, 117, 110,
+ 114, 119, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, 22, 41, 4,
+ 65, 20, 87, 122, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 35,
+ 19, 11, 9, 3, 71, 66, 13, 4, 29, 39, 3, 6, 13, 17, 6, 15,
+ 32, 6, 64, 20, 87, 122, 126, 126, 126, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 95, 108, 12, 61, 10,
+ 38, 71, 12, 26, 67, 78, 3, 85, 116, 82, 126, 126, 126, 126, 62, 10,
+ 0, 12, 26, 67, 88, 15, 11, 68, 1, 66, 64, 65, 81, 77, 90, 4,
+ 64, 65, 4, 71, 0, 79, 1, 73, 73, 79, 7, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 7, 73, 86, 61, 30, 22, 62, 62, 38, 40,
+ 31, 41, 20, 19, 51, 80, 73, 71, 79, 24, 65, 27, 48, 66, 65, 1,
+ 35, 64, 78, 77, 86, 20, 68, 12, 4, 2, 14, 3, 16, 13, 15, 27,
+ 35, 17, 15, 19, 62, 62, 62, 62, 10, 1, 5, 17, 65, 12, 16, 8,
+ 0, 53, 65, 122, 117, 62, 9, 18, 5, 7, 12, 22, 59, 34, 14, 67,
+ 0, 2, 23, 29, 112, 5, 5, 83, 69, 82, 3, 5, 75, 19, 12, 11,
+ 98, 10, 85, 80, 1, 89, 6, 4, 1, 94, 122, 72, 89, 89, 96, 108,
+ 106, 90, 126, 62, 126, 101, 102, 112, 126, 115, 126, 126, 126, 126, 109, 126,
+ 103, 62, 122, 80, 78, 86, 93, 94, 90, 95, 94, 94, 111, 111, 105, 107,
+ 107, 126, 75, 78, 102, 79, 88, 89, 96, 99, 105, 102, 112, 105, 88, 107,
+ 108, 98, 84, 25, 40, 25, 10, 13, 22, 12, 8, 8, 45, 29, 34, 26,
+ 25, 24, 34, 27, 36, 32, 31, 23, 51, 43, 38, 34, 42, 17, 7, 5,
+ 6, 72, 58, 28, 66, 67, 15, 3, 73, 0, 2, 37, 24, 1, 70, 17,
+ 6, 6, 66, 65, 62, 4, 13, 17, 20, 19, 13, 29, 33, 16, 29, 34,
+ 47, 0, 8, 69, 7, 39, 69, 73, 69, 7, 8, 68, 79, 70, 84, 69,
+ 72, 91, 17, 16, 37, 6, 67, 16, 9, 0, 8, 7, 1, 79, 1, 64,
+ 68, 66, 20, 104, 88, 16, 92, 72, 79, 72, 9, 79, 82, 4, 4, 100,
+ 75, 107, 9, 12, 19, 70, 82, 80, 83, 89, 94, 103, 107, 107, 122, 113,
+ 111, 126, 126, 126, 126, 126, 126, 120, 114, 126, 109, 115, 110, 93, 100, 84,
+ 88, 90, 91, 113, 103, 103, 126, 109, 117, 118, 126, 118, 122, 123, 86, 84,
+ 126, 92, 95, 107, 125, 110, 119, 120, 99, 118, 107, 108, 120, 115, 118, 111,
+ 115, 120, 69, 2, 18, 5, 38, 48, 2, 12, 21, 25, 6, 23, 42, 4,
+ 65, 19, 89, 124, 126, 126, 126, 126, 126, 126, 8, 39, 31, 28, 18, 35,
+ 20, 11, 9, 4, 71, 66, 14, 5, 30, 40, 3, 7, 13, 17, 6, 15,
+ 32, 6, 64, 19, 89, 124, 126, 126, 126, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 47, 62, 62, 12, 1,
+ 99, 47, 85, 102, 6, 6, 73, 6, 23, 53, 62, 62, 21, 97, 126, 117,
+ 74, 85, 102, 6, 93, 88, 19, 8, 89, 103, 116, 6, 5, 84, 96, 0,
+ 85, 106, 0, 75, 90, 101, 8, 79, 75, 97, 13, 3, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 29, 88, 126, 126, 91, 95, 84, 86, 89, 91,
+ 126, 76, 103, 90, 126, 80, 76, 84, 78, 8, 2, 83, 126, 79, 104, 91,
+ 126, 65, 79, 72, 92, 7, 68, 71, 98, 86, 88, 82, 72, 67, 72, 89,
+ 69, 4, 66, 6, 71, 71, 5, 74, 19, 69, 1, 12, 16, 21, 22, 10,
+ 76, 78, 83, 11, 67, 90, 67, 72, 75, 80, 83, 64, 32, 64, 94, 75,
+ 0, 74, 28, 36, 91, 65, 69, 77, 66, 1, 68, 81, 33, 56, 40, 74,
+ 66, 124, 26, 62, 62, 126, 24, 21, 29, 34, 32, 26, 21, 23, 30, 20,
+ 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, 11, 26, 14, 5, 15, 18,
+ 69, 30, 0, 62, 62, 62, 53, 62, 62, 62, 62, 46, 38, 34, 30, 48,
+ 43, 73, 29, 32, 19, 47, 27, 27, 35, 42, 43, 51, 47, 21, 93, 7,
+ 6, 25, 126, 115, 82, 1, 10, 4, 85, 89, 94, 92, 126, 100, 6, 67,
+ 71, 77, 85, 88, 104, 98, 126, 82, 15, 2, 66, 70, 75, 79, 83, 92,
+ 108, 79, 69, 75, 5, 5, 78, 83, 81, 99, 81, 25, 1, 5, 4, 73,
+ 76, 86, 83, 87, 62, 126, 126, 120, 126, 114, 117, 118, 117, 113, 118, 120,
+ 124, 94, 102, 99, 106, 126, 92, 6, 86, 94, 91, 77, 71, 73, 64, 81,
+ 64, 6, 67, 68, 67, 68, 77, 64, 68, 78, 8, 4, 65, 9, 19, 3,
+ 70, 76, 86, 70, 64, 70, 8, 7, 69, 65, 74, 9, 9, 76, 82, 77,
+ 77, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 52, 62, 62, 62, 62, 62, 62, 48, 62, 62, 46, 25, 18, 9, 79, 62,
+ 62, 62, 62, 48, 48, 38, 41, 47, 45, 35, 22, 35, 16, 1, 32, 37,
+ 39, 40, 47, 33, 34, 22, 21, 3, 11, 3, 78, 123, 10, 7, 2, 30,
+ 13, 2, 78, 74, 72, 72, 75, 71, 0, 70, 75, 72, 67, 10, 4, 11,
+ 68, 62, 62, 62, 62, 56, 51, 40, 25, 64, 71, 26, 19, 14, 7, 4,
+ 0, 67, 68, 79, 78, 74, 72, 72, 75, 71, 0, 70, 75, 72, 67, 10,
+ 4, 11, 68, 62, 62, 62, 62, 56, 51, 40, 25, 64, 75, 65, 4, 67,
+ 67, 104, 106},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 46, 62, 62, 13, 2,
+ 97, 46, 84, 100, 6, 6, 71, 6, 22, 52, 62, 60, 19, 97, 125, 115,
+ 73, 84, 100, 6, 92, 87, 20, 8, 88, 102, 114, 5, 4, 84, 96, 0,
+ 84, 105, 0, 75, 89, 100, 8, 78, 74, 96, 14, 3, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 29, 87, 125, 124, 89, 94, 82, 84, 88, 89,
+ 125, 75, 101, 89, 124, 80, 76, 84, 78, 9, 2, 82, 124, 78, 103, 90,
+ 125, 65, 78, 72, 91, 8, 68, 70, 97, 85, 87, 81, 71, 66, 71, 88,
+ 68, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11,
+ 76, 77, 82, 11, 67, 89, 67, 71, 74, 79, 81, 1, 33, 1, 92, 75,
+ 64, 73, 29, 37, 91, 65, 68, 77, 65, 1, 67, 79, 33, 56, 41, 72,
+ 67, 122, 25, 62, 62, 125, 24, 21, 29, 34, 32, 26, 21, 23, 30, 20,
+ 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, 11, 26, 14, 4, 15, 18,
+ 69, 29, 0, 62, 62, 62, 52, 62, 62, 62, 62, 45, 37, 32, 29, 46,
+ 42, 74, 28, 31, 18, 46, 27, 27, 34, 41, 42, 50, 46, 20, 93, 7,
+ 6, 24, 125, 113, 80, 2, 10, 4, 84, 88, 93, 91, 125, 98, 7, 66,
+ 70, 76, 83, 87, 102, 97, 124, 81, 16, 3, 65, 69, 74, 78, 82, 91,
+ 106, 78, 67, 74, 6, 5, 77, 82, 80, 98, 80, 26, 2, 6, 5, 72,
+ 75, 85, 82, 86, 62, 125, 125, 118, 125, 112, 115, 116, 115, 111, 116, 118,
+ 121, 93, 101, 98, 105, 123, 91, 5, 85, 93, 90, 76, 71, 72, 64, 80,
+ 64, 6, 67, 68, 66, 68, 77, 64, 68, 77, 8, 4, 65, 9, 19, 3,
+ 70, 75, 84, 70, 64, 69, 8, 7, 69, 65, 73, 9, 9, 75, 81, 76,
+ 76, 20, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 50, 62, 62, 62, 62, 62, 62, 47, 60, 60, 45, 24, 17, 9, 79, 62,
+ 62, 62, 60, 46, 47, 37, 39, 46, 43, 34, 20, 33, 15, 0, 31, 36,
+ 37, 39, 46, 32, 33, 21, 20, 2, 11, 3, 78, 122, 9, 6, 1, 29,
+ 12, 1, 77, 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, 12,
+ 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, 70, 27, 20, 15, 8, 5,
+ 1, 66, 67, 78, 77, 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11,
+ 5, 12, 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, 75, 65, 4, 66,
+ 66, 102, 103},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 44, 60, 62, 14, 2,
+ 95, 44, 84, 99, 6, 6, 70, 5, 21, 51, 60, 57, 17, 98, 123, 114,
+ 73, 84, 99, 6, 92, 86, 20, 8, 87, 101, 113, 4, 3, 84, 96, 0,
+ 84, 104, 0, 75, 89, 100, 8, 78, 74, 95, 14, 3, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 29, 86, 124, 122, 88, 93, 80, 82, 87, 88,
+ 123, 74, 100, 88, 122, 81, 76, 84, 78, 9, 2, 81, 122, 78, 102, 89,
+ 123, 65, 78, 72, 91, 8, 68, 70, 96, 85, 86, 81, 71, 66, 71, 87,
+ 67, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11,
+ 77, 76, 81, 10, 67, 89, 67, 70, 74, 79, 80, 2, 34, 3, 90, 76,
+ 65, 73, 29, 37, 92, 65, 68, 78, 64, 1, 67, 78, 33, 56, 41, 71,
+ 68, 121, 24, 62, 62, 124, 24, 21, 29, 33, 31, 26, 21, 23, 29, 19,
+ 26, 16, 8, 5, 3, 18, 18, 20, 15, 7, 11, 25, 13, 3, 14, 17,
+ 69, 28, 64, 62, 62, 62, 50, 60, 62, 62, 62, 44, 35, 30, 27, 44,
+ 40, 75, 27, 30, 16, 45, 26, 26, 33, 39, 40, 48, 44, 18, 93, 6,
+ 5, 22, 124, 112, 79, 3, 10, 4, 83, 87, 92, 90, 123, 97, 8, 65,
+ 69, 75, 82, 86, 101, 96, 122, 80, 16, 3, 65, 69, 73, 77, 81, 90,
+ 105, 78, 66, 73, 6, 5, 76, 81, 80, 97, 79, 26, 3, 6, 5, 71,
+ 74, 84, 81, 85, 62, 124, 123, 116, 123, 111, 114, 114, 113, 110, 114, 116,
+ 119, 92, 100, 97, 104, 120, 91, 4, 85, 92, 89, 76, 71, 72, 64, 80,
+ 64, 5, 67, 68, 65, 68, 77, 64, 68, 77, 8, 4, 65, 8, 18, 3,
+ 70, 75, 83, 71, 64, 68, 7, 7, 69, 65, 73, 9, 9, 75, 80, 76,
+ 76, 18, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 48, 62, 62, 62, 62, 62, 61, 45, 58, 58, 43, 23, 16, 8, 79, 62,
+ 62, 62, 58, 44, 45, 35, 37, 44, 41, 32, 18, 31, 13, 64, 30, 35,
+ 35, 37, 44, 30, 31, 20, 19, 1, 10, 2, 78, 121, 8, 5, 64, 28,
+ 11, 0, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11, 6, 13,
+ 66, 62, 62, 62, 60, 52, 48, 36, 22, 66, 69, 27, 20, 16, 9, 6,
+ 1, 65, 67, 77, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11,
+ 6, 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, 66, 75, 65, 4, 66,
+ 66, 101, 101},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 42, 59, 61, 14, 2,
+ 93, 43, 84, 97, 6, 5, 69, 4, 20, 50, 58, 53, 15, 99, 121, 112,
+ 73, 84, 97, 6, 91, 85, 21, 8, 86, 100, 112, 3, 2, 84, 97, 0,
+ 84, 103, 0, 76, 89, 100, 8, 78, 74, 94, 15, 3, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 28, 86, 123, 120, 87, 92, 79, 81, 86, 87,
+ 121, 73, 99, 87, 120, 82, 76, 84, 78, 10, 2, 80, 120, 78, 101, 88,
+ 121, 65, 78, 72, 91, 9, 68, 69, 95, 85, 85, 81, 71, 66, 70, 86,
+ 67, 5, 66, 6, 70, 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12,
+ 77, 76, 80, 10, 67, 89, 67, 69, 74, 78, 79, 3, 35, 4, 88, 76,
+ 66, 72, 29, 37, 93, 65, 67, 78, 64, 1, 67, 77, 33, 56, 41, 70,
+ 69, 119, 23, 62, 62, 122, 24, 21, 28, 32, 31, 25, 20, 23, 29, 18,
+ 25, 16, 8, 5, 2, 18, 17, 19, 14, 7, 11, 24, 13, 2, 14, 16,
+ 69, 27, 64, 62, 62, 61, 49, 58, 62, 62, 62, 43, 33, 28, 26, 42,
+ 38, 77, 26, 29, 14, 44, 25, 25, 32, 38, 38, 46, 42, 17, 93, 5,
+ 4, 21, 122, 110, 77, 3, 10, 4, 82, 86, 91, 89, 121, 96, 9, 64,
+ 68, 75, 81, 85, 99, 95, 120, 80, 17, 4, 64, 68, 72, 77, 81, 89,
+ 104, 78, 64, 72, 6, 5, 75, 81, 80, 96, 78, 27, 4, 7, 5, 70,
+ 74, 83, 81, 85, 62, 122, 122, 115, 121, 110, 112, 113, 112, 108, 112, 114,
+ 117, 92, 99, 97, 103, 117, 91, 3, 85, 91, 88, 76, 71, 72, 64, 79,
+ 64, 4, 67, 68, 65, 68, 77, 64, 68, 77, 7, 4, 65, 7, 17, 3,
+ 70, 75, 82, 72, 64, 67, 6, 7, 69, 65, 72, 9, 8, 74, 79, 76,
+ 76, 17, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 46, 62, 62, 62, 62, 62, 59, 43, 56, 55, 41, 22, 15, 7, 79, 62,
+ 62, 62, 56, 42, 43, 34, 35, 42, 39, 30, 16, 29, 11, 65, 29, 34,
+ 33, 36, 42, 29, 29, 18, 17, 0, 9, 1, 78, 120, 7, 3, 65, 27,
+ 10, 64, 77, 72, 70, 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13,
+ 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 69, 28, 21, 17, 9, 7,
+ 2, 65, 66, 77, 77, 72, 70, 70, 71, 68, 3, 69, 71, 69, 64, 12,
+ 7, 13, 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 75, 65, 4, 65,
+ 65, 99, 99},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 40, 57, 60, 15, 2,
+ 92, 41, 84, 96, 5, 5, 68, 3, 18, 48, 56, 50, 12, 100, 119, 111,
+ 73, 84, 96, 5, 91, 84, 21, 7, 86, 99, 110, 2, 0, 85, 97, 0,
+ 83, 102, 64, 76, 89, 100, 8, 78, 74, 94, 15, 3, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 28, 85, 122, 118, 86, 91, 77, 79, 86, 86,
+ 119, 72, 98, 86, 117, 82, 77, 84, 79, 10, 1, 79, 117, 77, 101, 88,
+ 119, 65, 78, 72, 91, 9, 68, 69, 94, 85, 85, 80, 71, 66, 70, 85,
+ 66, 5, 67, 5, 70, 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12,
+ 78, 75, 80, 9, 67, 88, 67, 68, 73, 78, 77, 5, 36, 6, 86, 77,
+ 67, 72, 30, 37, 94, 65, 67, 79, 0, 1, 67, 76, 33, 56, 41, 68,
+ 70, 118, 22, 62, 62, 121, 23, 21, 28, 32, 30, 25, 20, 23, 28, 17,
+ 24, 15, 8, 5, 2, 17, 17, 18, 14, 6, 10, 23, 12, 1, 13, 15,
+ 69, 25, 65, 62, 62, 59, 47, 57, 62, 62, 62, 42, 31, 25, 24, 40,
+ 36, 78, 24, 28, 13, 43, 24, 24, 30, 36, 36, 44, 41, 15, 93, 4,
+ 3, 19, 121, 109, 76, 4, 10, 4, 81, 85, 90, 89, 119, 94, 10, 64,
+ 68, 74, 79, 84, 98, 94, 117, 79, 17, 4, 64, 68, 71, 76, 80, 89,
+ 103, 78, 0, 71, 6, 5, 74, 80, 80, 95, 77, 27, 5, 7, 5, 69,
+ 73, 82, 80, 84, 62, 121, 120, 113, 120, 109, 111, 111, 110, 107, 111, 112,
+ 114, 91, 98, 96, 102, 114, 90, 2, 84, 90, 88, 76, 71, 72, 65, 79,
+ 65, 3, 67, 68, 64, 68, 77, 64, 68, 76, 7, 3, 65, 6, 16, 2,
+ 70, 75, 81, 73, 65, 67, 6, 6, 69, 65, 72, 8, 8, 74, 79, 76,
+ 76, 15, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 44, 62, 62, 62, 62, 62, 57, 41, 54, 53, 39, 20, 14, 6, 79, 62,
+ 62, 62, 54, 40, 41, 32, 33, 40, 37, 28, 14, 26, 10, 67, 28, 33,
+ 30, 34, 41, 27, 27, 17, 16, 64, 8, 0, 78, 119, 5, 2, 67, 25,
+ 9, 65, 77, 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, 14,
+ 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, 68, 28, 21, 17, 10, 7,
+ 2, 64, 66, 76, 77, 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12,
+ 8, 14, 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, 75, 65, 4, 65,
+ 65, 98, 97},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 38, 56, 59, 16, 2,
+ 90, 39, 83, 94, 5, 5, 67, 2, 17, 47, 54, 47, 10, 100, 117, 110,
+ 73, 83, 94, 5, 91, 83, 21, 7, 85, 98, 109, 1, 64, 85, 97, 0,
+ 83, 101, 64, 76, 89, 100, 8, 77, 74, 93, 16, 3, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 27, 85, 120, 115, 85, 90, 76, 78, 85, 85,
+ 117, 71, 97, 85, 115, 83, 77, 84, 79, 10, 1, 78, 115, 77, 100, 87,
+ 117, 65, 78, 72, 90, 9, 68, 68, 93, 84, 84, 80, 71, 65, 69, 84,
+ 66, 5, 67, 5, 69, 70, 5, 73, 21, 68, 1, 15, 18, 23, 23, 12,
+ 78, 75, 79, 9, 67, 88, 67, 67, 73, 77, 76, 6, 37, 7, 84, 77,
+ 68, 71, 30, 37, 95, 65, 66, 79, 1, 1, 67, 74, 33, 56, 41, 67,
+ 71, 116, 21, 62, 62, 120, 23, 21, 27, 31, 30, 25, 19, 23, 28, 16,
+ 23, 15, 8, 5, 2, 17, 16, 17, 13, 6, 10, 22, 12, 0, 12, 15,
+ 69, 24, 65, 62, 62, 58, 46, 55, 62, 62, 62, 41, 29, 23, 23, 38,
+ 34, 79, 23, 27, 11, 42, 23, 23, 29, 35, 34, 42, 39, 14, 93, 3,
+ 2, 17, 119, 107, 75, 4, 10, 4, 80, 84, 89, 88, 117, 93, 11, 0,
+ 67, 73, 78, 83, 96, 93, 115, 78, 18, 5, 0, 67, 70, 75, 80, 88,
+ 102, 77, 1, 70, 6, 5, 73, 80, 79, 94, 76, 27, 6, 7, 5, 68,
+ 72, 81, 80, 83, 62, 120, 119, 112, 118, 108, 109, 110, 108, 105, 109, 110,
+ 112, 90, 97, 95, 101, 111, 90, 1, 84, 89, 87, 76, 71, 72, 65, 78,
+ 65, 2, 67, 68, 0, 68, 77, 64, 68, 76, 6, 3, 65, 5, 15, 2,
+ 70, 75, 80, 73, 65, 66, 5, 6, 69, 65, 72, 8, 7, 74, 78, 76,
+ 76, 14, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 42, 62, 62, 62, 62, 62, 55, 40, 52, 50, 37, 19, 13, 5, 79, 62,
+ 62, 62, 52, 38, 39, 31, 31, 38, 35, 26, 12, 24, 8, 68, 27, 32,
+ 28, 33, 39, 26, 25, 16, 15, 65, 7, 64, 78, 118, 4, 1, 68, 24,
+ 8, 66, 77, 71, 69, 68, 69, 67, 4, 68, 69, 67, 1, 13, 9, 14,
+ 64, 62, 62, 58, 54, 46, 42, 29, 16, 70, 68, 29, 22, 18, 11, 8,
+ 3, 64, 66, 75, 77, 71, 69, 68, 69, 67, 4, 68, 69, 67, 1, 13,
+ 9, 14, 64, 62, 62, 58, 54, 46, 42, 29, 16, 70, 75, 65, 4, 65,
+ 65, 96, 95},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 37, 54, 58, 16, 3,
+ 88, 38, 83, 93, 5, 4, 66, 1, 16, 46, 53, 43, 8, 101, 115, 108,
+ 73, 83, 93, 5, 90, 82, 22, 7, 84, 97, 108, 64, 65, 85, 98, 0,
+ 83, 101, 64, 77, 88, 100, 7, 77, 74, 92, 16, 3, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 27, 84, 119, 113, 84, 89, 74, 76, 84, 84,
+ 115, 70, 96, 85, 113, 84, 77, 84, 79, 11, 1, 77, 113, 77, 99, 86,
+ 115, 65, 78, 72, 90, 10, 69, 68, 93, 84, 83, 80, 70, 65, 69, 83,
+ 65, 5, 67, 5, 69, 70, 5, 73, 21, 68, 1, 15, 18, 24, 24, 13,
+ 79, 74, 78, 8, 67, 88, 67, 66, 73, 77, 75, 7, 37, 9, 83, 78,
+ 69, 71, 30, 37, 95, 66, 66, 80, 1, 0, 66, 73, 33, 56, 42, 66,
+ 72, 115, 20, 62, 62, 118, 23, 21, 27, 30, 29, 24, 19, 22, 27, 16,
+ 23, 15, 7, 5, 1, 16, 15, 16, 13, 6, 10, 22, 11, 65, 12, 14,
+ 69, 23, 66, 62, 62, 56, 44, 53, 62, 62, 62, 39, 27, 21, 21, 36,
+ 32, 81, 22, 25, 9, 40, 22, 22, 28, 33, 32, 40, 37, 12, 93, 2,
+ 1, 16, 118, 106, 73, 5, 10, 4, 79, 84, 89, 87, 116, 92, 12, 1,
+ 66, 73, 77, 82, 95, 92, 113, 78, 18, 5, 0, 67, 69, 75, 79, 87,
+ 101, 77, 3, 69, 6, 5, 73, 79, 79, 94, 76, 28, 6, 8, 5, 67,
+ 72, 81, 79, 83, 62, 118, 117, 110, 116, 106, 108, 108, 107, 104, 107, 108,
+ 110, 90, 96, 95, 101, 108, 90, 0, 84, 89, 86, 76, 71, 72, 65, 78,
+ 65, 1, 67, 68, 0, 68, 77, 64, 68, 76, 6, 3, 65, 4, 14, 2,
+ 70, 75, 79, 74, 65, 65, 4, 6, 69, 65, 71, 8, 7, 73, 77, 76,
+ 76, 12, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 40, 62, 62, 62, 62, 62, 52, 38, 50, 48, 35, 18, 12, 4, 79, 62,
+ 62, 62, 50, 36, 38, 29, 29, 36, 32, 24, 10, 22, 6, 69, 26, 30,
+ 26, 31, 37, 24, 23, 14, 13, 66, 6, 65, 79, 117, 3, 64, 70, 23,
+ 6, 67, 76, 71, 68, 68, 68, 66, 5, 68, 68, 66, 2, 13, 10, 15,
+ 0, 62, 62, 56, 52, 44, 40, 27, 14, 71, 67, 29, 22, 19, 11, 9,
+ 3, 0, 65, 75, 76, 71, 68, 68, 68, 66, 5, 68, 68, 66, 2, 13,
+ 10, 15, 0, 62, 62, 56, 52, 44, 40, 27, 14, 71, 75, 65, 4, 64,
+ 64, 95, 92},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 35, 53, 57, 17, 3,
+ 87, 36, 83, 91, 4, 4, 65, 0, 15, 45, 51, 40, 5, 102, 113, 107,
+ 73, 83, 91, 4, 90, 81, 22, 7, 84, 96, 106, 65, 66, 85, 98, 0,
+ 82, 100, 65, 77, 88, 100, 7, 77, 74, 91, 17, 3, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 26, 84, 118, 111, 83, 88, 73, 75, 83, 83,
+ 113, 69, 95, 84, 110, 84, 78, 84, 80, 11, 1, 76, 110, 76, 99, 86,
+ 113, 65, 78, 72, 90, 10, 69, 67, 92, 84, 82, 79, 70, 65, 68, 82,
+ 65, 5, 68, 5, 69, 70, 5, 73, 21, 68, 1, 16, 18, 24, 24, 13,
+ 79, 74, 78, 8, 67, 87, 67, 65, 72, 76, 73, 9, 38, 10, 81, 78,
+ 70, 70, 31, 37, 96, 66, 65, 80, 2, 0, 66, 72, 33, 56, 42, 64,
+ 73, 113, 19, 62, 62, 117, 23, 21, 26, 30, 29, 24, 18, 22, 27, 15,
+ 22, 15, 7, 5, 1, 16, 15, 15, 12, 6, 10, 21, 11, 66, 11, 13,
+ 69, 22, 66, 62, 62, 54, 43, 52, 62, 62, 62, 38, 25, 19, 20, 34,
+ 30, 82, 21, 24, 8, 39, 21, 21, 26, 32, 30, 38, 36, 11, 93, 1,
+ 0, 14, 116, 104, 72, 5, 10, 4, 78, 83, 88, 87, 114, 90, 13, 2,
+ 66, 72, 75, 81, 93, 91, 110, 77, 19, 6, 1, 66, 68, 74, 79, 86,
+ 100, 77, 4, 68, 6, 5, 72, 79, 79, 93, 75, 28, 7, 8, 5, 66,
+ 71, 80, 79, 82, 62, 117, 116, 109, 115, 105, 106, 107, 105, 102, 105, 106,
+ 107, 89, 95, 94, 100, 105, 89, 64, 83, 88, 85, 76, 71, 72, 65, 77,
+ 66, 0, 67, 68, 1, 68, 77, 64, 68, 75, 5, 2, 65, 3, 13, 1,
+ 70, 75, 78, 75, 66, 64, 4, 5, 69, 65, 71, 7, 6, 73, 77, 76,
+ 76, 11, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 38, 62, 62, 62, 62, 62, 50, 36, 48, 45, 33, 17, 11, 3, 79, 62,
+ 61, 62, 48, 34, 36, 28, 27, 34, 30, 22, 8, 20, 5, 71, 25, 29,
+ 24, 30, 36, 23, 21, 13, 12, 67, 5, 66, 79, 116, 1, 65, 71, 21,
+ 5, 68, 76, 70, 68, 67, 67, 65, 5, 67, 67, 65, 3, 14, 11, 15,
+ 0, 62, 60, 54, 50, 42, 38, 24, 12, 72, 67, 30, 23, 19, 12, 10,
+ 4, 0, 65, 74, 76, 70, 68, 67, 67, 65, 5, 67, 67, 65, 3, 14,
+ 11, 15, 0, 62, 60, 54, 50, 42, 38, 24, 12, 72, 75, 65, 4, 64,
+ 64, 93, 90},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 33, 51, 56, 17, 3,
+ 85, 34, 83, 90, 4, 3, 64, 64, 13, 43, 49, 36, 3, 103, 111, 106,
+ 73, 83, 90, 4, 90, 81, 22, 6, 83, 95, 105, 66, 68, 86, 99, 0,
+ 82, 99, 65, 78, 88, 100, 7, 77, 74, 91, 17, 3, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 26, 83, 117, 109, 82, 88, 71, 73, 83, 82,
+ 111, 69, 94, 83, 108, 85, 78, 85, 80, 11, 0, 76, 108, 76, 98, 85,
+ 112, 65, 78, 72, 90, 10, 69, 67, 91, 84, 82, 79, 70, 65, 68, 81,
+ 64, 5, 68, 4, 69, 70, 4, 73, 21, 68, 1, 16, 18, 24, 24, 13,
+ 80, 73, 77, 7, 67, 87, 67, 64, 72, 76, 72, 10, 39, 12, 79, 79,
+ 71, 70, 31, 37, 97, 66, 65, 81, 2, 0, 66, 71, 33, 56, 42, 0,
+ 74, 112, 18, 59, 62, 116, 22, 21, 26, 29, 28, 23, 18, 22, 26, 14,
+ 21, 14, 7, 4, 0, 15, 14, 14, 12, 5, 9, 20, 10, 67, 10, 12,
+ 69, 20, 67, 62, 62, 52, 41, 50, 60, 62, 62, 37, 23, 16, 18, 31,
+ 28, 84, 19, 23, 6, 38, 20, 20, 25, 30, 28, 36, 34, 9, 93, 0,
+ 64, 12, 115, 103, 71, 6, 10, 4, 78, 82, 87, 86, 112, 89, 13, 2,
+ 65, 72, 74, 80, 92, 90, 108, 77, 19, 6, 1, 66, 68, 74, 78, 86,
+ 99, 77, 5, 67, 6, 5, 71, 78, 79, 92, 74, 28, 8, 8, 5, 65,
+ 71, 79, 78, 82, 62, 116, 114, 107, 113, 104, 105, 105, 104, 101, 104, 104,
+ 105, 89, 94, 94, 99, 102, 89, 65, 83, 87, 85, 76, 71, 72, 66, 77,
+ 66, 64, 67, 68, 1, 68, 77, 65, 68, 75, 5, 2, 66, 2, 12, 1,
+ 71, 75, 77, 76, 66, 64, 3, 5, 69, 66, 71, 7, 6, 73, 76, 76,
+ 76, 9, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61,
+ 36, 62, 62, 62, 62, 61, 48, 34, 45, 43, 31, 15, 9, 2, 79, 61,
+ 59, 62, 46, 31, 34, 26, 24, 32, 28, 20, 6, 17, 3, 72, 23, 28,
+ 21, 28, 34, 21, 19, 11, 10, 68, 4, 67, 79, 115, 0, 67, 73, 20,
+ 4, 69, 76, 70, 67, 67, 66, 65, 6, 67, 66, 65, 4, 14, 11, 16,
+ 1, 61, 58, 52, 48, 40, 36, 22, 10, 74, 66, 30, 23, 20, 12, 10,
+ 4, 1, 65, 74, 76, 70, 67, 67, 66, 65, 6, 67, 66, 65, 4, 14,
+ 11, 16, 1, 61, 58, 52, 48, 40, 36, 22, 10, 74, 75, 66, 3, 64,
+ 64, 92, 88},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 31, 49, 56, 18, 3,
+ 83, 33, 82, 88, 4, 3, 0, 64, 12, 42, 47, 33, 1, 103, 109, 104,
+ 72, 82, 88, 4, 89, 80, 23, 6, 82, 94, 104, 67, 69, 86, 99, 0,
+ 82, 98, 65, 78, 88, 100, 7, 76, 73, 90, 17, 3, 22, 0, 0, 0,
+ 77, 88, 97, 68, 15, 0, 26, 82, 115, 106, 81, 87, 69, 71, 82, 81,
+ 109, 68, 92, 82, 106, 86, 78, 85, 80, 12, 0, 75, 106, 76, 97, 84,
+ 110, 65, 77, 72, 89, 11, 69, 66, 90, 83, 81, 79, 70, 64, 67, 80,
+ 0, 5, 68, 4, 68, 69, 4, 73, 22, 68, 1, 16, 19, 25, 24, 14,
+ 80, 72, 76, 6, 67, 87, 67, 0, 72, 75, 71, 11, 40, 14, 77, 80,
+ 72, 69, 31, 38, 98, 66, 65, 81, 3, 0, 66, 69, 33, 56, 42, 1,
+ 75, 111, 17, 57, 62, 114, 22, 21, 26, 28, 28, 23, 18, 22, 26, 13,
+ 20, 14, 7, 4, 0, 15, 13, 14, 12, 5, 9, 19, 9, 68, 10, 12,
+ 69, 19, 67, 62, 62, 51, 40, 48, 58, 62, 62, 36, 21, 14, 17, 29,
+ 27, 85, 18, 22, 4, 37, 19, 19, 24, 28, 27, 34, 32, 8, 93, 0,
+ 65, 11, 113, 101, 69, 7, 10, 4, 77, 81, 86, 85, 110, 88, 14, 3,
+ 64, 71, 73, 79, 91, 89, 106, 76, 20, 7, 2, 66, 67, 73, 77, 85,
+ 97, 76, 7, 66, 7, 5, 70, 77, 78, 91, 73, 29, 9, 9, 6, 64,
+ 70, 78, 77, 81, 62, 114, 112, 105, 111, 103, 104, 103, 102, 99, 102, 102,
+ 103, 88, 93, 93, 98, 98, 89, 66, 83, 86, 84, 75, 71, 72, 66, 77,
+ 66, 65, 67, 68, 2, 68, 77, 65, 68, 75, 5, 2, 66, 2, 11, 1,
+ 71, 74, 75, 76, 66, 0, 2, 5, 69, 66, 70, 7, 6, 72, 75, 75,
+ 75, 7, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 58,
+ 34, 62, 62, 62, 62, 58, 46, 33, 43, 41, 30, 14, 8, 1, 79, 59,
+ 57, 60, 44, 29, 32, 25, 22, 30, 26, 18, 4, 15, 1, 73, 22, 27,
+ 19, 27, 32, 20, 17, 10, 9, 69, 3, 67, 79, 114, 64, 68, 75, 19,
+ 3, 70, 76, 69, 66, 66, 64, 64, 7, 67, 65, 64, 5, 15, 12, 17,
+ 2, 60, 57, 50, 46, 38, 34, 20, 8, 75, 65, 30, 24, 21, 13, 11,
+ 5, 2, 64, 73, 76, 69, 66, 66, 64, 64, 7, 67, 65, 64, 5, 15,
+ 12, 17, 2, 60, 57, 50, 46, 38, 34, 20, 8, 75, 75, 66, 3, 0,
+ 0, 91, 86},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 29, 48, 55, 19, 3,
+ 82, 31, 82, 87, 3, 3, 1, 65, 11, 41, 45, 30, 65, 104, 107, 103,
+ 72, 82, 87, 3, 89, 79, 23, 6, 82, 93, 102, 68, 70, 86, 99, 0,
+ 81, 97, 66, 78, 88, 100, 7, 76, 73, 89, 18, 3, 22, 0, 0, 0,
+ 77, 88, 97, 67, 14, 0, 25, 82, 114, 104, 80, 86, 68, 70, 81, 80,
+ 107, 67, 91, 81, 103, 86, 79, 85, 81, 12, 0, 74, 103, 75, 97, 84,
+ 108, 65, 77, 72, 89, 11, 69, 66, 89, 83, 80, 78, 70, 64, 67, 79,
+ 0, 5, 69, 4, 68, 69, 4, 73, 22, 68, 1, 17, 19, 25, 24, 14,
+ 81, 72, 76, 6, 67, 86, 67, 1, 71, 75, 69, 13, 41, 15, 75, 80,
+ 73, 69, 32, 38, 99, 66, 64, 82, 4, 0, 66, 68, 33, 56, 42, 3,
+ 76, 109, 16, 54, 62, 113, 22, 21, 25, 28, 27, 23, 17, 22, 25, 12,
+ 19, 14, 7, 4, 0, 14, 13, 13, 11, 5, 9, 18, 9, 69, 9, 11,
+ 69, 18, 68, 60, 62, 49, 38, 47, 56, 62, 62, 35, 19, 12, 15, 27,
+ 25, 86, 17, 21, 3, 36, 18, 18, 22, 27, 25, 32, 31, 6, 93, 64,
+ 66, 9, 112, 100, 68, 7, 10, 4, 76, 80, 85, 85, 108, 86, 15, 4,
+ 64, 70, 71, 78, 89, 88, 103, 75, 20, 7, 2, 65, 66, 72, 77, 84,
+ 96, 76, 8, 65, 7, 5, 69, 77, 78, 90, 72, 29, 10, 9, 6, 0,
+ 69, 77, 77, 80, 62, 113, 111, 104, 110, 102, 102, 102, 100, 98, 100, 100,
+ 100, 87, 92, 92, 97, 95, 88, 67, 82, 85, 83, 75, 71, 72, 66, 76,
+ 67, 66, 67, 68, 3, 68, 77, 65, 68, 74, 4, 1, 66, 1, 10, 0,
+ 71, 74, 74, 77, 67, 1, 2, 4, 69, 66, 70, 6, 5, 72, 75, 75,
+ 75, 6, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 56,
+ 32, 62, 62, 62, 62, 55, 44, 31, 41, 38, 28, 13, 7, 0, 79, 57,
+ 54, 57, 42, 27, 30, 23, 20, 28, 24, 16, 2, 13, 0, 75, 21, 26,
+ 17, 25, 31, 18, 15, 9, 8, 70, 2, 68, 79, 113, 66, 69, 76, 17,
+ 2, 71, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, 15, 13, 17,
+ 2, 60, 55, 48, 44, 36, 32, 17, 6, 76, 65, 31, 24, 21, 14, 12,
+ 5, 2, 64, 72, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, 15,
+ 13, 17, 2, 60, 55, 48, 44, 36, 32, 17, 6, 76, 75, 66, 3, 0,
+ 0, 89, 84},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 28, 46, 54, 19, 4,
+ 80, 30, 82, 85, 3, 2, 2, 66, 10, 40, 44, 26, 67, 105, 105, 101,
+ 72, 82, 85, 3, 88, 78, 24, 6, 81, 92, 101, 70, 71, 86, 100, 0,
+ 81, 97, 66, 79, 87, 100, 6, 76, 73, 88, 18, 3, 22, 0, 0, 0,
+ 76, 88, 97, 67, 14, 64, 25, 81, 113, 102, 79, 85, 66, 68, 80, 79,
+ 105, 66, 90, 81, 101, 87, 79, 85, 81, 13, 0, 73, 101, 75, 96, 83,
+ 106, 65, 77, 72, 89, 12, 70, 65, 89, 83, 79, 78, 69, 64, 66, 78,
+ 1, 5, 69, 4, 68, 69, 4, 73, 22, 68, 1, 17, 19, 26, 25, 15,
+ 81, 71, 75, 5, 67, 86, 67, 2, 71, 74, 68, 14, 41, 17, 74, 81,
+ 74, 68, 32, 38, 99, 67, 64, 82, 4, 64, 65, 67, 33, 56, 43, 4,
+ 77, 108, 15, 51, 62, 111, 22, 21, 25, 27, 27, 22, 17, 21, 25, 12,
+ 19, 14, 6, 4, 64, 14, 12, 12, 11, 5, 9, 18, 8, 71, 9, 10,
+ 69, 17, 68, 57, 62, 47, 37, 45, 54, 62, 61, 33, 17, 10, 14, 25,
+ 23, 88, 16, 19, 1, 34, 17, 17, 21, 25, 23, 30, 29, 5, 93, 65,
+ 67, 8, 110, 98, 66, 8, 10, 4, 75, 80, 85, 84, 107, 85, 16, 5,
+ 0, 70, 70, 77, 88, 87, 101, 75, 21, 8, 3, 65, 65, 72, 76, 83,
+ 95, 76, 10, 64, 7, 5, 69, 76, 78, 90, 72, 30, 10, 10, 6, 1,
+ 69, 77, 76, 80, 62, 111, 109, 102, 108, 100, 101, 100, 99, 96, 98, 98,
+ 98, 87, 91, 92, 97, 92, 88, 68, 82, 85, 82, 75, 71, 72, 66, 76,
+ 67, 67, 67, 68, 3, 68, 77, 65, 68, 74, 4, 1, 66, 0, 9, 0,
+ 71, 74, 73, 78, 67, 2, 1, 4, 69, 66, 69, 6, 5, 71, 74, 75,
+ 75, 4, 62, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 53,
+ 30, 62, 62, 62, 62, 53, 41, 29, 39, 36, 26, 12, 6, 64, 79, 55,
+ 52, 55, 40, 25, 29, 22, 18, 26, 21, 14, 0, 11, 65, 76, 20, 24,
+ 15, 24, 29, 17, 13, 7, 6, 71, 1, 69, 80, 112, 67, 71, 78, 16,
+ 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, 7, 16, 14, 18,
+ 3, 59, 53, 46, 42, 34, 30, 15, 4, 77, 64, 31, 25, 22, 14, 13,
+ 6, 3, 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, 7, 16,
+ 14, 18, 3, 59, 53, 46, 42, 34, 30, 15, 4, 77, 75, 66, 3, 1,
+ 1, 88, 81},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 26, 45, 53, 20, 4, 78,
+ 28, 82, 84, 3, 2, 3, 67, 8, 38, 42, 23, 69, 106, 103, 100, 72, 82,
+ 84, 3, 88, 77, 24, 5, 80, 91, 100, 71, 73, 87, 100, 0, 81, 96, 66,
+ 79, 87, 100, 6, 76, 73, 88, 19, 3, 22, 0, 0, 0, 76, 89, 97, 66,
+ 13, 64, 24, 81, 112, 100, 78, 84, 65, 67, 80, 78, 103, 65, 89, 80, 99,
+ 88, 79, 85, 81, 13, 64, 72, 99, 75, 95, 82, 104, 65, 77, 72, 89, 12,
+ 70, 65, 88, 83, 79, 78, 69, 64, 66, 77, 1, 5, 69, 3, 68, 69, 4,
+ 73, 22, 68, 1, 18, 19, 26, 25, 15, 82, 71, 74, 5, 67, 86, 67, 3,
+ 71, 74, 67, 15, 42, 18, 72, 81, 75, 68, 32, 38, 100, 67, 0, 83, 5,
+ 64, 65, 66, 33, 56, 43, 5, 78, 106, 14, 48, 60, 110, 21, 21, 24, 26,
+ 26, 22, 16, 21, 24, 11, 18, 13, 6, 4, 64, 13, 11, 11, 10, 4, 8,
+ 17, 8, 72, 8, 9, 69, 15, 69, 55, 62, 45, 35, 43, 52, 62, 58, 32,
+ 15, 7, 12, 23, 21, 89, 14, 18, 64, 33, 16, 16, 20, 24, 21, 28, 27,
+ 3, 93, 66, 68, 6, 109, 97, 65, 8, 10, 4, 74, 79, 84, 83, 105, 84,
+ 17, 5, 1, 69, 69, 76, 86, 86, 99, 74, 21, 8, 3, 64, 64, 71, 76,
+ 83, 94, 76, 11, 0, 7, 5, 68, 76, 78, 89, 71, 30, 11, 10, 6, 2,
+ 68, 76, 76, 79, 62, 110, 108, 101, 106, 99, 99, 99, 97, 95, 97, 96, 96,
+ 86, 90, 91, 96, 89, 88, 69, 82, 84, 82, 75, 71, 72, 67, 75, 67, 68,
+ 67, 68, 4, 68, 77, 65, 68, 74, 3, 1, 66, 64, 8, 0, 71, 74, 72,
+ 79, 67, 2, 0, 4, 69, 66, 69, 6, 4, 71, 73, 75, 75, 3, 62, 60,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, 28, 62, 62, 62, 62,
+ 50, 39, 27, 37, 33, 24, 10, 5, 65, 79, 52, 50, 53, 38, 23, 27, 20,
+ 16, 24, 19, 12, 65, 8, 67, 77, 19, 23, 12, 22, 27, 15, 11, 6, 5,
+ 72, 0, 70, 80, 111, 68, 72, 79, 15, 64, 73, 75, 68, 65, 64, 2, 1,
+ 9, 66, 1, 2, 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, 2,
+ 79, 64, 32, 25, 23, 15, 13, 6, 3, 0, 71, 75, 68, 65, 64, 2, 1,
+ 9, 66, 1, 2, 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, 2,
+ 79, 75, 66, 3, 1, 1, 86, 79},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 24, 43, 52, 21, 4, 77,
+ 26, 81, 82, 2, 2, 4, 68, 7, 37, 40, 20, 72, 106, 101, 99, 72, 81,
+ 82, 2, 88, 76, 24, 5, 80, 90, 98, 72, 74, 87, 100, 0, 80, 95, 67,
+ 79, 87, 100, 6, 75, 73, 87, 19, 3, 22, 0, 0, 0, 75, 89, 97, 66,
+ 12, 64, 24, 80, 110, 97, 77, 83, 0, 65, 79, 77, 101, 64, 88, 79, 96,
+ 88, 80, 85, 82, 13, 64, 71, 96, 74, 95, 82, 102, 65, 77, 72, 88, 12,
+ 70, 64, 87, 82, 78, 77, 69, 0, 65, 76, 2, 5, 70, 3, 67, 69, 4,
+ 73, 23, 68, 1, 18, 20, 26, 25, 15, 82, 70, 74, 4, 67, 85, 67, 4,
+ 70, 73, 65, 17, 43, 20, 70, 82, 76, 67, 33, 38, 101, 67, 0, 83, 6,
+ 64, 65, 64, 33, 56, 43, 7, 79, 105, 13, 46, 57, 109, 21, 21, 24, 26,
+ 26, 22, 16, 21, 24, 10, 17, 13, 6, 4, 64, 13, 11, 10, 10, 4, 8,
+ 16, 7, 73, 7, 9, 69, 14, 69, 53, 62, 44, 34, 42, 50, 62, 56, 31,
+ 13, 5, 11, 21, 19, 90, 13, 17, 65, 32, 15, 15, 18, 22, 19, 26, 26,
+ 2, 93, 67, 69, 4, 107, 95, 64, 9, 10, 4, 73, 78, 83, 83, 103, 82,
+ 18, 6, 1, 68, 67, 75, 85, 85, 96, 73, 22, 9, 4, 64, 0, 70, 75,
+ 82, 93, 75, 12, 1, 7, 5, 67, 75, 77, 88, 70, 30, 12, 10, 6, 3,
+ 67, 75, 75, 78, 62, 109, 106, 99, 105, 98, 98, 97, 95, 93, 95, 94, 93,
+ 85, 89, 90, 95, 86, 87, 70, 81, 83, 81, 75, 71, 72, 67, 75, 68, 69,
+ 67, 68, 5, 68, 77, 65, 68, 73, 3, 0, 66, 65, 7, 64, 71, 74, 71,
+ 79, 68, 3, 0, 3, 69, 66, 69, 5, 4, 71, 73, 75, 75, 1, 62, 59,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 48, 26, 62, 62, 62, 62,
+ 47, 37, 26, 35, 31, 22, 9, 4, 66, 79, 50, 47, 50, 36, 21, 25, 19,
+ 14, 22, 17, 10, 67, 6, 68, 79, 18, 22, 10, 21, 26, 14, 9, 5, 4,
+ 73, 64, 71, 80, 110, 70, 73, 81, 13, 65, 74, 75, 67, 64, 0, 3, 2,
+ 9, 65, 2, 3, 9, 17, 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0,
+ 80, 0, 32, 26, 23, 16, 14, 7, 4, 0, 70, 75, 67, 64, 0, 3, 2,
+ 9, 65, 2, 3, 9, 17, 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0,
+ 80, 75, 66, 3, 1, 1, 85, 77},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 22, 42, 51, 21, 4, 75,
+ 25, 81, 81, 2, 1, 5, 69, 6, 36, 38, 16, 74, 107, 99, 97, 72, 81,
+ 81, 2, 87, 75, 25, 5, 79, 89, 97, 73, 75, 87, 101, 0, 80, 94, 67,
+ 80, 87, 100, 6, 75, 73, 86, 20, 3, 22, 0, 0, 0, 75, 89, 97, 65,
+ 11, 64, 23, 80, 109, 95, 76, 82, 1, 64, 78, 76, 99, 0, 87, 78, 94,
+ 89, 80, 85, 82, 14, 64, 70, 94, 74, 94, 81, 100, 65, 77, 72, 88, 13,
+ 70, 64, 86, 82, 77, 77, 69, 0, 65, 75, 2, 5, 70, 3, 67, 69, 4,
+ 73, 23, 68, 1, 19, 20, 27, 25, 16, 83, 70, 73, 4, 67, 85, 67, 5,
+ 70, 73, 64, 18, 44, 21, 68, 82, 77, 67, 33, 38, 102, 67, 1, 84, 6,
+ 64, 65, 0, 33, 56, 43, 8, 80, 103, 12, 43, 54, 107, 21, 21, 23, 25,
+ 25, 21, 15, 21, 23, 9, 16, 13, 6, 4, 65, 12, 10, 9, 9, 4, 8,
+ 15, 7, 74, 7, 8, 69, 13, 70, 51, 60, 42, 32, 40, 48, 62, 53, 30,
+ 11, 3, 9, 19, 17, 92, 12, 16, 67, 31, 14, 14, 17, 21, 17, 24, 24,
+ 0, 93, 68, 70, 3, 106, 94, 1, 9, 10, 4, 72, 77, 82, 82, 101, 81,
+ 19, 7, 2, 68, 66, 74, 83, 84, 94, 73, 22, 9, 4, 0, 1, 70, 75,
+ 81, 92, 75, 14, 2, 7, 5, 66, 75, 77, 87, 69, 31, 13, 11, 6, 4,
+ 67, 74, 75, 78, 62, 107, 105, 98, 103, 97, 96, 96, 94, 92, 93, 92, 91,
+ 85, 88, 90, 94, 83, 87, 71, 81, 82, 80, 75, 71, 72, 67, 74, 68, 70,
+ 67, 68, 5, 68, 77, 65, 68, 73, 2, 0, 66, 66, 6, 64, 71, 74, 70,
+ 80, 68, 4, 64, 3, 69, 66, 68, 5, 3, 70, 72, 75, 75, 0, 62, 58,
+ 61, 61, 61, 62, 62, 62, 61, 62, 62, 62, 57, 45, 24, 62, 60, 59, 60,
+ 44, 35, 24, 33, 28, 20, 8, 3, 67, 79, 48, 45, 48, 34, 19, 23, 17,
+ 12, 20, 15, 8, 69, 4, 70, 80, 17, 21, 8, 19, 24, 12, 7, 3, 2,
+ 74, 65, 72, 80, 109, 71, 75, 82, 12, 66, 75, 75, 67, 64, 0, 4, 3,
+ 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, 36, 28, 24, 8, 65,
+ 81, 0, 33, 26, 24, 16, 15, 7, 4, 1, 70, 75, 67, 64, 0, 4, 3,
+ 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, 36, 28, 24, 8, 65,
+ 81, 75, 66, 3, 2, 2, 83, 75},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 20, 40, 50, 22, 4, 73, 23,
+ 81, 79, 2, 1, 6, 70, 5, 35, 36, 13, 76, 108, 97, 96, 72, 81, 79, 2,
+ 87, 74, 25, 5, 78, 88, 96, 74, 76, 87, 101, 0, 80, 93, 67, 80, 87, 100,
+ 6, 75, 73, 85, 20, 3, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 23, 79,
+ 108, 93, 75, 81, 3, 1, 77, 75, 97, 1, 86, 77, 92, 90, 80, 85, 82, 14,
+ 64, 69, 92, 74, 93, 80, 98, 65, 77, 72, 88, 13, 70, 0, 85, 82, 76, 77,
+ 69, 0, 64, 74, 3, 5, 70, 3, 67, 69, 4, 73, 23, 68, 1, 19, 20, 27,
+ 25, 16, 83, 69, 72, 3, 67, 85, 67, 6, 70, 72, 0, 19, 45, 23, 66, 83,
+ 78, 66, 33, 38, 103, 67, 1, 84, 7, 64, 65, 1, 33, 56, 43, 9, 81, 102,
+ 11, 40, 51, 106, 21, 21, 23, 24, 25, 21, 15, 21, 23, 8, 15, 13, 6, 4,
+ 65, 12, 9, 8, 9, 4, 8, 14, 6, 75, 6, 7, 69, 12, 70, 49, 58, 40,
+ 31, 38, 46, 59, 51, 29, 9, 1, 8, 17, 15, 93, 11, 15, 69, 30, 13, 13,
+ 16, 19, 15, 22, 22, 64, 93, 69, 71, 1, 104, 92, 2, 10, 10, 4, 71, 76,
+ 81, 81, 99, 80, 20, 8, 3, 67, 65, 73, 82, 83, 92, 72, 23, 10, 5, 0,
+ 2, 69, 74, 80, 91, 75, 15, 3, 7, 5, 65, 74, 77, 86, 68, 31, 14, 11,
+ 6, 5, 66, 73, 74, 77, 62, 106, 103, 96, 101, 96, 95, 94, 92, 90, 91, 90,
+ 89, 84, 87, 89, 93, 80, 87, 72, 81, 81, 79, 75, 71, 72, 67, 74, 68, 71,
+ 67, 68, 6, 68, 77, 65, 68, 73, 2, 0, 66, 67, 5, 64, 71, 74, 69, 81,
+ 68, 5, 65, 3, 69, 66, 68, 5, 3, 70, 71, 75, 75, 65, 61, 57, 60, 59,
+ 59, 62, 62, 62, 59, 60, 62, 61, 54, 42, 22, 61, 57, 55, 55, 41, 33, 22,
+ 31, 26, 18, 7, 2, 68, 79, 46, 43, 46, 32, 17, 21, 16, 10, 18, 13, 6,
+ 71, 2, 72, 81, 16, 20, 6, 18, 22, 11, 5, 2, 1, 75, 66, 73, 80, 108,
+ 72, 76, 84, 11, 67, 76, 75, 66, 0, 1, 5, 4, 11, 65, 4, 5, 11, 18,
+ 18, 20, 6, 57, 45, 38, 34, 26, 22, 6, 67, 82, 1, 33, 27, 25, 17, 16,
+ 8, 5, 1, 69, 75, 66, 0, 1, 5, 4, 11, 65, 4, 5, 11, 18, 18, 20,
+ 6, 57, 45, 38, 34, 26, 22, 6, 67, 82, 75, 66, 3, 2, 2, 82, 73},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 18, 38, 49, 22, 4, 72, 21,
+ 81, 78, 1, 0, 7, 71, 3, 33, 34, 9, 79, 109, 95, 95, 72, 81, 78, 1,
+ 87, 74, 25, 4, 78, 88, 95, 76, 78, 88, 102, 64, 80, 93, 68, 81, 87, 100,
+ 5, 75, 73, 85, 20, 2, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 22, 79,
+ 107, 91, 74, 81, 4, 2, 77, 74, 96, 1, 85, 77, 90, 91, 81, 86, 83, 14,
+ 65, 69, 90, 74, 93, 80, 97, 65, 77, 72, 88, 13, 71, 0, 85, 82, 76, 77,
+ 69, 0, 64, 73, 3, 5, 71, 2, 67, 69, 3, 73, 23, 68, 1, 19, 20, 27,
+ 25, 16, 84, 69, 72, 2, 67, 85, 68, 6, 70, 72, 1, 20, 45, 24, 65, 84,
+ 80, 66, 33, 38, 104, 68, 1, 85, 7, 65, 65, 2, 33, 55, 43, 10, 82, 101,
+ 9, 37, 47, 105, 20, 21, 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3,
+ 66, 11, 8, 7, 8, 3, 7, 13, 5, 77, 5, 6, 69, 10, 71, 46, 55, 38,
+ 29, 36, 43, 55, 48, 27, 7, 65, 6, 14, 13, 95, 9, 13, 71, 28, 12, 12,
+ 14, 17, 13, 20, 20, 66, 93, 70, 72, 64, 103, 91, 3, 10, 10, 4, 71, 76,
+ 81, 81, 98, 79, 20, 8, 3, 67, 64, 72, 81, 83, 90, 72, 23, 10, 5, 0,
+ 2, 69, 74, 80, 90, 75, 16, 4, 7, 4, 65, 74, 77, 86, 68, 31, 14, 11,
+ 6, 6, 66, 73, 74, 77, 62, 105, 102, 95, 100, 95, 94, 93, 91, 89, 90, 89,
+ 87, 84, 87, 89, 93, 77, 87, 74, 81, 81, 79, 75, 71, 72, 68, 74, 69, 72,
+ 68, 68, 6, 69, 77, 66, 68, 73, 1, 64, 67, 68, 4, 65, 72, 74, 68, 82,
+ 69, 5, 66, 2, 69, 67, 68, 4, 2, 70, 71, 75, 75, 67, 59, 56, 58, 57,
+ 56, 62, 62, 62, 56, 57, 62, 58, 50, 39, 20, 57, 53, 51, 49, 38, 30, 20,
+ 28, 23, 16, 5, 0, 69, 79, 43, 40, 43, 30, 14, 19, 14, 7, 16, 10, 4,
+ 74, 64, 74, 83, 14, 18, 3, 16, 20, 9, 3, 0, 64, 76, 67, 74, 81, 107,
+ 74, 78, 86, 9, 69, 78, 75, 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18,
+ 18, 20, 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 1, 33, 27, 25, 17, 16,
+ 8, 5, 1, 69, 75, 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18, 18, 20,
+ 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 75, 67, 2, 2, 2, 81, 71},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 17, 37, 49, 23, 5, 70, 20,
+ 80, 76, 1, 0, 9, 71, 2, 32, 33, 6, 81, 109, 93, 93, 71, 80, 76, 1,
+ 86, 73, 26, 4, 77, 87, 93, 77, 79, 88, 102, 64, 79, 92, 68, 81, 86, 99,
+ 5, 74, 72, 84, 21, 2, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 22, 78,
+ 105, 88, 72, 80, 6, 4, 76, 72, 94, 2, 83, 76, 87, 91, 81, 86, 83, 15,
+ 65, 68, 87, 73, 92, 79, 95, 65, 76, 72, 87, 14, 71, 1, 84, 81, 75, 76,
+ 68, 1, 0, 72, 4, 6, 71, 2, 66, 68, 3, 72, 24, 67, 1, 20, 21, 28,
+ 26, 17, 84, 68, 71, 2, 67, 84, 68, 7, 69, 71, 3, 22, 46, 26, 0, 84,
+ 81, 65, 34, 39, 104, 68, 2, 85, 8, 65, 64, 4, 33, 55, 44, 12, 83, 99,
+ 8, 35, 44, 103, 20, 21, 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3,
+ 66, 11, 8, 7, 8, 3, 7, 13, 5, 78, 5, 6, 69, 9, 71, 44, 53, 37,
+ 28, 35, 41, 52, 46, 26, 6, 67, 5, 12, 12, 96, 8, 12, 72, 27, 12, 12,
+ 13, 16, 12, 19, 19, 67, 93, 70, 72, 65, 101, 89, 5, 11, 10, 4, 70, 75,
+ 80, 80, 96, 77, 21, 9, 4, 66, 1, 71, 79, 82, 87, 71, 24, 11, 6, 1,
+ 3, 68, 73, 79, 88, 74, 18, 5, 8, 4, 64, 73, 76, 85, 67, 32, 15, 12,
+ 7, 7, 65, 72, 73, 76, 62, 103, 100, 93, 98, 93, 92, 91, 89, 87, 88, 87,
+ 84, 83, 86, 88, 92, 73, 86, 75, 80, 80, 78, 74, 71, 71, 68, 73, 69, 72,
+ 68, 68, 7, 69, 77, 66, 68, 72, 1, 64, 67, 68, 4, 65, 72, 73, 66, 82,
+ 69, 6, 66, 2, 69, 67, 67, 4, 2, 69, 70, 74, 74, 68, 58, 55, 57, 56,
+ 54, 60, 60, 59, 54, 55, 59, 56, 47, 37, 18, 54, 50, 48, 44, 36, 28, 19,
+ 26, 21, 15, 4, 64, 69, 79, 41, 38, 41, 28, 12, 18, 13, 5, 15, 8, 3,
+ 76, 66, 75, 84, 13, 17, 1, 15, 19, 8, 2, 64, 65, 77, 67, 74, 81, 106,
+ 75, 79, 87, 8, 70, 79, 74, 65, 1, 2, 8, 5, 12, 64, 7, 6, 13, 19,
+ 19, 21, 7, 56, 42, 35, 29, 21, 19, 1, 70, 85, 2, 34, 28, 26, 18, 17,
+ 9, 6, 2, 68, 74, 65, 1, 2, 8, 5, 12, 64, 7, 6, 13, 19, 19, 21,
+ 7, 56, 42, 35, 29, 21, 19, 1, 70, 85, 75, 67, 2, 3, 3, 79, 68},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 15, 35, 48, 24, 5, 68, 18,
+ 80, 75, 1, 0, 10, 72, 1, 31, 31, 3, 83, 110, 91, 92, 71, 80, 75, 1,
+ 86, 72, 26, 4, 76, 86, 92, 78, 80, 88, 102, 64, 79, 91, 68, 81, 86, 99,
+ 5, 74, 72, 83, 21, 2, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 22, 77,
+ 104, 86, 71, 79, 8, 6, 75, 71, 92, 3, 82, 75, 85, 92, 81, 86, 83, 15,
+ 65, 67, 85, 73, 91, 78, 93, 65, 76, 72, 87, 14, 71, 1, 83, 81, 74, 76,
+ 68, 1, 0, 71, 5, 6, 71, 2, 66, 68, 3, 72, 24, 67, 1, 20, 21, 28,
+ 26, 17, 85, 67, 70, 1, 67, 84, 68, 8, 69, 71, 4, 23, 47, 28, 2, 85,
+ 82, 65, 34, 39, 105, 68, 2, 86, 9, 65, 64, 5, 33, 55, 44, 13, 84, 98,
+ 7, 32, 41, 102, 20, 21, 22, 22, 23, 20, 14, 20, 21, 6, 13, 12, 5, 3,
+ 66, 10, 7, 6, 8, 3, 7, 12, 4, 79, 4, 5, 69, 8, 72, 42, 51, 35,
+ 26, 33, 39, 49, 44, 25, 4, 69, 3, 10, 10, 97, 7, 11, 74, 26, 11, 11,
+ 12, 14, 10, 17, 17, 69, 93, 71, 73, 67, 100, 88, 6, 12, 10, 4, 69, 74,
+ 79, 79, 94, 76, 22, 10, 5, 65, 2, 70, 78, 81, 85, 70, 24, 11, 6, 1,
+ 4, 67, 72, 78, 87, 74, 19, 6, 8, 4, 0, 72, 76, 84, 66, 32, 16, 12,
+ 7, 8, 64, 71, 72, 75, 62, 102, 98, 91, 96, 92, 91, 89, 87, 86, 86, 85,
+ 82, 82, 85, 87, 91, 70, 86, 76, 80, 79, 77, 74, 71, 71, 68, 73, 69, 73,
+ 68, 68, 8, 69, 77, 66, 68, 72, 1, 64, 67, 69, 3, 65, 72, 73, 65, 83,
+ 69, 7, 67, 2, 69, 67, 67, 4, 2, 69, 69, 74, 74, 70, 57, 54, 56, 54,
+ 52, 57, 57, 56, 52, 52, 56, 53, 44, 34, 16, 50, 46, 44, 39, 33, 26, 17,
+ 24, 19, 13, 3, 65, 70, 79, 39, 36, 39, 26, 10, 16, 11, 3, 13, 6, 1,
+ 78, 68, 77, 85, 12, 16, 64, 13, 17, 6, 0, 65, 66, 78, 68, 75, 81, 105,
+ 76, 80, 89, 7, 71, 80, 74, 65, 2, 3, 9, 6, 13, 64, 8, 7, 14, 19,
+ 20, 22, 8, 55, 40, 33, 27, 19, 17, 64, 72, 86, 3, 34, 28, 27, 19, 18,
+ 9, 7, 2, 67, 74, 65, 2, 3, 9, 6, 13, 64, 8, 7, 14, 19, 20, 22,
+ 8, 55, 40, 33, 27, 19, 17, 64, 72, 86, 75, 67, 2, 3, 3, 78, 66},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 13, 34, 47, 24, 5, 66, 17, 80,
+ 73, 1, 64, 11, 73, 0, 30, 29, 64, 85, 111, 89, 90, 71, 80, 73, 1, 85, 71,
+ 27, 4, 75, 85, 91, 79, 81, 88, 103, 64, 79, 90, 68, 82, 86, 99, 5, 74, 72,
+ 82, 22, 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 21, 77, 103, 84, 70, 78,
+ 9, 7, 74, 70, 90, 4, 81, 74, 83, 93, 81, 86, 83, 16, 65, 66, 83, 73, 90,
+ 77, 91, 65, 76, 72, 87, 15, 71, 2, 82, 81, 73, 76, 68, 1, 1, 70, 5, 6,
+ 71, 2, 66, 68, 3, 72, 24, 67, 1, 21, 21, 29, 26, 18, 85, 67, 69, 1, 67,
+ 84, 68, 9, 69, 70, 5, 24, 48, 29, 4, 85, 83, 64, 34, 39, 106, 68, 3, 86,
+ 9, 65, 64, 6, 33, 55, 44, 14, 85, 96, 6, 29, 38, 100, 20, 21, 21, 21, 23,
+ 19, 13, 20, 21, 5, 12, 12, 5, 3, 67, 10, 6, 5, 7, 3, 7, 11, 4, 80,
+ 4, 4, 69, 7, 72, 40, 49, 33, 25, 31, 37, 46, 41, 24, 2, 71, 2, 8, 8,
+ 99, 6, 10, 76, 25, 10, 10, 11, 13, 8, 15, 15, 70, 93, 72, 74, 68, 98, 86,
+ 8, 12, 10, 4, 68, 73, 78, 78, 92, 75, 23, 11, 6, 65, 3, 69, 76, 80, 83,
+ 70, 25, 12, 7, 2, 5, 67, 72, 77, 86, 74, 21, 7, 8, 4, 1, 72, 76, 83,
+ 65, 33, 17, 13, 7, 9, 64, 70, 72, 75, 62, 100, 97, 90, 94, 91, 89, 88, 86,
+ 84, 84, 83, 80, 82, 84, 87, 90, 67, 86, 77, 80, 78, 76, 74, 71, 71, 68, 72,
+ 69, 74, 68, 68, 8, 69, 77, 66, 68, 72, 0, 64, 67, 70, 2, 65, 72, 73, 64,
+ 84, 69, 8, 68, 2, 69, 67, 66, 4, 1, 68, 68, 74, 74, 71, 56, 53, 55, 52,
+ 50, 55, 55, 53, 49, 49, 53, 50, 41, 31, 14, 46, 43, 40, 34, 30, 24, 15, 22,
+ 16, 11, 2, 66, 71, 79, 37, 34, 37, 24, 8, 14, 10, 1, 11, 4, 64, 80, 70,
+ 79, 86, 11, 15, 66, 12, 15, 5, 65, 67, 68, 79, 69, 76, 81, 104, 77, 82, 90,
+ 6, 72, 81, 74, 64, 2, 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55,
+ 38, 31, 25, 17, 15, 66, 74, 87, 3, 35, 29, 28, 19, 19, 10, 7, 3, 67, 74,
+ 64, 2, 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55, 38, 31, 25, 17,
+ 15, 66, 74, 87, 75, 67, 2, 4, 4, 76, 64},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 32, 46, 25, 5, 65, 15, 80,
+ 72, 0, 64, 12, 74, 65, 28, 27, 67, 88, 112, 87, 89, 71, 80, 72, 0, 85, 70,
+ 27, 3, 75, 84, 89, 80, 83, 89, 103, 64, 78, 89, 69, 82, 86, 99, 5, 74, 72,
+ 82, 22, 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 21, 76, 102, 82, 69, 77,
+ 11, 9, 74, 69, 88, 5, 80, 73, 80, 93, 82, 86, 84, 16, 66, 65, 80, 72, 90,
+ 77, 89, 65, 76, 72, 87, 15, 71, 2, 81, 81, 73, 75, 68, 1, 1, 69, 6, 6,
+ 72, 1, 66, 68, 3, 72, 24, 67, 1, 21, 21, 29, 26, 18, 86, 66, 69, 0, 67,
+ 83, 68, 10, 68, 70, 7, 26, 49, 31, 6, 86, 84, 64, 35, 39, 107, 68, 3, 87,
+ 10, 65, 64, 7, 33, 55, 44, 16, 86, 95, 5, 26, 35, 99, 19, 21, 21, 21, 22,
+ 19, 13, 20, 20, 4, 11, 11, 5, 3, 67, 9, 6, 4, 7, 2, 6, 10, 3, 81,
+ 3, 3, 69, 5, 73, 38, 47, 31, 23, 30, 35, 42, 39, 23, 0, 74, 0, 6, 6,
+ 100, 4, 9, 77, 24, 9, 9, 9, 11, 6, 13, 14, 72, 93, 73, 75, 70, 97, 85,
+ 9, 13, 10, 4, 67, 72, 77, 78, 90, 73, 24, 11, 6, 64, 5, 68, 75, 79, 80,
+ 69, 25, 12, 7, 2, 6, 66, 71, 77, 85, 74, 22, 8, 8, 4, 2, 71, 76, 82,
+ 64, 33, 18, 13, 7, 10, 0, 69, 71, 74, 62, 99, 95, 88, 93, 90, 88, 86, 84,
+ 83, 83, 81, 77, 81, 83, 86, 89, 64, 85, 78, 79, 77, 76, 74, 71, 71, 69, 72,
+ 70, 75, 68, 68, 9, 69, 77, 66, 68, 71, 0, 65, 67, 71, 1, 66, 72, 73, 0,
+ 85, 70, 8, 68, 1, 69, 67, 66, 3, 1, 68, 68, 74, 74, 73, 55, 52, 54, 51,
+ 47, 52, 52, 50, 47, 46, 49, 47, 37, 29, 12, 42, 39, 36, 29, 27, 22, 13, 20,
+ 14, 9, 0, 67, 72, 79, 34, 31, 34, 22, 6, 12, 8, 64, 9, 2, 66, 82, 73,
+ 80, 88, 10, 14, 69, 10, 14, 3, 67, 68, 69, 80, 70, 77, 81, 103, 79, 83, 92,
+ 4, 73, 82, 74, 64, 3, 4, 11, 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54,
+ 36, 29, 23, 15, 13, 69, 76, 89, 4, 35, 29, 28, 20, 19, 10, 8, 3, 66, 74,
+ 64, 3, 4, 11, 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54, 36, 29, 23, 15,
+ 13, 69, 76, 89, 75, 67, 2, 4, 4, 75, 1},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 9, 31, 45, 26, 5, 0, 13, 79,
+ 70, 0, 64, 13, 75, 66, 27, 25, 70, 90, 112, 85, 88, 71, 79, 70, 0, 85, 69,
+ 27, 3, 74, 83, 88, 81, 84, 89, 103, 64, 78, 88, 69, 82, 86, 99, 5, 73, 72,
+ 81, 23, 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 20, 76, 100, 79, 68, 76,
+ 12, 10, 73, 68, 86, 6, 79, 72, 78, 94, 82, 86, 84, 16, 66, 64, 78, 72, 89,
+ 76, 87, 65, 76, 72, 86, 15, 71, 3, 80, 80, 72, 75, 68, 2, 2, 68, 6, 6,
+ 72, 1, 65, 68, 3, 72, 25, 67, 1, 22, 22, 29, 26, 18, 86, 66, 68, 0, 67,
+ 83, 68, 11, 68, 69, 8, 27, 50, 32, 8, 86, 85, 0, 35, 39, 108, 68, 4, 87,
+ 11, 65, 64, 9, 33, 55, 44, 17, 87, 93, 4, 24, 32, 98, 19, 21, 20, 20, 22,
+ 19, 12, 20, 20, 3, 10, 11, 5, 3, 67, 9, 5, 3, 6, 2, 6, 9, 3, 82,
+ 2, 3, 69, 4, 73, 36, 45, 30, 22, 28, 33, 39, 36, 22, 65, 76, 64, 4, 4,
+ 101, 3, 8, 79, 23, 8, 8, 8, 10, 4, 11, 12, 73, 93, 74, 76, 72, 95, 83,
+ 10, 13, 10, 4, 66, 71, 76, 77, 88, 72, 25, 12, 7, 0, 6, 67, 73, 78, 78,
+ 68, 26, 13, 8, 3, 7, 65, 71, 76, 84, 73, 23, 9, 8, 4, 3, 71, 75, 81,
+ 0, 33, 19, 13, 7, 11, 1, 68, 71, 73, 62, 98, 94, 87, 91, 89, 86, 85, 82,
+ 81, 81, 79, 75, 80, 82, 85, 88, 2, 85, 79, 79, 76, 75, 74, 71, 71, 69, 71,
+ 70, 76, 68, 68, 10, 69, 77, 66, 68, 71, 64, 65, 67, 72, 0, 66, 72, 73, 1,
+ 85, 70, 9, 69, 1, 69, 67, 66, 3, 0, 68, 67, 74, 74, 74, 54, 51, 53, 49,
+ 45, 50, 49, 47, 44, 43, 46, 44, 34, 26, 10, 38, 36, 32, 24, 24, 20, 12, 18,
+ 11, 7, 64, 68, 73, 79, 32, 29, 32, 20, 4, 10, 7, 66, 7, 0, 68, 84, 75,
+ 82, 89, 9, 13, 71, 9, 12, 2, 69, 69, 70, 81, 71, 78, 81, 102, 80, 84, 93,
+ 3, 74, 83, 74, 0, 3, 5, 12, 8, 15, 0, 11, 10, 17, 21, 23, 23, 10, 54,
+ 34, 27, 21, 13, 11, 71, 78, 90, 4, 36, 30, 29, 21, 20, 11, 8, 3, 65, 74,
+ 0, 3, 5, 12, 8, 15, 0, 11, 10, 17, 21, 23, 23, 10, 54, 34, 27, 21, 13,
+ 11, 71, 78, 90, 75, 67, 2, 4, 4, 73, 3},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 29, 44, 26, 6, 2, 12, 79,
+ 69, 0, 65, 14, 76, 67, 26, 24, 74, 92, 113, 83, 86, 71, 79, 69, 0, 84, 68,
+ 28, 3, 73, 82, 87, 83, 85, 89, 104, 64, 78, 88, 69, 83, 85, 99, 4, 73, 72,
+ 80, 23, 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 20, 75, 99, 77, 67, 75,
+ 14, 12, 72, 67, 84, 7, 78, 72, 76, 95, 82, 86, 84, 17, 66, 0, 76, 72, 88,
+ 75, 85, 65, 76, 72, 86, 16, 72, 3, 80, 80, 71, 75, 67, 2, 2, 67, 7, 6,
+ 72, 1, 65, 68, 3, 72, 25, 67, 1, 22, 22, 30, 27, 19, 87, 65, 67, 64, 67,
+ 83, 68, 12, 68, 69, 9, 28, 50, 34, 9, 87, 86, 0, 35, 39, 108, 69, 4, 88,
+ 11, 66, 0, 10, 33, 55, 45, 18, 88, 92, 3, 21, 29, 96, 19, 21, 20, 19, 21,
+ 18, 12, 19, 19, 3, 10, 11, 4, 3, 68, 8, 4, 2, 6, 2, 6, 9, 2, 84,
+ 2, 2, 69, 3, 74, 33, 43, 28, 20, 26, 31, 36, 34, 20, 67, 78, 66, 2, 2,
+ 103, 2, 6, 81, 21, 7, 7, 7, 8, 2, 9, 10, 75, 93, 75, 77, 73, 94, 82,
+ 12, 14, 10, 4, 65, 71, 76, 76, 87, 71, 26, 13, 8, 0, 7, 66, 72, 77, 76,
+ 68, 26, 13, 8, 3, 8, 65, 70, 75, 83, 73, 25, 10, 8, 4, 3, 70, 75, 81,
+ 0, 34, 19, 14, 7, 12, 1, 68, 70, 73, 62, 96, 92, 85, 89, 87, 85, 83, 81,
+ 80, 79, 77, 73, 80, 81, 85, 88, 5, 85, 80, 79, 76, 74, 74, 71, 71, 69, 71,
+ 70, 77, 68, 68, 10, 69, 77, 66, 68, 71, 64, 65, 67, 73, 64, 66, 72, 73, 2,
+ 86, 70, 10, 70, 1, 69, 67, 65, 3, 0, 67, 66, 74, 74, 76, 53, 50, 52, 47,
+ 43, 47, 47, 44, 42, 40, 43, 41, 31, 23, 8, 35, 32, 28, 19, 22, 17, 10, 16,
+ 9, 5, 65, 69, 74, 79, 30, 27, 30, 18, 2, 9, 5, 68, 5, 66, 70, 86, 77,
+ 84, 90, 8, 11, 73, 7, 10, 0, 71, 71, 72, 82, 72, 79, 82, 101, 81, 86, 95,
+ 2, 76, 84, 73, 0, 4, 5, 13, 9, 16, 0, 12, 11, 18, 21, 24, 24, 11, 53,
+ 32, 25, 19, 11, 9, 73, 80, 91, 5, 36, 30, 30, 21, 21, 11, 9, 4, 65, 73,
+ 0, 4, 5, 13, 9, 16, 0, 12, 11, 18, 21, 24, 24, 11, 53, 32, 25, 19, 11,
+ 9, 73, 80, 91, 75, 67, 2, 5, 5, 72, 6},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 6, 28, 43, 27, 6, 3, 10, 79,
+ 67, 64, 65, 15, 77, 68, 25, 22, 77, 95, 114, 81, 85, 71, 79, 67, 64, 84, 67,
+ 28, 3, 73, 81, 85, 84, 86, 89, 104, 64, 77, 87, 70, 83, 85, 99, 4, 73, 72,
+ 79, 24, 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 19, 75, 98, 75, 66, 74,
+ 15, 13, 71, 66, 82, 8, 77, 71, 73, 95, 83, 86, 85, 17, 66, 1, 73, 71, 88,
+ 75, 83, 65, 76, 72, 86, 16, 72, 4, 79, 80, 70, 74, 67, 2, 3, 66, 7, 6,
+ 73, 1, 65, 68, 3, 72, 25, 67, 1, 23, 22, 30, 27, 19, 87, 65, 67, 64, 67,
+ 82, 68, 13, 67, 68, 11, 30, 51, 35, 11, 87, 87, 1, 36, 39, 109, 69, 5, 88,
+ 12, 66, 0, 11, 33, 55, 45, 20, 89, 90, 2, 18, 26, 95, 19, 21, 19, 19, 21,
+ 18, 11, 19, 19, 2, 9, 11, 4, 3, 68, 8, 4, 1, 5, 2, 6, 8, 2, 85,
+ 1, 1, 69, 2, 74, 31, 41, 26, 19, 25, 29, 33, 31, 19, 69, 80, 67, 0, 0,
+ 104, 1, 5, 82, 20, 6, 6, 5, 7, 0, 7, 9, 76, 93, 76, 78, 75, 92, 80,
+ 13, 14, 10, 4, 64, 70, 75, 76, 85, 69, 27, 14, 8, 1, 9, 65, 70, 76, 73,
+ 67, 27, 14, 9, 4, 9, 64, 70, 74, 82, 73, 26, 11, 8, 4, 4, 70, 75, 80,
+ 1, 34, 20, 14, 7, 13, 2, 67, 70, 72, 62, 95, 91, 84, 88, 86, 83, 82, 79,
+ 78, 77, 75, 70, 79, 80, 84, 87, 8, 84, 81, 78, 75, 73, 74, 71, 71, 69, 70,
+ 71, 78, 68, 68, 11, 69, 77, 66, 68, 70, 65, 66, 67, 74, 65, 67, 72, 73, 3,
+ 87, 71, 11, 70, 0, 69, 67, 65, 2, 64, 67, 66, 74, 74, 77, 52, 49, 51, 46,
+ 40, 45, 44, 41, 39, 37, 40, 38, 28, 21, 6, 31, 29, 24, 14, 19, 15, 8, 14,
+ 6, 3, 66, 70, 75, 79, 28, 24, 27, 16, 0, 7, 4, 70, 3, 68, 72, 88, 79,
+ 85, 92, 7, 10, 75, 6, 9, 64, 73, 72, 73, 83, 73, 80, 82, 100, 83, 87, 96,
+ 0, 77, 85, 73, 1, 4, 6, 14, 10, 16, 1, 13, 12, 19, 22, 25, 24, 11, 53,
+ 30, 23, 17, 9, 7, 76, 82, 92, 5, 37, 31, 30, 22, 22, 12, 9, 4, 64, 73,
+ 1, 4, 6, 14, 10, 16, 1, 13, 12, 19, 22, 25, 24, 11, 53, 30, 23, 17, 9,
+ 7, 76, 82, 92, 75, 67, 2, 5, 5, 70, 8},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 4, 26, 42, 27, 6, 5, 8, 79,
+ 66, 64, 66, 16, 78, 70, 23, 20, 81, 97, 115, 79, 84, 71, 79, 66, 64, 84, 67,
+ 28, 2, 72, 80, 84, 85, 88, 90, 105, 64, 77, 86, 70, 84, 85, 99, 4, 73, 72,
+ 79, 24, 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 19, 74, 97, 73, 65, 74,
+ 17, 15, 71, 65, 80, 8, 76, 70, 71, 96, 83, 87, 85, 17, 67, 1, 71, 71, 87,
+ 74, 82, 65, 76, 72, 86, 16, 72, 4, 78, 80, 70, 74, 67, 2, 3, 65, 8, 6,
+ 73, 0, 65, 68, 2, 72, 25, 67, 1, 23, 22, 30, 27, 19, 88, 64, 66, 65, 67,
+ 82, 68, 14, 67, 68, 12, 31, 52, 37, 13, 88, 88, 1, 36, 39, 110, 69, 5, 89,
+ 12, 66, 0, 12, 33, 55, 45, 21, 90, 89, 1, 15, 22, 94, 18, 21, 19, 18, 20,
+ 17, 11, 19, 18, 1, 8, 10, 4, 2, 69, 7, 3, 0, 5, 1, 5, 7, 1, 86,
+ 0, 0, 69, 0, 75, 29, 39, 24, 17, 23, 26, 29, 29, 18, 71, 83, 69, 66, 65,
+ 106, 64, 4, 84, 19, 5, 5, 4, 5, 65, 5, 7, 78, 93, 77, 79, 77, 91, 79,
+ 14, 15, 10, 4, 64, 69, 74, 75, 83, 68, 27, 14, 9, 1, 10, 64, 69, 75, 71,
+ 67, 27, 14, 9, 4, 9, 64, 69, 74, 81, 73, 27, 12, 8, 4, 5, 69, 75, 79,
+ 2, 34, 21, 14, 7, 14, 2, 66, 69, 72, 62, 94, 89, 82, 86, 85, 82, 80, 78,
+ 77, 76, 73, 68, 79, 79, 84, 86, 11, 84, 82, 78, 74, 73, 74, 71, 71, 70, 70,
+ 71, 79, 68, 68, 11, 69, 77, 67, 68, 70, 65, 66, 68, 75, 66, 67, 73, 73, 4,
+ 88, 71, 11, 71, 0, 69, 68, 65, 2, 64, 67, 65, 74, 74, 79, 51, 48, 50, 44,
+ 38, 42, 41, 38, 37, 34, 36, 35, 24, 18, 4, 27, 25, 20, 9, 16, 13, 6, 11,
+ 4, 1, 68, 72, 76, 79, 25, 22, 25, 14, 66, 5, 2, 73, 1, 70, 74, 90, 82,
+ 87, 93, 5, 9, 78, 4, 7, 66, 75, 74, 75, 84, 74, 81, 82, 99, 84, 89, 98,
+ 64, 78, 86, 73, 1, 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52,
+ 28, 21, 15, 7, 5, 78, 84, 94, 6, 37, 31, 31, 22, 22, 12, 10, 4, 64, 73,
+ 1, 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52, 28, 21, 15, 7,
+ 5, 78, 84, 94, 75, 68, 1, 5, 5, 69, 10},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 2, 24, 42, 28, 6, 7, 7, 78,
+ 64, 64, 66, 17, 78, 71, 22, 18, 84, 99, 115, 77, 82, 70, 78, 64, 64, 83, 66,
+ 29, 2, 71, 79, 83, 86, 89, 90, 105, 64, 77, 85, 70, 84, 85, 99, 4, 72, 71,
+ 78, 24, 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 19, 73, 95, 70, 64, 73,
+ 19, 17, 70, 64, 78, 9, 74, 69, 69, 97, 83, 87, 85, 18, 67, 2, 69, 71, 86,
+ 73, 80, 65, 75, 72, 85, 17, 72, 5, 77, 79, 69, 74, 67, 3, 4, 64, 9, 6,
+ 73, 0, 64, 67, 2, 72, 26, 67, 1, 23, 23, 31, 27, 20, 88, 0, 65, 66, 67,
+ 82, 68, 15, 67, 67, 13, 32, 53, 39, 15, 89, 89, 2, 36, 40, 111, 69, 5, 89,
+ 13, 66, 0, 14, 33, 55, 45, 22, 91, 88, 0, 13, 19, 92, 18, 21, 19, 17, 20,
+ 17, 11, 19, 18, 0, 7, 10, 4, 2, 69, 7, 2, 0, 5, 1, 5, 6, 0, 87,
+ 0, 0, 69, 64, 75, 27, 37, 23, 16, 21, 24, 26, 27, 17, 73, 85, 70, 68, 66,
+ 107, 65, 3, 86, 18, 4, 4, 3, 3, 66, 3, 5, 79, 93, 77, 80, 78, 89, 77,
+ 16, 16, 10, 4, 0, 68, 73, 74, 81, 67, 28, 15, 10, 2, 11, 0, 68, 74, 69,
+ 66, 28, 15, 10, 4, 10, 0, 68, 73, 79, 72, 29, 13, 9, 4, 6, 68, 74, 78,
+ 3, 35, 22, 15, 8, 15, 3, 65, 68, 71, 62, 92, 87, 80, 84, 84, 81, 78, 76,
+ 75, 74, 71, 66, 78, 78, 83, 85, 15, 84, 83, 78, 73, 72, 73, 71, 71, 70, 70,
+ 71, 80, 68, 68, 12, 69, 77, 67, 68, 70, 65, 66, 68, 75, 67, 67, 73, 72, 6,
+ 88, 71, 12, 72, 0, 69, 68, 64, 2, 64, 66, 64, 73, 73, 81, 50, 47, 49, 42,
+ 36, 39, 39, 35, 35, 32, 33, 33, 21, 15, 2, 23, 22, 17, 4, 13, 11, 5, 9,
+ 2, 0, 69, 73, 77, 79, 23, 20, 23, 12, 68, 3, 1, 75, 64, 72, 76, 92, 84,
+ 89, 94, 4, 8, 80, 3, 5, 67, 77, 75, 76, 85, 75, 81, 82, 98, 85, 90, 100,
+ 65, 79, 87, 73, 2, 6, 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, 51,
+ 27, 19, 13, 5, 3, 80, 86, 95, 7, 37, 32, 32, 23, 23, 13, 11, 5, 0, 73,
+ 2, 6, 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, 51, 27, 19, 13, 5,
+ 3, 80, 86, 95, 75, 68, 1, 6, 6, 68, 12},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 0, 23, 41, 29, 6, 8, 5,
+ 78, 0, 65, 66, 18, 79, 72, 21, 16, 87, 102, 116, 75, 81, 70, 78, 0, 65,
+ 83, 65, 29, 2, 71, 78, 81, 87, 90, 90, 105, 64, 76, 84, 71, 84, 85, 99,
+ 4, 72, 71, 77, 25, 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 73,
+ 94, 68, 0, 72, 20, 18, 69, 0, 76, 10, 73, 68, 66, 97, 84, 87, 86, 18,
+ 67, 3, 66, 70, 86, 73, 78, 65, 75, 72, 85, 17, 72, 5, 76, 79, 68, 73,
+ 67, 3, 4, 0, 9, 6, 74, 0, 64, 67, 2, 72, 26, 67, 1, 24, 23, 31,
+ 27, 20, 89, 0, 65, 66, 67, 81, 68, 16, 66, 67, 15, 34, 54, 40, 17, 89,
+ 90, 2, 37, 40, 112, 69, 6, 90, 14, 66, 0, 15, 33, 55, 45, 24, 92, 86,
+ 64, 10, 16, 91, 18, 21, 18, 17, 19, 17, 10, 19, 17, 64, 6, 10, 4, 2,
+ 69, 6, 2, 64, 4, 1, 5, 5, 0, 88, 64, 64, 69, 65, 76, 25, 35, 21,
+ 14, 20, 22, 23, 24, 16, 75, 87, 72, 70, 68, 108, 66, 2, 87, 17, 3, 3,
+ 1, 2, 68, 1, 4, 81, 93, 78, 81, 80, 88, 76, 17, 16, 10, 4, 1, 67,
+ 72, 74, 79, 65, 29, 16, 10, 3, 13, 1, 66, 73, 66, 65, 28, 15, 10, 5,
+ 11, 1, 68, 72, 78, 72, 30, 14, 9, 4, 7, 68, 74, 77, 4, 35, 23, 15,
+ 8, 16, 4, 64, 68, 70, 62, 91, 86, 79, 83, 83, 79, 77, 74, 74, 72, 69,
+ 0, 77, 77, 82, 84, 18, 83, 84, 77, 72, 71, 73, 71, 71, 70, 69, 72, 81,
+ 68, 68, 13, 69, 77, 67, 68, 69, 66, 67, 68, 76, 68, 68, 73, 72, 7, 89,
+ 72, 13, 72, 64, 69, 68, 64, 1, 65, 66, 64, 73, 73, 82, 49, 46, 48, 41,
+ 33, 37, 36, 32, 32, 29, 30, 30, 18, 13, 0, 19, 18, 13, 64, 10, 9, 3,
+ 7, 64, 65, 70, 74, 78, 79, 21, 17, 20, 10, 70, 1, 64, 77, 66, 74, 78,
+ 94, 86, 90, 96, 3, 7, 82, 1, 4, 69, 79, 76, 77, 86, 76, 82, 82, 97,
+ 87, 91, 101, 67, 80, 88, 73, 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23,
+ 27, 26, 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 7, 38, 32, 32, 24, 24,
+ 13, 11, 5, 1, 73, 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23, 27, 26,
+ 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 75, 68, 1, 6, 6, 66, 14},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 64, 21, 40, 29, 7, 10, 4,
+ 78, 2, 65, 67, 19, 80, 73, 20, 15, 91, 104, 117, 73, 79, 70, 78, 2, 65,
+ 82, 64, 30, 2, 70, 77, 80, 89, 91, 90, 106, 64, 76, 84, 71, 85, 84, 99,
+ 3, 72, 71, 76, 25, 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 72,
+ 93, 66, 1, 71, 22, 20, 68, 1, 74, 11, 72, 68, 64, 98, 84, 87, 86, 19,
+ 67, 4, 64, 70, 85, 72, 76, 65, 75, 72, 85, 18, 73, 6, 76, 79, 67, 73,
+ 66, 3, 5, 1, 10, 6, 74, 0, 64, 67, 2, 72, 26, 67, 1, 24, 23, 32,
+ 28, 21, 89, 1, 64, 67, 67, 81, 68, 17, 66, 66, 16, 35, 54, 42, 18, 90,
+ 91, 3, 37, 40, 112, 70, 6, 90, 14, 67, 1, 16, 33, 55, 46, 25, 93, 85,
+ 65, 7, 13, 89, 18, 21, 18, 16, 19, 16, 10, 18, 17, 64, 6, 10, 3, 2,
+ 70, 6, 1, 65, 4, 1, 5, 5, 64, 90, 64, 65, 69, 66, 76, 22, 33, 19,
+ 13, 18, 20, 20, 22, 14, 77, 89, 73, 72, 70, 110, 67, 0, 89, 15, 2, 2,
+ 0, 0, 70, 64, 2, 82, 93, 79, 82, 81, 86, 74, 19, 17, 10, 4, 2, 67,
+ 72, 73, 78, 64, 30, 17, 11, 3, 14, 2, 65, 72, 64, 65, 29, 16, 11, 5,
+ 12, 1, 67, 71, 77, 72, 32, 15, 9, 4, 7, 67, 74, 77, 4, 36, 23, 16,
+ 8, 17, 4, 64, 67, 70, 62, 89, 84, 77, 81, 81, 78, 75, 73, 72, 70, 67,
+ 2, 77, 76, 82, 84, 21, 83, 85, 77, 72, 70, 73, 71, 71, 70, 69, 72, 82,
+ 68, 68, 13, 69, 77, 67, 68, 69, 66, 67, 68, 77, 69, 68, 73, 72, 8, 90,
+ 72, 14, 73, 64, 69, 68, 0, 1, 65, 65, 0, 73, 73, 84, 48, 45, 47, 39,
+ 31, 34, 34, 29, 30, 26, 27, 27, 15, 10, 65, 16, 15, 9, 69, 8, 6, 1,
+ 5, 66, 67, 71, 75, 79, 79, 19, 15, 18, 8, 72, 0, 65, 79, 68, 77, 80,
+ 96, 88, 92, 97, 2, 5, 84, 0, 2, 70, 81, 78, 79, 87, 77, 83, 83, 96,
+ 88, 93, 103, 68, 82, 89, 72, 3, 7, 8, 19, 13, 19, 2, 17, 15, 23, 24,
+ 28, 27, 14, 50, 23, 15, 9, 1, 64, 85, 90, 97, 8, 38, 33, 33, 24, 25,
+ 14, 12, 6, 1, 72, 3, 7, 8, 19, 13, 19, 2, 17, 15, 23, 24, 28, 27,
+ 14, 50, 23, 15, 9, 1, 64, 85, 90, 97, 75, 68, 1, 7, 7, 65, 17},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 66, 20, 39, 30, 7, 12, 2,
+ 78, 3, 65, 67, 20, 81, 75, 18, 13, 94, 106, 118, 71, 78, 70, 78, 3, 65,
+ 82, 0, 30, 1, 69, 76, 79, 90, 93, 91, 106, 64, 76, 83, 71, 85, 84, 99,
+ 3, 72, 71, 76, 26, 2, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 17, 72,
+ 92, 64, 2, 70, 23, 21, 68, 2, 72, 12, 71, 67, 1, 99, 84, 87, 86, 19,
+ 68, 5, 1, 70, 84, 71, 74, 65, 75, 72, 85, 18, 73, 6, 75, 79, 67, 73,
+ 66, 3, 5, 2, 10, 6, 74, 64, 64, 67, 2, 72, 26, 67, 1, 25, 23, 32,
+ 28, 21, 90, 1, 0, 67, 67, 81, 68, 18, 66, 66, 17, 36, 55, 43, 20, 90,
+ 92, 3, 37, 40, 113, 70, 7, 91, 15, 67, 1, 17, 33, 55, 46, 26, 94, 83,
+ 66, 4, 10, 88, 17, 21, 17, 15, 18, 16, 9, 18, 16, 65, 5, 9, 3, 2,
+ 70, 5, 0, 66, 3, 0, 4, 4, 64, 91, 65, 66, 69, 68, 77, 20, 31, 17,
+ 11, 16, 18, 16, 19, 13, 79, 92, 75, 74, 72, 111, 69, 64, 91, 14, 1, 1,
+ 64, 64, 72, 66, 0, 84, 93, 80, 83, 83, 85, 73, 20, 17, 10, 4, 3, 66,
+ 71, 72, 76, 0, 31, 17, 12, 4, 15, 3, 0, 71, 1, 64, 29, 16, 11, 6,
+ 13, 2, 67, 71, 76, 72, 33, 16, 9, 4, 8, 67, 74, 76, 5, 36, 24, 16,
+ 8, 18, 5, 0, 67, 69, 62, 88, 83, 76, 79, 80, 76, 74, 71, 71, 69, 65,
+ 4, 76, 75, 81, 83, 24, 83, 86, 77, 71, 70, 73, 71, 71, 71, 68, 72, 83,
+ 68, 68, 14, 69, 77, 67, 68, 69, 67, 67, 68, 78, 70, 68, 73, 72, 9, 91,
+ 72, 14, 74, 64, 69, 68, 0, 1, 66, 65, 1, 73, 73, 85, 47, 44, 46, 37,
+ 29, 32, 31, 26, 27, 23, 23, 24, 11, 7, 67, 12, 11, 5, 74, 5, 4, 64,
+ 3, 69, 69, 73, 76, 80, 79, 16, 13, 16, 6, 74, 65, 67, 81, 70, 79, 82,
+ 98, 91, 94, 98, 1, 4, 87, 65, 0, 72, 83, 79, 80, 88, 78, 84, 83, 95,
+ 89, 94, 104, 69, 83, 90, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, 24, 24,
+ 29, 27, 15, 50, 21, 13, 7, 64, 66, 87, 92, 99, 8, 39, 33, 34, 25, 25,
+ 14, 12, 6, 2, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, 24, 24, 29, 27,
+ 15, 50, 21, 13, 7, 64, 66, 87, 92, 99, 75, 68, 1, 7, 7, 0, 19},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 68, 18, 38, 31, 7, 13, 0,
+ 77, 5, 66, 67, 21, 82, 76, 17, 11, 97, 109, 118, 69, 77, 70, 77, 5, 66,
+ 82, 1, 30, 1, 69, 75, 77, 91, 94, 91, 106, 64, 75, 82, 72, 85, 84, 99,
+ 3, 71, 71, 75, 26, 2, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 17, 71,
+ 90, 2, 3, 69, 25, 23, 67, 3, 70, 13, 70, 66, 4, 99, 85, 87, 87, 19,
+ 68, 6, 4, 69, 84, 71, 72, 65, 75, 72, 84, 18, 73, 7, 74, 78, 66, 72,
+ 66, 4, 6, 3, 11, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 25, 24, 32,
+ 28, 21, 90, 2, 0, 68, 67, 80, 68, 19, 65, 65, 19, 38, 56, 45, 22, 91,
+ 93, 4, 38, 40, 114, 70, 7, 91, 16, 67, 1, 19, 33, 55, 46, 28, 95, 82,
+ 67, 2, 7, 87, 17, 21, 17, 15, 18, 16, 9, 18, 16, 66, 4, 9, 3, 2,
+ 70, 5, 0, 67, 3, 0, 4, 3, 65, 92, 66, 66, 69, 69, 77, 18, 29, 16,
+ 10, 15, 16, 13, 17, 12, 81, 94, 76, 76, 74, 112, 70, 65, 92, 13, 0, 0,
+ 66, 66, 74, 68, 64, 85, 93, 81, 84, 85, 83, 71, 21, 18, 10, 4, 4, 65,
+ 70, 72, 74, 2, 32, 18, 12, 5, 17, 4, 1, 70, 4, 0, 30, 17, 12, 6,
+ 14, 3, 66, 70, 75, 71, 34, 17, 9, 4, 9, 66, 73, 75, 6, 36, 25, 16,
+ 8, 19, 6, 1, 66, 68, 62, 87, 81, 74, 78, 79, 75, 72, 69, 69, 67, 0,
+ 7, 75, 74, 80, 82, 27, 82, 87, 76, 70, 69, 73, 71, 71, 71, 68, 73, 84,
+ 68, 68, 15, 69, 77, 67, 68, 68, 67, 68, 68, 79, 71, 69, 73, 72, 10, 91,
+ 73, 15, 74, 65, 69, 68, 0, 0, 66, 65, 1, 73, 73, 87, 46, 43, 45, 36,
+ 26, 29, 28, 23, 25, 20, 20, 21, 8, 5, 69, 8, 8, 1, 79, 2, 2, 65,
+ 1, 71, 71, 74, 77, 81, 79, 14, 10, 13, 4, 76, 67, 68, 83, 72, 81, 84,
+ 100, 93, 95, 100, 0, 3, 89, 66, 64, 73, 85, 80, 81, 89, 79, 85, 83, 94,
+ 91, 95, 106, 71, 84, 91, 72, 4, 8, 10, 21, 14, 20, 3, 19, 17, 25, 25,
+ 30, 28, 15, 49, 19, 11, 5, 66, 68, 90, 94, 100, 9, 39, 34, 34, 26, 26,
+ 15, 13, 6, 3, 72, 4, 8, 10, 21, 14, 20, 3, 19, 17, 25, 25, 30, 28,
+ 15, 49, 19, 11, 5, 66, 68, 90, 94, 100, 75, 68, 1, 7, 7, 1, 21},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 70, 17, 37, 31, 7, 15, 64,
+ 77, 6, 66, 68, 22, 83, 77, 16, 9, 101, 111, 119, 67, 75, 70, 77, 6, 66,
+ 81, 2, 31, 1, 68, 74, 76, 92, 95, 91, 107, 64, 75, 81, 72, 86, 84, 99,
+ 3, 71, 71, 74, 27, 2, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 16, 71,
+ 89, 4, 4, 68, 26, 24, 66, 4, 68, 14, 69, 65, 6, 100, 85, 87, 87, 20,
+ 68, 7, 6, 69, 83, 70, 70, 65, 75, 72, 84, 19, 73, 7, 73, 78, 65, 72,
+ 66, 4, 6, 4, 11, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 26, 24, 33,
+ 28, 22, 91, 2, 1, 68, 67, 80, 68, 20, 65, 65, 20, 39, 57, 46, 24, 91,
+ 94, 4, 38, 40, 115, 70, 8, 92, 16, 67, 1, 20, 33, 55, 46, 29, 96, 80,
+ 68, 64, 4, 85, 17, 21, 16, 14, 17, 15, 8, 18, 15, 67, 3, 9, 3, 2,
+ 71, 4, 64, 68, 2, 0, 4, 2, 65, 93, 66, 67, 69, 70, 78, 16, 27, 14,
+ 8, 13, 14, 10, 14, 11, 83, 96, 78, 78, 76, 114, 71, 66, 94, 12, 64, 64,
+ 67, 67, 76, 70, 66, 87, 93, 82, 85, 86, 82, 70, 23, 18, 10, 4, 5, 64,
+ 69, 71, 72, 3, 33, 19, 13, 5, 18, 5, 3, 69, 6, 0, 30, 17, 12, 7,
+ 15, 3, 66, 69, 74, 71, 36, 18, 9, 4, 10, 66, 73, 74, 7, 37, 26, 17,
+ 8, 20, 6, 2, 66, 68, 62, 85, 80, 73, 76, 78, 73, 71, 68, 68, 65, 2,
+ 9, 75, 73, 80, 81, 30, 82, 88, 76, 69, 68, 73, 71, 71, 71, 67, 73, 85,
+ 68, 68, 15, 69, 77, 67, 68, 68, 68, 68, 68, 80, 72, 69, 73, 72, 11, 92,
+ 73, 16, 75, 65, 69, 68, 1, 0, 67, 64, 2, 73, 73, 88, 45, 42, 44, 34,
+ 24, 27, 26, 20, 22, 17, 17, 18, 5, 2, 71, 4, 4, 66, 84, 64, 0, 67,
+ 64, 74, 73, 75, 78, 82, 79, 12, 8, 11, 2, 78, 69, 70, 85, 74, 83, 86,
+ 102, 95, 97, 101, 64, 2, 91, 68, 66, 75, 87, 82, 83, 90, 80, 86, 83, 93,
+ 92, 97, 107, 72, 85, 92, 72, 4, 8, 10, 22, 15, 21, 3, 20, 18, 26, 25,
+ 31, 28, 16, 49, 17, 9, 3, 68, 70, 92, 96, 101, 9, 40, 34, 35, 26, 27,
+ 15, 13, 7, 3, 72, 4, 8, 10, 22, 15, 21, 3, 20, 18, 26, 25, 31, 28,
+ 16, 49, 17, 9, 3, 68, 70, 92, 96, 101, 75, 68, 1, 8, 8, 3, 23},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 72, 15, 36, 32, 7, 17, 66,
+ 77, 8, 66, 68, 23, 84, 78, 15, 7, 104, 113, 120, 65, 74, 70, 77, 8, 66,
+ 81, 3, 31, 1, 67, 73, 75, 93, 96, 91, 107, 64, 75, 80, 72, 86, 84, 99,
+ 3, 71, 71, 73, 27, 2, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 16, 70,
+ 88, 6, 5, 67, 28, 26, 65, 5, 66, 15, 68, 64, 8, 101, 85, 87, 87, 20,
+ 68, 8, 8, 69, 82, 69, 68, 65, 75, 72, 84, 19, 73, 8, 72, 78, 64, 72,
+ 66, 4, 7, 5, 12, 6, 75, 64, 0, 67, 2, 72, 27, 67, 1, 26, 24, 33,
+ 28, 22, 91, 3, 2, 69, 67, 80, 68, 21, 65, 64, 21, 40, 58, 48, 26, 92,
+ 95, 5, 38, 40, 116, 70, 8, 92, 17, 67, 1, 21, 33, 55, 46, 30, 97, 79,
+ 69, 67, 1, 84, 17, 21, 16, 13, 17, 15, 8, 18, 15, 68, 2, 9, 3, 2,
+ 71, 4, 65, 69, 2, 0, 4, 1, 66, 94, 67, 68, 69, 71, 78, 14, 25, 12,
+ 7, 11, 12, 7, 12, 10, 85, 98, 79, 80, 78, 115, 72, 67, 96, 11, 65, 65,
+ 68, 69, 78, 72, 68, 88, 93, 83, 86, 88, 80, 68, 24, 19, 10, 4, 6, 0,
+ 68, 70, 70, 4, 34, 20, 14, 6, 19, 6, 4, 68, 8, 1, 31, 18, 13, 7,
+ 16, 4, 65, 68, 73, 71, 37, 19, 9, 4, 11, 65, 73, 73, 8, 37, 27, 17,
+ 8, 21, 7, 3, 65, 67, 62, 84, 78, 71, 74, 77, 72, 69, 66, 66, 0, 4,
+ 11, 74, 72, 79, 80, 33, 82, 89, 76, 68, 67, 73, 71, 71, 71, 67, 73, 86,
+ 68, 68, 16, 69, 77, 67, 68, 68, 68, 68, 68, 81, 73, 69, 73, 72, 12, 93,
+ 73, 17, 76, 65, 69, 68, 1, 0, 67, 64, 3, 73, 73, 90, 44, 41, 43, 32,
+ 22, 24, 23, 17, 20, 14, 14, 15, 2, 64, 73, 0, 1, 70, 89, 67, 65, 69,
+ 66, 76, 75, 76, 79, 83, 79, 10, 6, 9, 0, 80, 71, 71, 87, 76, 85, 88,
+ 104, 97, 99, 102, 65, 1, 93, 69, 68, 76, 89, 83, 84, 91, 81, 87, 83, 92,
+ 93, 98, 109, 73, 86, 93, 72, 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26,
+ 32, 29, 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 10, 40, 35, 36, 27, 28,
+ 16, 14, 7, 4, 72, 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, 29,
+ 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 75, 68, 1, 8, 8, 4, 25},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 74, 13, 35, 32, 7, 18,
+ 68, 77, 9, 67, 69, 24, 85, 80, 13, 5, 108, 116, 121, 0, 73, 70, 77,
+ 9, 67, 81, 3, 31, 0, 67, 73, 74, 95, 98, 92, 108, 65, 75, 80, 73,
+ 87, 84, 99, 2, 71, 71, 73, 27, 1, 22, 0, 0, 0, 65, 94, 97, 5,
+ 67, 68, 15, 70, 87, 8, 6, 67, 29, 27, 65, 6, 65, 15, 67, 64, 10,
+ 102, 86, 88, 88, 20, 69, 8, 10, 69, 82, 69, 67, 65, 75, 72, 84, 19,
+ 74, 8, 72, 78, 64, 72, 66, 4, 7, 6, 12, 6, 76, 65, 0, 67, 1,
+ 72, 27, 67, 1, 26, 24, 33, 28, 22, 92, 3, 2, 70, 67, 80, 69, 21,
+ 65, 64, 22, 41, 58, 49, 27, 93, 97, 5, 38, 40, 117, 71, 8, 93, 17,
+ 68, 1, 22, 33, 54, 46, 31, 98, 78, 71, 70, 66, 83, 16, 21, 15, 12,
+ 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, 72, 3, 66, 70, 1, 64, 3,
+ 0, 67, 96, 68, 69, 69, 73, 79, 11, 22, 10, 5, 9, 9, 3, 9, 8,
+ 87, 101, 81, 83, 80, 117, 74, 69, 98, 9, 66, 66, 70, 71, 80, 74, 70,
+ 90, 93, 84, 87, 90, 79, 67, 25, 19, 10, 4, 6, 0, 68, 70, 69, 5,
+ 34, 20, 14, 6, 20, 7, 5, 68, 10, 1, 31, 18, 13, 7, 16, 4, 65,
+ 68, 72, 71, 38, 20, 9, 3, 11, 65, 73, 73, 8, 37, 27, 17, 8, 22,
+ 7, 3, 65, 67, 62, 83, 77, 70, 73, 76, 71, 68, 65, 65, 1, 5, 13,
+ 74, 72, 79, 80, 36, 82, 91, 76, 68, 67, 73, 71, 71, 72, 67, 74, 87,
+ 69, 68, 16, 70, 77, 68, 68, 68, 69, 69, 69, 82, 74, 70, 74, 72, 13,
+ 94, 74, 17, 77, 66, 69, 69, 1, 64, 68, 64, 3, 73, 73, 92, 42, 40,
+ 41, 30, 19, 21, 20, 14, 17, 11, 10, 12, 65, 67, 75, 67, 66, 74, 95,
+ 70, 68, 71, 69, 79, 77, 78, 81, 84, 79, 7, 3, 6, 65, 83, 73, 73,
+ 90, 78, 88, 90, 107, 100, 101, 104, 67, 64, 96, 71, 70, 78, 91, 85, 86,
+ 92, 82, 88, 84, 91, 95, 100, 111, 75, 88, 95, 72, 5, 9, 11, 24, 16,
+ 22, 3, 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, 100,
+ 104, 10, 40, 35, 36, 27, 28, 16, 14, 7, 4, 72, 5, 9, 11, 24, 16,
+ 22, 3, 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, 100,
+ 104, 75, 69, 0, 8, 8, 5, 27},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 75, 12, 35, 33, 8, 20,
+ 69, 76, 11, 67, 69, 26, 85, 81, 12, 4, 111, 118, 121, 2, 71, 69, 76,
+ 11, 67, 80, 4, 32, 0, 66, 72, 72, 96, 99, 92, 108, 65, 74, 79, 73,
+ 87, 83, 98, 2, 70, 70, 72, 28, 1, 22, 0, 0, 0, 64, 94, 97, 6,
+ 67, 68, 15, 69, 85, 11, 8, 66, 31, 29, 64, 8, 0, 16, 65, 0, 13,
+ 102, 86, 88, 88, 21, 69, 9, 13, 68, 81, 68, 65, 65, 74, 72, 83, 20,
+ 74, 9, 71, 77, 0, 71, 65, 5, 8, 7, 13, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 27, 25, 34, 29, 23, 92, 4, 3, 70, 67, 79, 69, 22,
+ 64, 0, 24, 43, 59, 51, 29, 93, 98, 6, 39, 41, 117, 71, 9, 93, 18,
+ 68, 2, 24, 33, 54, 47, 33, 99, 76, 72, 72, 69, 81, 16, 21, 15, 12,
+ 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, 72, 3, 66, 70, 1, 64, 3,
+ 0, 67, 97, 68, 69, 69, 74, 79, 9, 20, 9, 4, 8, 7, 0, 7, 7,
+ 88, 103, 82, 85, 81, 118, 75, 70, 99, 8, 66, 66, 71, 72, 81, 75, 71,
+ 91, 93, 84, 87, 91, 77, 65, 27, 20, 10, 4, 7, 1, 67, 69, 67, 7,
+ 35, 21, 15, 7, 22, 8, 7, 67, 13, 2, 32, 19, 14, 8, 17, 5, 64,
+ 67, 70, 70, 40, 21, 10, 3, 12, 64, 72, 72, 9, 38, 28, 18, 9, 23,
+ 8, 4, 64, 66, 62, 81, 75, 68, 71, 74, 69, 66, 0, 0, 3, 7, 16,
+ 73, 71, 78, 79, 40, 81, 92, 75, 67, 66, 72, 71, 70, 72, 66, 74, 87,
+ 69, 68, 17, 70, 77, 68, 68, 67, 69, 69, 69, 82, 74, 70, 74, 71, 15,
+ 94, 74, 18, 77, 66, 69, 69, 2, 64, 68, 0, 4, 72, 72, 93, 41, 39,
+ 40, 29, 17, 19, 18, 11, 15, 9, 7, 10, 68, 69, 77, 70, 69, 77, 100,
+ 72, 70, 72, 71, 81, 78, 79, 82, 84, 79, 5, 1, 4, 67, 85, 74, 74,
+ 92, 79, 90, 91, 109, 102, 102, 105, 68, 65, 98, 72, 71, 79, 92, 86, 87,
+ 93, 82, 88, 84, 90, 96, 101, 112, 76, 89, 96, 71, 6, 10, 12, 26, 17,
+ 23, 4, 24, 20, 29, 27, 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101,
+ 105, 11, 41, 36, 37, 28, 29, 17, 15, 8, 5, 71, 6, 10, 12, 26, 17,
+ 23, 4, 24, 20, 29, 27, 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101,
+ 105, 75, 69, 0, 9, 9, 7, 30},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 77, 10, 34, 34, 8, 22,
+ 71, 76, 12, 67, 69, 27, 86, 82, 11, 2, 114, 120, 122, 4, 70, 69, 76,
+ 12, 67, 80, 5, 32, 0, 65, 71, 71, 97, 100, 92, 108, 65, 74, 78, 73,
+ 87, 83, 98, 2, 70, 70, 71, 28, 1, 22, 0, 0, 0, 0, 94, 97, 6,
+ 68, 68, 15, 68, 84, 13, 9, 65, 33, 31, 0, 9, 2, 17, 64, 1, 15,
+ 103, 86, 88, 88, 21, 69, 10, 15, 68, 80, 67, 0, 65, 74, 72, 83, 20,
+ 74, 9, 70, 77, 1, 71, 65, 5, 8, 8, 14, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 27, 25, 34, 29, 23, 93, 5, 4, 71, 67, 79, 69, 23,
+ 64, 0, 25, 44, 60, 53, 31, 94, 99, 6, 39, 41, 118, 71, 9, 94, 19,
+ 68, 2, 25, 33, 54, 47, 34, 100, 75, 73, 75, 72, 80, 16, 21, 15, 11,
+ 15, 14, 7, 17, 13, 70, 0, 8, 2, 1, 72, 2, 67, 71, 1, 64, 3,
+ 64, 68, 98, 69, 70, 69, 75, 80, 7, 18, 7, 2, 6, 5, 66, 5, 6,
+ 90, 105, 84, 87, 83, 119, 76, 71, 101, 7, 67, 67, 72, 74, 83, 77, 73,
+ 93, 93, 85, 88, 93, 76, 64, 28, 21, 10, 4, 8, 2, 66, 68, 65, 8,
+ 36, 22, 16, 8, 23, 9, 8, 66, 15, 3, 32, 19, 14, 8, 18, 6, 0,
+ 66, 69, 70, 41, 22, 10, 3, 13, 0, 72, 71, 10, 38, 29, 18, 9, 24,
+ 9, 5, 0, 65, 62, 80, 73, 66, 69, 73, 68, 64, 2, 1, 5, 9, 18,
+ 72, 70, 77, 78, 43, 81, 93, 75, 66, 65, 72, 71, 70, 72, 66, 74, 88,
+ 69, 68, 18, 70, 77, 68, 68, 67, 69, 69, 69, 83, 75, 70, 74, 71, 16,
+ 95, 74, 19, 78, 66, 69, 69, 2, 64, 68, 0, 5, 72, 72, 95, 40, 38,
+ 39, 27, 15, 16, 15, 8, 13, 6, 4, 7, 71, 72, 79, 74, 73, 81, 105,
+ 75, 72, 74, 73, 83, 80, 80, 83, 85, 79, 3, 64, 2, 69, 87, 76, 76,
+ 94, 81, 92, 93, 111, 104, 104, 106, 69, 66, 100, 74, 73, 81, 94, 87, 88,
+ 94, 83, 89, 84, 89, 97, 102, 114, 77, 90, 97, 71, 6, 11, 13, 27, 18,
+ 24, 4, 25, 21, 30, 27, 34, 31, 19, 46, 10, 2, 69, 77, 77, 101, 103,
+ 106, 12, 41, 36, 38, 29, 30, 17, 16, 8, 6, 71, 6, 11, 13, 27, 18,
+ 24, 4, 25, 21, 30, 27, 34, 31, 19, 46, 10, 2, 69, 77, 77, 101, 103,
+ 106, 75, 69, 0, 9, 9, 8, 32},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 79, 9, 33, 34, 8, 24,
+ 72, 76, 14, 67, 70, 28, 87, 83, 10, 0, 118, 122, 123, 6, 68, 69, 76,
+ 14, 67, 79, 6, 33, 0, 64, 70, 70, 98, 101, 92, 109, 65, 74, 77, 73,
+ 88, 83, 98, 2, 70, 70, 70, 29, 1, 22, 0, 0, 0, 0, 94, 97, 7,
+ 69, 68, 14, 68, 83, 15, 10, 64, 34, 32, 1, 10, 4, 18, 0, 2, 17,
+ 104, 86, 88, 88, 22, 69, 11, 17, 68, 79, 66, 2, 65, 74, 72, 83, 21,
+ 74, 10, 69, 77, 2, 71, 65, 5, 9, 9, 14, 7, 76, 65, 1, 66, 1,
+ 71, 28, 66, 1, 28, 25, 35, 29, 24, 93, 5, 5, 71, 67, 79, 69, 24,
+ 64, 1, 26, 45, 61, 54, 33, 94, 100, 7, 39, 41, 119, 71, 10, 94, 19,
+ 68, 2, 26, 33, 54, 47, 35, 101, 73, 74, 78, 75, 78, 16, 21, 14, 10,
+ 15, 13, 6, 17, 13, 71, 64, 8, 2, 1, 73, 2, 68, 72, 0, 64, 3,
+ 65, 68, 99, 69, 71, 69, 76, 80, 5, 16, 5, 1, 4, 3, 69, 2, 5,
+ 92, 107, 85, 89, 85, 121, 77, 72, 103, 6, 68, 68, 73, 75, 85, 79, 75,
+ 94, 93, 86, 89, 94, 74, 1, 30, 21, 10, 4, 9, 3, 65, 67, 0, 9,
+ 37, 23, 17, 8, 24, 10, 10, 65, 17, 3, 33, 20, 15, 9, 19, 6, 0,
+ 65, 68, 70, 43, 23, 10, 3, 14, 0, 72, 70, 11, 39, 30, 19, 9, 25,
+ 9, 6, 0, 65, 62, 78, 72, 65, 67, 72, 66, 0, 3, 3, 7, 11, 20,
+ 72, 69, 77, 77, 46, 81, 94, 75, 65, 64, 72, 71, 70, 72, 65, 74, 89,
+ 69, 68, 18, 70, 77, 68, 68, 67, 70, 69, 69, 84, 76, 70, 74, 71, 17,
+ 96, 74, 20, 79, 66, 69, 69, 3, 64, 69, 1, 6, 72, 72, 96, 39, 37,
+ 38, 25, 13, 14, 13, 5, 10, 3, 1, 4, 74, 75, 81, 78, 76, 85, 110,
+ 78, 74, 76, 75, 86, 82, 81, 84, 86, 79, 1, 66, 0, 71, 89, 78, 77,
+ 96, 83, 94, 95, 113, 106, 106, 107, 70, 67, 102, 75, 75, 82, 96, 89, 90,
+ 95, 84, 90, 84, 88, 98, 104, 115, 78, 91, 98, 71, 7, 11, 13, 28, 19,
+ 25, 4, 26, 22, 31, 28, 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105,
+ 107, 12, 42, 37, 39, 29, 31, 18, 16, 9, 6, 71, 7, 11, 13, 28, 19,
+ 25, 4, 26, 22, 31, 28, 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105,
+ 107, 75, 69, 0, 10, 10, 10, 34},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 81, 7, 32, 35, 8, 25,
+ 74, 76, 15, 68, 70, 29, 88, 85, 8, 65, 121, 125, 124, 8, 67, 69, 76,
+ 15, 68, 79, 7, 33, 64, 64, 69, 68, 99, 103, 93, 109, 65, 73, 76, 74,
+ 88, 83, 98, 2, 70, 70, 70, 29, 1, 22, 0, 0, 0, 1, 95, 97, 7,
+ 70, 68, 14, 67, 82, 17, 11, 0, 36, 34, 1, 11, 6, 19, 1, 3, 20,
+ 104, 87, 88, 89, 22, 70, 12, 20, 67, 79, 66, 4, 65, 74, 72, 83, 21,
+ 74, 10, 68, 77, 2, 70, 65, 5, 9, 10, 15, 7, 77, 66, 1, 66, 1,
+ 71, 28, 66, 1, 28, 25, 35, 29, 24, 94, 6, 5, 72, 67, 78, 69, 25,
+ 0, 1, 28, 47, 62, 56, 35, 95, 101, 7, 40, 41, 120, 71, 10, 95, 20,
+ 68, 2, 27, 33, 54, 47, 37, 102, 72, 75, 81, 78, 77, 15, 21, 14, 10,
+ 14, 13, 6, 17, 12, 72, 65, 7, 2, 1, 73, 1, 68, 73, 0, 65, 2,
+ 66, 69, 100, 70, 72, 69, 78, 81, 3, 14, 3, 64, 3, 1, 73, 0, 4,
+ 94, 110, 87, 91, 87, 122, 79, 73, 104, 5, 69, 69, 75, 77, 87, 81, 76,
+ 96, 93, 87, 90, 96, 73, 2, 31, 22, 10, 4, 10, 4, 64, 67, 2, 11,
+ 38, 23, 17, 9, 26, 11, 11, 64, 20, 4, 33, 20, 15, 9, 20, 7, 1,
+ 65, 67, 70, 44, 24, 10, 3, 15, 1, 72, 69, 12, 39, 31, 19, 9, 26,
+ 10, 7, 1, 64, 62, 77, 70, 0, 66, 71, 65, 2, 5, 4, 8, 13, 23,
+ 71, 68, 76, 76, 49, 80, 95, 74, 64, 64, 72, 71, 70, 73, 65, 75, 90,
+ 69, 68, 19, 70, 77, 68, 68, 66, 70, 70, 69, 85, 77, 71, 74, 71, 18,
+ 97, 75, 20, 79, 67, 69, 69, 3, 65, 69, 1, 6, 72, 72, 98, 38, 36,
+ 37, 24, 10, 11, 10, 2, 8, 0, 66, 1, 78, 77, 83, 82, 80, 89, 115,
+ 81, 76, 78, 77, 88, 84, 83, 85, 87, 79, 65, 69, 66, 73, 91, 80, 79,
+ 98, 85, 96, 97, 115, 109, 107, 109, 71, 68, 105, 77, 76, 84, 98, 90, 91,
+ 96, 85, 91, 84, 87, 100, 105, 117, 80, 92, 99, 71, 7, 12, 14, 29, 19,
+ 25, 5, 27, 23, 32, 28, 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107,
+ 109, 13, 42, 37, 39, 30, 31, 18, 17, 9, 7, 71, 7, 12, 14, 29, 19,
+ 25, 5, 27, 23, 32, 28, 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107,
+ 109, 75, 69, 0, 10, 10, 11, 36},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 83, 6, 31, 36, 8,
+ 27, 76, 75, 17, 68, 70, 30, 89, 86, 7, 67, 124, 126, 124, 10, 66,
+ 69, 75, 17, 68, 79, 8, 33, 64, 0, 68, 67, 100, 104, 93, 109, 65,
+ 73, 75, 74, 88, 83, 98, 2, 69, 70, 69, 30, 1, 22, 0, 0, 0,
+ 1, 95, 97, 8, 71, 68, 13, 67, 80, 20, 12, 1, 37, 35, 2, 12,
+ 8, 20, 2, 4, 22, 105, 87, 88, 89, 22, 70, 13, 22, 67, 78, 65,
+ 6, 65, 74, 72, 82, 21, 74, 11, 67, 76, 3, 70, 65, 6, 10, 11,
+ 15, 7, 77, 66, 2, 66, 1, 71, 29, 66, 1, 29, 26, 35, 29, 24,
+ 94, 6, 6, 72, 67, 78, 69, 26, 0, 2, 29, 48, 62, 57, 37, 95,
+ 102, 8, 40, 41, 121, 71, 11, 95, 21, 68, 2, 29, 33, 54, 47, 38,
+ 103, 70, 76, 83, 81, 76, 15, 21, 13, 9, 14, 13, 5, 17, 12, 73,
+ 66, 7, 2, 1, 73, 1, 69, 74, 64, 65, 2, 67, 69, 101, 71, 72,
+ 69, 79, 81, 1, 12, 2, 65, 1, 64, 76, 66, 3, 96, 112, 88, 93,
+ 89, 123, 80, 74, 106, 4, 70, 70, 76, 78, 89, 83, 78, 97, 93, 88,
+ 91, 98, 71, 4, 32, 22, 10, 4, 11, 5, 0, 66, 4, 12, 39, 24,
+ 18, 10, 27, 12, 13, 0, 22, 5, 34, 21, 16, 10, 21, 8, 1, 64,
+ 66, 69, 45, 25, 10, 3, 16, 1, 71, 68, 13, 39, 32, 19, 9, 27,
+ 11, 8, 1, 0, 62, 76, 69, 1, 64, 70, 0, 3, 7, 6, 10, 15,
+ 25, 70, 67, 75, 75, 52, 80, 96, 74, 0, 0, 72, 71, 70, 73, 64,
+ 75, 91, 69, 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 86, 78, 71,
+ 74, 71, 19, 97, 75, 21, 80, 67, 69, 69, 3, 65, 70, 1, 7, 72,
+ 72, 99, 37, 35, 36, 22, 8, 9, 7, 64, 5, 66, 69, 65, 81, 80,
+ 85, 86, 83, 93, 120, 84, 78, 79, 79, 91, 86, 84, 86, 88, 79, 67,
+ 71, 68, 75, 93, 82, 80, 100, 87, 98, 99, 117, 111, 109, 110, 72, 69,
+ 107, 78, 78, 85, 100, 91, 92, 97, 86, 92, 84, 86, 101, 106, 118, 81,
+ 93, 100, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, 33, 29, 37, 32,
+ 21, 45, 4, 67, 75, 83, 83, 108, 109, 110, 13, 43, 38, 40, 31, 32,
+ 19, 17, 9, 8, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, 33, 29,
+ 37, 32, 21, 45, 4, 67, 75, 83, 83, 108, 109, 110, 75, 69, 0, 10,
+ 10, 13, 38},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 84, 4, 30, 36, 9,
+ 29, 77, 75, 18, 68, 71, 31, 90, 87, 6, 68, 126, 126, 125, 12, 64,
+ 69, 75, 18, 68, 78, 9, 34, 64, 1, 67, 66, 102, 105, 93, 110, 65,
+ 73, 75, 74, 89, 82, 98, 1, 69, 70, 68, 30, 1, 22, 0, 0, 0,
+ 2, 95, 97, 8, 71, 69, 13, 66, 79, 22, 13, 2, 39, 37, 3, 13,
+ 10, 21, 3, 4, 24, 106, 87, 88, 89, 23, 70, 14, 24, 67, 77, 64,
+ 8, 65, 74, 72, 82, 22, 75, 11, 67, 76, 4, 70, 64, 6, 10, 12,
+ 16, 7, 77, 66, 2, 66, 1, 71, 29, 66, 1, 29, 26, 36, 30, 25,
+ 95, 7, 7, 73, 67, 78, 69, 27, 0, 2, 30, 49, 62, 59, 38, 96,
+ 103, 8, 40, 41, 121, 72, 11, 96, 21, 69, 3, 30, 33, 54, 48, 39,
+ 104, 69, 77, 86, 84, 74, 15, 21, 13, 8, 13, 12, 5, 16, 11, 73,
+ 66, 7, 1, 1, 74, 0, 70, 75, 64, 65, 2, 67, 70, 103, 71, 73,
+ 69, 80, 82, 65, 10, 0, 67, 64, 66, 79, 68, 1, 98, 114, 90, 95,
+ 91, 125, 81, 76, 108, 2, 71, 71, 77, 80, 91, 85, 80, 99, 93, 89,
+ 92, 99, 70, 5, 34, 23, 10, 4, 12, 5, 0, 65, 5, 13, 40, 25,
+ 19, 10, 28, 13, 14, 1, 24, 5, 34, 21, 16, 10, 22, 8, 2, 0,
+ 65, 69, 47, 26, 10, 3, 16, 2, 71, 68, 13, 40, 32, 20, 9, 28,
+ 11, 8, 2, 0, 62, 74, 67, 3, 1, 68, 1, 5, 8, 7, 12, 17,
+ 27, 70, 66, 75, 75, 55, 80, 97, 74, 0, 1, 72, 71, 70, 73, 64,
+ 75, 92, 69, 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 87, 79, 71,
+ 74, 71, 20, 98, 75, 22, 81, 67, 69, 69, 4, 65, 70, 2, 8, 72,
+ 72, 101, 36, 34, 35, 20, 6, 6, 5, 67, 3, 69, 72, 68, 84, 83,
+ 87, 89, 87, 97, 125, 86, 81, 81, 81, 93, 88, 85, 87, 89, 79, 69,
+ 73, 70, 77, 95, 83, 82, 102, 89, 101, 101, 119, 113, 111, 111, 73, 71,
+ 109, 80, 80, 87, 102, 93, 94, 98, 87, 93, 85, 85, 102, 108, 120, 82,
+ 95, 101, 70, 8, 13, 15, 31, 21, 27, 5, 29, 25, 34, 29, 38, 33,
+ 22, 44, 2, 69, 77, 85, 85, 110, 111, 111, 14, 43, 38, 41, 31, 33,
+ 19, 18, 10, 8, 70, 8, 13, 15, 31, 21, 27, 5, 29, 25, 34, 29,
+ 38, 33, 22, 44, 2, 69, 77, 85, 85, 110, 111, 111, 75, 69, 0, 11,
+ 11, 14, 41},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 86, 3, 29, 37, 9,
+ 30, 79, 75, 20, 69, 71, 32, 91, 88, 5, 70, 126, 126, 126, 14, 0,
+ 69, 75, 20, 69, 78, 10, 34, 64, 1, 66, 64, 103, 106, 93, 110, 65,
+ 72, 74, 75, 89, 82, 98, 1, 69, 70, 67, 31, 1, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 12, 66, 78, 24, 14, 3, 40, 38, 4, 14,
+ 12, 22, 4, 5, 27, 106, 88, 88, 90, 23, 70, 15, 27, 66, 77, 64,
+ 10, 65, 74, 72, 82, 22, 75, 12, 66, 76, 5, 69, 64, 6, 11, 13,
+ 16, 7, 78, 66, 2, 66, 1, 71, 29, 66, 1, 30, 26, 36, 30, 25,
+ 95, 7, 7, 73, 67, 77, 69, 28, 1, 3, 32, 51, 62, 60, 40, 96,
+ 104, 9, 41, 41, 122, 72, 12, 96, 22, 69, 3, 31, 33, 54, 48, 41,
+ 105, 67, 78, 89, 87, 73, 15, 21, 12, 8, 13, 12, 4, 16, 11, 74,
+ 67, 7, 1, 1, 74, 0, 70, 76, 65, 65, 2, 68, 70, 104, 72, 74,
+ 69, 81, 82, 67, 8, 65, 68, 65, 68, 82, 71, 0, 100, 116, 91, 97,
+ 93, 126, 82, 77, 109, 1, 72, 72, 79, 81, 93, 87, 81, 100, 93, 90,
+ 93, 101, 68, 7, 35, 23, 10, 4, 13, 6, 1, 65, 7, 15, 41, 26,
+ 19, 11, 30, 14, 16, 2, 27, 6, 35, 22, 17, 11, 23, 9, 2, 1,
+ 64, 69, 48, 27, 10, 3, 17, 2, 71, 67, 14, 40, 33, 20, 9, 29,
+ 12, 9, 2, 1, 62, 73, 66, 4, 2, 67, 3, 6, 10, 9, 14, 19,
+ 30, 69, 65, 74, 74, 58, 79, 98, 73, 1, 2, 72, 71, 70, 73, 0,
+ 76, 93, 69, 68, 21, 70, 77, 68, 68, 65, 72, 71, 69, 88, 80, 72,
+ 74, 71, 21, 99, 76, 23, 81, 68, 69, 69, 4, 66, 71, 2, 8, 72,
+ 72, 102, 35, 33, 34, 19, 3, 4, 2, 70, 0, 72, 75, 71, 87, 85,
+ 89, 93, 90, 101, 126, 89, 83, 83, 83, 96, 90, 86, 88, 90, 79, 71,
+ 76, 73, 79, 97, 85, 83, 104, 91, 103, 103, 121, 115, 112, 113, 74, 72,
+ 111, 81, 81, 88, 104, 94, 95, 99, 88, 94, 85, 84, 104, 109, 121, 84,
+ 96, 102, 70, 9, 13, 16, 32, 22, 27, 6, 30, 26, 35, 30, 39, 33,
+ 22, 44, 0, 71, 79, 87, 87, 113, 113, 112, 14, 44, 39, 41, 32, 34,
+ 20, 18, 10, 9, 70, 9, 13, 16, 32, 22, 27, 6, 30, 26, 35, 30,
+ 39, 33, 22, 44, 0, 71, 79, 87, 87, 113, 113, 112, 75, 69, 0, 11,
+ 11, 16, 43},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 88, 1, 28, 37, 9,
+ 32, 81, 75, 21, 69, 72, 33, 92, 90, 3, 72, 126, 126, 126, 16, 1,
+ 69, 75, 21, 69, 78, 10, 34, 65, 2, 65, 0, 104, 108, 94, 111, 65,
+ 72, 73, 75, 90, 82, 98, 1, 69, 70, 67, 31, 1, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 12, 65, 77, 26, 15, 3, 42, 40, 4, 15,
+ 14, 22, 5, 6, 29, 107, 88, 89, 90, 23, 71, 15, 29, 66, 76, 0,
+ 11, 65, 74, 72, 82, 22, 75, 12, 65, 76, 5, 69, 64, 6, 11, 14,
+ 17, 7, 78, 67, 2, 66, 0, 71, 29, 66, 1, 30, 26, 36, 30, 25,
+ 96, 8, 8, 74, 67, 77, 69, 29, 1, 3, 33, 52, 62, 62, 42, 97,
+ 105, 9, 41, 41, 123, 72, 12, 97, 22, 69, 3, 32, 33, 54, 48, 42,
+ 106, 66, 79, 92, 91, 72, 14, 21, 12, 7, 12, 11, 4, 16, 10, 75,
+ 68, 6, 1, 0, 75, 64, 71, 77, 65, 66, 1, 69, 71, 105, 73, 75,
+ 69, 83, 83, 69, 6, 67, 70, 67, 71, 86, 73, 64, 102, 119, 93, 100,
+ 95, 126, 84, 78, 111, 0, 73, 73, 80, 83, 95, 89, 83, 102, 93, 91,
+ 94, 103, 67, 8, 36, 24, 10, 4, 13, 7, 2, 64, 9, 16, 41, 26,
+ 20, 11, 31, 15, 17, 3, 29, 6, 35, 22, 17, 11, 23, 9, 3, 1,
+ 0, 69, 49, 28, 10, 3, 18, 3, 71, 66, 15, 40, 34, 20, 9, 30,
+ 12, 10, 3, 1, 62, 72, 64, 6, 4, 66, 4, 8, 11, 10, 15, 21,
+ 32, 69, 64, 74, 73, 61, 79, 99, 73, 2, 2, 72, 71, 70, 74, 0,
+ 76, 94, 69, 68, 21, 70, 77, 69, 68, 65, 72, 71, 70, 89, 81, 72,
+ 75, 71, 22, 100, 76, 23, 82, 68, 69, 70, 4, 66, 71, 2, 9, 72,
+ 72, 104, 34, 32, 33, 17, 1, 1, 64, 73, 65, 75, 79, 74, 91, 88,
+ 91, 97, 94, 105, 126, 92, 85, 85, 86, 98, 92, 88, 90, 91, 79, 74,
+ 78, 75, 81, 100, 87, 85, 107, 93, 105, 105, 123, 118, 114, 114, 76, 73,
+ 114, 83, 83, 90, 106, 96, 97, 100, 89, 95, 85, 83, 105, 111, 123, 85,
+ 97, 103, 70, 9, 14, 16, 33, 22, 28, 6, 31, 26, 36, 30, 39, 34,
+ 23, 43, 65, 73, 81, 89, 89, 115, 115, 114, 15, 44, 39, 42, 32, 34,
+ 20, 19, 10, 9, 70, 9, 14, 16, 33, 22, 28, 6, 31, 26, 36, 30,
+ 39, 34, 23, 43, 65, 73, 81, 89, 89, 115, 115, 114, 75, 70, 64, 11,
+ 11, 17, 45},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 90, 64, 28, 38, 9,
+ 34, 82, 74, 23, 69, 72, 34, 92, 91, 2, 74, 126, 126, 126, 18, 3,
+ 68, 74, 23, 69, 77, 11, 35, 65, 3, 64, 1, 105, 109, 94, 111, 65,
+ 72, 72, 75, 90, 82, 98, 1, 68, 69, 66, 31, 1, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 12, 64, 75, 29, 16, 4, 44, 42, 5, 16,
+ 16, 23, 7, 7, 31, 108, 88, 89, 90, 24, 71, 16, 31, 66, 75, 1,
+ 13, 65, 73, 72, 81, 23, 75, 13, 64, 75, 6, 69, 64, 7, 12, 15,
+ 18, 7, 78, 67, 3, 65, 0, 71, 30, 66, 1, 30, 27, 37, 30, 26,
+ 96, 9, 9, 75, 67, 77, 69, 30, 1, 4, 34, 53, 62, 62, 44, 98,
+ 106, 10, 41, 42, 124, 72, 12, 97, 23, 69, 3, 34, 33, 54, 48, 43,
+ 107, 65, 80, 94, 94, 70, 14, 21, 12, 6, 12, 11, 4, 16, 10, 76,
+ 69, 6, 1, 0, 75, 64, 72, 77, 65, 66, 1, 70, 72, 106, 73, 75,
+ 69, 84, 83, 71, 4, 68, 71, 69, 73, 89, 75, 65, 104, 121, 94, 102,
+ 96, 126, 85, 79, 113, 64, 74, 74, 81, 85, 96, 91, 85, 103, 93, 91,
+ 95, 104, 65, 10, 38, 25, 10, 4, 14, 8, 3, 0, 11, 17, 42, 27,
+ 21, 12, 32, 16, 18, 4, 31, 7, 36, 23, 18, 11, 24, 10, 4, 2,
+ 2, 68, 51, 29, 11, 3, 19, 4, 70, 65, 16, 41, 35, 21, 10, 31,
+ 13, 11, 4, 2, 62, 70, 1, 8, 6, 65, 5, 10, 13, 12, 17, 23,
+ 34, 68, 0, 73, 72, 62, 79, 100, 73, 3, 3, 71, 71, 70, 74, 0,
+ 76, 95, 69, 68, 22, 70, 77, 69, 68, 65, 72, 71, 70, 89, 82, 72,
+ 75, 70, 24, 100, 76, 24, 83, 68, 69, 70, 5, 66, 71, 3, 10, 71,
+ 71, 106, 33, 31, 32, 15, 64, 65, 66, 76, 67, 77, 82, 76, 94, 91,
+ 93, 101, 97, 108, 126, 95, 87, 86, 88, 100, 93, 89, 91, 92, 79, 76,
+ 80, 77, 83, 102, 89, 86, 109, 95, 107, 107, 125, 120, 116, 115, 77, 74,
+ 116, 84, 85, 91, 108, 97, 98, 101, 90, 95, 85, 82, 106, 112, 125, 86,
+ 98, 104, 70, 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, 35,
+ 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, 16, 44, 40, 43, 33, 35,
+ 21, 20, 11, 10, 70, 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31,
+ 40, 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, 75, 70, 64, 12,
+ 12, 18, 47},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 92, 65, 27, 39, 9,
+ 35, 84, 74, 24, 70, 72, 35, 93, 92, 1, 76, 126, 126, 126, 20, 4,
+ 68, 74, 24, 70, 77, 12, 35, 65, 3, 0, 3, 106, 110, 94, 111, 65,
+ 71, 71, 76, 90, 82, 98, 1, 68, 69, 65, 32, 1, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 11, 64, 74, 31, 17, 5, 45, 43, 6, 17,
+ 18, 24, 8, 8, 34, 108, 89, 89, 91, 24, 71, 17, 34, 65, 75, 1,
+ 15, 65, 73, 72, 81, 23, 75, 13, 0, 75, 7, 68, 64, 7, 12, 16,
+ 18, 7, 79, 67, 3, 65, 0, 71, 30, 66, 1, 31, 27, 37, 30, 26,
+ 97, 9, 9, 75, 67, 76, 69, 31, 2, 4, 36, 55, 62, 62, 46, 98,
+ 107, 10, 42, 42, 125, 72, 13, 98, 24, 69, 3, 35, 33, 54, 48, 45,
+ 108, 0, 81, 97, 97, 69, 14, 21, 11, 6, 11, 11, 3, 16, 9, 77,
+ 70, 6, 1, 0, 75, 65, 72, 78, 66, 66, 1, 71, 72, 107, 74, 76,
+ 69, 85, 84, 73, 2, 70, 73, 70, 75, 92, 78, 66, 106, 123, 96, 104,
+ 98, 126, 86, 80, 114, 65, 75, 75, 83, 86, 98, 93, 86, 105, 93, 92,
+ 96, 106, 64, 11, 39, 25, 10, 4, 15, 9, 4, 0, 13, 19, 43, 28,
+ 21, 13, 34, 17, 20, 5, 34, 8, 36, 23, 18, 12, 25, 11, 4, 3,
+ 3, 68, 52, 30, 11, 3, 20, 4, 70, 64, 17, 41, 36, 21, 10, 32,
+ 14, 12, 4, 3, 62, 69, 2, 9, 7, 64, 7, 11, 15, 13, 19, 25,
+ 37, 67, 1, 72, 71, 62, 78, 101, 72, 4, 4, 71, 71, 70, 74, 1,
+ 77, 96, 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, 90, 83, 73,
+ 75, 70, 25, 101, 77, 25, 83, 69, 69, 70, 5, 67, 72, 3, 10, 71,
+ 71, 107, 32, 30, 31, 14, 67, 67, 69, 79, 70, 80, 85, 79, 97, 93,
+ 95, 105, 101, 112, 126, 98, 89, 88, 90, 103, 95, 90, 92, 93, 79, 78,
+ 83, 80, 85, 104, 91, 88, 111, 97, 109, 109, 126, 122, 117, 117, 78, 75,
+ 118, 86, 86, 93, 110, 98, 99, 102, 91, 96, 85, 81, 108, 113, 126, 88,
+ 99, 105, 70, 10, 15, 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35,
+ 24, 42, 68, 77, 85, 93, 93, 120, 119, 116, 16, 45, 40, 43, 34, 36,
+ 21, 20, 11, 11, 70, 10, 15, 18, 36, 24, 29, 7, 33, 28, 38, 31,
+ 41, 35, 24, 42, 68, 77, 85, 93, 93, 120, 119, 116, 75, 70, 64, 12,
+ 12, 20, 49},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 93, 67, 26, 39, 10,
+ 37, 85, 74, 26, 70, 73, 36, 94, 93, 0, 77, 126, 126, 126, 22, 6,
+ 68, 74, 26, 70, 76, 13, 36, 65, 4, 1, 4, 108, 111, 94, 112, 65,
+ 71, 71, 76, 91, 81, 98, 0, 68, 69, 64, 32, 1, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 11, 0, 73, 33, 18, 6, 47, 45, 7, 18,
+ 20, 25, 9, 8, 36, 109, 89, 89, 91, 25, 71, 18, 36, 65, 74, 2,
+ 17, 65, 73, 72, 81, 24, 76, 14, 0, 75, 8, 68, 0, 7, 13, 17,
+ 19, 7, 79, 67, 3, 65, 0, 71, 30, 66, 1, 31, 27, 38, 31, 27,
+ 97, 10, 10, 76, 67, 76, 69, 32, 2, 5, 37, 56, 62, 62, 47, 99,
+ 108, 11, 42, 42, 125, 73, 13, 98, 24, 70, 4, 36, 33, 54, 49, 46,
+ 109, 1, 82, 100, 100, 67, 14, 21, 11, 5, 11, 10, 3, 15, 9, 77,
+ 70, 6, 0, 0, 76, 65, 73, 79, 66, 66, 1, 71, 73, 109, 74, 77,
+ 69, 86, 84, 76, 0, 72, 74, 72, 77, 95, 80, 68, 108, 125, 97, 106,
+ 100, 126, 87, 82, 116, 67, 76, 76, 84, 88, 100, 95, 88, 106, 93, 93,
+ 97, 107, 1, 13, 41, 26, 10, 4, 16, 9, 4, 1, 14, 20, 44, 29,
+ 22, 13, 35, 18, 21, 6, 36, 8, 37, 24, 19, 12, 26, 11, 5, 4,
+ 4, 68, 54, 31, 11, 3, 20, 5, 70, 64, 17, 42, 36, 22, 10, 33,
+ 14, 12, 5, 3, 62, 67, 4, 11, 9, 1, 8, 13, 16, 15, 21, 27,
+ 39, 67, 2, 72, 71, 62, 78, 102, 72, 4, 5, 71, 71, 70, 74, 1,
+ 77, 97, 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, 91, 84, 73,
+ 75, 70, 26, 102, 77, 26, 84, 69, 69, 70, 6, 67, 72, 4, 11, 71,
+ 71, 109, 31, 29, 30, 12, 69, 70, 71, 82, 72, 83, 88, 82, 100, 96,
+ 97, 108, 104, 116, 126, 100, 92, 90, 92, 105, 97, 91, 93, 94, 79, 80,
+ 85, 82, 87, 106, 92, 89, 113, 99, 112, 111, 126, 124, 119, 118, 79, 77,
+ 120, 87, 88, 94, 112, 100, 101, 103, 92, 97, 86, 80, 109, 115, 126, 89,
+ 101, 106, 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, 42, 36,
+ 25, 41, 70, 79, 87, 95, 95, 122, 121, 117, 17, 45, 41, 44, 34, 37,
+ 22, 21, 12, 11, 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32,
+ 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, 117, 75, 70, 64, 13,
+ 13, 21, 52},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 95, 68, 25, 40, 10,
+ 39, 87, 74, 27, 70, 73, 37, 95, 95, 65, 79, 126, 126, 126, 24, 7,
+ 68, 74, 27, 70, 76, 14, 36, 66, 5, 2, 5, 109, 113, 95, 112, 65,
+ 71, 70, 76, 91, 81, 98, 0, 68, 69, 64, 33, 1, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 10, 0, 72, 35, 19, 7, 48, 46, 7, 19,
+ 22, 26, 10, 9, 38, 110, 89, 89, 91, 25, 72, 19, 38, 65, 73, 3,
+ 19, 65, 73, 72, 81, 24, 76, 14, 1, 75, 8, 68, 0, 7, 13, 18,
+ 19, 7, 79, 68, 3, 65, 0, 71, 30, 66, 1, 32, 27, 38, 31, 27,
+ 98, 10, 11, 76, 67, 76, 69, 33, 2, 5, 38, 57, 62, 62, 49, 99,
+ 109, 11, 42, 42, 126, 73, 14, 99, 25, 70, 4, 37, 33, 54, 49, 47,
+ 110, 3, 83, 103, 103, 66, 13, 21, 10, 4, 10, 10, 2, 15, 8, 78,
+ 71, 5, 0, 0, 76, 66, 74, 80, 67, 67, 0, 72, 73, 110, 75, 78,
+ 69, 88, 85, 78, 65, 74, 76, 74, 79, 99, 83, 69, 110, 126, 99, 108,
+ 102, 126, 89, 83, 118, 68, 77, 77, 85, 89, 102, 97, 90, 108, 93, 94,
+ 98, 109, 2, 14, 42, 26, 10, 4, 17, 10, 5, 2, 16, 21, 45, 29,
+ 23, 14, 36, 19, 23, 7, 38, 9, 37, 24, 19, 13, 27, 12, 5, 4,
+ 5, 68, 55, 32, 11, 3, 21, 5, 70, 0, 18, 42, 37, 22, 10, 34,
+ 15, 13, 5, 4, 62, 66, 5, 12, 11, 2, 10, 14, 18, 16, 22, 29,
+ 41, 66, 3, 71, 70, 62, 78, 103, 72, 5, 5, 71, 71, 70, 75, 2,
+ 77, 98, 69, 68, 24, 70, 77, 69, 68, 64, 74, 72, 70, 92, 85, 73,
+ 75, 70, 27, 103, 77, 26, 85, 69, 69, 70, 6, 67, 73, 4, 12, 71,
+ 71, 110, 30, 28, 29, 10, 71, 72, 74, 85, 75, 86, 92, 85, 104, 99,
+ 99, 112, 108, 120, 126, 103, 94, 92, 94, 108, 99, 93, 94, 95, 79, 83,
+ 87, 84, 89, 108, 94, 91, 115, 101, 114, 113, 126, 126, 121, 119, 80, 78,
+ 123, 89, 90, 96, 114, 101, 102, 104, 93, 98, 86, 79, 110, 116, 126, 90,
+ 102, 107, 69, 11, 16, 19, 38, 25, 31, 7, 35, 30, 40, 32, 43, 36,
+ 26, 41, 72, 81, 89, 97, 97, 124, 123, 119, 17, 46, 41, 45, 35, 37,
+ 22, 21, 12, 12, 69, 11, 16, 19, 38, 25, 31, 7, 35, 30, 40, 32,
+ 43, 36, 26, 41, 72, 81, 89, 97, 97, 124, 123, 119, 75, 70, 64, 13,
+ 13, 23, 54},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 70, 24, 41, 10,
+ 40, 89, 73, 29, 71, 73, 38, 96, 96, 66, 81, 126, 126, 126, 26, 8,
+ 68, 73, 29, 71, 76, 15, 36, 66, 5, 3, 7, 110, 114, 95, 112, 65,
+ 70, 69, 77, 91, 81, 98, 0, 67, 69, 0, 33, 1, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 10, 1, 70, 38, 20, 8, 50, 48, 8, 20,
+ 24, 27, 11, 10, 41, 110, 90, 89, 92, 25, 72, 20, 41, 64, 73, 3,
+ 21, 65, 73, 72, 80, 24, 76, 15, 2, 74, 9, 67, 0, 8, 14, 19,
+ 20, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 32, 28, 38, 31, 27,
+ 98, 11, 11, 77, 67, 75, 69, 34, 3, 6, 40, 59, 62, 62, 51, 100,
+ 110, 12, 43, 42, 126, 73, 14, 99, 26, 70, 4, 39, 33, 54, 49, 49,
+ 111, 4, 84, 105, 106, 65, 13, 21, 10, 4, 10, 10, 2, 15, 8, 79,
+ 72, 5, 0, 0, 76, 66, 74, 81, 67, 67, 0, 73, 74, 111, 76, 78,
+ 69, 89, 85, 80, 67, 75, 77, 75, 81, 102, 85, 70, 112, 126, 100, 110,
+ 104, 126, 90, 84, 119, 69, 78, 78, 87, 91, 104, 99, 91, 109, 93, 95,
+ 99, 111, 4, 16, 43, 27, 10, 4, 18, 11, 6, 2, 18, 23, 46, 30,
+ 23, 15, 38, 20, 24, 8, 41, 10, 38, 25, 20, 13, 28, 13, 6, 5,
+ 6, 67, 56, 33, 11, 3, 22, 6, 69, 1, 19, 42, 38, 22, 10, 35,
+ 16, 14, 6, 5, 62, 65, 7, 14, 12, 3, 11, 16, 20, 18, 24, 31,
+ 44, 65, 4, 70, 69, 62, 77, 104, 71, 6, 6, 71, 71, 70, 75, 2,
+ 78, 99, 69, 68, 25, 70, 77, 69, 68, 0, 74, 73, 70, 93, 86, 74,
+ 75, 70, 28, 103, 78, 27, 85, 70, 69, 70, 6, 68, 73, 4, 12, 71,
+ 71, 112, 29, 27, 28, 9, 74, 75, 77, 88, 77, 89, 95, 88, 107, 101,
+ 101, 116, 111, 124, 126, 106, 96, 93, 96, 110, 101, 94, 95, 96, 79, 85,
+ 90, 87, 91, 110, 96, 92, 117, 103, 116, 115, 126, 126, 122, 121, 81, 79,
+ 125, 90, 91, 97, 116, 102, 103, 105, 94, 99, 86, 78, 112, 117, 126, 92,
+ 103, 108, 69, 12, 17, 20, 39, 26, 31, 8, 36, 31, 41, 33, 44, 37,
+ 26, 40, 74, 83, 91, 99, 99, 126, 125, 120, 18, 46, 42, 45, 36, 38,
+ 23, 22, 12, 13, 69, 12, 17, 20, 39, 26, 31, 8, 36, 31, 41, 33,
+ 44, 37, 26, 40, 74, 83, 91, 99, 99, 126, 125, 120, 75, 70, 64, 13,
+ 13, 24, 56},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 71, 23, 41, 10,
+ 42, 90, 73, 30, 71, 74, 39, 97, 97, 67, 83, 126, 126, 126, 28, 10,
+ 68, 73, 30, 71, 75, 16, 37, 66, 6, 4, 8, 111, 115, 95, 113, 65,
+ 70, 68, 77, 92, 81, 98, 0, 67, 69, 1, 34, 1, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 9, 1, 69, 40, 21, 9, 51, 49, 9, 21,
+ 26, 28, 12, 11, 43, 111, 90, 89, 92, 26, 72, 21, 43, 64, 72, 4,
+ 23, 65, 73, 72, 80, 25, 76, 15, 3, 74, 10, 67, 0, 8, 14, 20,
+ 20, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 99, 11, 12, 77, 67, 75, 69, 35, 3, 6, 41, 60, 62, 62, 53, 100,
+ 111, 12, 43, 42, 126, 73, 15, 100, 26, 70, 4, 40, 33, 54, 49, 50,
+ 112, 6, 85, 108, 109, 0, 13, 21, 9, 3, 9, 9, 1, 15, 7, 80,
+ 73, 5, 0, 0, 77, 67, 75, 82, 68, 67, 0, 74, 74, 112, 76, 79,
+ 69, 90, 86, 82, 69, 77, 79, 77, 83, 105, 88, 71, 114, 126, 102, 112,
+ 106, 126, 91, 85, 121, 70, 79, 79, 88, 92, 106, 101, 93, 111, 93, 96,
+ 100, 112, 5, 17, 45, 27, 10, 4, 19, 12, 7, 3, 20, 24, 47, 31,
+ 24, 15, 39, 21, 26, 9, 43, 10, 38, 25, 20, 14, 29, 13, 6, 6,
+ 7, 67, 58, 34, 11, 3, 23, 6, 69, 2, 20, 43, 39, 23, 10, 36,
+ 16, 15, 6, 5, 62, 0, 8, 15, 14, 4, 13, 17, 21, 19, 26, 33,
+ 46, 65, 5, 70, 68, 62, 77, 105, 71, 7, 7, 71, 71, 70, 75, 3,
+ 78, 100, 69, 68, 25, 70, 77, 69, 68, 0, 75, 73, 70, 94, 87, 74,
+ 75, 70, 29, 104, 78, 28, 86, 70, 69, 70, 7, 68, 74, 5, 13, 71,
+ 71, 113, 28, 26, 27, 7, 76, 77, 79, 91, 80, 92, 98, 91, 110, 104,
+ 103, 120, 115, 126, 126, 109, 98, 95, 98, 113, 103, 95, 96, 97, 79, 87,
+ 92, 89, 93, 112, 98, 94, 119, 105, 118, 117, 126, 126, 124, 122, 82, 80,
+ 126, 92, 93, 99, 118, 104, 105, 106, 95, 100, 86, 77, 113, 119, 126, 93,
+ 104, 109, 69, 12, 17, 20, 40, 27, 32, 8, 37, 32, 42, 33, 45, 37,
+ 27, 40, 76, 85, 93, 101, 101, 126, 126, 121, 18, 47, 42, 46, 36, 39,
+ 23, 22, 13, 13, 69, 12, 17, 20, 40, 27, 32, 8, 37, 32, 42, 33,
+ 45, 37, 27, 40, 76, 85, 93, 101, 101, 126, 126, 121, 75, 70, 64, 14,
+ 14, 26, 58},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 101, 73, 22, 42, 10,
+ 44, 92, 73, 32, 71, 74, 40, 98, 98, 68, 85, 126, 126, 126, 30, 11,
+ 68, 73, 32, 71, 75, 17, 37, 66, 7, 5, 9, 112, 116, 95, 113, 65,
+ 70, 67, 77, 92, 81, 98, 0, 67, 69, 2, 34, 1, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 9, 2, 68, 42, 22, 10, 53, 51, 10, 22,
+ 28, 29, 13, 12, 45, 112, 90, 89, 92, 26, 72, 22, 45, 64, 71, 5,
+ 25, 65, 73, 72, 80, 25, 76, 16, 4, 74, 11, 67, 0, 8, 15, 21,
+ 21, 7, 80, 68, 4, 65, 0, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 99, 12, 13, 78, 67, 75, 69, 36, 3, 7, 42, 61, 62, 62, 55, 101,
+ 112, 13, 43, 42, 126, 73, 15, 100, 27, 70, 4, 41, 33, 54, 49, 51,
+ 113, 7, 86, 111, 112, 1, 13, 21, 9, 2, 9, 9, 1, 15, 7, 81,
+ 74, 5, 0, 0, 77, 67, 76, 83, 68, 67, 0, 75, 75, 113, 77, 80,
+ 69, 91, 86, 84, 71, 79, 80, 79, 85, 108, 90, 72, 116, 126, 103, 114,
+ 108, 126, 92, 86, 123, 71, 80, 80, 89, 94, 108, 103, 95, 112, 93, 97,
+ 101, 114, 7, 19, 46, 28, 10, 4, 20, 13, 8, 4, 22, 25, 48, 32,
+ 25, 16, 40, 22, 27, 10, 45, 11, 39, 26, 21, 14, 30, 14, 7, 7,
+ 8, 67, 59, 35, 11, 3, 24, 7, 69, 3, 21, 43, 40, 23, 10, 37,
+ 17, 16, 7, 6, 62, 1, 10, 17, 16, 5, 14, 19, 23, 21, 28, 35,
+ 48, 64, 6, 69, 67, 62, 77, 106, 71, 8, 8, 71, 71, 70, 75, 3,
+ 78, 101, 69, 68, 26, 70, 77, 69, 68, 0, 75, 73, 70, 95, 88, 74,
+ 75, 70, 30, 105, 78, 29, 87, 70, 69, 70, 7, 68, 74, 5, 14, 71,
+ 71, 115, 27, 25, 26, 5, 78, 80, 82, 94, 82, 95, 101, 94, 113, 107,
+ 105, 124, 118, 126, 126, 112, 100, 97, 100, 115, 105, 96, 97, 98, 79, 89,
+ 94, 91, 95, 114, 100, 95, 121, 107, 120, 119, 126, 126, 126, 123, 83, 81,
+ 126, 93, 95, 100, 120, 105, 106, 107, 96, 101, 86, 76, 114, 120, 126, 94,
+ 105, 110, 69, 13, 18, 21, 41, 28, 33, 8, 38, 33, 43, 34, 46, 38,
+ 28, 39, 78, 87, 95, 103, 103, 126, 126, 122, 19, 47, 43, 47, 37, 40,
+ 24, 23, 13, 14, 69, 13, 18, 21, 41, 28, 33, 8, 38, 33, 43, 34,
+ 46, 38, 28, 39, 78, 87, 95, 103, 103, 126, 126, 122, 75, 70, 64, 14,
+ 14, 27, 60},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 103, 75, 21, 42, 10,
+ 45, 94, 73, 33, 72, 75, 41, 99, 100, 70, 87, 126, 126, 126, 32, 12,
+ 68, 73, 33, 72, 75, 17, 37, 67, 7, 5, 10, 114, 118, 96, 114, 66,
+ 70, 67, 78, 93, 81, 98, 64, 67, 69, 2, 34, 0, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 8, 2, 67, 44, 23, 10, 54, 52, 10, 23,
+ 29, 29, 14, 12, 47, 113, 91, 90, 93, 26, 73, 22, 47, 64, 71, 5,
+ 26, 65, 73, 72, 80, 25, 77, 16, 4, 74, 11, 67, 0, 8, 15, 22,
+ 21, 7, 81, 69, 4, 65, 64, 71, 31, 66, 1, 33, 28, 39, 31, 28,
+ 100, 12, 13, 79, 67, 75, 70, 36, 3, 7, 43, 62, 62, 62, 56, 102,
+ 114, 13, 43, 42, 126, 74, 15, 101, 27, 71, 4, 42, 33, 53, 49, 52,
+ 114, 8, 88, 114, 116, 2, 12, 21, 8, 1, 8, 8, 0, 14, 6, 82,
+ 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, 76, 76, 115, 78, 81,
+ 69, 93, 87, 87, 74, 81, 82, 81, 88, 112, 93, 74, 118, 126, 105, 117,
+ 110, 126, 94, 88, 125, 73, 81, 81, 91, 96, 110, 105, 97, 114, 93, 98,
+ 102, 116, 8, 20, 47, 28, 10, 4, 20, 13, 8, 4, 23, 26, 48, 32,
+ 25, 16, 41, 23, 28, 10, 47, 11, 39, 26, 21, 14, 30, 14, 7, 7,
+ 9, 67, 60, 36, 11, 2, 24, 7, 69, 3, 21, 43, 40, 23, 10, 38,
+ 17, 16, 7, 6, 62, 2, 11, 18, 17, 6, 15, 20, 24, 22, 29, 36,
+ 50, 64, 6, 69, 67, 62, 77, 108, 71, 8, 8, 71, 71, 70, 76, 3,
+ 79, 102, 70, 68, 26, 71, 77, 70, 68, 0, 76, 74, 71, 96, 89, 75,
+ 76, 70, 31, 106, 79, 29, 88, 71, 69, 71, 7, 69, 75, 5, 14, 71,
+ 71, 117, 25, 24, 24, 3, 81, 83, 85, 97, 85, 98, 105, 97, 117, 110,
+ 107, 126, 122, 126, 126, 115, 103, 99, 103, 118, 107, 98, 99, 99, 79, 92,
+ 97, 94, 97, 117, 102, 97, 124, 109, 123, 121, 126, 126, 126, 125, 85, 83,
+ 126, 95, 97, 102, 122, 107, 108, 108, 97, 102, 87, 75, 116, 122, 126, 96,
+ 107, 112, 69, 13, 18, 21, 42, 28, 33, 8, 39, 33, 44, 34, 46, 38,
+ 28, 38, 80, 89, 98, 106, 105, 126, 126, 124, 19, 47, 43, 47, 37, 40,
+ 24, 23, 13, 14, 69, 13, 18, 21, 42, 28, 33, 8, 39, 33, 44, 34,
+ 46, 38, 28, 38, 80, 89, 98, 106, 105, 126, 126, 124, 75, 71, 65, 14,
+ 14, 28, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 104, 76, 21, 43, 11,
+ 47, 95, 72, 35, 72, 75, 43, 99, 101, 71, 88, 126, 126, 126, 34, 14,
+ 67, 72, 35, 72, 74, 18, 38, 67, 8, 6, 12, 115, 119, 96, 114, 66,
+ 69, 66, 78, 93, 80, 97, 64, 66, 68, 3, 35, 0, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 8, 3, 65, 47, 25, 11, 56, 54, 11, 25,
+ 31, 30, 16, 13, 50, 113, 91, 90, 93, 27, 73, 23, 50, 0, 70, 6,
+ 28, 65, 72, 72, 79, 26, 77, 17, 5, 73, 12, 66, 1, 9, 16, 23,
+ 22, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29,
+ 100, 13, 14, 79, 67, 74, 70, 37, 4, 8, 45, 62, 62, 62, 58, 102,
+ 115, 14, 44, 43, 126, 74, 16, 101, 28, 71, 5, 44, 33, 53, 50, 54,
+ 115, 10, 89, 116, 119, 4, 12, 21, 8, 1, 8, 8, 0, 14, 6, 82,
+ 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, 76, 76, 116, 78, 81,
+ 69, 94, 87, 89, 76, 82, 83, 82, 90, 115, 95, 75, 119, 126, 106, 119,
+ 111, 126, 95, 89, 126, 74, 81, 81, 92, 97, 111, 106, 98, 115, 93, 98,
+ 102, 117, 10, 22, 49, 29, 10, 4, 21, 14, 9, 5, 25, 28, 49, 33,
+ 26, 17, 43, 24, 30, 11, 50, 12, 40, 27, 22, 15, 31, 15, 8, 8,
+ 11, 66, 62, 37, 12, 2, 25, 8, 68, 4, 22, 44, 41, 24, 11, 39,
+ 18, 17, 8, 7, 62, 4, 13, 20, 19, 8, 17, 22, 26, 24, 31, 38,
+ 53, 0, 7, 68, 66, 62, 76, 109, 70, 9, 9, 70, 71, 69, 76, 4,
+ 79, 102, 70, 68, 27, 71, 77, 70, 68, 1, 76, 74, 71, 96, 89, 75,
+ 76, 69, 33, 106, 79, 30, 88, 71, 69, 71, 8, 69, 75, 6, 15, 70,
+ 70, 118, 24, 23, 23, 2, 83, 85, 87, 100, 87, 100, 108, 99, 120, 112,
+ 109, 126, 125, 126, 126, 117, 105, 100, 105, 120, 108, 99, 100, 99, 79, 94,
+ 99, 96, 99, 119, 103, 98, 126, 110, 125, 122, 126, 126, 126, 126, 86, 84,
+ 126, 96, 98, 103, 123, 108, 109, 109, 97, 102, 87, 74, 117, 123, 126, 97,
+ 108, 113, 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, 47, 39,
+ 29, 38, 81, 90, 100, 108, 106, 126, 126, 125, 20, 48, 44, 48, 38, 41,
+ 25, 24, 14, 15, 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35,
+ 47, 39, 29, 38, 81, 90, 100, 108, 106, 126, 126, 125, 75, 71, 65, 15,
+ 15, 30, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 106, 78, 20, 44, 11,
+ 49, 97, 72, 36, 72, 75, 44, 100, 102, 72, 90, 126, 126, 126, 36, 15,
+ 67, 72, 36, 72, 74, 19, 38, 67, 9, 7, 13, 116, 120, 96, 114, 66,
+ 69, 65, 78, 93, 80, 97, 64, 66, 68, 4, 35, 0, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 8, 4, 64, 49, 26, 12, 58, 56, 12, 26,
+ 33, 31, 17, 14, 52, 114, 91, 90, 93, 27, 73, 24, 52, 0, 69, 7,
+ 30, 65, 72, 72, 79, 26, 77, 17, 6, 73, 13, 66, 1, 9, 16, 24,
+ 23, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29,
+ 101, 14, 15, 80, 67, 74, 70, 38, 4, 8, 46, 62, 62, 62, 60, 103,
+ 116, 14, 44, 43, 126, 74, 16, 102, 29, 71, 5, 45, 33, 53, 50, 55,
+ 116, 11, 90, 119, 122, 5, 12, 21, 8, 0, 7, 8, 0, 14, 5, 83,
+ 76, 4, 64, 64, 78, 69, 78, 85, 69, 68, 64, 77, 77, 117, 79, 82,
+ 69, 95, 88, 91, 78, 84, 85, 84, 92, 118, 97, 76, 121, 126, 108, 121,
+ 113, 126, 96, 90, 126, 75, 82, 82, 93, 99, 113, 108, 100, 117, 93, 99,
+ 103, 119, 11, 23, 50, 30, 10, 4, 22, 15, 10, 6, 27, 29, 50, 34,
+ 27, 18, 44, 25, 31, 12, 52, 13, 40, 27, 22, 15, 32, 16, 9, 9,
+ 12, 66, 62, 38, 12, 2, 26, 9, 68, 5, 23, 44, 42, 24, 11, 40,
+ 19, 18, 9, 8, 62, 5, 15, 22, 21, 9, 18, 24, 28, 25, 33, 40,
+ 55, 1, 8, 67, 65, 62, 76, 110, 70, 10, 10, 70, 71, 69, 76, 4,
+ 79, 103, 70, 68, 28, 71, 77, 70, 68, 1, 76, 74, 71, 97, 90, 75,
+ 76, 69, 34, 107, 79, 31, 89, 71, 69, 71, 8, 69, 75, 6, 16, 70,
+ 70, 120, 23, 22, 22, 0, 85, 88, 90, 103, 89, 103, 111, 102, 123, 115,
+ 111, 126, 126, 126, 126, 120, 107, 102, 107, 122, 110, 100, 101, 100, 79, 96,
+ 101, 98, 101, 121, 105, 100, 126, 112, 126, 124, 126, 126, 126, 126, 87, 85,
+ 126, 98, 100, 105, 125, 109, 110, 110, 98, 103, 87, 73, 118, 124, 126, 98,
+ 109, 114, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35, 48, 40,
+ 30, 37, 83, 92, 102, 110, 108, 126, 126, 126, 21, 48, 44, 49, 39, 42,
+ 25, 25, 14, 16, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35,
+ 48, 40, 30, 37, 83, 92, 102, 110, 108, 126, 126, 126, 75, 71, 65, 15,
+ 15, 31, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 108, 79, 19, 44, 11,
+ 51, 98, 72, 38, 72, 76, 45, 101, 103, 73, 92, 126, 126, 126, 38, 17,
+ 67, 72, 38, 72, 73, 20, 39, 67, 10, 8, 14, 117, 121, 96, 115, 66,
+ 69, 64, 78, 94, 80, 97, 64, 66, 68, 5, 36, 0, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 7, 4, 0, 51, 27, 13, 59, 57, 13, 27,
+ 35, 32, 18, 15, 54, 115, 91, 90, 93, 28, 73, 25, 54, 0, 68, 8,
+ 32, 65, 72, 72, 79, 27, 77, 18, 7, 73, 14, 66, 1, 9, 17, 25,
+ 23, 8, 81, 69, 5, 64, 64, 70, 32, 65, 1, 35, 29, 41, 32, 30,
+ 101, 14, 16, 80, 67, 74, 70, 39, 4, 9, 47, 62, 62, 62, 62, 103,
+ 117, 15, 44, 43, 126, 74, 17, 102, 29, 71, 5, 46, 33, 53, 50, 56,
+ 117, 13, 91, 122, 125, 7, 12, 21, 7, 64, 7, 7, 64, 14, 5, 84,
+ 77, 4, 64, 64, 79, 69, 79, 86, 70, 68, 64, 78, 77, 118, 79, 83,
+ 69, 96, 88, 93, 80, 86, 86, 86, 94, 121, 100, 77, 123, 126, 109, 123,
+ 115, 126, 97, 91, 126, 76, 83, 83, 94, 100, 115, 110, 102, 118, 93, 100,
+ 104, 120, 13, 25, 52, 30, 10, 4, 23, 16, 11, 7, 29, 30, 51, 35,
+ 28, 18, 45, 26, 33, 13, 54, 13, 41, 28, 23, 16, 33, 16, 9, 10,
+ 13, 66, 62, 39, 12, 2, 27, 9, 68, 6, 24, 45, 43, 25, 11, 41,
+ 19, 19, 9, 8, 62, 7, 16, 23, 23, 10, 20, 25, 29, 27, 35, 42,
+ 57, 1, 9, 67, 64, 62, 76, 111, 70, 11, 11, 70, 71, 69, 76, 5,
+ 79, 104, 70, 68, 28, 71, 77, 70, 68, 1, 77, 74, 71, 98, 91, 75,
+ 76, 69, 35, 108, 79, 32, 90, 71, 69, 71, 9, 69, 76, 7, 17, 70,
+ 70, 121, 22, 21, 21, 65, 87, 90, 92, 106, 92, 106, 114, 105, 126, 118,
+ 113, 126, 126, 126, 126, 123, 109, 104, 109, 125, 112, 101, 102, 101, 79, 98,
+ 103, 100, 103, 123, 107, 101, 126, 114, 126, 126, 126, 126, 126, 126, 88, 86,
+ 126, 99, 102, 106, 126, 111, 112, 111, 99, 104, 87, 72, 119, 126, 126, 99,
+ 110, 115, 68, 15, 20, 23, 46, 31, 36, 9, 43, 36, 47, 36, 49, 40,
+ 31, 37, 85, 94, 104, 112, 110, 126, 126, 126, 21, 49, 45, 50, 39, 43,
+ 26, 25, 15, 16, 68, 15, 20, 23, 46, 31, 36, 9, 43, 36, 47, 36,
+ 49, 40, 31, 37, 85, 94, 104, 112, 110, 126, 126, 126, 75, 71, 65, 16,
+ 16, 33, 62},
+
+ },
+
+ {
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, 54, 14,
+ 118, 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, 67, 90, 104, 126, 104,
+ 67, 78, 65, 1, 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5,
+ 76, 94, 9, 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0,
+ 83, 86, 97, 72, 22, 1, 52, 8, 69, 126, 102, 82, 74, 107, 126, 126,
+ 126, 95, 126, 114, 126, 123, 115, 122, 115, 0, 68, 84, 104, 70, 93, 90,
+ 126, 74, 97, 91, 126, 7, 82, 76, 125, 93, 87, 77, 71, 0, 68, 84,
+ 1, 65, 2, 7, 66, 64, 2, 78, 13, 11, 28, 19, 25, 18, 17, 19,
+ 46, 12, 13, 44, 30, 1, 108, 100, 101, 91, 94, 88, 84, 86, 83, 87,
+ 94, 70, 72, 74, 4, 102, 100, 95, 75, 72, 75, 71, 17, 69, 1, 65,
+ 26, 72, 6, 9, 1, 72, 62, 54, 38, 45, 54, 44, 26, 45, 34, 30,
+ 33, 18, 5, 1, 2, 25, 18, 24, 21, 19, 18, 22, 14, 29, 21, 8,
+ 12, 17, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 62, 46, 62, 60, 41, 62, 62, 62, 62, 60, 58, 62, 47, 41, 15, 26,
+ 3, 68, 97, 71, 21, 13, 9, 1, 5, 0, 72, 74, 91, 67, 36, 24,
+ 19, 17, 64, 68, 78, 77, 86, 92, 8, 3, 1, 65, 73, 76, 80, 88,
+ 110, 97, 84, 79, 73, 74, 86, 96, 97, 117, 78, 30, 15, 10, 1, 71,
+ 79, 86, 90, 97, 62, 93, 84, 79, 66, 71, 1, 3, 4, 75, 1, 5,
+ 66, 79, 71, 68, 19, 1, 27, 23, 36, 34, 19, 27, 31, 21, 15, 1,
+ 17, 64, 104, 97, 96, 88, 85, 85, 85, 88, 66, 77, 76, 76, 5, 76,
+ 83, 99, 95, 95, 76, 74, 70, 75, 68, 65, 73, 1, 1, 68, 75, 8,
+ 64, 70, 57, 44, 47, 49, 50, 52, 48, 47, 40, 40, 43, 37, 19, 23,
+ 16, 46, 42, 41, 36, 34, 28, 13, 6, 0, 77, 82, 94, 69, 109, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 50, 28, 5, 62, 62,
+ 33, 62, 62, 62, 60, 62, 58, 52, 58, 51, 52, 34, 37, 24, 66, 42,
+ 32, 13, 120, 112, 114, 85, 92, 89, 71, 81, 80, 68, 70, 7, 68, 13,
+ 74, 62, 62, 62, 62, 60, 57, 29, 9, 82, 75, 40, 29, 20, 9, 8,
+ 2, 64, 68, 92, 106, 97, 90, 90, 88, 73, 79, 86, 73, 70, 69, 66,
+ 64, 5, 4, 62, 62, 62, 62, 60, 54, 43, 27, 67, 126, 126, 99, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, 62, 54, 14,
+ 115, 6, 77, 64, 1, 14, 72, 12, 65, 20, 62, 68, 91, 104, 124, 102,
+ 67, 77, 64, 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5,
+ 75, 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0,
+ 82, 86, 97, 71, 22, 1, 52, 8, 69, 125, 101, 82, 73, 105, 125, 125,
+ 125, 93, 125, 112, 125, 121, 114, 121, 114, 1, 67, 83, 103, 69, 92, 89,
+ 125, 73, 96, 90, 125, 8, 81, 75, 123, 92, 86, 76, 70, 1, 67, 83,
+ 2, 64, 2, 7, 65, 64, 2, 77, 13, 11, 28, 19, 25, 18, 17, 19,
+ 45, 12, 13, 43, 29, 1, 107, 99, 100, 90, 93, 87, 83, 85, 82, 86,
+ 92, 70, 72, 73, 3, 101, 99, 95, 74, 72, 74, 70, 17, 68, 1, 65,
+ 25, 71, 6, 8, 1, 72, 62, 54, 38, 45, 54, 44, 26, 45, 34, 29,
+ 33, 18, 5, 1, 2, 25, 18, 24, 21, 19, 17, 22, 14, 28, 20, 8,
+ 11, 16, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 60, 44, 62, 59, 40, 62, 62, 62, 62, 58, 56, 61, 45, 39, 15, 25,
+ 2, 68, 97, 70, 22, 14, 10, 2, 5, 0, 71, 73, 90, 66, 37, 25,
+ 20, 17, 0, 67, 77, 76, 85, 91, 9, 4, 2, 64, 72, 75, 79, 87,
+ 108, 96, 82, 78, 72, 73, 85, 95, 96, 115, 77, 31, 16, 11, 2, 70,
+ 78, 85, 89, 96, 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6,
+ 65, 78, 71, 68, 19, 2, 27, 23, 35, 34, 19, 26, 30, 21, 15, 1,
+ 16, 64, 103, 96, 95, 87, 84, 84, 84, 87, 66, 76, 75, 75, 5, 75,
+ 82, 98, 94, 95, 76, 73, 70, 74, 68, 65, 72, 1, 1, 67, 74, 8,
+ 64, 70, 57, 44, 47, 49, 49, 52, 48, 47, 40, 40, 43, 37, 19, 22,
+ 15, 45, 41, 40, 35, 33, 27, 13, 6, 0, 76, 81, 93, 69, 108, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 59, 48, 27, 5, 62, 62,
+ 32, 62, 62, 62, 58, 62, 56, 50, 56, 49, 50, 33, 35, 23, 67, 41,
+ 31, 12, 118, 110, 112, 84, 91, 88, 69, 80, 79, 68, 69, 9, 66, 15,
+ 73, 62, 62, 62, 62, 58, 55, 27, 7, 83, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 91, 105, 96, 89, 89, 86, 72, 78, 85, 72, 69, 68, 65,
+ 0, 6, 4, 62, 62, 62, 62, 59, 53, 41, 26, 67, 126, 126, 98, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, 61, 54, 14,
+ 113, 6, 76, 0, 1, 13, 72, 11, 66, 19, 60, 70, 92, 105, 121, 101,
+ 67, 76, 0, 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5,
+ 75, 92, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, 0,
+ 81, 86, 97, 71, 21, 1, 52, 8, 69, 124, 100, 82, 73, 104, 123, 123,
+ 124, 92, 123, 111, 123, 120, 113, 120, 113, 2, 67, 82, 102, 69, 92, 88,
+ 123, 73, 96, 90, 124, 8, 81, 75, 122, 92, 85, 76, 70, 1, 67, 82,
+ 2, 64, 1, 7, 65, 64, 2, 77, 13, 11, 27, 19, 24, 18, 17, 19,
+ 43, 12, 13, 41, 28, 0, 106, 98, 99, 89, 92, 86, 82, 84, 82, 85,
+ 91, 70, 72, 73, 2, 101, 98, 95, 74, 72, 73, 70, 16, 67, 1, 65,
+ 24, 70, 5, 7, 1, 73, 60, 53, 37, 44, 53, 43, 25, 44, 34, 28,
+ 32, 18, 5, 1, 2, 24, 17, 23, 20, 18, 16, 21, 13, 26, 19, 7,
+ 10, 15, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 58, 41, 62, 57, 38, 62, 62, 62, 62, 56, 54, 58, 43, 37, 14, 23,
+ 1, 69, 97, 70, 22, 14, 10, 2, 5, 0, 71, 73, 89, 66, 37, 25,
+ 20, 17, 1, 67, 76, 76, 84, 90, 10, 5, 2, 64, 71, 75, 79, 86,
+ 107, 95, 81, 77, 72, 73, 84, 94, 95, 114, 77, 31, 16, 11, 2, 69,
+ 77, 84, 88, 95, 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6,
+ 64, 78, 71, 68, 18, 2, 26, 22, 34, 33, 19, 25, 29, 21, 15, 0,
+ 15, 65, 102, 95, 94, 87, 84, 84, 83, 86, 66, 76, 75, 75, 4, 75,
+ 82, 98, 93, 95, 76, 73, 70, 73, 68, 65, 71, 1, 1, 67, 73, 7,
+ 64, 71, 56, 44, 47, 48, 48, 51, 47, 46, 39, 39, 42, 36, 18, 21,
+ 14, 43, 40, 38, 33, 32, 26, 12, 5, 0, 76, 81, 93, 70, 107, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 57, 46, 26, 4, 62, 60,
+ 31, 62, 62, 62, 56, 60, 54, 48, 54, 47, 48, 31, 33, 21, 68, 39,
+ 29, 10, 117, 109, 111, 83, 90, 87, 67, 79, 78, 68, 68, 10, 65, 16,
+ 72, 62, 62, 62, 62, 55, 52, 24, 5, 84, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 90, 104, 95, 88, 88, 85, 71, 77, 84, 71, 68, 67, 65,
+ 1, 6, 4, 62, 62, 62, 61, 57, 51, 39, 24, 68, 126, 126, 97, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, 60, 54, 14,
+ 111, 6, 75, 1, 1, 12, 72, 10, 67, 19, 58, 71, 93, 105, 118, 100,
+ 67, 75, 1, 1, 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5,
+ 75, 92, 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, 0,
+ 81, 86, 97, 70, 20, 1, 52, 8, 69, 123, 99, 82, 72, 103, 121, 121,
+ 122, 91, 121, 110, 121, 119, 112, 119, 112, 3, 67, 81, 101, 69, 91, 88,
+ 121, 73, 95, 89, 123, 8, 81, 74, 120, 91, 84, 76, 70, 1, 67, 81,
+ 3, 0, 1, 7, 65, 64, 2, 77, 13, 10, 27, 19, 23, 18, 17, 19,
+ 41, 12, 12, 39, 27, 64, 105, 97, 98, 88, 91, 86, 81, 84, 81, 84,
+ 90, 70, 72, 73, 1, 100, 97, 95, 74, 72, 72, 70, 15, 66, 1, 65,
+ 23, 69, 5, 6, 1, 74, 59, 52, 37, 43, 52, 42, 25, 43, 33, 27,
+ 31, 18, 5, 1, 1, 23, 16, 22, 19, 17, 15, 20, 13, 24, 18, 7,
+ 9, 14, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+ 55, 39, 62, 55, 37, 62, 61, 62, 59, 54, 51, 56, 41, 34, 13, 21,
+ 0, 70, 97, 70, 23, 14, 10, 2, 5, 0, 71, 73, 89, 66, 37, 25,
+ 20, 17, 2, 66, 76, 75, 84, 89, 11, 5, 3, 64, 70, 74, 78, 86,
+ 106, 94, 80, 76, 71, 73, 83, 93, 94, 113, 76, 31, 16, 11, 2, 68,
+ 77, 83, 87, 94, 62, 91, 82, 77, 66, 70, 1, 4, 5, 74, 2, 6,
+ 64, 78, 71, 68, 18, 3, 25, 21, 33, 32, 19, 24, 28, 21, 15, 0,
+ 14, 65, 101, 94, 93, 86, 83, 83, 83, 85, 66, 76, 75, 74, 4, 75,
+ 82, 97, 92, 95, 76, 73, 70, 72, 68, 65, 70, 1, 1, 67, 72, 6,
+ 64, 72, 55, 43, 46, 47, 47, 50, 46, 45, 38, 38, 41, 35, 17, 20,
+ 13, 42, 39, 37, 31, 30, 25, 11, 5, 64, 76, 81, 93, 70, 106, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 54, 44, 24, 3, 61, 59,
+ 29, 62, 62, 60, 54, 58, 52, 46, 52, 45, 45, 29, 31, 19, 69, 37,
+ 27, 9, 116, 108, 110, 82, 89, 86, 66, 78, 77, 68, 67, 12, 0, 18,
+ 71, 62, 62, 62, 62, 52, 49, 21, 3, 85, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 90, 103, 94, 87, 87, 84, 71, 77, 83, 71, 68, 67, 65,
+ 1, 6, 4, 62, 62, 62, 59, 55, 49, 37, 22, 69, 126, 126, 96, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, 58, 54, 14,
+ 108, 5, 74, 1, 1, 11, 72, 9, 68, 18, 56, 73, 94, 106, 115, 99,
+ 67, 74, 1, 1, 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5,
+ 75, 91, 8, 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0,
+ 80, 87, 97, 70, 19, 1, 52, 8, 69, 122, 98, 82, 72, 101, 120, 119,
+ 121, 90, 120, 108, 119, 118, 112, 118, 112, 3, 67, 80, 100, 69, 91, 87,
+ 119, 73, 95, 89, 122, 8, 80, 74, 119, 91, 84, 76, 69, 1, 67, 81,
+ 3, 0, 0, 6, 65, 64, 2, 77, 13, 10, 26, 19, 23, 18, 17, 18,
+ 39, 12, 12, 37, 26, 65, 104, 96, 97, 87, 91, 85, 80, 83, 81, 83,
+ 89, 70, 72, 72, 0, 100, 96, 95, 74, 72, 72, 70, 14, 65, 1, 65,
+ 21, 68, 4, 5, 1, 75, 57, 51, 36, 42, 51, 41, 24, 42, 33, 25,
+ 30, 17, 5, 1, 1, 22, 16, 21, 19, 16, 14, 19, 12, 22, 17, 6,
+ 8, 13, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59,
+ 53, 36, 62, 54, 35, 62, 59, 62, 57, 51, 49, 53, 39, 32, 12, 20,
+ 65, 71, 97, 70, 23, 15, 10, 2, 5, 0, 71, 73, 88, 65, 38, 25,
+ 20, 17, 3, 66, 75, 75, 83, 89, 12, 6, 3, 64, 70, 74, 78, 85,
+ 105, 94, 79, 76, 71, 73, 82, 92, 94, 112, 76, 32, 16, 11, 2, 67,
+ 76, 83, 86, 93, 62, 91, 82, 77, 66, 70, 1, 4, 5, 73, 2, 6,
+ 0, 78, 71, 68, 17, 3, 24, 20, 32, 31, 19, 22, 27, 20, 15, 64,
+ 13, 66, 101, 94, 92, 86, 83, 83, 82, 84, 67, 76, 75, 74, 3, 75,
+ 82, 97, 91, 95, 76, 72, 70, 72, 68, 65, 69, 1, 0, 67, 71, 6,
+ 65, 73, 54, 43, 46, 46, 46, 49, 45, 44, 37, 37, 40, 34, 16, 19,
+ 12, 40, 37, 35, 29, 29, 24, 10, 4, 64, 76, 81, 93, 71, 106, 62,
+ 62, 62, 62, 62, 62, 62, 62, 62, 60, 55, 52, 42, 23, 2, 59, 57,
+ 28, 62, 62, 58, 52, 55, 50, 44, 50, 43, 43, 27, 29, 17, 70, 35,
+ 25, 7, 115, 107, 109, 82, 88, 85, 64, 77, 76, 68, 66, 13, 1, 19,
+ 71, 62, 62, 62, 62, 49, 46, 18, 1, 86, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 89, 102, 93, 86, 87, 83, 70, 76, 82, 70, 67, 66, 64,
+ 2, 7, 4, 62, 62, 62, 57, 53, 47, 35, 20, 70, 126, 126, 96, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, 57, 54, 14,
+ 106, 5, 73, 2, 1, 11, 71, 8, 69, 18, 54, 75, 95, 106, 112, 97,
+ 67, 73, 2, 1, 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5,
+ 75, 90, 8, 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0,
+ 80, 87, 97, 69, 18, 1, 52, 8, 69, 121, 97, 82, 71, 100, 118, 117,
+ 119, 89, 118, 107, 117, 117, 111, 117, 111, 4, 67, 79, 99, 69, 90, 86,
+ 117, 73, 95, 88, 120, 9, 80, 73, 118, 90, 83, 76, 69, 2, 66, 80,
+ 4, 1, 0, 6, 65, 64, 2, 77, 13, 9, 25, 19, 22, 18, 17, 18,
+ 37, 12, 11, 36, 25, 66, 103, 95, 96, 86, 90, 84, 79, 82, 80, 82,
+ 88, 70, 72, 72, 64, 99, 95, 95, 73, 72, 71, 70, 13, 64, 1, 65,
+ 20, 67, 4, 4, 1, 75, 56, 50, 36, 41, 50, 40, 23, 42, 33, 24,
+ 29, 17, 5, 1, 0, 22, 15, 20, 18, 15, 13, 19, 11, 20, 16, 5,
+ 7, 12, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57,
+ 51, 34, 60, 52, 33, 62, 57, 60, 55, 49, 47, 50, 37, 29, 11, 18,
+ 66, 71, 97, 70, 23, 15, 10, 2, 5, 0, 71, 73, 88, 65, 38, 25,
+ 20, 17, 4, 65, 74, 75, 82, 88, 13, 7, 3, 0, 69, 73, 77, 85,
+ 104, 93, 77, 75, 71, 72, 81, 91, 93, 111, 75, 32, 17, 11, 2, 66,
+ 75, 82, 85, 92, 62, 91, 82, 76, 66, 70, 1, 4, 5, 73, 2, 7,
+ 0, 78, 71, 68, 16, 4, 23, 19, 31, 31, 19, 21, 26, 20, 15, 65,
+ 12, 66, 100, 93, 91, 85, 82, 82, 82, 83, 67, 76, 75, 74, 2, 75,
+ 82, 96, 90, 95, 76, 72, 70, 71, 68, 65, 68, 1, 0, 67, 70, 5,
+ 65, 73, 53, 43, 45, 46, 45, 48, 44, 43, 37, 36, 39, 33, 15, 18,
+ 11, 39, 36, 34, 27, 28, 23, 9, 3, 65, 76, 80, 93, 71, 105, 62,
+ 62, 62, 62, 62, 62, 62, 62, 60, 58, 53, 50, 40, 21, 1, 57, 55,
+ 27, 61, 62, 56, 50, 53, 48, 42, 48, 41, 40, 25, 27, 15, 71, 33,
+ 23, 6, 114, 105, 108, 81, 87, 84, 1, 76, 75, 68, 65, 15, 3, 21,
+ 70, 62, 62, 62, 62, 47, 43, 16, 64, 87, 74, 41, 29, 20, 9, 9,
+ 2, 64, 68, 89, 101, 92, 85, 86, 82, 69, 76, 81, 69, 66, 65, 64,
+ 2, 7, 4, 62, 62, 62, 56, 51, 45, 33, 18, 71, 126, 126, 95, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, 56, 54, 14,
+ 104, 5, 73, 3, 1, 10, 71, 7, 70, 17, 53, 76, 96, 107, 109, 96,
+ 67, 73, 3, 1, 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5,
+ 74, 90, 8, 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0,
+ 79, 87, 97, 69, 18, 0, 52, 8, 69, 120, 97, 82, 71, 99, 116, 115,
+ 118, 88, 116, 106, 115, 116, 110, 116, 110, 5, 67, 78, 99, 68, 90, 86,
+ 115, 73, 94, 88, 119, 9, 80, 73, 116, 90, 82, 75, 69, 2, 66, 79,
+ 4, 1, 64, 6, 65, 64, 2, 77, 13, 9, 25, 19, 21, 18, 17, 18,
+ 35, 12, 11, 34, 24, 67, 103, 94, 96, 86, 89, 84, 78, 82, 80, 82,
+ 86, 70, 72, 72, 65, 99, 94, 95, 73, 72, 70, 69, 12, 64, 1, 65,
+ 19, 66, 3, 3, 1, 76, 54, 49, 35, 41, 49, 40, 23, 41, 32, 23,
+ 28, 17, 5, 1, 0, 21, 14, 19, 17, 15, 12, 18, 11, 18, 15, 5,
+ 6, 11, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 54,
+ 48, 31, 58, 50, 32, 62, 54, 57, 52, 47, 44, 48, 34, 27, 10, 16,
+ 67, 72, 97, 69, 24, 15, 11, 2, 5, 0, 71, 73, 87, 65, 38, 26,
+ 20, 17, 5, 65, 74, 74, 82, 87, 14, 7, 4, 0, 68, 73, 77, 84,
+ 103, 92, 76, 74, 70, 72, 81, 91, 92, 109, 75, 32, 17, 11, 3, 66,
+ 75, 81, 85, 91, 62, 90, 81, 76, 66, 70, 1, 4, 5, 73, 3, 7,
+ 1, 78, 71, 69, 16, 4, 22, 18, 30, 30, 19, 20, 25, 20, 15, 65,
+ 11, 67, 99, 92, 90, 85, 82, 82, 81, 83, 67, 75, 74, 73, 2, 75,
+ 82, 96, 89, 95, 76, 72, 70, 70, 68, 65, 67, 0, 0, 67, 70, 4,
+ 65, 74, 52, 42, 45, 45, 44, 48, 44, 42, 36, 36, 38, 32, 14, 17,
+ 10, 37, 35, 32, 25, 26, 21, 8, 3, 65, 76, 80, 92, 72, 104, 62,
+ 62, 62, 62, 62, 62, 62, 62, 58, 55, 51, 47, 38, 20, 1, 56, 54,
+ 25, 59, 62, 54, 48, 51, 46, 40, 45, 39, 38, 23, 25, 14, 73, 31,
+ 21, 4, 113, 104, 107, 80, 86, 83, 2, 75, 74, 68, 64, 16, 4, 22,
+ 69, 62, 62, 62, 59, 44, 41, 13, 66, 89, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 88, 100, 92, 84, 85, 81, 69, 75, 80, 69, 66, 65, 64,
+ 3, 7, 4, 62, 62, 61, 54, 50, 44, 30, 17, 72, 126, 126, 94, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, 54, 54, 14,
+ 101, 4, 72, 3, 1, 9, 71, 6, 71, 17, 51, 78, 97, 107, 106, 95,
+ 67, 72, 3, 1, 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5,
+ 74, 89, 7, 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0,
+ 79, 87, 97, 68, 17, 0, 52, 8, 69, 119, 96, 82, 70, 97, 115, 113,
+ 116, 87, 115, 104, 113, 115, 109, 115, 110, 6, 67, 77, 98, 68, 89, 85,
+ 113, 73, 94, 87, 118, 9, 79, 72, 115, 89, 82, 75, 68, 2, 66, 78,
+ 5, 2, 64, 5, 65, 64, 2, 77, 13, 8, 24, 19, 21, 18, 17, 17,
+ 33, 12, 10, 32, 23, 68, 102, 93, 95, 85, 88, 83, 77, 81, 79, 81,
+ 85, 70, 72, 71, 66, 98, 93, 95, 73, 72, 70, 69, 11, 0, 1, 65,
+ 17, 65, 3, 2, 1, 77, 53, 48, 35, 40, 48, 39, 22, 40, 32, 22,
+ 27, 17, 5, 1, 64, 20, 14, 18, 17, 14, 11, 17, 10, 16, 14, 4,
+ 5, 10, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 60, 61, 52,
+ 46, 29, 56, 49, 30, 62, 52, 55, 50, 44, 42, 45, 32, 24, 9, 15,
+ 69, 73, 97, 69, 24, 16, 11, 2, 5, 0, 71, 73, 87, 64, 39, 26,
+ 20, 17, 6, 64, 73, 74, 81, 86, 15, 8, 4, 0, 67, 72, 76, 84,
+ 102, 92, 75, 74, 70, 72, 80, 90, 92, 108, 74, 33, 17, 11, 3, 65,
+ 74, 80, 84, 90, 62, 90, 81, 75, 66, 70, 1, 4, 5, 72, 3, 7,
+ 1, 78, 71, 69, 15, 5, 21, 17, 29, 29, 19, 19, 24, 19, 15, 66,
+ 10, 67, 98, 92, 89, 84, 81, 81, 81, 82, 67, 75, 74, 73, 1, 75,
+ 82, 95, 88, 95, 76, 71, 70, 70, 68, 65, 66, 0, 0, 67, 69, 4,
+ 66, 75, 51, 42, 44, 44, 43, 47, 43, 41, 35, 35, 37, 31, 13, 16,
+ 9, 36, 33, 31, 23, 25, 20, 7, 2, 66, 76, 80, 92, 72, 103, 62,
+ 62, 62, 62, 62, 62, 62, 61, 56, 53, 49, 45, 36, 18, 0, 54, 52,
+ 24, 57, 62, 52, 46, 49, 44, 38, 43, 37, 35, 21, 23, 12, 74, 29,
+ 19, 3, 112, 103, 106, 80, 85, 82, 4, 74, 73, 68, 0, 18, 6, 24,
+ 69, 62, 62, 61, 56, 41, 38, 10, 68, 90, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 88, 99, 91, 83, 84, 80, 68, 75, 79, 68, 65, 64, 0,
+ 3, 8, 4, 62, 62, 59, 52, 48, 42, 28, 15, 73, 126, 126, 94, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, 53, 54, 14,
+ 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, 49, 80, 98, 108, 104, 94,
+ 67, 71, 4, 1, 83, 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5,
+ 74, 89, 7, 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0,
+ 78, 88, 97, 68, 16, 0, 52, 8, 69, 118, 95, 82, 70, 96, 113, 111,
+ 115, 86, 113, 103, 112, 114, 109, 114, 109, 6, 67, 76, 97, 68, 89, 85,
+ 112, 73, 94, 87, 117, 9, 79, 72, 114, 89, 81, 75, 68, 2, 66, 78,
+ 5, 2, 65, 5, 65, 64, 2, 77, 13, 8, 23, 19, 20, 18, 17, 17,
+ 31, 12, 10, 30, 22, 69, 101, 92, 94, 84, 88, 83, 76, 81, 79, 80,
+ 84, 70, 72, 71, 68, 98, 92, 95, 73, 73, 69, 69, 10, 1, 1, 65,
+ 16, 64, 2, 1, 1, 78, 51, 47, 34, 39, 47, 38, 21, 39, 31, 20,
+ 26, 16, 5, 1, 64, 19, 13, 17, 16, 13, 10, 16, 9, 14, 12, 3,
+ 4, 9, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 58, 49,
+ 43, 26, 54, 47, 28, 61, 50, 52, 47, 42, 39, 42, 30, 22, 8, 13,
+ 70, 74, 98, 69, 24, 16, 11, 2, 5, 0, 71, 73, 86, 64, 39, 26,
+ 20, 17, 7, 64, 73, 74, 81, 86, 16, 8, 4, 0, 67, 72, 76, 83,
+ 101, 91, 74, 73, 70, 72, 79, 89, 91, 107, 74, 33, 17, 11, 3, 64,
+ 74, 80, 83, 90, 62, 90, 81, 75, 66, 70, 1, 4, 5, 72, 3, 7,
+ 2, 78, 71, 69, 14, 5, 20, 16, 28, 28, 19, 17, 22, 19, 15, 67,
+ 9, 68, 98, 91, 88, 84, 81, 81, 80, 81, 68, 75, 74, 73, 0, 75,
+ 82, 95, 88, 96, 76, 71, 70, 69, 68, 65, 66, 0, 64, 67, 68, 3,
+ 66, 76, 50, 41, 44, 43, 41, 46, 42, 40, 34, 34, 36, 30, 12, 15,
+ 8, 34, 32, 29, 21, 23, 19, 6, 1, 66, 76, 80, 92, 73, 103, 62,
+ 62, 62, 62, 62, 62, 61, 58, 54, 51, 47, 42, 34, 17, 64, 52, 50,
+ 22, 55, 61, 49, 43, 46, 41, 36, 41, 34, 33, 19, 20, 10, 75, 27,
+ 17, 1, 111, 102, 105, 79, 84, 82, 5, 73, 73, 68, 0, 19, 7, 25,
+ 68, 62, 62, 58, 53, 38, 35, 7, 70, 91, 73, 41, 29, 20, 9, 9,
+ 2, 64, 68, 87, 99, 90, 82, 84, 79, 68, 74, 79, 68, 65, 64, 0,
+ 4, 8, 3, 62, 62, 57, 50, 46, 40, 26, 13, 74, 126, 126, 93, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, 52, 54, 14,
+ 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, 47, 81, 99, 109, 101, 92,
+ 67, 70, 5, 1, 82, 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5,
+ 74, 88, 7, 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, 0, 0, 0,
+ 77, 88, 97, 68, 15, 0, 52, 8, 69, 117, 94, 82, 70, 95, 111, 109,
+ 113, 84, 111, 102, 110, 113, 108, 113, 108, 7, 66, 75, 96, 68, 88, 84,
+ 110, 73, 93, 87, 115, 10, 79, 72, 112, 89, 80, 75, 68, 3, 65, 77,
+ 5, 2, 65, 5, 64, 64, 2, 76, 13, 8, 23, 19, 19, 18, 17, 17,
+ 29, 12, 10, 29, 21, 69, 100, 91, 93, 83, 87, 82, 75, 80, 79, 79,
+ 83, 70, 72, 71, 69, 97, 91, 95, 72, 73, 68, 69, 9, 2, 1, 65,
+ 15, 0, 1, 0, 1, 78, 50, 46, 34, 38, 46, 37, 21, 39, 31, 19,
+ 25, 16, 5, 1, 64, 19, 12, 16, 15, 12, 9, 16, 9, 13, 11, 3,
+ 3, 8, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 56, 46,
+ 41, 23, 53, 45, 27, 59, 48, 50, 45, 40, 37, 40, 28, 20, 8, 11,
+ 71, 74, 98, 69, 25, 16, 11, 3, 5, 0, 70, 73, 85, 64, 39, 26,
+ 21, 17, 8, 0, 72, 73, 80, 85, 17, 9, 5, 1, 66, 71, 76, 82,
+ 100, 90, 72, 72, 69, 71, 78, 88, 90, 106, 73, 33, 18, 12, 3, 0,
+ 73, 79, 82, 89, 62, 89, 80, 74, 66, 70, 1, 5, 6, 72, 3, 8,
+ 3, 78, 71, 69, 14, 5, 19, 16, 27, 28, 19, 16, 21, 19, 15, 67,
+ 8, 69, 97, 90, 87, 84, 80, 81, 79, 80, 68, 75, 74, 72, 0, 75,
+ 82, 95, 87, 96, 76, 71, 70, 68, 68, 65, 65, 0, 64, 67, 67, 2,
+ 66, 76, 49, 41, 44, 43, 40, 45, 41, 39, 34, 33, 35, 30, 12, 14,
+ 7, 33, 31, 27, 19, 22, 18, 6, 1, 66, 75, 79, 92, 74, 102, 62,
+ 62, 62, 62, 62, 62, 59, 56, 52, 49, 45, 40, 32, 16, 65, 50, 49,
+ 21, 53, 59, 47, 41, 44, 39, 34, 39, 32, 31, 18, 18, 8, 76, 25,
+ 15, 64, 110, 100, 103, 78, 83, 81, 7, 72, 72, 68, 1, 21, 8, 27,
+ 67, 62, 62, 56, 50, 36, 32, 5, 72, 92, 73, 41, 29, 20, 9, 10,
+ 2, 64, 68, 86, 98, 89, 81, 83, 77, 67, 73, 78, 67, 64, 0, 0,
+ 5, 8, 3, 62, 61, 56, 49, 44, 38, 24, 11, 74, 126, 126, 92, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, 50, 54, 14,
+ 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, 45, 83, 100, 109, 98, 91,
+ 67, 69, 5, 1, 82, 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5,
+ 74, 87, 6, 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0,
+ 77, 88, 97, 67, 14, 0, 52, 8, 69, 116, 93, 82, 69, 93, 110, 107,
+ 112, 83, 110, 100, 108, 112, 107, 112, 108, 8, 66, 74, 95, 68, 88, 83,
+ 108, 73, 93, 86, 114, 10, 78, 71, 111, 88, 80, 75, 67, 3, 65, 76,
+ 6, 3, 66, 4, 64, 64, 2, 76, 13, 7, 22, 19, 19, 18, 17, 16,
+ 27, 12, 9, 27, 20, 70, 99, 90, 92, 82, 86, 81, 74, 79, 78, 78,
+ 82, 70, 72, 70, 70, 97, 90, 95, 72, 73, 68, 69, 8, 3, 1, 65,
+ 13, 1, 1, 64, 1, 79, 48, 45, 33, 37, 45, 36, 20, 38, 31, 18,
+ 24, 16, 5, 1, 65, 18, 12, 15, 15, 11, 8, 15, 8, 11, 10, 2,
+ 2, 7, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 54, 53, 44,
+ 39, 21, 51, 44, 25, 56, 46, 48, 43, 37, 35, 37, 26, 17, 7, 10,
+ 73, 75, 98, 69, 25, 17, 11, 3, 5, 0, 70, 73, 85, 0, 40, 26,
+ 21, 17, 9, 0, 71, 73, 79, 84, 18, 10, 5, 1, 65, 71, 75, 82,
+ 99, 90, 71, 72, 69, 71, 77, 87, 90, 105, 73, 34, 18, 12, 3, 1,
+ 72, 78, 81, 88, 62, 89, 80, 74, 66, 70, 1, 5, 6, 71, 3, 8,
+ 3, 78, 71, 69, 13, 6, 18, 15, 26, 27, 19, 15, 20, 18, 15, 68,
+ 7, 69, 96, 90, 86, 83, 80, 80, 79, 79, 68, 75, 74, 72, 64, 75,
+ 82, 94, 86, 96, 76, 70, 70, 68, 68, 65, 64, 0, 64, 67, 66, 2,
+ 67, 77, 48, 41, 43, 42, 39, 44, 40, 38, 33, 32, 34, 29, 11, 13,
+ 6, 31, 29, 26, 17, 21, 17, 5, 0, 67, 75, 79, 92, 74, 101, 62,
+ 62, 62, 62, 62, 60, 57, 53, 50, 47, 43, 38, 30, 14, 66, 48, 47,
+ 20, 51, 57, 45, 39, 42, 37, 32, 37, 30, 28, 16, 16, 6, 77, 23,
+ 13, 65, 109, 99, 102, 78, 82, 80, 9, 71, 71, 68, 2, 22, 10, 28,
+ 67, 62, 60, 53, 47, 33, 29, 2, 74, 93, 73, 41, 29, 20, 9, 10,
+ 2, 64, 68, 86, 97, 88, 80, 82, 76, 66, 73, 77, 66, 0, 1, 1,
+ 5, 9, 3, 60, 59, 54, 47, 42, 36, 22, 9, 75, 126, 126, 92, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, 49, 54, 14,
+ 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, 44, 84, 101, 110, 95, 90,
+ 67, 69, 6, 1, 81, 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5,
+ 73, 87, 6, 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0,
+ 76, 88, 97, 67, 14, 64, 52, 8, 69, 115, 93, 82, 69, 92, 108, 105,
+ 110, 82, 108, 99, 106, 111, 106, 111, 107, 9, 66, 73, 95, 67, 87, 83,
+ 106, 73, 92, 86, 113, 10, 78, 71, 109, 88, 79, 74, 67, 3, 65, 75,
+ 6, 3, 66, 4, 64, 64, 2, 76, 13, 7, 22, 19, 18, 18, 17, 16,
+ 25, 12, 9, 25, 19, 71, 99, 89, 92, 82, 85, 81, 73, 79, 78, 78,
+ 80, 70, 72, 70, 71, 96, 89, 95, 72, 73, 67, 68, 7, 3, 1, 65,
+ 12, 2, 0, 65, 1, 80, 47, 44, 33, 37, 44, 36, 20, 37, 30, 17,
+ 23, 16, 5, 1, 65, 17, 11, 14, 14, 11, 7, 14, 8, 9, 9, 2,
+ 1, 6, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, 54, 52, 51, 41,
+ 36, 18, 49, 42, 24, 54, 43, 45, 40, 35, 32, 35, 23, 15, 6, 8,
+ 74, 76, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, 84, 0, 40, 27,
+ 21, 17, 10, 1, 71, 72, 79, 83, 19, 10, 6, 1, 64, 70, 75, 81,
+ 98, 89, 70, 71, 68, 71, 77, 87, 89, 103, 72, 34, 18, 12, 4, 1,
+ 72, 77, 81, 87, 62, 88, 79, 73, 66, 70, 1, 5, 6, 71, 4, 8,
+ 4, 78, 71, 70, 13, 6, 17, 14, 25, 26, 19, 14, 19, 18, 15, 68,
+ 6, 70, 95, 89, 85, 83, 79, 80, 78, 79, 68, 74, 73, 71, 64, 75,
+ 82, 94, 85, 96, 76, 70, 70, 67, 68, 65, 0, 64, 64, 67, 66, 1,
+ 67, 78, 47, 40, 43, 41, 38, 44, 40, 37, 32, 32, 33, 28, 10, 12,
+ 5, 30, 28, 24, 15, 19, 15, 4, 0, 67, 75, 79, 91, 75, 100, 62,
+ 62, 62, 62, 62, 58, 55, 51, 48, 44, 41, 35, 28, 13, 66, 47, 46,
+ 18, 49, 54, 43, 37, 40, 35, 30, 34, 28, 26, 14, 14, 5, 79, 21,
+ 11, 67, 108, 98, 101, 77, 81, 79, 10, 70, 70, 68, 3, 24, 11, 30,
+ 66, 61, 59, 51, 44, 30, 27, 64, 76, 95, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 85, 96, 88, 79, 81, 75, 66, 72, 76, 66, 0, 1, 1,
+ 6, 9, 3, 59, 58, 52, 45, 41, 35, 19, 8, 76, 126, 124, 91, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, 48, 54, 14,
+ 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, 42, 86, 102, 110, 92, 89,
+ 67, 68, 7, 1, 81, 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5,
+ 73, 86, 6, 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, 0, 0, 0,
+ 76, 89, 97, 66, 13, 64, 52, 8, 69, 114, 92, 82, 68, 91, 106, 103,
+ 109, 81, 106, 98, 104, 110, 106, 110, 106, 9, 66, 72, 94, 67, 87, 82,
+ 104, 73, 92, 85, 112, 10, 78, 70, 108, 87, 78, 74, 67, 3, 65, 75,
+ 7, 4, 67, 4, 64, 64, 2, 76, 13, 6, 21, 19, 17, 18, 17, 16,
+ 23, 12, 8, 23, 18, 72, 98, 88, 91, 81, 85, 80, 72, 78, 77, 77,
+ 79, 70, 72, 70, 72, 96, 88, 95, 72, 73, 66, 68, 6, 4, 1, 65,
+ 11, 3, 0, 66, 1, 81, 45, 43, 32, 36, 43, 35, 19, 36, 30, 15,
+ 22, 15, 5, 1, 66, 16, 10, 13, 13, 10, 6, 13, 7, 7, 8, 1,
+ 0, 5, 89, 62, 62, 61, 62, 62, 62, 62, 62, 61, 52, 50, 48, 39,
+ 34, 16, 47, 40, 22, 52, 41, 43, 38, 33, 30, 32, 21, 12, 5, 6,
+ 75, 77, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, 84, 0, 40, 27,
+ 21, 17, 11, 1, 70, 72, 78, 83, 20, 11, 6, 1, 64, 70, 74, 81,
+ 97, 88, 69, 70, 68, 71, 76, 86, 88, 102, 72, 34, 18, 12, 4, 2,
+ 71, 77, 80, 86, 62, 88, 79, 73, 66, 70, 1, 5, 6, 71, 4, 8,
+ 4, 78, 71, 70, 12, 7, 16, 13, 24, 25, 19, 12, 18, 18, 15, 69,
+ 5, 70, 95, 88, 84, 82, 79, 79, 78, 78, 69, 74, 73, 71, 65, 75,
+ 82, 93, 84, 96, 76, 70, 70, 66, 68, 65, 1, 64, 65, 67, 65, 0,
+ 67, 79, 46, 40, 42, 40, 37, 43, 39, 36, 31, 31, 32, 27, 9, 11,
+ 4, 28, 27, 23, 13, 18, 14, 3, 64, 68, 75, 79, 91, 75, 100, 62,
+ 62, 62, 62, 62, 56, 53, 48, 46, 42, 39, 33, 26, 11, 67, 45, 44,
+ 17, 47, 52, 41, 35, 37, 33, 28, 32, 26, 23, 12, 12, 3, 80, 19,
+ 9, 68, 107, 97, 100, 76, 80, 78, 12, 69, 69, 68, 4, 25, 13, 31,
+ 65, 59, 57, 48, 41, 27, 24, 67, 78, 96, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 85, 95, 87, 78, 81, 74, 65, 72, 75, 65, 1, 2, 1,
+ 6, 9, 3, 58, 56, 50, 43, 39, 33, 17, 6, 77, 126, 123, 90, 62,
+ 62, 62, 62},
+
+ {
+
+ 62, 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, 46, 54, 14, 87,
+ 2, 67, 7, 1, 5, 69, 0, 78, 13, 40, 88, 103, 111, 89, 87, 67, 67,
+ 7, 1, 81, 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5,
+ 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, 75, 89, 97, 66,
+ 12, 64, 52, 8, 69, 113, 91, 82, 68, 89, 105, 101, 107, 80, 105, 96, 102,
+ 109, 105, 109, 106, 10, 66, 71, 93, 67, 86, 81, 102, 73, 92, 85, 110, 11,
+ 77, 70, 107, 87, 78, 74, 66, 4, 64, 74, 7, 4, 67, 3, 64, 64, 2,
+ 76, 13, 6, 20, 19, 17, 18, 17, 15, 21, 12, 8, 22, 17, 73, 97, 87,
+ 90, 80, 84, 79, 71, 77, 77, 76, 78, 70, 72, 69, 73, 95, 87, 95, 71,
+ 73, 66, 68, 5, 5, 1, 65, 9, 4, 64, 67, 1, 81, 44, 42, 32, 35,
+ 42, 34, 18, 36, 30, 14, 21, 15, 5, 1, 66, 16, 10, 12, 13, 9, 5,
+ 13, 6, 5, 7, 0, 64, 4, 89, 61, 62, 59, 62, 61, 60, 60, 60, 59,
+ 50, 48, 46, 36, 32, 13, 45, 39, 20, 49, 39, 41, 36, 30, 28, 29, 19,
+ 10, 4, 5, 77, 77, 98, 68, 26, 18, 12, 3, 5, 0, 70, 73, 83, 1,
+ 41, 27, 21, 17, 12, 2, 69, 72, 77, 82, 21, 12, 6, 2, 0, 69, 74,
+ 80, 96, 88, 67, 70, 68, 70, 75, 85, 88, 101, 71, 35, 19, 12, 4, 3,
+ 70, 76, 79, 85, 62, 88, 79, 72, 66, 70, 1, 5, 6, 70, 4, 9, 5,
+ 78, 71, 70, 11, 7, 15, 12, 23, 25, 19, 11, 17, 17, 15, 70, 4, 71,
+ 94, 88, 83, 82, 78, 79, 77, 77, 69, 74, 73, 71, 66, 75, 82, 93, 83,
+ 96, 76, 69, 70, 66, 68, 65, 2, 64, 65, 67, 64, 0, 68, 79, 45, 40,
+ 42, 40, 36, 42, 38, 35, 31, 30, 31, 26, 8, 10, 3, 27, 25, 21, 11,
+ 17, 13, 2, 65, 68, 75, 78, 91, 76, 99, 62, 62, 62, 62, 60, 54, 51,
+ 46, 44, 40, 37, 31, 24, 10, 68, 43, 42, 16, 45, 50, 39, 33, 35, 31,
+ 26, 30, 24, 21, 10, 10, 1, 81, 17, 7, 70, 106, 95, 99, 76, 79, 77,
+ 14, 68, 68, 68, 5, 27, 14, 33, 65, 58, 55, 46, 38, 25, 21, 69, 80,
+ 97, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 94, 86, 77, 80, 73, 64,
+ 71, 74, 64, 2, 3, 2, 7, 10, 3, 56, 55, 49, 42, 37, 31, 15, 4,
+ 78, 126, 122, 90, 62, 62, 62, 62},
+
+ {
+
+ 61, 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, 45, 54, 14, 85,
+ 2, 66, 8, 1, 4, 69, 64, 79, 13, 38, 89, 104, 111, 86, 86, 67, 66,
+ 8, 1, 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5,
+ 72, 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 75, 89, 97, 65,
+ 11, 64, 52, 8, 69, 112, 90, 82, 67, 88, 103, 99, 106, 79, 103, 95, 100,
+ 108, 104, 108, 105, 11, 66, 70, 92, 67, 86, 81, 100, 73, 91, 84, 109, 11,
+ 77, 69, 105, 86, 77, 74, 66, 4, 64, 73, 8, 5, 68, 3, 64, 64, 2,
+ 76, 13, 5, 20, 19, 16, 18, 17, 15, 19, 12, 7, 20, 16, 74, 96, 86,
+ 89, 79, 83, 79, 70, 77, 76, 75, 77, 70, 72, 69, 74, 95, 86, 95, 71,
+ 73, 65, 68, 4, 6, 1, 65, 8, 5, 64, 68, 1, 82, 42, 41, 31, 34,
+ 41, 33, 18, 35, 29, 13, 20, 15, 5, 1, 67, 15, 9, 11, 12, 8, 4,
+ 12, 6, 3, 6, 0, 65, 3, 89, 60, 61, 58, 62, 59, 58, 58, 58, 56,
+ 47, 46, 43, 34, 29, 11, 43, 37, 19, 47, 37, 38, 33, 28, 25, 27, 17,
+ 7, 3, 3, 78, 78, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, 83, 1,
+ 41, 27, 21, 17, 13, 2, 69, 71, 77, 81, 22, 12, 7, 2, 1, 69, 73,
+ 80, 95, 87, 66, 69, 67, 70, 74, 84, 87, 100, 71, 35, 19, 12, 4, 4,
+ 70, 75, 78, 84, 62, 87, 78, 72, 66, 70, 1, 5, 6, 70, 4, 9, 5,
+ 78, 71, 70, 11, 8, 14, 11, 22, 24, 19, 10, 16, 17, 15, 70, 3, 71,
+ 93, 87, 82, 81, 78, 78, 77, 76, 69, 74, 73, 70, 66, 75, 82, 92, 82,
+ 96, 76, 69, 70, 65, 68, 65, 3, 64, 65, 67, 0, 64, 68, 80, 44, 39,
+ 41, 39, 35, 41, 37, 34, 30, 29, 30, 25, 7, 9, 2, 25, 24, 20, 9,
+ 15, 12, 1, 65, 69, 75, 78, 91, 76, 98, 62, 62, 61, 61, 57, 52, 49,
+ 43, 42, 38, 35, 28, 22, 8, 69, 41, 41, 14, 43, 48, 37, 31, 33, 29,
+ 24, 28, 22, 18, 8, 8, 64, 82, 15, 5, 71, 105, 94, 98, 75, 78, 76,
+ 15, 67, 67, 68, 6, 28, 16, 34, 64, 56, 54, 43, 35, 22, 18, 72, 82,
+ 98, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 93, 85, 76, 79, 72, 64,
+ 71, 73, 64, 2, 3, 2, 7, 10, 3, 55, 53, 47, 40, 35, 29, 13, 2,
+ 79, 125, 120, 89, 62, 62, 62, 62},
+
+ {
+
+ 60, 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, 54, 14, 83, 2,
+ 65, 9, 1, 3, 69, 65, 80, 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1,
+ 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, 78, 88,
+ 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 52, 8,
+ 69, 111, 89, 82, 67, 87, 101, 97, 104, 78, 101, 94, 98, 107, 103, 107, 104, 12,
+ 66, 69, 91, 67, 85, 80, 98, 73, 91, 84, 108, 11, 77, 69, 104, 86, 76, 74,
+ 66, 4, 64, 72, 8, 5, 68, 3, 64, 64, 2, 76, 13, 5, 19, 19, 15, 18,
+ 17, 15, 17, 12, 7, 18, 15, 75, 95, 85, 88, 78, 82, 78, 69, 76, 76, 74,
+ 76, 70, 72, 69, 75, 94, 85, 95, 71, 73, 64, 68, 3, 7, 1, 65, 7, 6,
+ 65, 69, 1, 83, 41, 40, 31, 33, 40, 32, 17, 34, 29, 12, 19, 15, 5, 1,
+ 67, 14, 8, 10, 11, 7, 3, 11, 5, 1, 5, 64, 66, 2, 89, 58, 60, 56,
+ 60, 57, 56, 56, 56, 54, 45, 44, 41, 31, 27, 8, 41, 35, 17, 45, 35, 36,
+ 31, 26, 23, 24, 15, 5, 2, 1, 79, 79, 98, 68, 27, 18, 12, 3, 5, 0,
+ 70, 73, 82, 1, 41, 27, 21, 17, 14, 3, 68, 71, 76, 80, 23, 13, 7, 2,
+ 2, 68, 73, 79, 94, 86, 65, 68, 67, 70, 73, 83, 86, 99, 70, 35, 19, 12,
+ 4, 5, 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, 70, 4, 9,
+ 6, 78, 71, 70, 10, 8, 13, 10, 21, 23, 19, 9, 15, 17, 15, 71, 2, 72,
+ 92, 86, 81, 81, 77, 78, 76, 75, 69, 74, 73, 70, 67, 75, 82, 92, 81, 96,
+ 76, 69, 70, 64, 68, 65, 4, 64, 65, 67, 1, 65, 68, 81, 43, 39, 41, 38,
+ 34, 40, 36, 33, 29, 28, 29, 24, 6, 8, 1, 24, 23, 18, 7, 14, 11, 0,
+ 66, 69, 75, 78, 91, 77, 97, 62, 62, 59, 59, 54, 50, 47, 41, 40, 36, 33,
+ 26, 20, 7, 70, 39, 39, 13, 41, 46, 35, 29, 31, 27, 22, 26, 20, 16, 6,
+ 6, 66, 83, 13, 3, 73, 104, 93, 97, 74, 77, 75, 17, 66, 66, 68, 7, 30,
+ 17, 36, 0, 55, 52, 41, 32, 19, 15, 75, 84, 99, 72, 41, 29, 20, 9, 10,
+ 2, 64, 68, 83, 92, 84, 75, 78, 71, 0, 70, 72, 0, 3, 4, 2, 8, 10,
+ 3, 54, 52, 45, 38, 33, 27, 11, 0, 80, 124, 119, 88, 62, 62, 62, 62},
+
+ {
+
+ 58, 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, 53, 14, 81, 1,
+ 65, 9, 0, 2, 69, 67, 82, 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0,
+ 80, 78, 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, 78, 88,
+ 3, 69, 70, 75, 65, 4, 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 52, 7,
+ 69, 110, 89, 82, 67, 86, 100, 96, 103, 77, 100, 93, 97, 106, 103, 106, 104, 12,
+ 66, 69, 91, 67, 85, 80, 97, 73, 91, 84, 107, 11, 77, 69, 103, 86, 76, 74,
+ 66, 4, 64, 72, 8, 5, 69, 2, 64, 65, 2, 76, 12, 4, 18, 19, 14, 17,
+ 17, 14, 15, 11, 6, 16, 14, 76, 95, 85, 88, 78, 82, 78, 68, 76, 76, 74,
+ 75, 71, 72, 69, 77, 94, 85, 95, 71, 74, 64, 68, 2, 7, 1, 65, 5, 6,
+ 66, 70, 1, 84, 39, 39, 30, 32, 39, 31, 16, 33, 28, 10, 18, 14, 4, 1,
+ 68, 13, 7, 9, 10, 6, 2, 10, 4, 64, 3, 65, 68, 0, 89, 56, 58, 54,
+ 58, 55, 53, 53, 53, 51, 42, 41, 38, 28, 24, 5, 39, 33, 15, 42, 32, 33,
+ 28, 23, 20, 21, 12, 2, 1, 64, 81, 80, 99, 68, 27, 18, 12, 3, 5, 64,
+ 70, 73, 82, 1, 41, 27, 21, 17, 15, 3, 68, 71, 76, 80, 23, 13, 7, 2,
+ 2, 68, 73, 79, 93, 86, 64, 68, 67, 70, 73, 83, 86, 98, 70, 35, 19, 12,
+ 4, 5, 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, 70, 4, 9,
+ 6, 78, 71, 71, 9, 8, 12, 9, 20, 22, 18, 7, 13, 16, 14, 72, 0, 73,
+ 92, 86, 80, 81, 77, 78, 76, 75, 70, 74, 73, 70, 68, 75, 82, 92, 81, 97,
+ 76, 69, 70, 64, 69, 65, 4, 65, 66, 67, 1, 66, 69, 82, 42, 38, 40, 37,
+ 32, 39, 35, 32, 28, 27, 28, 23, 5, 6, 64, 22, 21, 16, 5, 12, 9, 64,
+ 67, 70, 75, 78, 91, 78, 97, 62, 61, 57, 56, 51, 47, 44, 38, 37, 33, 30,
+ 23, 17, 5, 71, 37, 37, 11, 39, 43, 32, 26, 28, 24, 20, 23, 17, 13, 4,
+ 3, 68, 85, 11, 1, 75, 103, 92, 96, 74, 77, 75, 18, 66, 66, 68, 7, 31,
+ 18, 37, 0, 53, 50, 38, 28, 16, 12, 78, 87, 101, 72, 41, 28, 19, 9, 10,
+ 2, 65, 68, 83, 92, 84, 75, 78, 70, 0, 70, 72, 0, 3, 4, 2, 8, 10,
+ 2, 52, 50, 43, 36, 31, 25, 8, 65, 81, 124, 118, 88, 62, 62, 62, 62},
+
+ {
+
+ 57, 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, 53, 14, 78, 1,
+ 64, 10, 0, 2, 68, 68, 83, 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0,
+ 79, 76, 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, 77, 88,
+ 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 52, 7,
+ 69, 108, 88, 82, 66, 84, 98, 94, 101, 75, 98, 91, 95, 104, 102, 105, 103, 13,
+ 65, 68, 90, 66, 84, 79, 95, 72, 90, 83, 105, 12, 76, 68, 101, 85, 75, 73,
+ 65, 5, 0, 71, 9, 6, 69, 2, 0, 65, 2, 75, 12, 4, 18, 19, 14, 17,
+ 17, 14, 14, 11, 6, 15, 13, 76, 94, 84, 87, 77, 81, 77, 67, 75, 75, 73,
+ 73, 71, 72, 68, 78, 93, 84, 95, 70, 74, 0, 67, 2, 8, 1, 65, 4, 7,
+ 66, 71, 1, 84, 38, 39, 30, 32, 39, 31, 16, 33, 28, 9, 18, 14, 4, 1,
+ 68, 13, 7, 9, 10, 6, 1, 10, 4, 65, 2, 65, 69, 64, 89, 55, 57, 53,
+ 57, 54, 51, 51, 51, 49, 40, 39, 36, 26, 22, 3, 38, 32, 14, 40, 30, 31,
+ 26, 21, 18, 19, 10, 0, 1, 65, 82, 80, 99, 67, 28, 19, 13, 4, 5, 64,
+ 69, 72, 81, 2, 42, 28, 22, 17, 16, 4, 67, 70, 75, 79, 24, 14, 8, 3,
+ 3, 67, 72, 78, 91, 85, 1, 67, 66, 69, 72, 82, 85, 96, 69, 36, 20, 13,
+ 5, 6, 68, 73, 76, 82, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, 10,
+ 7, 77, 71, 71, 9, 9, 12, 9, 19, 22, 18, 6, 12, 16, 14, 72, 64, 73,
+ 91, 85, 79, 80, 76, 77, 75, 74, 70, 73, 72, 69, 68, 74, 81, 91, 80, 97,
+ 76, 68, 70, 0, 69, 65, 5, 65, 66, 66, 2, 66, 69, 82, 42, 38, 40, 37,
+ 31, 39, 35, 32, 28, 27, 28, 23, 5, 5, 65, 21, 20, 15, 4, 11, 8, 64,
+ 67, 70, 74, 77, 90, 78, 96, 60, 59, 55, 54, 49, 45, 42, 36, 35, 31, 28,
+ 21, 15, 4, 71, 36, 36, 10, 38, 41, 30, 24, 26, 22, 18, 21, 15, 11, 3,
+ 1, 69, 86, 10, 0, 76, 101, 90, 94, 73, 76, 74, 20, 65, 65, 68, 8, 33,
+ 20, 39, 1, 52, 49, 36, 25, 14, 10, 80, 89, 102, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 82, 91, 83, 74, 77, 68, 1, 69, 71, 1, 4, 5, 3, 9, 11,
+ 2, 51, 49, 42, 35, 30, 24, 6, 66, 81, 123, 116, 87, 62, 62, 62, 62},
+
+ {
+
+ 56, 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, 53, 14, 76, 1,
+ 0, 11, 0, 1, 68, 69, 84, 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0,
+ 79, 75, 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, 77, 88,
+ 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 52, 7,
+ 69, 107, 87, 82, 66, 83, 96, 92, 100, 74, 96, 90, 93, 103, 101, 104, 102, 14,
+ 65, 67, 89, 66, 84, 78, 93, 72, 90, 83, 104, 12, 76, 68, 100, 85, 74, 73,
+ 65, 5, 0, 70, 9, 6, 70, 2, 0, 65, 2, 75, 12, 4, 17, 19, 13, 17,
+ 17, 14, 12, 11, 6, 13, 12, 77, 93, 83, 86, 76, 80, 76, 66, 74, 75, 72,
+ 72, 71, 72, 68, 79, 93, 83, 95, 70, 74, 1, 67, 1, 9, 1, 65, 3, 8,
+ 67, 72, 1, 85, 36, 38, 29, 31, 38, 30, 15, 32, 28, 8, 17, 14, 4, 1,
+ 68, 12, 6, 8, 9, 5, 0, 9, 3, 67, 1, 66, 70, 65, 89, 53, 56, 51,
+ 55, 52, 49, 49, 49, 46, 38, 37, 33, 23, 20, 0, 36, 30, 12, 38, 28, 29,
+ 24, 19, 16, 16, 8, 65, 0, 67, 83, 81, 99, 67, 28, 19, 13, 4, 5, 64,
+ 69, 72, 80, 2, 42, 28, 22, 17, 17, 4, 66, 70, 74, 78, 25, 15, 8, 3,
+ 4, 67, 72, 77, 90, 84, 2, 66, 66, 69, 71, 81, 84, 95, 69, 36, 20, 13,
+ 5, 7, 67, 72, 75, 81, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, 10,
+ 8, 77, 71, 71, 8, 9, 11, 8, 18, 21, 18, 5, 11, 16, 14, 73, 65, 74,
+ 90, 84, 78, 80, 76, 77, 74, 73, 70, 73, 72, 69, 69, 74, 81, 91, 79, 97,
+ 76, 68, 70, 1, 69, 65, 6, 65, 66, 66, 3, 67, 69, 83, 41, 38, 40, 36,
+ 30, 38, 34, 31, 27, 26, 27, 22, 4, 4, 66, 19, 19, 13, 2, 10, 7, 65,
+ 68, 70, 74, 77, 90, 79, 95, 58, 57, 53, 52, 46, 43, 40, 33, 33, 29, 26,
+ 19, 13, 3, 72, 34, 34, 9, 36, 39, 28, 22, 24, 20, 16, 19, 13, 9, 1,
+ 64, 71, 87, 8, 65, 78, 100, 89, 93, 72, 75, 73, 22, 64, 64, 68, 9, 34,
+ 21, 40, 2, 51, 47, 33, 22, 11, 7, 83, 91, 103, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 81, 90, 82, 73, 76, 67, 2, 68, 70, 2, 5, 6, 3, 10, 11,
+ 2, 50, 47, 40, 33, 28, 22, 4, 68, 82, 122, 115, 86, 62, 62, 62, 62},
+
+ {
+
+ 55, 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, 53, 14, 74, 1,
+ 1, 12, 0, 0, 68, 70, 85, 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0,
+ 78, 74, 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, 77, 88,
+ 5, 68, 69, 74, 0, 4, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 52, 7,
+ 69, 106, 86, 82, 65, 82, 94, 90, 98, 73, 94, 89, 91, 102, 100, 103, 101, 15,
+ 65, 66, 88, 66, 83, 78, 91, 72, 89, 82, 103, 12, 76, 67, 98, 84, 73, 73,
+ 65, 5, 0, 69, 10, 7, 70, 2, 0, 65, 2, 75, 12, 3, 17, 19, 12, 17,
+ 17, 14, 10, 11, 5, 11, 11, 78, 92, 82, 85, 75, 79, 76, 65, 74, 74, 71,
+ 71, 71, 72, 68, 80, 92, 82, 95, 70, 74, 2, 67, 0, 10, 1, 65, 2, 9,
+ 67, 73, 1, 86, 35, 37, 29, 30, 37, 29, 15, 31, 27, 7, 16, 14, 4, 1,
+ 69, 11, 5, 7, 8, 4, 64, 8, 3, 69, 0, 66, 71, 66, 89, 52, 54, 50,
+ 53, 50, 47, 47, 47, 44, 35, 35, 31, 21, 17, 65, 34, 28, 11, 36, 26, 26,
+ 21, 17, 13, 14, 6, 68, 64, 69, 84, 82, 99, 67, 29, 19, 13, 4, 5, 64,
+ 69, 72, 80, 2, 42, 28, 22, 17, 18, 5, 66, 69, 74, 77, 26, 15, 9, 3,
+ 5, 66, 71, 77, 89, 83, 3, 65, 65, 69, 70, 80, 83, 94, 68, 36, 20, 13,
+ 5, 8, 67, 71, 74, 80, 62, 85, 76, 69, 66, 69, 1, 6, 7, 69, 5, 10,
+ 8, 77, 71, 71, 8, 10, 10, 7, 17, 20, 18, 4, 10, 16, 14, 73, 66, 74,
+ 89, 83, 77, 79, 75, 76, 74, 72, 70, 73, 72, 68, 69, 74, 81, 90, 78, 97,
+ 76, 68, 70, 2, 69, 65, 7, 65, 66, 66, 4, 68, 69, 84, 40, 37, 39, 35,
+ 29, 37, 33, 30, 26, 25, 26, 21, 3, 3, 67, 18, 18, 12, 0, 8, 6, 66,
+ 68, 71, 74, 77, 90, 79, 94, 56, 55, 51, 50, 43, 41, 38, 31, 31, 27, 24,
+ 16, 11, 1, 73, 32, 33, 7, 34, 37, 26, 20, 22, 18, 14, 17, 11, 6, 64,
+ 66, 73, 88, 6, 67, 79, 99, 88, 92, 71, 74, 72, 23, 0, 0, 68, 10, 36,
+ 23, 42, 3, 49, 46, 31, 19, 8, 4, 86, 93, 104, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 81, 89, 81, 72, 75, 66, 2, 68, 69, 2, 5, 6, 3, 10, 11,
+ 2, 49, 46, 38, 31, 26, 20, 2, 70, 83, 121, 113, 85, 62, 62, 62, 62},
+
+ {
+
+ 53, 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, 53, 14, 71, 0,
+ 2, 12, 0, 64, 68, 71, 86, 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0,
+ 78, 73, 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, 77, 88,
+ 5, 67, 69, 73, 0, 4, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 52, 7,
+ 69, 105, 85, 82, 65, 80, 93, 88, 97, 72, 93, 87, 89, 101, 100, 102, 101, 15,
+ 65, 65, 87, 66, 83, 77, 89, 72, 89, 82, 102, 12, 75, 67, 97, 84, 73, 73,
+ 64, 5, 0, 69, 10, 7, 71, 1, 0, 65, 2, 75, 12, 3, 16, 19, 12, 17,
+ 17, 13, 8, 11, 5, 9, 10, 79, 91, 81, 84, 74, 79, 75, 64, 73, 74, 70,
+ 70, 71, 72, 67, 81, 92, 81, 95, 70, 74, 2, 67, 64, 11, 1, 65, 0, 10,
+ 68, 74, 1, 87, 33, 36, 28, 29, 36, 28, 14, 30, 27, 5, 15, 13, 4, 1,
+ 69, 10, 5, 6, 8, 3, 65, 7, 2, 71, 64, 67, 72, 67, 89, 50, 53, 48,
+ 51, 48, 45, 44, 45, 41, 33, 33, 28, 18, 15, 68, 32, 27, 9, 33, 24, 24,
+ 19, 14, 11, 11, 4, 70, 65, 70, 86, 83, 99, 67, 29, 20, 13, 4, 5, 64,
+ 69, 72, 79, 3, 43, 28, 22, 17, 19, 5, 65, 69, 73, 77, 27, 16, 9, 3,
+ 5, 66, 71, 76, 88, 83, 4, 65, 65, 69, 69, 79, 83, 93, 68, 37, 20, 13,
+ 5, 9, 66, 71, 73, 79, 62, 85, 76, 69, 66, 69, 1, 6, 7, 68, 5, 10,
+ 9, 77, 71, 71, 7, 10, 9, 6, 16, 19, 18, 2, 9, 15, 14, 74, 67, 75,
+ 89, 83, 76, 79, 75, 76, 73, 71, 71, 73, 72, 68, 70, 74, 81, 90, 77, 97,
+ 76, 67, 70, 2, 69, 65, 8, 65, 67, 66, 5, 68, 70, 85, 39, 37, 39, 34,
+ 28, 36, 32, 29, 25, 24, 25, 20, 2, 2, 68, 16, 16, 10, 65, 7, 5, 67,
+ 69, 71, 74, 77, 90, 80, 94, 53, 52, 49, 47, 40, 39, 36, 28, 29, 25, 22,
+ 14, 9, 0, 74, 30, 31, 6, 32, 35, 24, 18, 19, 16, 12, 15, 9, 4, 66,
+ 68, 75, 89, 4, 69, 81, 98, 87, 91, 71, 73, 71, 25, 1, 1, 68, 11, 37,
+ 24, 43, 3, 48, 44, 28, 16, 5, 1, 89, 95, 105, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 80, 88, 80, 71, 75, 65, 3, 67, 68, 3, 6, 7, 4, 11, 12,
+ 2, 47, 44, 36, 29, 24, 18, 0, 72, 84, 120, 112, 85, 62, 62, 62, 62},
+
+ {
+
+ 52, 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, 53, 14, 69, 0,
+ 3, 13, 0, 64, 67, 72, 87, 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0,
+ 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, 77, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 52, 7,
+ 69, 104, 84, 82, 64, 79, 91, 86, 95, 71, 91, 86, 87, 100, 99, 101, 100, 16,
+ 65, 64, 86, 66, 82, 76, 87, 72, 89, 81, 100, 13, 75, 66, 96, 83, 72, 73,
+ 64, 6, 1, 68, 11, 8, 71, 1, 0, 65, 2, 75, 12, 2, 15, 19, 11, 17,
+ 17, 13, 6, 11, 4, 8, 9, 80, 90, 80, 83, 73, 78, 74, 0, 72, 73, 69,
+ 69, 71, 72, 67, 82, 91, 80, 95, 69, 74, 3, 67, 65, 12, 1, 65, 64, 11,
+ 68, 75, 1, 87, 32, 35, 28, 28, 35, 27, 13, 30, 27, 4, 14, 13, 4, 1,
+ 70, 10, 4, 5, 7, 2, 66, 7, 1, 73, 65, 68, 73, 68, 89, 48, 52, 46,
+ 49, 47, 43, 42, 43, 39, 31, 31, 26, 16, 13, 70, 30, 25, 7, 31, 22, 22,
+ 17, 12, 9, 8, 2, 73, 66, 72, 87, 83, 99, 67, 29, 20, 13, 4, 5, 64,
+ 69, 72, 79, 3, 43, 28, 22, 17, 20, 6, 64, 69, 72, 76, 28, 17, 9, 4,
+ 6, 65, 70, 76, 87, 82, 6, 64, 65, 68, 68, 78, 82, 92, 67, 37, 21, 13,
+ 5, 10, 65, 70, 72, 78, 62, 85, 76, 68, 66, 69, 1, 6, 7, 68, 5, 11,
+ 9, 77, 71, 71, 6, 11, 8, 5, 15, 19, 18, 1, 8, 15, 14, 75, 68, 75,
+ 88, 82, 75, 78, 74, 75, 73, 70, 71, 73, 72, 68, 71, 74, 81, 89, 76, 97,
+ 76, 67, 70, 3, 69, 65, 9, 65, 67, 66, 6, 69, 70, 85, 38, 37, 38, 34,
+ 27, 35, 31, 28, 25, 23, 24, 19, 1, 1, 69, 15, 15, 9, 67, 6, 4, 68,
+ 70, 72, 74, 76, 90, 80, 93, 51, 50, 47, 45, 38, 37, 34, 26, 27, 23, 20,
+ 12, 7, 65, 75, 28, 29, 5, 30, 33, 22, 16, 17, 14, 10, 13, 7, 1, 68,
+ 70, 77, 90, 2, 71, 82, 97, 85, 90, 70, 72, 70, 27, 2, 2, 68, 12, 39,
+ 26, 45, 4, 46, 42, 26, 13, 3, 65, 91, 97, 106, 71, 42, 28, 19, 9, 11,
+ 2, 65, 68, 80, 87, 79, 70, 74, 64, 4, 67, 67, 4, 7, 8, 4, 11, 12,
+ 2, 46, 43, 35, 28, 22, 16, 65, 74, 85, 119, 111, 84, 62, 62, 62, 62},
+
+ {
+
+ 51, 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, 53, 14, 67, 0,
+ 3, 14, 0, 65, 67, 73, 88, 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0,
+ 77, 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, 76, 88,
+ 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 52, 7,
+ 69, 103, 84, 82, 64, 78, 89, 84, 94, 70, 89, 85, 85, 99, 98, 100, 99, 17,
+ 65, 0, 86, 65, 82, 76, 85, 72, 88, 81, 99, 13, 75, 66, 94, 83, 71, 72,
+ 64, 6, 1, 67, 11, 8, 72, 1, 0, 65, 2, 75, 12, 2, 15, 19, 10, 17,
+ 17, 13, 4, 11, 4, 6, 8, 81, 90, 79, 83, 73, 77, 74, 1, 72, 73, 69,
+ 67, 71, 72, 67, 83, 91, 79, 95, 69, 74, 4, 66, 66, 12, 1, 65, 65, 12,
+ 69, 76, 1, 88, 30, 34, 27, 28, 34, 27, 13, 29, 26, 3, 13, 13, 4, 1,
+ 70, 9, 3, 4, 6, 2, 67, 6, 1, 75, 66, 68, 74, 69, 89, 47, 50, 45,
+ 47, 45, 41, 40, 41, 36, 28, 29, 23, 13, 10, 73, 28, 23, 6, 29, 19, 19,
+ 14, 10, 6, 6, 64, 75, 67, 74, 88, 84, 99, 66, 30, 20, 14, 4, 5, 64,
+ 69, 72, 78, 3, 43, 29, 22, 17, 21, 6, 64, 68, 72, 75, 29, 17, 10, 4,
+ 7, 65, 70, 75, 86, 81, 7, 0, 64, 68, 68, 78, 81, 90, 67, 37, 21, 13,
+ 6, 10, 65, 69, 72, 77, 62, 84, 75, 68, 66, 69, 1, 6, 7, 68, 6, 11,
+ 10, 77, 71, 72, 6, 11, 7, 4, 14, 18, 18, 0, 7, 15, 14, 75, 69, 76,
+ 87, 81, 74, 78, 74, 75, 72, 70, 71, 72, 71, 67, 71, 74, 81, 89, 75, 97,
+ 76, 67, 70, 4, 69, 65, 10, 66, 67, 66, 6, 70, 70, 86, 37, 36, 38, 33,
+ 26, 35, 31, 27, 24, 23, 23, 18, 0, 0, 70, 13, 14, 7, 69, 4, 2, 69,
+ 70, 72, 74, 76, 89, 81, 92, 49, 48, 45, 43, 35, 35, 32, 23, 25, 20, 18,
+ 9, 5, 66, 75, 27, 28, 3, 28, 30, 20, 14, 15, 12, 8, 10, 5, 64, 70,
+ 72, 78, 92, 0, 73, 84, 96, 84, 89, 69, 71, 69, 28, 3, 3, 68, 13, 40,
+ 27, 46, 5, 45, 41, 23, 10, 0, 67, 94, 99, 108, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 79, 86, 79, 69, 73, 0, 4, 66, 66, 4, 7, 8, 4, 12, 12,
+ 2, 45, 41, 33, 26, 21, 15, 68, 75, 86, 118, 109, 83, 62, 62, 62, 62},
+
+ {
+
+ 50, 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, 53, 14, 64, 64,
+ 4, 14, 0, 66, 67, 74, 89, 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0,
+ 77, 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 52, 7,
+ 69, 102, 83, 82, 0, 76, 88, 82, 92, 69, 88, 83, 83, 98, 97, 99, 99, 18,
+ 65, 1, 85, 65, 81, 75, 83, 72, 88, 80, 98, 13, 74, 65, 93, 82, 71, 72,
+ 0, 6, 1, 66, 12, 9, 72, 0, 0, 65, 2, 75, 12, 1, 14, 19, 10, 17,
+ 17, 12, 2, 11, 3, 4, 7, 82, 89, 78, 82, 72, 76, 73, 2, 71, 72, 68,
+ 66, 71, 72, 66, 84, 90, 78, 95, 69, 74, 4, 66, 67, 13, 1, 65, 67, 13,
+ 69, 77, 1, 89, 29, 33, 27, 27, 33, 26, 12, 28, 26, 2, 12, 13, 4, 1,
+ 71, 8, 3, 3, 6, 1, 68, 5, 0, 77, 67, 69, 75, 70, 89, 45, 49, 43,
+ 45, 43, 39, 37, 39, 34, 26, 27, 21, 11, 8, 75, 26, 22, 4, 26, 17, 17,
+ 12, 7, 4, 3, 66, 78, 68, 75, 90, 85, 99, 66, 30, 21, 14, 4, 5, 64,
+ 69, 72, 78, 4, 44, 29, 22, 17, 22, 7, 0, 68, 71, 74, 30, 18, 10, 4,
+ 8, 64, 69, 75, 85, 81, 8, 0, 64, 68, 67, 77, 81, 89, 66, 38, 21, 13,
+ 6, 11, 64, 68, 71, 76, 62, 84, 75, 67, 66, 69, 1, 6, 7, 67, 6, 11,
+ 10, 77, 71, 72, 5, 12, 6, 3, 13, 17, 18, 64, 6, 14, 14, 76, 70, 76,
+ 86, 81, 73, 77, 73, 74, 72, 69, 71, 72, 71, 67, 72, 74, 81, 88, 74, 97,
+ 76, 66, 70, 4, 69, 65, 11, 66, 67, 66, 7, 70, 71, 87, 36, 36, 37, 32,
+ 25, 34, 30, 26, 23, 22, 22, 17, 64, 64, 71, 12, 12, 6, 71, 3, 1, 70,
+ 71, 73, 74, 76, 89, 81, 91, 47, 46, 43, 40, 32, 33, 30, 21, 23, 18, 16,
+ 7, 3, 68, 76, 25, 26, 2, 26, 28, 18, 12, 13, 10, 6, 8, 3, 67, 72,
+ 74, 80, 93, 65, 75, 85, 95, 83, 88, 69, 70, 68, 30, 4, 4, 68, 14, 42,
+ 29, 48, 5, 43, 39, 21, 7, 66, 70, 97, 101, 109, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 79, 85, 78, 68, 72, 1, 5, 66, 65, 5, 8, 9, 5, 12, 13,
+ 2, 43, 40, 31, 24, 19, 13, 70, 77, 87, 117, 108, 83, 62, 62, 62, 62},
+
+ {
+
+ 48, 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, 53, 14, 1, 64,
+ 5, 15, 0, 67, 67, 75, 91, 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0,
+ 77, 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, 76, 88,
+ 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 52, 7,
+ 69, 101, 82, 82, 0, 75, 86, 80, 91, 68, 86, 82, 82, 97, 97, 98, 98, 18,
+ 65, 2, 84, 65, 81, 75, 82, 72, 88, 80, 97, 13, 74, 65, 92, 82, 70, 72,
+ 0, 6, 1, 66, 12, 9, 73, 0, 0, 65, 2, 75, 12, 1, 13, 19, 9, 17,
+ 17, 12, 0, 11, 3, 2, 6, 83, 88, 77, 81, 71, 76, 73, 3, 71, 72, 67,
+ 65, 71, 72, 66, 86, 90, 77, 95, 69, 75, 5, 66, 68, 14, 1, 65, 68, 14,
+ 70, 78, 1, 90, 27, 32, 26, 26, 32, 25, 11, 27, 25, 0, 11, 12, 4, 1,
+ 71, 7, 2, 2, 5, 0, 69, 4, 64, 79, 69, 70, 76, 71, 89, 43, 47, 41,
+ 43, 41, 37, 35, 37, 31, 23, 25, 18, 8, 5, 78, 24, 20, 2, 24, 15, 14,
+ 9, 5, 1, 0, 68, 80, 69, 77, 91, 86, 100, 66, 30, 21, 14, 4, 5, 64,
+ 69, 72, 77, 4, 44, 29, 22, 17, 23, 7, 0, 68, 71, 74, 31, 18, 10, 4,
+ 8, 64, 69, 74, 84, 80, 9, 1, 64, 68, 66, 76, 80, 88, 66, 38, 21, 13,
+ 6, 12, 64, 68, 70, 76, 62, 84, 75, 67, 66, 69, 1, 6, 7, 67, 6, 11,
+ 11, 77, 71, 72, 4, 12, 5, 2, 12, 16, 18, 66, 4, 14, 14, 77, 71, 77,
+ 86, 80, 72, 77, 73, 74, 71, 68, 72, 72, 71, 67, 73, 74, 81, 88, 74, 98,
+ 76, 66, 70, 5, 69, 65, 11, 66, 68, 66, 8, 71, 71, 88, 35, 35, 37, 31,
+ 23, 33, 29, 25, 22, 21, 21, 16, 65, 65, 72, 10, 11, 4, 73, 1, 0, 71,
+ 72, 73, 74, 76, 89, 82, 91, 44, 43, 41, 38, 29, 30, 27, 18, 21, 16, 14,
+ 4, 1, 69, 77, 23, 24, 0, 24, 26, 15, 9, 10, 7, 4, 6, 0, 69, 74,
+ 77, 82, 94, 67, 77, 87, 94, 82, 87, 68, 69, 68, 31, 5, 4, 68, 14, 43,
+ 30, 49, 6, 42, 37, 18, 4, 69, 73, 100, 103, 110, 70, 42, 28, 19, 9, 11,
+ 2, 65, 68, 78, 85, 77, 67, 72, 2, 5, 65, 65, 5, 8, 9, 5, 13, 13,
+ 1, 42, 38, 29, 22, 17, 11, 72, 79, 88, 117, 107, 82, 62, 62, 62, 62},
+
+ {
+
+ 47, 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, 53, 14, 3, 64,
+ 6, 16, 0, 67, 66, 76, 92, 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0,
+ 76, 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, 76, 88,
+ 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 52, 7,
+ 69, 100, 81, 82, 0, 74, 84, 78, 89, 66, 84, 81, 80, 96, 96, 97, 97, 19,
+ 64, 3, 83, 65, 80, 74, 80, 72, 87, 80, 95, 14, 74, 65, 90, 82, 69, 72,
+ 0, 7, 2, 65, 12, 9, 73, 0, 1, 65, 2, 74, 12, 1, 13, 19, 8, 17,
+ 17, 12, 65, 11, 3, 1, 5, 83, 87, 76, 80, 70, 75, 72, 4, 70, 72, 66,
+ 64, 71, 72, 66, 87, 89, 76, 95, 68, 75, 6, 66, 69, 15, 1, 65, 69, 15,
+ 71, 79, 1, 90, 26, 31, 26, 25, 31, 24, 11, 27, 25, 64, 10, 12, 4, 1,
+ 71, 7, 1, 1, 4, 64, 70, 4, 64, 80, 70, 70, 77, 72, 89, 42, 46, 40,
+ 42, 40, 35, 33, 35, 29, 21, 23, 16, 5, 3, 81, 23, 18, 1, 22, 13, 12,
+ 7, 3, 64, 65, 70, 82, 69, 79, 92, 86, 100, 66, 31, 21, 14, 5, 5, 64,
+ 68, 72, 76, 4, 44, 29, 23, 17, 24, 8, 1, 67, 70, 73, 32, 19, 11, 5,
+ 9, 0, 69, 73, 83, 79, 11, 2, 0, 67, 65, 75, 79, 87, 65, 38, 22, 14,
+ 6, 13, 0, 67, 69, 75, 62, 83, 74, 66, 66, 69, 1, 7, 8, 67, 6, 12,
+ 12, 77, 71, 72, 4, 12, 4, 2, 11, 16, 18, 67, 3, 14, 14, 77, 72, 78,
+ 85, 79, 71, 77, 72, 74, 70, 67, 72, 72, 71, 66, 73, 74, 81, 88, 73, 98,
+ 76, 66, 70, 6, 69, 65, 12, 66, 68, 66, 9, 72, 71, 88, 34, 35, 37, 31,
+ 22, 32, 28, 24, 22, 20, 20, 16, 65, 66, 73, 9, 10, 2, 75, 0, 64, 71,
+ 72, 73, 73, 75, 89, 83, 90, 42, 41, 39, 36, 27, 28, 25, 16, 19, 14, 12,
+ 2, 64, 70, 78, 21, 23, 64, 22, 24, 13, 7, 8, 5, 2, 4, 65, 71, 75,
+ 79, 84, 95, 69, 79, 89, 93, 80, 85, 67, 68, 67, 33, 6, 5, 68, 15, 45,
+ 31, 51, 7, 41, 36, 16, 1, 71, 76, 102, 105, 111, 70, 42, 28, 19, 9, 12,
+ 2, 65, 68, 77, 84, 76, 66, 71, 4, 6, 64, 64, 6, 9, 10, 5, 14, 13,
+ 1, 41, 37, 28, 21, 15, 9, 74, 81, 88, 116, 105, 81, 62, 62, 62, 62},
+
+ {
+
+ 46, 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, 53, 14, 6, 65,
+ 7, 16, 0, 68, 66, 77, 93, 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0,
+ 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, 76, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 52, 7,
+ 69, 99, 80, 82, 1, 72, 83, 76, 88, 65, 83, 79, 78, 95, 95, 96, 97, 20,
+ 64, 4, 82, 65, 80, 73, 78, 72, 87, 79, 94, 14, 73, 64, 89, 81, 69, 72,
+ 1, 7, 2, 64, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, 12, 19, 8, 17,
+ 17, 11, 67, 11, 2, 64, 4, 84, 86, 75, 79, 69, 74, 71, 5, 69, 71, 65,
+ 0, 71, 72, 65, 88, 89, 75, 95, 68, 75, 6, 66, 70, 16, 1, 65, 71, 16,
+ 71, 80, 1, 91, 24, 30, 25, 24, 30, 23, 10, 26, 25, 65, 9, 12, 4, 1,
+ 72, 6, 1, 0, 4, 65, 71, 3, 65, 82, 71, 71, 78, 73, 89, 40, 45, 38,
+ 40, 38, 33, 30, 33, 26, 19, 21, 13, 3, 1, 83, 21, 17, 64, 19, 11, 10,
+ 5, 0, 66, 68, 72, 85, 70, 80, 94, 87, 100, 66, 31, 22, 14, 5, 5, 64,
+ 68, 72, 76, 5, 45, 29, 23, 17, 25, 8, 2, 67, 69, 72, 33, 20, 11, 5,
+ 10, 0, 68, 73, 82, 79, 12, 2, 0, 67, 64, 74, 79, 86, 65, 39, 22, 14,
+ 6, 14, 1, 66, 68, 74, 62, 83, 74, 66, 66, 69, 1, 7, 8, 66, 6, 12,
+ 12, 77, 71, 72, 3, 13, 3, 1, 10, 15, 18, 68, 2, 13, 14, 78, 73, 78,
+ 84, 79, 70, 76, 72, 73, 70, 66, 72, 72, 71, 66, 74, 74, 81, 87, 72, 98,
+ 76, 65, 70, 6, 69, 65, 13, 66, 68, 66, 10, 72, 72, 89, 33, 35, 36, 30,
+ 21, 31, 27, 23, 21, 19, 19, 15, 66, 67, 74, 7, 8, 1, 77, 64, 65, 72,
+ 73, 74, 73, 75, 89, 83, 89, 40, 39, 37, 33, 24, 26, 23, 13, 17, 12, 10,
+ 0, 66, 72, 79, 19, 21, 65, 20, 22, 11, 5, 6, 3, 0, 2, 67, 74, 77,
+ 81, 86, 96, 71, 81, 90, 92, 79, 84, 67, 67, 66, 35, 7, 6, 68, 16, 46,
+ 33, 52, 7, 39, 34, 13, 65, 74, 79, 105, 107, 112, 70, 42, 28, 19, 9, 12,
+ 2, 65, 68, 77, 83, 75, 65, 70, 5, 7, 64, 0, 7, 10, 11, 6, 14, 14,
+ 1, 39, 35, 26, 19, 13, 7, 76, 83, 89, 115, 104, 81, 62, 62, 62, 62},
+
+ {
+
+ 45, 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, 53, 14, 8, 65,
+ 7, 17, 0, 69, 66, 78, 94, 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0,
+ 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, 75, 88,
+ 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 52, 7,
+ 69, 98, 80, 82, 1, 71, 81, 74, 86, 64, 81, 78, 76, 94, 94, 95, 96, 21,
+ 64, 5, 82, 64, 79, 73, 76, 72, 86, 79, 93, 14, 73, 64, 87, 81, 68, 71,
+ 1, 7, 2, 0, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, 12, 19, 7, 17,
+ 17, 11, 69, 11, 2, 66, 3, 85, 86, 74, 79, 69, 73, 71, 6, 69, 71, 65,
+ 2, 71, 72, 65, 89, 88, 74, 95, 68, 75, 7, 65, 71, 16, 1, 65, 72, 17,
+ 72, 81, 1, 92, 23, 29, 25, 24, 29, 23, 10, 25, 24, 66, 8, 12, 4, 1,
+ 72, 5, 0, 64, 3, 65, 72, 2, 65, 84, 72, 71, 79, 74, 89, 39, 43, 37,
+ 38, 36, 31, 28, 31, 24, 16, 19, 11, 0, 65, 86, 19, 15, 65, 17, 8, 7,
+ 2, 65, 69, 70, 75, 87, 71, 82, 95, 88, 100, 65, 32, 22, 15, 5, 5, 64,
+ 68, 72, 75, 5, 45, 30, 23, 17, 26, 9, 2, 66, 69, 71, 34, 20, 12, 5,
+ 11, 1, 68, 72, 81, 78, 13, 3, 1, 67, 64, 74, 78, 84, 64, 39, 22, 14,
+ 7, 14, 1, 65, 68, 73, 62, 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12,
+ 13, 77, 71, 73, 3, 13, 2, 0, 9, 14, 18, 69, 1, 13, 14, 78, 74, 79,
+ 83, 78, 69, 76, 71, 73, 69, 66, 72, 71, 70, 65, 74, 74, 81, 87, 71, 98,
+ 76, 65, 70, 7, 69, 65, 14, 67, 68, 66, 10, 73, 72, 90, 32, 34, 36, 29,
+ 20, 31, 27, 22, 20, 19, 18, 14, 67, 68, 75, 6, 7, 64, 79, 66, 67, 73,
+ 73, 74, 73, 75, 88, 84, 88, 38, 37, 35, 31, 21, 24, 21, 11, 15, 9, 8,
+ 66, 68, 73, 79, 18, 20, 67, 18, 19, 9, 3, 4, 1, 65, 64, 69, 76, 79,
+ 83, 87, 98, 73, 83, 92, 91, 78, 83, 66, 66, 65, 36, 8, 7, 68, 17, 48,
+ 34, 54, 8, 38, 33, 11, 68, 77, 81, 108, 109, 114, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 76, 82, 75, 64, 69, 6, 7, 0, 1, 7, 10, 11, 6, 15, 14,
+ 1, 38, 34, 24, 17, 12, 6, 79, 84, 90, 114, 102, 80, 62, 62, 62, 62},
+
+ {
+
+ 43, 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, 53, 14, 10, 65,
+ 8, 18, 0, 70, 66, 79, 95, 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0,
+ 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, 75, 88,
+ 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 52, 7,
+ 69, 97, 79, 82, 2, 70, 79, 72, 85, 0, 79, 77, 74, 93, 94, 94, 95, 21,
+ 64, 6, 81, 64, 79, 72, 74, 72, 86, 78, 92, 14, 73, 0, 86, 80, 67, 71,
+ 1, 7, 2, 0, 14, 11, 75, 64, 1, 65, 2, 74, 12, 64, 11, 19, 6, 17,
+ 17, 11, 71, 11, 1, 68, 2, 86, 85, 73, 78, 68, 73, 70, 7, 68, 70, 64,
+ 3, 71, 72, 65, 90, 88, 73, 95, 68, 75, 8, 65, 72, 17, 1, 65, 73, 18,
+ 72, 82, 1, 93, 21, 28, 24, 23, 28, 22, 9, 24, 24, 68, 7, 11, 4, 1,
+ 73, 4, 64, 65, 2, 66, 73, 1, 66, 86, 73, 72, 80, 75, 89, 37, 42, 35,
+ 36, 34, 29, 26, 29, 21, 14, 17, 8, 65, 67, 88, 17, 13, 67, 15, 6, 5,
+ 0, 67, 71, 73, 77, 90, 72, 84, 96, 89, 100, 65, 32, 22, 15, 5, 5, 64,
+ 68, 72, 75, 5, 45, 30, 23, 17, 27, 9, 3, 66, 68, 71, 35, 21, 12, 5,
+ 11, 1, 67, 72, 80, 77, 14, 4, 1, 67, 0, 73, 77, 83, 64, 39, 22, 14,
+ 7, 15, 2, 65, 67, 72, 62, 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12,
+ 13, 77, 71, 73, 2, 14, 1, 64, 8, 13, 18, 71, 0, 13, 14, 79, 75, 79,
+ 83, 77, 68, 75, 71, 72, 69, 65, 73, 71, 70, 65, 75, 74, 81, 86, 70, 98,
+ 76, 65, 70, 8, 69, 65, 15, 67, 69, 66, 11, 74, 72, 91, 31, 34, 35, 28,
+ 19, 30, 26, 21, 19, 18, 17, 13, 68, 69, 76, 4, 6, 65, 81, 67, 68, 74,
+ 74, 75, 73, 75, 88, 84, 88, 35, 34, 33, 29, 18, 22, 19, 8, 13, 7, 6,
+ 68, 70, 75, 80, 16, 18, 68, 16, 17, 7, 1, 1, 64, 67, 66, 71, 79, 81,
+ 85, 89, 99, 75, 85, 93, 90, 77, 82, 65, 65, 64, 38, 9, 8, 68, 18, 49,
+ 36, 55, 9, 36, 31, 8, 71, 80, 84, 111, 111, 115, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 76, 81, 74, 0, 69, 7, 8, 0, 2, 8, 11, 12, 6, 15, 14,
+ 1, 37, 32, 22, 15, 10, 4, 81, 86, 91, 113, 101, 79, 62, 62, 62, 62},
+
+ {
+
+ 42, 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, 53, 14, 13, 66,
+ 9, 18, 0, 70, 65, 80, 96, 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0,
+ 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 52, 7,
+ 69, 96, 78, 82, 2, 68, 78, 70, 83, 1, 78, 75, 72, 92, 93, 93, 95, 22,
+ 64, 7, 80, 64, 78, 71, 72, 72, 86, 78, 90, 15, 72, 0, 85, 80, 67, 71,
+ 2, 8, 3, 1, 14, 11, 75, 65, 1, 65, 2, 74, 12, 64, 10, 19, 6, 17,
+ 17, 10, 73, 11, 1, 69, 1, 87, 84, 72, 77, 67, 72, 69, 8, 67, 70, 0,
+ 4, 71, 72, 64, 91, 87, 72, 95, 67, 75, 8, 65, 73, 18, 1, 65, 75, 19,
+ 73, 83, 1, 93, 20, 27, 24, 22, 27, 21, 8, 24, 24, 69, 6, 11, 4, 1,
+ 73, 4, 64, 66, 2, 67, 74, 1, 67, 88, 74, 73, 81, 76, 89, 35, 41, 33,
+ 34, 33, 27, 23, 27, 19, 12, 15, 6, 68, 69, 91, 15, 12, 69, 12, 4, 3,
+ 65, 70, 73, 76, 79, 92, 73, 85, 98, 89, 100, 65, 32, 23, 15, 5, 5, 64,
+ 68, 72, 74, 6, 46, 30, 23, 17, 28, 10, 4, 66, 67, 70, 36, 22, 12, 6,
+ 12, 2, 67, 71, 79, 77, 16, 4, 1, 66, 1, 72, 77, 82, 0, 40, 23, 14,
+ 7, 16, 3, 64, 66, 71, 62, 82, 73, 64, 66, 69, 1, 7, 8, 65, 7, 13,
+ 14, 77, 71, 73, 1, 14, 0, 65, 7, 13, 18, 72, 64, 12, 14, 80, 76, 80,
+ 82, 77, 67, 75, 70, 72, 68, 64, 73, 71, 70, 65, 76, 74, 81, 86, 69, 98,
+ 76, 64, 70, 8, 69, 65, 16, 67, 69, 66, 12, 74, 73, 91, 30, 34, 35, 28,
+ 18, 29, 25, 20, 19, 17, 16, 12, 69, 70, 77, 3, 4, 67, 83, 68, 69, 75,
+ 75, 75, 73, 74, 88, 85, 87, 33, 32, 31, 26, 16, 20, 17, 6, 11, 5, 4,
+ 70, 72, 76, 81, 14, 16, 69, 14, 15, 5, 64, 64, 66, 69, 68, 73, 81, 83,
+ 87, 91, 100, 77, 87, 95, 89, 75, 81, 65, 64, 0, 40, 10, 9, 68, 19, 51,
+ 37, 57, 9, 35, 29, 6, 74, 82, 87, 113, 113, 116, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 75, 80, 73, 1, 68, 8, 9, 1, 3, 9, 12, 13, 7, 16, 15,
+ 1, 35, 31, 21, 14, 8, 2, 83, 88, 92, 112, 100, 79, 62, 62, 62, 62},
+
+ {
+
+ 41, 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, 53, 14, 15, 66,
+ 10, 19, 0, 71, 65, 81, 97, 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0,
+ 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 52, 7,
+ 69, 95, 77, 82, 3, 67, 76, 68, 82, 2, 76, 74, 70, 91, 92, 92, 94, 23,
+ 64, 8, 79, 64, 78, 71, 70, 72, 85, 77, 89, 15, 72, 1, 83, 79, 66, 71,
+ 2, 8, 3, 2, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, 10, 19, 5, 17,
+ 17, 10, 75, 11, 0, 71, 0, 88, 83, 71, 76, 66, 71, 69, 9, 67, 69, 1,
+ 5, 71, 72, 64, 92, 87, 71, 95, 67, 75, 9, 65, 74, 19, 1, 65, 76, 20,
+ 73, 84, 1, 94, 18, 26, 23, 21, 26, 20, 8, 23, 23, 70, 5, 11, 4, 1,
+ 74, 3, 65, 67, 1, 68, 75, 0, 67, 90, 75, 73, 82, 77, 89, 34, 39, 32,
+ 32, 31, 25, 21, 25, 16, 9, 13, 3, 70, 72, 93, 13, 10, 70, 10, 2, 0,
+ 68, 72, 76, 78, 81, 95, 74, 87, 99, 90, 100, 65, 33, 23, 15, 5, 5, 64,
+ 68, 72, 74, 6, 46, 30, 23, 17, 29, 10, 4, 65, 67, 69, 37, 22, 13, 6,
+ 13, 2, 66, 71, 78, 76, 17, 5, 2, 66, 2, 71, 76, 81, 0, 40, 23, 14,
+ 7, 17, 3, 0, 65, 70, 62, 81, 72, 64, 66, 69, 1, 7, 8, 65, 7, 13,
+ 14, 77, 71, 73, 1, 15, 64, 66, 6, 12, 18, 73, 65, 12, 14, 80, 77, 80,
+ 81, 76, 66, 74, 70, 71, 68, 0, 73, 71, 70, 64, 76, 74, 81, 85, 68, 98,
+ 76, 64, 70, 9, 69, 65, 17, 67, 69, 66, 13, 75, 73, 92, 29, 33, 34, 27,
+ 17, 28, 24, 19, 18, 16, 15, 11, 70, 71, 78, 1, 3, 68, 85, 70, 70, 76,
+ 75, 76, 73, 74, 88, 85, 86, 31, 30, 29, 24, 13, 18, 15, 3, 9, 3, 2,
+ 73, 74, 78, 82, 12, 15, 71, 12, 13, 3, 66, 66, 68, 71, 70, 75, 84, 85,
+ 89, 93, 101, 79, 89, 96, 88, 74, 80, 64, 0, 1, 41, 11, 10, 68, 20, 52,
+ 39, 58, 10, 33, 28, 3, 77, 85, 90, 116, 115, 117, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 75, 79, 72, 2, 67, 9, 9, 1, 4, 9, 12, 13, 7, 16, 15,
+ 1, 34, 29, 19, 12, 6, 0, 85, 90, 93, 111, 98, 78, 62, 62, 62, 62},
+
+ {
+
+ 40, 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, 53, 14, 17, 66,
+ 11, 20, 0, 72, 65, 82, 98, 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0,
+ 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, 75, 88,
+ 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 52, 7,
+ 69, 94, 76, 82, 3, 66, 74, 66, 80, 3, 74, 73, 68, 90, 91, 91, 93, 24,
+ 64, 9, 78, 64, 77, 70, 68, 72, 85, 77, 88, 15, 72, 1, 82, 79, 65, 71,
+ 2, 8, 3, 3, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, 9, 19, 4, 17,
+ 17, 10, 77, 11, 0, 73, 64, 89, 82, 70, 75, 65, 70, 68, 10, 66, 69, 2,
+ 6, 71, 72, 64, 93, 86, 70, 95, 67, 75, 10, 65, 75, 20, 1, 65, 77, 21,
+ 74, 85, 1, 95, 17, 25, 23, 20, 25, 19, 7, 22, 23, 71, 4, 11, 4, 1,
+ 74, 2, 66, 68, 0, 69, 76, 64, 68, 92, 76, 74, 83, 78, 89, 32, 38, 30,
+ 30, 29, 23, 19, 23, 14, 7, 11, 1, 73, 74, 96, 11, 8, 72, 8, 0, 65,
+ 70, 74, 78, 81, 83, 97, 75, 89, 100, 91, 100, 65, 33, 23, 15, 5, 5, 64,
+ 68, 72, 73, 6, 46, 30, 23, 17, 30, 11, 5, 65, 66, 68, 38, 23, 13, 6,
+ 14, 3, 66, 70, 77, 75, 18, 6, 2, 66, 3, 70, 75, 80, 1, 40, 23, 14,
+ 7, 18, 4, 1, 64, 69, 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13,
+ 15, 77, 71, 73, 0, 15, 65, 67, 5, 11, 18, 74, 66, 12, 14, 81, 78, 81,
+ 80, 75, 65, 74, 69, 71, 67, 1, 73, 71, 70, 64, 77, 74, 81, 85, 67, 98,
+ 76, 64, 70, 10, 69, 65, 18, 67, 69, 66, 14, 76, 73, 93, 28, 33, 34, 26,
+ 16, 27, 23, 18, 17, 15, 14, 10, 71, 72, 79, 0, 2, 70, 87, 71, 71, 77,
+ 76, 76, 73, 74, 88, 86, 85, 29, 28, 27, 22, 10, 16, 13, 1, 7, 1, 0,
+ 75, 76, 79, 83, 10, 13, 72, 10, 11, 1, 68, 68, 70, 73, 72, 77, 86, 87,
+ 91, 95, 102, 81, 91, 98, 87, 73, 79, 0, 1, 2, 43, 12, 11, 68, 21, 54,
+ 40, 60, 11, 32, 26, 1, 80, 88, 93, 119, 117, 118, 69, 42, 28, 19, 9, 12,
+ 2, 65, 68, 74, 78, 71, 3, 66, 10, 10, 2, 5, 10, 13, 14, 7, 17, 15,
+ 1, 33, 28, 17, 10, 4, 65, 87, 92, 94, 110, 97, 77, 62, 62, 62, 62},
+
+ {
+
+ 38, 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, 52, 14, 19, 67,
+ 11, 20, 64, 73, 65, 84, 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, 64,
+ 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, 77, 75, 88,
+ 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 52, 6,
+ 69, 93, 76, 82, 3, 65, 73, 65, 79, 4, 73, 72, 67, 89, 91, 90, 93, 24,
+ 64, 9, 78, 64, 77, 70, 67, 72, 85, 77, 87, 15, 72, 1, 81, 79, 65, 71,
+ 2, 8, 3, 3, 15, 12, 77, 66, 1, 66, 2, 74, 11, 66, 8, 19, 3, 16,
+ 17, 9, 79, 10, 64, 75, 65, 90, 82, 70, 75, 65, 70, 68, 11, 66, 69, 2,
+ 7, 72, 72, 64, 95, 86, 70, 95, 67, 76, 10, 65, 76, 20, 1, 65, 79, 21,
+ 75, 86, 1, 96, 15, 24, 22, 19, 24, 18, 6, 21, 22, 73, 3, 10, 3, 1,
+ 75, 1, 67, 69, 64, 70, 77, 65, 69, 94, 78, 75, 85, 80, 89, 30, 36, 28,
+ 28, 27, 20, 16, 20, 11, 4, 8, 65, 76, 77, 99, 9, 6, 74, 5, 66, 68,
+ 73, 77, 81, 84, 86, 100, 76, 91, 102, 92, 101, 65, 33, 23, 15, 5, 5, 65,
+ 68, 72, 73, 6, 46, 30, 23, 17, 31, 11, 5, 65, 66, 68, 38, 23, 13, 6,
+ 14, 3, 66, 70, 76, 75, 19, 6, 2, 66, 3, 70, 75, 79, 1, 40, 23, 14,
+ 7, 18, 4, 1, 64, 69, 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13,
+ 15, 77, 71, 74, 64, 15, 66, 68, 4, 10, 17, 76, 68, 11, 13, 82, 80, 82,
+ 80, 75, 64, 74, 69, 71, 67, 1, 74, 71, 70, 64, 78, 74, 81, 85, 67, 99,
+ 76, 64, 70, 10, 70, 65, 18, 68, 70, 66, 14, 77, 74, 94, 27, 32, 33, 25,
+ 14, 26, 22, 17, 16, 14, 13, 9, 72, 74, 81, 65, 0, 72, 89, 73, 73, 78,
+ 77, 77, 73, 74, 88, 87, 85, 26, 25, 25, 19, 7, 13, 10, 65, 4, 65, 66,
+ 78, 79, 81, 84, 8, 11, 74, 8, 8, 65, 71, 71, 73, 75, 75, 80, 89, 89,
+ 94, 97, 104, 83, 93, 100, 86, 72, 78, 0, 1, 2, 44, 12, 11, 68, 21, 55,
+ 41, 61, 11, 30, 24, 65, 84, 91, 96, 122, 120, 120, 69, 42, 27, 18, 9, 12,
+ 2, 66, 68, 74, 78, 71, 3, 66, 11, 10, 2, 5, 10, 13, 14, 7, 17, 15,
+ 0, 31, 26, 15, 8, 2, 67, 90, 94, 95, 110, 96, 77, 62, 62, 62, 62},
+
+ {
+
+ 37, 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, 52, 14, 22, 67,
+ 12, 21, 64, 73, 64, 85, 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, 64,
+ 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 52, 6,
+ 69, 91, 75, 82, 4, 0, 71, 0, 77, 6, 71, 70, 65, 87, 90, 89, 92, 25,
+ 0, 10, 77, 0, 76, 69, 65, 71, 84, 76, 85, 16, 71, 2, 79, 78, 64, 70,
+ 3, 9, 4, 4, 16, 13, 77, 66, 2, 66, 2, 73, 11, 66, 8, 19, 3, 16,
+ 17, 9, 80, 10, 64, 76, 66, 90, 81, 69, 74, 64, 69, 67, 12, 65, 68, 3,
+ 9, 72, 72, 0, 96, 85, 69, 95, 66, 76, 11, 64, 76, 21, 1, 65, 80, 22,
+ 75, 87, 1, 96, 14, 24, 22, 19, 24, 18, 6, 21, 22, 74, 3, 10, 3, 1,
+ 75, 1, 67, 69, 64, 70, 78, 65, 69, 95, 79, 75, 86, 81, 89, 29, 35, 27,
+ 27, 26, 18, 14, 18, 9, 2, 6, 67, 78, 79, 101, 8, 5, 75, 3, 68, 70,
+ 75, 79, 83, 86, 88, 102, 76, 92, 103, 92, 101, 64, 34, 24, 16, 6, 5, 65,
+ 67, 71, 72, 7, 47, 31, 24, 17, 32, 12, 6, 64, 65, 67, 39, 24, 14, 7,
+ 15, 4, 65, 69, 74, 74, 21, 7, 3, 65, 4, 69, 74, 77, 2, 41, 24, 15,
+ 8, 19, 5, 2, 0, 68, 62, 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14,
+ 16, 76, 71, 74, 64, 16, 66, 68, 3, 10, 17, 77, 69, 11, 13, 82, 81, 82,
+ 79, 74, 0, 73, 68, 70, 66, 2, 74, 70, 69, 0, 78, 73, 80, 84, 66, 99,
+ 76, 0, 70, 11, 70, 65, 19, 68, 70, 65, 15, 77, 74, 94, 27, 32, 33, 25,
+ 13, 26, 22, 17, 16, 14, 13, 9, 72, 75, 82, 66, 64, 73, 90, 74, 74, 78,
+ 77, 77, 72, 73, 87, 87, 84, 24, 23, 23, 17, 5, 11, 8, 67, 2, 67, 68,
+ 80, 81, 82, 84, 7, 10, 75, 7, 6, 67, 73, 73, 75, 77, 77, 82, 91, 90,
+ 96, 98, 105, 84, 94, 101, 84, 70, 76, 1, 2, 3, 46, 13, 12, 68, 22, 57,
+ 43, 62, 12, 29, 23, 67, 87, 93, 98, 124, 122, 121, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 73, 77, 70, 4, 65, 13, 11, 3, 6, 11, 14, 15, 8, 18, 16,
+ 0, 30, 25, 14, 7, 1, 68, 92, 95, 95, 109, 94, 76, 62, 62, 62, 62},
+
+ {
+
+ 36, 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, 52, 14, 24, 67,
+ 13, 22, 64, 74, 64, 86, 102, 1, 2, 122, 124, 123, 34, 2, 69, 13, 22, 64,
+ 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, 64, 77, 74, 88,
+ 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 52, 6,
+ 69, 90, 74, 82, 4, 1, 69, 2, 76, 7, 69, 69, 0, 86, 89, 88, 91, 26,
+ 0, 11, 76, 0, 76, 68, 0, 71, 84, 76, 84, 16, 71, 2, 78, 78, 0, 70,
+ 3, 9, 4, 5, 16, 13, 78, 66, 2, 66, 2, 73, 11, 66, 7, 19, 2, 16,
+ 17, 9, 82, 10, 64, 78, 67, 91, 80, 68, 73, 0, 68, 66, 13, 64, 68, 4,
+ 10, 72, 72, 0, 97, 85, 68, 95, 66, 76, 12, 64, 77, 22, 1, 65, 81, 23,
+ 76, 88, 1, 97, 12, 23, 21, 18, 23, 17, 5, 20, 22, 75, 2, 10, 3, 1,
+ 75, 0, 68, 70, 65, 71, 79, 66, 70, 97, 80, 76, 87, 82, 89, 27, 34, 25,
+ 25, 24, 16, 12, 16, 6, 0, 4, 70, 81, 81, 104, 6, 3, 77, 1, 70, 72,
+ 77, 81, 85, 89, 90, 104, 77, 94, 104, 93, 101, 64, 34, 24, 16, 6, 5, 65,
+ 67, 71, 71, 7, 47, 31, 24, 17, 33, 12, 7, 64, 64, 66, 40, 25, 14, 7,
+ 16, 4, 65, 68, 73, 73, 22, 8, 3, 65, 5, 68, 73, 76, 2, 41, 24, 15,
+ 8, 20, 6, 3, 1, 67, 62, 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14,
+ 17, 76, 71, 74, 65, 16, 67, 69, 2, 9, 17, 78, 70, 11, 13, 83, 82, 83,
+ 78, 73, 1, 73, 68, 70, 65, 3, 74, 70, 69, 0, 79, 73, 80, 84, 65, 99,
+ 76, 0, 70, 12, 70, 65, 20, 68, 70, 65, 16, 78, 74, 95, 26, 32, 33, 24,
+ 12, 25, 21, 16, 15, 13, 12, 8, 73, 76, 83, 68, 65, 75, 92, 75, 75, 79,
+ 78, 77, 72, 73, 87, 88, 83, 22, 21, 21, 15, 2, 9, 6, 70, 0, 69, 70,
+ 82, 83, 83, 85, 5, 8, 76, 5, 4, 69, 75, 75, 77, 79, 79, 84, 93, 92,
+ 98, 100, 106, 86, 96, 103, 83, 69, 75, 2, 3, 4, 48, 14, 13, 68, 23, 58,
+ 44, 62, 13, 28, 21, 70, 90, 96, 101, 126, 124, 122, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 72, 76, 69, 5, 64, 14, 12, 4, 7, 12, 15, 16, 8, 19, 16,
+ 0, 29, 23, 12, 5, 64, 70, 94, 97, 96, 108, 93, 75, 62, 62, 62, 62},
+
+ {
+
+ 35, 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, 18, 52, 14, 26, 67,
+ 14, 23, 64, 75, 64, 87, 103, 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, 64,
+ 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, 64, 77, 74, 88,
+ 12, 0, 65, 69, 7, 3, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 52, 6,
+ 69, 89, 73, 82, 5, 2, 67, 4, 74, 8, 67, 68, 2, 85, 88, 87, 90, 27,
+ 0, 12, 75, 0, 75, 68, 2, 71, 83, 75, 83, 16, 71, 3, 76, 77, 1, 70,
+ 3, 9, 4, 6, 17, 14, 78, 66, 2, 66, 2, 73, 11, 67, 7, 19, 1, 16,
+ 17, 9, 84, 10, 65, 80, 68, 92, 79, 67, 72, 1, 67, 66, 14, 64, 67, 5,
+ 11, 72, 72, 0, 98, 84, 67, 95, 66, 76, 13, 64, 78, 23, 1, 65, 82, 24,
+ 76, 89, 1, 98, 11, 22, 21, 17, 22, 16, 5, 19, 21, 76, 1, 10, 3, 1,
+ 76, 64, 69, 71, 66, 72, 80, 67, 70, 99, 81, 76, 88, 83, 89, 26, 32, 24,
+ 23, 22, 14, 10, 14, 4, 66, 2, 72, 83, 84, 106, 4, 1, 78, 64, 72, 75,
+ 80, 83, 88, 91, 92, 107, 78, 96, 105, 94, 101, 64, 35, 24, 16, 6, 5, 65,
+ 67, 71, 71, 7, 47, 31, 24, 17, 34, 13, 7, 0, 64, 65, 41, 25, 15, 7,
+ 17, 5, 64, 68, 72, 72, 23, 9, 4, 65, 6, 67, 72, 75, 3, 41, 24, 15,
+ 8, 21, 6, 4, 2, 66, 62, 79, 70, 2, 66, 68, 1, 8, 9, 64, 8, 14,
+ 17, 76, 71, 74, 65, 17, 68, 70, 1, 8, 17, 79, 71, 11, 13, 83, 83, 83,
+ 77, 72, 2, 72, 67, 69, 65, 4, 74, 70, 69, 1, 79, 73, 80, 83, 64, 99,
+ 76, 0, 70, 13, 70, 65, 21, 68, 70, 65, 17, 79, 74, 96, 25, 31, 32, 23,
+ 11, 24, 20, 15, 14, 12, 11, 7, 74, 77, 84, 69, 66, 76, 94, 77, 76, 80,
+ 78, 78, 72, 73, 87, 88, 82, 20, 19, 19, 13, 64, 7, 4, 72, 65, 71, 72,
+ 85, 85, 85, 86, 3, 7, 78, 3, 2, 71, 77, 77, 79, 81, 81, 86, 96, 94,
+ 100, 102, 107, 88, 98, 104, 82, 68, 74, 3, 4, 5, 49, 15, 14, 68, 24, 60,
+ 46, 62, 14, 26, 20, 72, 93, 99, 104, 126, 126, 123, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 72, 75, 68, 6, 0, 15, 12, 4, 8, 12, 15, 16, 8, 19, 16,
+ 0, 28, 22, 10, 3, 66, 72, 96, 99, 97, 107, 91, 74, 62, 62, 62, 62},
+
+ {
+
+ 33, 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, 16, 52, 14,
+ 29, 68, 15, 23, 64, 76, 64, 88, 104, 0, 65, 125, 126, 124, 40, 4,
+ 69, 15, 23, 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5,
+ 69, 71, 65, 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, 0,
+ 1, 95, 97, 7, 70, 68, 52, 6, 69, 88, 72, 82, 5, 4, 66, 6,
+ 73, 9, 66, 66, 4, 84, 88, 86, 90, 27, 0, 13, 74, 0, 75, 67,
+ 4, 71, 83, 75, 82, 16, 70, 3, 75, 77, 1, 70, 4, 9, 4, 6,
+ 17, 14, 79, 67, 2, 66, 2, 73, 11, 67, 6, 19, 1, 16, 17, 8,
+ 86, 10, 65, 82, 69, 93, 78, 66, 71, 2, 67, 65, 15, 0, 67, 6,
+ 12, 72, 72, 1, 99, 84, 66, 95, 66, 76, 13, 64, 79, 24, 1, 65,
+ 84, 25, 77, 90, 1, 99, 9, 21, 20, 16, 21, 15, 4, 18, 21, 78,
+ 0, 9, 3, 1, 76, 65, 69, 72, 66, 73, 81, 68, 71, 101, 82, 77,
+ 89, 84, 89, 24, 31, 22, 21, 20, 12, 7, 12, 1, 68, 0, 75, 86,
+ 86, 109, 2, 0, 80, 67, 74, 77, 82, 86, 90, 94, 94, 109, 79, 97,
+ 107, 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31,
+ 24, 17, 35, 13, 8, 0, 0, 65, 42, 26, 15, 7, 17, 5, 64, 67,
+ 71, 72, 24, 9, 4, 65, 7, 66, 72, 74, 3, 42, 24, 15, 8, 22,
+ 7, 4, 3, 65, 62, 79, 70, 2, 66, 68, 1, 8, 9, 0, 8, 14,
+ 18, 76, 71, 74, 66, 17, 69, 71, 0, 7, 17, 81, 72, 10, 13, 84,
+ 84, 84, 77, 72, 3, 72, 67, 69, 64, 5, 75, 70, 69, 1, 80, 73,
+ 80, 83, 0, 99, 76, 1, 70, 13, 70, 65, 22, 68, 71, 65, 18, 79,
+ 75, 97, 24, 31, 32, 22, 10, 23, 19, 14, 13, 11, 10, 6, 75, 78,
+ 85, 71, 68, 78, 96, 78, 77, 81, 79, 78, 72, 73, 87, 89, 82, 17,
+ 16, 17, 10, 67, 5, 2, 75, 67, 73, 74, 87, 87, 86, 87, 1, 5,
+ 79, 1, 0, 73, 79, 80, 81, 83, 83, 88, 98, 96, 102, 104, 108, 90,
+ 100, 106, 81, 67, 73, 3, 5, 6, 51, 16, 15, 68, 25, 61, 47, 62,
+ 14, 25, 18, 75, 96, 102, 107, 126, 126, 124, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 71, 74, 67, 7, 0, 16, 13, 5, 9, 13, 16, 17, 9,
+ 20, 17, 0, 26, 20, 8, 1, 68, 74, 98, 101, 98, 106, 90, 74, 62,
+ 62, 62, 62},
+
+ {
+
+ 32, 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, 52, 14,
+ 31, 68, 16, 24, 64, 76, 0, 89, 105, 0, 67, 126, 126, 124, 43, 6,
+ 69, 16, 24, 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, 5,
+ 69, 70, 65, 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0,
+ 1, 95, 97, 8, 71, 68, 52, 6, 69, 87, 71, 82, 6, 5, 64, 8,
+ 71, 10, 64, 65, 6, 83, 87, 85, 89, 28, 0, 14, 73, 0, 74, 66,
+ 6, 71, 83, 74, 80, 17, 70, 4, 74, 76, 2, 70, 4, 10, 5, 7,
+ 18, 15, 79, 67, 2, 66, 2, 73, 11, 68, 5, 19, 0, 16, 17, 8,
+ 88, 10, 66, 83, 70, 94, 77, 65, 70, 3, 66, 64, 16, 1, 66, 7,
+ 13, 72, 72, 1, 100, 83, 65, 95, 65, 76, 14, 64, 80, 25, 1, 65,
+ 85, 26, 77, 91, 1, 99, 8, 20, 20, 15, 20, 14, 3, 18, 21, 79,
+ 64, 9, 3, 1, 77, 65, 70, 73, 67, 74, 82, 68, 72, 103, 83, 78,
+ 90, 85, 89, 22, 30, 20, 19, 19, 10, 5, 10, 64, 70, 65, 77, 88,
+ 88, 111, 0, 65, 82, 69, 76, 79, 84, 88, 92, 97, 96, 112, 80, 99,
+ 108, 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31,
+ 24, 17, 36, 14, 9, 0, 1, 64, 43, 27, 15, 8, 18, 6, 0, 67,
+ 70, 71, 26, 10, 4, 64, 8, 65, 71, 73, 4, 42, 25, 15, 8, 23,
+ 8, 5, 4, 64, 62, 79, 70, 3, 66, 68, 1, 8, 9, 0, 8, 15,
+ 18, 76, 71, 74, 67, 18, 70, 72, 64, 7, 17, 82, 73, 10, 13, 85,
+ 85, 84, 76, 71, 4, 71, 66, 68, 64, 6, 75, 70, 69, 1, 81, 73,
+ 80, 82, 1, 99, 76, 1, 70, 14, 70, 65, 23, 68, 71, 65, 19, 80,
+ 75, 97, 23, 31, 31, 22, 9, 22, 18, 13, 13, 10, 9, 5, 76, 79,
+ 86, 72, 69, 79, 98, 79, 78, 82, 80, 79, 72, 72, 87, 89, 81, 15,
+ 14, 15, 8, 69, 3, 0, 77, 69, 75, 76, 89, 89, 88, 88, 64, 3,
+ 80, 64, 65, 75, 81, 82, 83, 85, 85, 90, 101, 98, 104, 106, 109, 92,
+ 102, 107, 80, 65, 72, 4, 6, 7, 53, 17, 16, 68, 26, 62, 49, 62,
+ 15, 23, 16, 77, 99, 104, 110, 126, 126, 125, 68, 43, 27, 18, 9, 13,
+ 2, 66, 68, 71, 73, 66, 8, 1, 17, 14, 5, 10, 14, 17, 18, 9,
+ 20, 17, 0, 25, 19, 7, 0, 70, 76, 100, 103, 99, 105, 89, 73, 62,
+ 62, 62, 62},
+
+ {
+
+ 31, 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, 52, 14,
+ 33, 68, 16, 25, 64, 77, 0, 90, 106, 64, 68, 126, 126, 125, 46, 7,
+ 69, 16, 25, 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, 5,
+ 68, 70, 65, 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, 0,
+ 2, 95, 97, 8, 71, 69, 52, 6, 69, 86, 71, 82, 6, 6, 1, 10,
+ 70, 11, 1, 64, 8, 82, 86, 84, 88, 29, 0, 15, 73, 1, 74, 66,
+ 8, 71, 82, 74, 79, 17, 70, 4, 72, 76, 3, 69, 4, 10, 5, 8,
+ 18, 15, 80, 67, 2, 66, 2, 73, 11, 68, 5, 19, 64, 16, 17, 8,
+ 90, 10, 66, 85, 71, 95, 77, 64, 70, 3, 65, 64, 17, 1, 66, 7,
+ 15, 72, 72, 1, 101, 83, 64, 95, 65, 76, 15, 0, 81, 25, 1, 65,
+ 86, 27, 78, 92, 1, 100, 6, 19, 19, 15, 19, 14, 3, 17, 20, 80,
+ 65, 9, 3, 1, 77, 66, 71, 74, 68, 74, 83, 69, 72, 105, 84, 78,
+ 91, 86, 89, 21, 28, 19, 17, 17, 8, 3, 8, 67, 73, 67, 80, 91,
+ 91, 114, 65, 67, 83, 71, 79, 82, 87, 90, 95, 99, 99, 114, 81, 101,
+ 109, 96, 101, 0, 36, 25, 17, 6, 5, 65, 67, 71, 69, 8, 48, 32,
+ 24, 17, 37, 14, 9, 1, 1, 0, 44, 27, 16, 8, 19, 6, 0, 66,
+ 69, 70, 27, 11, 5, 64, 8, 65, 70, 71, 4, 42, 25, 15, 9, 23,
+ 8, 6, 4, 0, 62, 78, 69, 3, 66, 68, 1, 8, 9, 0, 9, 15,
+ 19, 76, 71, 75, 67, 18, 71, 73, 65, 6, 17, 83, 74, 10, 13, 85,
+ 86, 85, 75, 70, 5, 71, 66, 68, 0, 6, 75, 69, 68, 2, 81, 73,
+ 80, 82, 2, 99, 76, 1, 70, 15, 70, 65, 24, 69, 71, 65, 19, 81,
+ 75, 98, 22, 30, 31, 21, 8, 22, 18, 12, 12, 10, 8, 4, 77, 80,
+ 87, 74, 70, 81, 100, 81, 80, 83, 80, 79, 72, 72, 86, 90, 80, 13,
+ 12, 13, 6, 72, 1, 65, 80, 71, 78, 78, 92, 91, 89, 88, 65, 2,
+ 82, 66, 68, 77, 83, 84, 85, 87, 88, 92, 103, 100, 106, 107, 111, 94,
+ 104, 109, 79, 64, 71, 5, 7, 8, 54, 18, 17, 68, 27, 62, 50, 62,
+ 16, 22, 15, 80, 102, 107, 112, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 70, 72, 66, 9, 2, 18, 14, 6, 11, 14, 17, 18, 9,
+ 21, 17, 0, 24, 17, 5, 65, 71, 77, 103, 104, 100, 104, 87, 72, 62,
+ 62, 62, 62},
+
+ {
+
+ 30, 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, 52, 14,
+ 36, 69, 17, 25, 64, 78, 0, 91, 107, 64, 70, 126, 126, 125, 49, 8,
+ 69, 17, 25, 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5,
+ 68, 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0,
+ 2, 95, 97, 9, 72, 69, 52, 6, 69, 85, 70, 82, 7, 8, 2, 12,
+ 68, 12, 2, 1, 10, 81, 85, 83, 88, 30, 0, 16, 72, 1, 73, 65,
+ 10, 71, 82, 73, 78, 17, 69, 5, 71, 75, 3, 69, 5, 10, 5, 9,
+ 19, 16, 80, 68, 2, 66, 2, 73, 11, 69, 4, 19, 64, 16, 17, 7,
+ 92, 10, 67, 87, 72, 96, 76, 0, 69, 4, 64, 0, 18, 2, 65, 8,
+ 16, 72, 72, 2, 102, 82, 0, 95, 65, 76, 15, 0, 82, 26, 1, 65,
+ 88, 28, 78, 93, 1, 101, 5, 18, 19, 14, 18, 13, 2, 16, 20, 81,
+ 66, 9, 3, 1, 78, 67, 71, 75, 68, 75, 84, 70, 73, 107, 85, 79,
+ 92, 87, 89, 19, 27, 17, 15, 15, 6, 0, 6, 69, 75, 69, 82, 93,
+ 93, 116, 67, 68, 85, 74, 81, 84, 89, 93, 97, 102, 101, 117, 82, 102,
+ 111, 97, 101, 0, 36, 26, 17, 6, 5, 65, 67, 71, 69, 9, 49, 32,
+ 24, 17, 38, 15, 10, 1, 2, 1, 45, 28, 16, 8, 20, 7, 1, 66,
+ 68, 70, 28, 11, 5, 64, 9, 64, 70, 70, 5, 43, 25, 15, 9, 24,
+ 9, 7, 5, 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15,
+ 19, 76, 71, 75, 68, 19, 72, 74, 66, 5, 17, 84, 75, 9, 13, 86,
+ 87, 85, 74, 70, 6, 70, 65, 67, 0, 7, 75, 69, 68, 2, 82, 73,
+ 80, 81, 3, 99, 76, 2, 70, 15, 70, 65, 25, 69, 71, 65, 20, 81,
+ 76, 99, 21, 30, 30, 20, 7, 21, 17, 11, 11, 9, 7, 3, 78, 81,
+ 88, 75, 72, 82, 102, 82, 81, 84, 81, 80, 72, 72, 86, 90, 79, 11,
+ 10, 11, 3, 75, 64, 67, 82, 73, 80, 80, 94, 93, 91, 89, 67, 0,
+ 83, 68, 70, 79, 85, 86, 87, 89, 90, 94, 106, 102, 108, 109, 112, 96,
+ 106, 110, 78, 0, 70, 5, 8, 9, 56, 19, 18, 68, 28, 62, 52, 62,
+ 16, 20, 13, 82, 105, 110, 115, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 70, 71, 65, 10, 3, 19, 15, 6, 12, 15, 18, 19, 10,
+ 21, 18, 0, 22, 16, 3, 67, 73, 79, 105, 106, 101, 103, 86, 72, 62,
+ 62, 62, 62},
+
+ {
+
+ 28, 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, 52, 14,
+ 38, 69, 18, 26, 64, 79, 0, 92, 109, 65, 72, 126, 126, 126, 51, 9,
+ 69, 18, 26, 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5,
+ 68, 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, 0, 0,
+ 3, 96, 97, 9, 73, 69, 52, 6, 69, 84, 69, 82, 7, 9, 4, 14,
+ 67, 13, 4, 2, 11, 80, 85, 82, 87, 30, 0, 17, 71, 1, 73, 65,
+ 11, 71, 82, 73, 77, 17, 69, 5, 70, 75, 4, 69, 5, 10, 5, 9,
+ 19, 16, 81, 68, 2, 66, 2, 73, 11, 69, 3, 19, 65, 16, 17, 7,
+ 94, 10, 67, 89, 73, 97, 75, 1, 68, 5, 64, 0, 19, 2, 65, 9,
+ 17, 72, 72, 2, 104, 82, 1, 95, 65, 77, 16, 0, 83, 27, 1, 65,
+ 89, 29, 79, 94, 1, 102, 3, 17, 18, 13, 17, 12, 1, 15, 19, 83,
+ 67, 8, 3, 1, 78, 68, 72, 76, 69, 76, 85, 71, 74, 109, 87, 80,
+ 93, 88, 89, 17, 25, 15, 13, 13, 4, 65, 4, 72, 78, 71, 85, 96,
+ 96, 119, 69, 70, 87, 76, 83, 87, 92, 95, 100, 105, 103, 119, 83, 104,
+ 112, 98, 102, 0, 36, 26, 17, 6, 5, 65, 67, 71, 68, 9, 49, 32,
+ 24, 17, 39, 15, 10, 1, 2, 1, 46, 28, 16, 8, 20, 7, 1, 65,
+ 67, 69, 29, 12, 5, 64, 10, 0, 69, 69, 5, 43, 25, 15, 9, 25,
+ 9, 7, 6, 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15,
+ 20, 76, 71, 75, 69, 19, 73, 75, 67, 4, 17, 86, 77, 9, 13, 87,
+ 88, 86, 74, 69, 7, 70, 65, 67, 1, 8, 76, 69, 68, 2, 83, 73,
+ 80, 81, 3, 100, 76, 2, 70, 16, 70, 65, 25, 69, 72, 65, 21, 82,
+ 76, 100, 20, 29, 30, 19, 5, 20, 16, 10, 10, 8, 6, 2, 79, 82,
+ 89, 77, 73, 84, 104, 84, 82, 85, 82, 80, 72, 72, 86, 91, 79, 8,
+ 7, 9, 1, 78, 67, 70, 85, 75, 82, 82, 97, 95, 92, 90, 69, 65,
+ 85, 70, 72, 82, 88, 89, 90, 91, 92, 97, 108, 104, 111, 111, 113, 98,
+ 108, 112, 77, 1, 69, 6, 9, 9, 57, 20, 18, 68, 28, 62, 53, 62,
+ 17, 19, 11, 85, 108, 113, 118, 126, 126, 126, 67, 43, 27, 18, 9, 13,
+ 2, 66, 68, 69, 71, 64, 11, 3, 20, 15, 7, 12, 15, 18, 19, 10,
+ 22, 18, 64, 21, 14, 1, 69, 75, 81, 107, 108, 102, 103, 85, 71, 62,
+ 62, 62, 62},
+
+ {
+
+ 27, 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, 52, 14,
+ 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, 74, 126, 126, 126, 54, 11,
+ 69, 19, 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5,
+ 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, 0, 0,
+ 4, 96, 97, 9, 74, 69, 52, 6, 69, 83, 68, 82, 7, 10, 6, 16,
+ 65, 15, 6, 3, 13, 79, 84, 81, 86, 31, 1, 18, 70, 1, 72, 64,
+ 13, 71, 81, 73, 75, 18, 69, 5, 68, 75, 5, 69, 5, 11, 6, 10,
+ 19, 16, 81, 68, 3, 66, 2, 72, 11, 69, 3, 19, 66, 16, 17, 7,
+ 96, 10, 67, 90, 74, 97, 74, 2, 67, 6, 0, 1, 20, 3, 65, 10,
+ 18, 72, 72, 2, 105, 81, 2, 95, 64, 77, 17, 0, 84, 28, 1, 65,
+ 90, 30, 80, 95, 1, 102, 2, 16, 18, 12, 16, 11, 1, 15, 19, 84,
+ 68, 8, 3, 1, 78, 68, 73, 77, 70, 77, 86, 71, 74, 110, 88, 80,
+ 94, 89, 89, 16, 24, 14, 12, 12, 2, 67, 2, 74, 80, 73, 87, 99,
+ 98, 122, 70, 72, 88, 78, 85, 89, 94, 97, 102, 107, 105, 121, 83, 106,
+ 113, 98, 102, 0, 37, 26, 17, 7, 5, 65, 66, 71, 67, 9, 49, 32,
+ 25, 17, 40, 16, 11, 2, 3, 2, 47, 29, 17, 9, 21, 8, 1, 64,
+ 66, 68, 31, 13, 6, 0, 11, 1, 68, 68, 6, 43, 26, 16, 9, 26,
+ 10, 8, 7, 2, 62, 77, 68, 5, 66, 68, 1, 9, 10, 1, 9, 16,
+ 21, 76, 71, 75, 69, 19, 74, 75, 68, 4, 17, 87, 78, 9, 13, 87,
+ 89, 87, 73, 68, 8, 70, 64, 67, 2, 9, 76, 69, 68, 3, 83, 73,
+ 80, 81, 4, 100, 76, 2, 70, 17, 70, 65, 26, 69, 72, 65, 22, 83,
+ 76, 100, 19, 29, 30, 19, 4, 19, 15, 9, 10, 7, 5, 2, 79, 83,
+ 90, 78, 74, 86, 106, 85, 83, 85, 82, 80, 71, 71, 86, 92, 78, 6,
+ 5, 7, 64, 80, 69, 72, 87, 77, 84, 84, 99, 97, 93, 91, 71, 66,
+ 86, 72, 74, 84, 90, 91, 92, 93, 94, 99, 110, 105, 113, 113, 114, 100,
+ 110, 114, 76, 3, 67, 7, 10, 10, 59, 21, 19, 68, 29, 62, 54, 62,
+ 18, 18, 10, 87, 111, 115, 121, 126, 126, 126, 67, 43, 27, 18, 9, 14,
+ 2, 66, 68, 68, 70, 0, 12, 4, 22, 16, 8, 13, 16, 19, 20, 10,
+ 23, 18, 64, 20, 13, 0, 70, 77, 83, 109, 110, 102, 102, 83, 70, 62,
+ 62, 62, 62},
+
+ {
+
+ 26, 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, 52, 14,
+ 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, 76, 126, 126, 126, 57, 12,
+ 69, 20, 27, 64, 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5,
+ 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 4, 96, 97, 10, 75, 69, 52, 6, 69, 82, 67, 82, 8, 12, 7, 18,
+ 64, 16, 7, 5, 15, 78, 83, 80, 86, 32, 1, 19, 69, 1, 72, 0,
+ 15, 71, 81, 72, 74, 18, 68, 6, 67, 74, 5, 69, 6, 11, 6, 11,
+ 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, 2, 19, 66, 16, 17, 6,
+ 98, 10, 68, 92, 75, 98, 73, 3, 66, 7, 1, 2, 21, 4, 64, 11,
+ 19, 72, 72, 3, 106, 81, 3, 95, 64, 77, 17, 0, 85, 29, 1, 65,
+ 92, 31, 80, 96, 1, 103, 0, 15, 17, 11, 15, 10, 0, 14, 19, 85,
+ 69, 8, 3, 1, 79, 69, 73, 78, 70, 78, 87, 72, 75, 112, 89, 81,
+ 95, 90, 89, 14, 23, 12, 10, 10, 0, 70, 0, 77, 82, 75, 90, 101,
+ 100, 124, 72, 73, 90, 81, 87, 91, 96, 100, 104, 110, 107, 124, 84, 107,
+ 115, 99, 102, 0, 37, 27, 17, 7, 5, 65, 66, 71, 67, 10, 50, 32,
+ 25, 17, 41, 16, 12, 2, 4, 3, 48, 30, 17, 9, 22, 8, 2, 64,
+ 65, 68, 32, 13, 6, 0, 12, 2, 68, 67, 6, 44, 26, 16, 9, 27,
+ 11, 9, 8, 3, 62, 77, 68, 5, 66, 68, 1, 9, 10, 2, 9, 16,
+ 21, 76, 71, 75, 70, 20, 75, 76, 69, 3, 17, 88, 79, 8, 13, 88,
+ 90, 87, 72, 68, 9, 69, 64, 66, 2, 10, 76, 69, 68, 3, 84, 73,
+ 80, 80, 5, 100, 76, 3, 70, 17, 70, 65, 27, 69, 72, 65, 23, 83,
+ 77, 101, 18, 29, 29, 18, 3, 18, 14, 8, 9, 6, 4, 1, 80, 84,
+ 91, 80, 76, 87, 108, 86, 84, 86, 83, 81, 71, 71, 86, 92, 77, 4,
+ 3, 5, 67, 83, 71, 74, 90, 79, 86, 86, 101, 99, 95, 92, 73, 68,
+ 87, 74, 76, 86, 92, 93, 94, 95, 96, 101, 113, 107, 115, 115, 115, 102,
+ 112, 115, 75, 4, 66, 7, 11, 11, 61, 22, 20, 68, 30, 62, 56, 62,
+ 18, 16, 8, 90, 114, 118, 124, 126, 126, 126, 67, 43, 27, 18, 9, 14,
+ 2, 66, 68, 68, 69, 1, 13, 5, 23, 17, 8, 14, 17, 20, 21, 11,
+ 23, 19, 64, 18, 11, 65, 72, 79, 85, 111, 112, 103, 101, 82, 70, 62,
+ 62, 62, 62},
+
+ {
+
+ 25, 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, 52, 14,
+ 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, 77, 126, 126, 126, 60, 13,
+ 69, 20, 28, 64, 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5,
+ 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, 0, 0,
+ 5, 96, 97, 10, 75, 70, 52, 6, 69, 81, 67, 82, 8, 13, 9, 20,
+ 1, 17, 9, 6, 17, 77, 82, 79, 85, 33, 1, 20, 69, 2, 71, 0,
+ 17, 71, 80, 72, 73, 18, 68, 6, 65, 74, 6, 68, 6, 11, 6, 12,
+ 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, 2, 19, 67, 16, 17, 6,
+ 100, 10, 68, 94, 76, 99, 73, 4, 66, 7, 2, 2, 22, 4, 64, 11,
+ 21, 72, 72, 3, 107, 80, 4, 95, 64, 77, 18, 1, 86, 29, 1, 65,
+ 93, 32, 81, 97, 1, 104, 64, 14, 17, 11, 14, 10, 0, 13, 18, 86,
+ 70, 8, 3, 1, 79, 70, 74, 79, 71, 78, 88, 73, 75, 114, 90, 81,
+ 96, 91, 89, 13, 21, 11, 8, 8, 65, 72, 65, 79, 85, 77, 92, 104,
+ 103, 126, 74, 75, 91, 83, 90, 94, 99, 102, 107, 112, 110, 126, 85, 109,
+ 116, 100, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, 10, 50, 33,
+ 25, 17, 42, 17, 12, 3, 4, 4, 49, 30, 18, 9, 23, 9, 2, 0,
+ 64, 67, 33, 14, 7, 0, 12, 2, 67, 65, 7, 44, 26, 16, 10, 27,
+ 11, 10, 8, 4, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, 16,
+ 22, 76, 71, 76, 70, 20, 76, 77, 70, 2, 17, 89, 80, 8, 13, 88,
+ 91, 88, 71, 67, 10, 69, 0, 66, 3, 10, 76, 68, 67, 4, 84, 73,
+ 80, 80, 6, 100, 76, 3, 70, 18, 70, 65, 28, 70, 72, 65, 23, 84,
+ 77, 102, 17, 28, 29, 17, 2, 18, 14, 7, 8, 6, 3, 0, 81, 85,
+ 92, 81, 77, 89, 110, 88, 86, 87, 83, 81, 71, 71, 85, 93, 76, 2,
+ 1, 3, 69, 86, 73, 76, 92, 81, 89, 88, 104, 101, 96, 92, 74, 69,
+ 89, 76, 79, 88, 94, 95, 96, 97, 99, 103, 115, 109, 117, 116, 117, 104,
+ 114, 117, 74, 5, 65, 8, 12, 12, 62, 23, 21, 68, 31, 62, 57, 62,
+ 19, 15, 7, 92, 117, 121, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 67, 68, 1, 14, 6, 24, 17, 9, 15, 17, 20, 21, 11,
+ 24, 19, 64, 17, 10, 67, 74, 80, 86, 114, 113, 104, 100, 80, 69, 62,
+ 62, 62, 62},
+
+ {
+
+ 23, 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, 52, 14,
+ 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, 79, 126, 126, 126, 62, 14,
+ 69, 21, 29, 64, 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5,
+ 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, 0, 0,
+ 5, 97, 97, 11, 76, 70, 52, 6, 69, 80, 66, 82, 9, 14, 11, 22,
+ 2, 18, 11, 7, 19, 76, 82, 78, 84, 33, 1, 21, 68, 2, 71, 1,
+ 19, 71, 80, 71, 72, 18, 68, 7, 64, 73, 7, 68, 6, 11, 6, 12,
+ 21, 18, 83, 69, 3, 66, 2, 72, 11, 71, 1, 19, 68, 16, 17, 6,
+ 102, 10, 69, 96, 77, 100, 72, 5, 65, 8, 2, 3, 23, 5, 0, 12,
+ 22, 72, 72, 3, 108, 80, 5, 95, 64, 77, 19, 1, 87, 30, 1, 65,
+ 94, 33, 81, 98, 1, 105, 66, 13, 16, 10, 13, 9, 64, 12, 18, 88,
+ 71, 7, 3, 1, 80, 71, 75, 80, 72, 79, 89, 74, 76, 116, 91, 82,
+ 97, 92, 89, 11, 20, 9, 6, 6, 67, 74, 67, 82, 87, 79, 95, 106,
+ 105, 126, 76, 77, 93, 85, 92, 96, 101, 104, 109, 115, 112, 126, 86, 111,
+ 117, 101, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, 10, 50, 33,
+ 25, 17, 43, 17, 13, 3, 5, 4, 50, 31, 18, 9, 23, 9, 3, 0,
+ 0, 66, 34, 15, 7, 0, 13, 3, 66, 64, 7, 44, 26, 16, 10, 28,
+ 12, 10, 9, 5, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, 16,
+ 22, 76, 71, 76, 71, 21, 77, 78, 71, 1, 17, 91, 81, 8, 13, 89,
+ 92, 88, 71, 66, 11, 68, 0, 65, 3, 11, 77, 68, 67, 4, 85, 73,
+ 80, 79, 7, 100, 76, 3, 70, 19, 70, 65, 29, 70, 73, 65, 24, 85,
+ 77, 103, 16, 28, 28, 16, 1, 17, 13, 6, 7, 5, 2, 64, 82, 86,
+ 93, 83, 78, 90, 112, 89, 87, 88, 84, 82, 71, 71, 85, 93, 76, 64,
+ 65, 1, 71, 89, 75, 78, 95, 83, 91, 90, 106, 103, 98, 93, 76, 71,
+ 90, 78, 81, 90, 96, 98, 98, 99, 101, 105, 118, 111, 119, 118, 118, 106,
+ 116, 118, 73, 6, 64, 9, 13, 13, 62, 24, 22, 68, 32, 62, 59, 62,
+ 20, 13, 5, 95, 120, 124, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 67, 67, 2, 15, 6, 25, 18, 9, 16, 18, 21, 22, 11,
+ 24, 19, 64, 16, 8, 69, 76, 82, 88, 116, 115, 105, 99, 79, 68, 62,
+ 62, 62, 62},
+
+ {
+
+ 22, 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, 52, 14,
+ 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, 81, 126, 126, 126, 62, 16,
+ 69, 22, 29, 64, 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, 0, 0,
+ 6, 97, 97, 11, 77, 70, 52, 6, 69, 79, 65, 82, 9, 16, 12, 24,
+ 4, 19, 12, 9, 21, 75, 81, 77, 84, 34, 1, 22, 67, 2, 70, 2,
+ 21, 71, 80, 71, 70, 19, 67, 7, 0, 73, 7, 68, 7, 12, 7, 13,
+ 21, 18, 83, 70, 3, 66, 2, 72, 11, 71, 0, 19, 68, 16, 17, 5,
+ 104, 10, 69, 97, 78, 101, 71, 6, 64, 9, 3, 4, 24, 6, 0, 13,
+ 23, 72, 72, 4, 109, 79, 6, 95, 0, 77, 19, 1, 88, 31, 1, 65,
+ 96, 34, 82, 99, 1, 105, 67, 12, 16, 9, 12, 8, 65, 12, 18, 89,
+ 72, 7, 3, 1, 80, 71, 75, 81, 72, 80, 90, 74, 77, 118, 92, 83,
+ 98, 93, 89, 9, 19, 7, 4, 5, 69, 77, 69, 84, 89, 81, 97, 109,
+ 107, 126, 78, 78, 95, 88, 94, 98, 103, 107, 111, 118, 114, 126, 87, 112,
+ 119, 101, 102, 1, 38, 28, 18, 7, 5, 65, 66, 71, 65, 11, 51, 33,
+ 25, 17, 44, 18, 14, 3, 6, 5, 51, 32, 18, 10, 24, 10, 3, 1,
+ 1, 66, 36, 15, 7, 1, 14, 4, 66, 0, 8, 45, 27, 16, 10, 29,
+ 13, 11, 10, 6, 62, 76, 67, 7, 66, 68, 1, 9, 10, 3, 10, 17,
+ 23, 76, 71, 76, 72, 21, 78, 79, 72, 1, 17, 92, 82, 7, 13, 90,
+ 93, 89, 70, 66, 12, 68, 1, 65, 4, 12, 77, 68, 67, 4, 86, 73,
+ 80, 79, 8, 100, 76, 4, 70, 19, 70, 65, 30, 70, 73, 65, 25, 85,
+ 78, 103, 15, 28, 28, 16, 0, 16, 12, 5, 7, 4, 1, 65, 83, 87,
+ 94, 84, 80, 92, 114, 90, 88, 89, 85, 82, 71, 70, 85, 94, 75, 66,
+ 67, 64, 74, 91, 77, 80, 97, 85, 93, 92, 108, 105, 99, 94, 78, 73,
+ 91, 80, 83, 92, 98, 100, 100, 101, 103, 107, 120, 113, 121, 120, 119, 108,
+ 118, 120, 72, 8, 0, 9, 14, 14, 62, 25, 23, 68, 33, 62, 60, 62,
+ 20, 12, 3, 97, 123, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 66, 66, 3, 16, 7, 26, 19, 10, 17, 19, 22, 23, 12,
+ 25, 20, 64, 14, 7, 70, 77, 84, 90, 118, 117, 106, 98, 78, 68, 62,
+ 62, 62, 62},
+
+ {
+
+ 21, 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, 52, 14,
+ 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, 83, 126, 126, 126, 62, 17,
+ 69, 23, 30, 64, 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5,
+ 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 6, 97, 97, 12, 78, 70, 52, 6, 69, 78, 64, 82, 10, 17, 14, 26,
+ 5, 20, 14, 10, 23, 74, 80, 76, 83, 35, 1, 23, 66, 2, 70, 2,
+ 23, 71, 79, 70, 69, 19, 67, 8, 2, 72, 8, 68, 7, 12, 7, 14,
+ 22, 19, 84, 70, 3, 66, 2, 72, 11, 72, 0, 19, 69, 16, 17, 5,
+ 106, 10, 70, 99, 79, 102, 70, 7, 0, 10, 4, 4, 25, 6, 1, 14,
+ 24, 72, 72, 4, 110, 79, 7, 95, 0, 77, 20, 1, 89, 32, 1, 65,
+ 97, 35, 82, 100, 1, 106, 69, 11, 15, 8, 11, 7, 65, 11, 17, 90,
+ 73, 7, 3, 1, 81, 72, 76, 82, 73, 81, 91, 75, 77, 120, 93, 83,
+ 99, 94, 89, 8, 17, 6, 2, 3, 71, 79, 71, 87, 92, 83, 100, 111,
+ 110, 126, 80, 80, 96, 90, 96, 101, 106, 109, 114, 120, 116, 126, 88, 114,
+ 120, 102, 102, 1, 39, 28, 18, 7, 5, 65, 66, 71, 65, 11, 51, 33,
+ 25, 17, 45, 18, 14, 4, 6, 6, 52, 32, 19, 10, 25, 10, 4, 1,
+ 2, 65, 37, 16, 8, 1, 15, 5, 65, 1, 8, 45, 27, 16, 10, 30,
+ 13, 12, 11, 7, 62, 75, 66, 7, 66, 68, 1, 9, 10, 3, 10, 17,
+ 23, 76, 71, 76, 72, 22, 79, 80, 73, 0, 17, 93, 83, 7, 13, 90,
+ 94, 89, 69, 65, 13, 67, 1, 64, 4, 13, 77, 68, 67, 5, 86, 73,
+ 80, 78, 9, 100, 76, 4, 70, 20, 70, 65, 31, 70, 73, 65, 26, 86,
+ 78, 104, 14, 27, 27, 15, 64, 15, 11, 4, 6, 3, 0, 66, 84, 88,
+ 95, 86, 81, 93, 116, 92, 89, 90, 85, 83, 71, 70, 85, 94, 74, 68,
+ 69, 66, 76, 94, 79, 82, 100, 87, 95, 94, 111, 107, 101, 95, 80, 74,
+ 93, 82, 85, 94, 100, 102, 102, 103, 105, 109, 123, 115, 123, 122, 120, 110,
+ 120, 121, 71, 9, 1, 10, 15, 15, 62, 26, 24, 68, 34, 62, 62, 62,
+ 21, 10, 2, 100, 126, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 66, 65, 4, 17, 8, 27, 19, 10, 18, 19, 22, 23, 12,
+ 25, 20, 64, 13, 5, 72, 79, 86, 92, 120, 119, 107, 97, 76, 67, 62,
+ 62, 62, 62},
+
+ {
+
+ 20, 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, 2, 52, 14,
+ 54, 71, 24, 31, 64, 84, 2, 99, 116, 69, 85, 126, 126, 126, 62, 18,
+ 69, 24, 31, 64, 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5,
+ 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, 0,
+ 7, 97, 97, 12, 79, 70, 52, 6, 69, 77, 0, 82, 10, 18, 16, 28,
+ 7, 21, 16, 11, 25, 73, 79, 75, 82, 36, 1, 24, 65, 2, 69, 3,
+ 25, 71, 79, 70, 68, 19, 67, 8, 3, 72, 9, 68, 7, 12, 7, 15,
+ 22, 19, 84, 70, 3, 66, 2, 72, 11, 72, 64, 19, 70, 16, 17, 5,
+ 108, 10, 70, 101, 80, 103, 69, 8, 1, 11, 5, 5, 26, 7, 1, 15,
+ 25, 72, 72, 4, 111, 78, 8, 95, 0, 77, 21, 1, 90, 33, 1, 65,
+ 98, 36, 83, 101, 1, 107, 70, 10, 15, 7, 10, 6, 66, 10, 17, 91,
+ 74, 7, 3, 1, 81, 73, 77, 83, 74, 82, 92, 76, 78, 122, 94, 84,
+ 100, 95, 89, 6, 16, 4, 0, 1, 73, 81, 73, 89, 94, 85, 102, 114,
+ 112, 126, 82, 82, 98, 92, 98, 103, 108, 111, 116, 123, 118, 126, 89, 116,
+ 121, 103, 102, 1, 39, 28, 18, 7, 5, 65, 66, 71, 64, 11, 51, 33,
+ 25, 17, 46, 19, 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2,
+ 3, 64, 38, 17, 8, 1, 16, 6, 64, 2, 9, 45, 27, 16, 10, 31,
+ 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, 10, 3, 10, 17,
+ 24, 76, 71, 76, 73, 22, 80, 81, 74, 64, 17, 94, 84, 7, 13, 91,
+ 95, 90, 68, 64, 14, 67, 2, 64, 5, 14, 77, 68, 67, 5, 87, 73,
+ 80, 78, 10, 100, 76, 4, 70, 21, 70, 65, 32, 70, 73, 65, 27, 87,
+ 78, 105, 13, 27, 27, 14, 65, 14, 10, 3, 5, 2, 64, 67, 85, 89,
+ 96, 87, 82, 95, 118, 93, 90, 91, 86, 83, 71, 70, 85, 95, 73, 70,
+ 71, 68, 78, 97, 81, 84, 102, 89, 97, 96, 113, 109, 102, 96, 82, 76,
+ 94, 84, 87, 96, 102, 104, 104, 105, 107, 111, 125, 117, 125, 124, 121, 112,
+ 122, 123, 70, 10, 2, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, 62,
+ 22, 9, 0, 102, 126, 126, 126, 126, 126, 126, 66, 43, 27, 18, 9, 14,
+ 2, 66, 68, 65, 64, 5, 18, 9, 28, 20, 11, 19, 20, 23, 24, 12,
+ 26, 20, 64, 12, 4, 74, 81, 88, 94, 122, 121, 108, 96, 75, 66, 62,
+ 62, 62, 62},
+
+ {
+
+ 18, 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, 0, 51, 14,
+ 56, 72, 24, 31, 65, 85, 2, 101, 118, 70, 87, 126, 126, 126, 62, 19,
+ 70, 24, 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5,
+ 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, 0, 0,
+ 7, 98, 97, 12, 80, 71, 52, 5, 69, 76, 0, 82, 10, 19, 17, 29,
+ 8, 22, 17, 12, 26, 72, 79, 74, 82, 36, 1, 24, 65, 2, 69, 3,
+ 26, 71, 79, 70, 67, 19, 67, 8, 4, 72, 9, 68, 7, 12, 7, 15,
+ 22, 19, 85, 71, 3, 67, 2, 72, 10, 73, 65, 19, 71, 15, 17, 4,
+ 110, 9, 71, 103, 81, 104, 69, 8, 1, 11, 5, 5, 27, 7, 1, 15,
+ 26, 73, 72, 4, 113, 78, 8, 95, 0, 78, 21, 1, 91, 33, 1, 65,
+ 100, 36, 84, 102, 1, 108, 72, 9, 14, 6, 9, 5, 67, 9, 16, 93,
+ 75, 6, 2, 1, 82, 74, 78, 84, 75, 83, 93, 77, 79, 124, 96, 85,
+ 102, 97, 89, 4, 14, 2, 65, 64, 76, 84, 76, 92, 97, 88, 105, 117,
+ 115, 126, 84, 84, 100, 95, 101, 106, 111, 114, 119, 126, 121, 126, 90, 118,
+ 123, 104, 103, 1, 39, 28, 18, 7, 5, 66, 66, 71, 64, 11, 51, 33,
+ 25, 17, 47, 19, 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2,
+ 4, 64, 39, 17, 8, 1, 16, 6, 64, 3, 9, 45, 27, 16, 10, 31,
+ 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, 10, 3, 10, 17,
+ 24, 76, 71, 77, 74, 22, 81, 82, 75, 65, 16, 96, 86, 6, 12, 92,
+ 97, 91, 68, 64, 15, 67, 2, 64, 5, 14, 78, 68, 67, 5, 88, 73,
+ 80, 78, 10, 101, 76, 4, 70, 21, 71, 65, 32, 71, 74, 65, 27, 88,
+ 79, 106, 12, 26, 26, 13, 67, 13, 9, 2, 4, 1, 65, 68, 86, 91,
+ 98, 89, 84, 97, 120, 95, 92, 92, 87, 84, 71, 70, 85, 96, 73, 73,
+ 74, 70, 81, 100, 84, 87, 105, 92, 100, 99, 116, 112, 104, 97, 84, 78,
+ 96, 86, 90, 99, 105, 107, 107, 107, 110, 114, 126, 119, 126, 126, 123, 114,
+ 124, 125, 69, 11, 3, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, 62,
+ 22, 7, 65, 105, 126, 126, 126, 126, 126, 126, 66, 43, 26, 17, 9, 14,
+ 2, 67, 68, 65, 64, 5, 18, 9, 29, 20, 11, 19, 20, 23, 24, 12,
+ 26, 20, 65, 10, 2, 76, 83, 90, 96, 125, 123, 109, 96, 74, 66, 62,
+ 62, 62, 62},
+
+ {
+
+ 17, 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, 64, 51, 14,
+ 59, 72, 25, 32, 65, 85, 3, 102, 119, 70, 88, 126, 126, 126, 62, 21,
+ 70, 25, 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5,
+ 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 8, 98, 97, 13, 80, 71, 52, 5, 69, 74, 1, 82, 11, 21, 19, 31,
+ 10, 24, 19, 14, 28, 70, 78, 73, 81, 37, 2, 25, 64, 3, 68, 4,
+ 28, 70, 78, 69, 65, 20, 66, 9, 6, 71, 10, 67, 8, 13, 8, 16,
+ 23, 20, 85, 71, 4, 67, 2, 71, 10, 73, 65, 19, 71, 15, 17, 4,
+ 111, 9, 71, 104, 82, 104, 68, 9, 2, 12, 6, 6, 28, 8, 2, 16,
+ 28, 73, 72, 5, 114, 77, 9, 95, 1, 78, 22, 2, 91, 34, 1, 65,
+ 101, 37, 84, 103, 1, 108, 73, 9, 14, 6, 9, 5, 67, 9, 16, 94,
+ 75, 6, 2, 1, 82, 74, 78, 84, 75, 83, 94, 77, 79, 125, 97, 85,
+ 103, 98, 89, 3, 13, 1, 66, 65, 78, 86, 78, 94, 99, 90, 107, 119,
+ 117, 126, 85, 85, 101, 97, 103, 108, 113, 116, 121, 126, 123, 126, 90, 119,
+ 124, 104, 103, 2, 40, 29, 19, 8, 5, 66, 65, 70, 0, 12, 52, 34,
+ 26, 17, 48, 20, 16, 5, 8, 8, 54, 34, 20, 11, 27, 12, 5, 3,
+ 6, 0, 41, 18, 9, 2, 17, 7, 0, 5, 10, 46, 28, 17, 11, 32,
+ 15, 14, 13, 9, 62, 74, 65, 9, 66, 67, 1, 10, 11, 4, 11, 18,
+ 25, 75, 71, 77, 74, 23, 81, 82, 76, 65, 16, 97, 87, 6, 12, 92,
+ 98, 91, 67, 0, 16, 66, 3, 0, 6, 15, 78, 67, 66, 6, 88, 72,
+ 79, 77, 11, 101, 76, 5, 70, 22, 71, 65, 33, 71, 74, 64, 28, 88,
+ 79, 106, 12, 26, 26, 13, 68, 13, 9, 2, 4, 1, 65, 68, 86, 92,
+ 99, 90, 85, 98, 121, 96, 93, 92, 87, 84, 70, 69, 84, 96, 72, 75,
+ 76, 72, 83, 102, 86, 89, 107, 94, 102, 101, 118, 114, 105, 97, 85, 79,
+ 97, 87, 92, 101, 107, 109, 109, 109, 112, 116, 126, 120, 126, 126, 124, 115,
+ 125, 126, 67, 13, 5, 12, 17, 17, 62, 28, 26, 68, 36, 62, 62, 62,
+ 23, 6, 66, 107, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 64, 0, 6, 19, 10, 31, 21, 12, 20, 21, 24, 25, 13,
+ 27, 21, 65, 9, 1, 77, 84, 91, 97, 126, 124, 109, 95, 72, 65, 62,
+ 62, 62, 62},
+
+ {
+
+ 16, 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, 65, 51, 14,
+ 61, 72, 26, 33, 65, 86, 3, 103, 120, 71, 90, 126, 126, 126, 62, 22,
+ 70, 26, 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, 0, 0,
+ 9, 98, 97, 13, 81, 71, 52, 5, 69, 73, 2, 82, 11, 22, 21, 33,
+ 11, 25, 21, 15, 30, 69, 77, 72, 80, 38, 2, 26, 0, 3, 68, 5,
+ 30, 70, 78, 69, 64, 20, 66, 9, 7, 71, 11, 67, 8, 13, 8, 17,
+ 23, 20, 86, 71, 4, 67, 2, 71, 10, 73, 66, 19, 72, 15, 17, 4,
+ 113, 9, 71, 106, 83, 105, 67, 10, 3, 13, 7, 7, 29, 9, 2, 17,
+ 29, 73, 72, 5, 115, 77, 10, 95, 1, 78, 23, 2, 92, 35, 1, 65,
+ 102, 38, 85, 104, 1, 109, 75, 8, 13, 5, 8, 4, 68, 8, 16, 95,
+ 76, 6, 2, 1, 82, 75, 79, 85, 76, 84, 95, 78, 80, 126, 98, 86,
+ 104, 99, 89, 1, 12, 64, 68, 67, 80, 88, 80, 97, 101, 92, 110, 122,
+ 119, 126, 87, 87, 103, 99, 105, 110, 115, 118, 123, 126, 125, 126, 91, 121,
+ 125, 105, 103, 2, 40, 29, 19, 8, 5, 66, 65, 70, 1, 12, 52, 34,
+ 26, 17, 49, 20, 17, 5, 9, 9, 55, 35, 20, 11, 28, 12, 5, 4,
+ 7, 1, 42, 19, 9, 2, 18, 8, 1, 6, 10, 46, 28, 17, 11, 33,
+ 16, 15, 14, 10, 62, 74, 65, 9, 66, 67, 1, 10, 11, 4, 11, 18,
+ 26, 75, 71, 77, 75, 23, 82, 83, 77, 66, 16, 98, 88, 6, 12, 93,
+ 99, 92, 66, 1, 17, 66, 3, 0, 7, 16, 78, 67, 66, 6, 89, 72,
+ 79, 77, 12, 101, 76, 5, 70, 23, 71, 65, 34, 71, 74, 64, 29, 89,
+ 79, 107, 11, 26, 26, 12, 69, 12, 8, 1, 3, 0, 66, 69, 87, 93,
+ 100, 92, 86, 100, 123, 97, 94, 93, 88, 84, 70, 69, 84, 97, 71, 77,
+ 78, 74, 85, 105, 88, 91, 110, 96, 104, 103, 120, 116, 106, 98, 87, 81,
+ 98, 89, 94, 103, 109, 111, 111, 111, 114, 118, 126, 122, 126, 126, 125, 117,
+ 126, 126, 66, 14, 6, 13, 18, 18, 62, 29, 27, 68, 37, 62, 62, 62,
+ 24, 5, 68, 110, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 0, 1, 7, 20, 11, 32, 22, 13, 21, 22, 25, 26, 13,
+ 28, 21, 65, 8, 64, 79, 86, 93, 99, 126, 126, 110, 94, 71, 64, 62,
+ 62, 62, 62},
+
+ {
+
+ 15, 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, 66, 51, 14,
+ 62, 72, 27, 34, 65, 87, 3, 104, 121, 71, 92, 126, 126, 126, 62, 23,
+ 70, 27, 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5,
+ 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, 0, 0,
+ 9, 98, 97, 14, 82, 71, 52, 5, 69, 72, 3, 82, 12, 23, 23, 35,
+ 13, 26, 23, 16, 32, 68, 76, 71, 79, 39, 2, 27, 1, 3, 67, 5,
+ 32, 70, 77, 68, 0, 20, 66, 10, 9, 70, 12, 67, 8, 13, 8, 18,
+ 24, 21, 86, 71, 4, 67, 2, 71, 10, 74, 66, 19, 73, 15, 17, 4,
+ 115, 9, 72, 108, 84, 106, 66, 11, 4, 14, 8, 7, 30, 9, 3, 18,
+ 30, 73, 72, 5, 116, 76, 11, 95, 1, 78, 24, 2, 93, 36, 1, 65,
+ 103, 39, 85, 105, 1, 110, 76, 7, 13, 4, 7, 3, 68, 7, 15, 96,
+ 77, 6, 2, 1, 83, 76, 80, 86, 77, 85, 96, 79, 80, 126, 99, 86,
+ 105, 100, 89, 0, 10, 65, 70, 69, 82, 90, 82, 99, 104, 94, 112, 124,
+ 122, 126, 89, 89, 104, 101, 107, 113, 118, 120, 126, 126, 126, 126, 92, 123,
+ 126, 106, 103, 2, 41, 29, 19, 8, 5, 66, 65, 70, 1, 12, 52, 34,
+ 26, 17, 50, 21, 17, 6, 9, 10, 56, 35, 21, 11, 29, 13, 6, 4,
+ 8, 2, 43, 20, 10, 2, 19, 9, 2, 7, 11, 46, 28, 17, 11, 34,
+ 16, 16, 15, 11, 62, 73, 64, 10, 66, 67, 1, 10, 11, 4, 11, 18,
+ 26, 75, 71, 77, 75, 24, 83, 84, 78, 67, 16, 99, 89, 6, 12, 93,
+ 100, 92, 65, 2, 18, 65, 4, 1, 7, 17, 78, 67, 66, 7, 89, 72,
+ 79, 76, 13, 101, 76, 5, 70, 24, 71, 65, 35, 71, 74, 64, 30, 90,
+ 79, 108, 10, 25, 25, 11, 70, 11, 7, 0, 2, 64, 67, 70, 88, 94,
+ 101, 93, 87, 101, 125, 99, 95, 94, 88, 85, 70, 69, 84, 97, 70, 79,
+ 80, 76, 87, 108, 90, 93, 112, 98, 106, 105, 123, 118, 108, 99, 89, 82,
+ 100, 91, 96, 105, 111, 113, 113, 113, 116, 120, 126, 124, 126, 126, 126, 119,
+ 126, 126, 65, 15, 7, 14, 19, 19, 62, 30, 28, 68, 38, 62, 62, 62,
+ 25, 3, 69, 112, 126, 126, 126, 126, 126, 126, 65, 44, 26, 17, 9, 15,
+ 2, 67, 68, 0, 2, 8, 21, 12, 33, 22, 13, 22, 22, 25, 26, 13,
+ 28, 21, 65, 7, 65, 81, 88, 95, 101, 126, 126, 111, 93, 69, 0, 62,
+ 62, 62, 62},
+
+ },
+};
+
+#endif /* _ISVCD_CABAC_INIT_TABLES_H_ */
diff --git a/decoder/svc/isvcd_compute_bs.c b/decoder/svc/isvcd_compute_bs.c
new file mode 100644
index 0000000..2a50e11
--- /dev/null
+++ b/decoder/svc/isvcd_compute_bs.c
@@ -0,0 +1,965 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_compute_bs.c
+ *
+ * @brief
+ * This file contains bit flags and info on target layer.
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_deblk_extract_bit_flags()
+ * - isvcd_fill_bs_ibl()
+ * - isvcd_compute_bs_non_mbaff_target_lyr_no_inter_layer()
+ * - isvcd_compute_bs_non_mbaff()
+ * - isvcd_compute_bs_non_mbaff_target_lyr()
+ * - isvcd_compute_bs_non_mbaff_medial_lyr()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_deblocking.h"
+#include "string.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+UWORD16 ih264d_update_csbp_8x8(UWORD16 u2_luma_csbp);
+void ih264d_fill_bs2_horz_vert(UWORD32 *pu4_bs, /* Base pointer of BS table */
+ WORD32 u4_left_mb_csbp, /* csbp of left mb */
+ WORD32 u4_top_mb_csbp, /* csbp of top mb */
+ WORD32 u4_cur_mb_csbp, /* csbp of current mb */
+ const UWORD32 *pu4_packed_bs2, const UWORD16 *pu2_4x4_v2h_reorder);
+const UWORD32 g_au4_extract_set[NUM_SUB_MB_PARTS] = {0x00000000F, 0x0000000F0, 0x000000F00,
+ 0x00000F000};
+
+/** \brief extracts the bits from given offset and packs it to last 4 bits */
+UWORD16 isvcd_deblk_extract_bit_flags(UWORD16 u2_bit_field, WORD32 i4_initial_bit_mask)
+{
+ WORD32 i4_i;
+ WORD32 i4_bit_mask;
+ UWORD16 u2_result = 0;
+
+ i4_bit_mask = i4_initial_bit_mask;
+
+ for(i4_i = 0; i4_i < NUM_SUB_MB_PARTS; i4_i++)
+ {
+ WORD32 i4_bit;
+ /* extract the bits of the last column 4x4 blocks */
+ if(0 == (i4_bit_mask & u2_bit_field))
+ {
+ i4_bit = 0;
+ }
+ else
+ {
+ i4_bit = 1;
+ }
+ /* store the result */
+ u2_result |= i4_bit << i4_i;
+ i4_bit_mask <<= 4;
+
+ } /* end of loop over num sub Mb parts */
+ return (u2_result);
+}
+
+/** \brief Fills the BS for edges falling on a IBL boundary */
+void isvcd_fill_bs_ibl(deblk_mb_t *ps_deblk_mb, UWORD8 u1_top_mb_type, UWORD8 u1_left_mb_type,
+ dec_mb_info_t *ps_cur_mb_info, UWORD16 *pu2_curr_res_luma_csbp,
+ UWORD16 *pu2_left_res_luma_csbp, UWORD16 *pu2_top_res_luma_csbp)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. checks if MB edge is falling on IBL boundary */
+ /*! 2. if only Mb edge then it fills the BS based on INTRA or INTER
+ stauts */
+ /*! 3. if the current MB is IBL and neighbours are also neighbours
+ then it uses the current layer t_coeff flag to decide the
+ BS of a particular edge */
+ /*!4. fills the BS for all the edges in curretn MB if IBL */
+
+ UWORD16 u2_top_horz_nnz;
+ UWORD8 u1_top_mb_ibl, u1_left_mb_ibl;
+ UWORD32 i4_i, i4_edge;
+ UWORD8 u1_bs;
+ UWORD8 u1_cnd;
+ UWORD8 u1_top_intra;
+ UWORD8 u1_left_intra;
+ UWORD8 u1_p_nnz, u1_q_nnz;
+ UWORD8 u1_curr_mb_ibl;
+ UWORD32 *pu4_bs_table;
+ UWORD16 u2_curr_nnz;
+ UWORD8 u1_left_mb_nnz = 0, u1_left_nnz;
+ WORD32 i4_horz_start = 0;
+ WORD32 i4_vertical_start = 0;
+
+ pu4_bs_table = &(ps_deblk_mb->u4_bs_table[0]);
+
+ u1_top_mb_ibl = u1_top_mb_type & D_INTRA_IBL;
+ u1_left_mb_ibl = u1_left_mb_type & D_INTRA_IBL;
+
+ u1_curr_mb_ibl = ps_deblk_mb->u1_mb_type & D_INTRA_IBL;
+
+ u1_top_intra = u1_top_mb_type & D_INTRA_MB;
+ u1_left_intra = u1_left_mb_type & D_INTRA_MB;
+
+ /* return if none of the current top and left is IBL */
+ if((0 == u1_curr_mb_ibl) && (0 == u1_top_mb_ibl) && (0 == u1_left_mb_ibl))
+ {
+ return;
+ }
+
+ /* set up the vertical and horz MB edge skip flags */
+ if(0 != u1_curr_mb_ibl)
+ {
+ /* if top is not IBL */
+ if(0 == u1_top_mb_ibl)
+ {
+ i4_horz_start = 1;
+ }
+
+ /* if left in not IBL */
+ if(0 == u1_left_mb_ibl)
+ {
+ i4_vertical_start = 1;
+ }
+ }
+
+ /*******************************************************/
+ /* Fill BS for mb egdex assuming non IBL case */
+ /*******************************************************/
+
+ /* only the MB edges fall across IBL boundary */
+ if((0 != u1_curr_mb_ibl) || (0 != u1_top_mb_ibl) || (0 != u1_left_mb_ibl))
+ {
+ UWORD16 u2_temp, u2_i;
+ u2_temp = *pu2_left_res_luma_csbp;
+ for(u2_i = 0; u2_i < 4; u2_i++)
+ {
+ u1_left_mb_nnz |= ((u2_temp & 0x08) >> (3 - u2_i));
+ u2_temp >>= 4;
+ }
+ u2_curr_nnz = *pu2_curr_res_luma_csbp;
+ u2_top_horz_nnz = *pu2_top_res_luma_csbp >> 12;
+
+ /* top is intra and not ibl */
+ if(0 != u1_top_intra)
+ {
+ pu4_bs_table[0] = 0x04040404;
+ }
+ /* left is intra and not ibl */
+ if(0 != u1_left_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ }
+
+ /* assume neighbours are inter and update bs */
+
+ /* Edge = 0 means Vert Edges and Edge = 1 means Horz edges */
+ for(i4_edge = 0; i4_edge < 2; i4_edge++)
+ {
+ UWORD8 u1_p_nnz, u1_q_nnz;
+ UWORD32 u4_bs_edge = 0;
+ WORD32 i4_bit_mask;
+ WORD32 i4_curr_intra_flag;
+ WORD32 i4_neibor_intra_flag;
+
+ i4_curr_intra_flag = (0 != u1_curr_mb_ibl);
+
+ if(0 != i4_edge)
+ {
+ /* Initialize for the TOP edge */
+ u1_p_nnz = (UWORD8) u2_top_horz_nnz;
+ u1_q_nnz = (UWORD8) (u2_curr_nnz & g_au4_extract_set[0]);
+ i4_neibor_intra_flag = (u1_top_mb_ibl || u1_top_intra);
+ }
+ else
+ {
+ u1_p_nnz = u1_left_mb_nnz;
+ u1_q_nnz = (UWORD8) isvcd_deblk_extract_bit_flags(u2_curr_nnz, 0x01);
+ i4_neibor_intra_flag = (u1_left_mb_ibl || u1_left_intra);
+ }
+
+ i4_bit_mask = 1;
+ /* find bs of 4 edges */
+ for(i4_i = 0; i4_i < 4; i4_i++)
+ {
+ UWORD8 u1_p_nnz_temp, u1_q_nnz_temp;
+
+ u1_p_nnz_temp = (u1_p_nnz & i4_bit_mask);
+ u1_q_nnz_temp = (u1_q_nnz & i4_bit_mask);
+
+ u1_cnd = ((u1_p_nnz_temp && (!i4_neibor_intra_flag)) ||
+ (u1_q_nnz_temp && (!i4_curr_intra_flag)));
+
+ u1_bs = u1_cnd ? 2 : 1;
+
+ /* update the bs of the edge */
+ u4_bs_edge = (u4_bs_edge << 8) + u1_bs;
+ i4_bit_mask <<= 1;
+
+ } /* end of loop over blk edges */
+
+ /* update the bs of edges */
+ if(i4_edge && !u1_top_intra)
+ {
+ pu4_bs_table[0] = u4_bs_edge;
+ }
+ else if(!i4_edge && !u1_left_intra)
+ {
+ pu4_bs_table[4] = u4_bs_edge;
+ }
+ } /* end of loop over v1 vetical and horizontal edge */
+ }
+ /* current MB is IBL */
+ if(0 != u1_curr_mb_ibl)
+ {
+ UWORD16 u2_temp, u2_i;
+ WORD32 i4_bit_mask_edge = 1;
+
+ u1_left_mb_nnz = 0;
+ u2_temp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp;
+ for(u2_i = 0; u2_i < 4; u2_i++)
+ {
+ u1_left_mb_nnz |= ((u2_temp & 0x08) >> (3 - u2_i));
+ u2_temp >>= 4;
+ }
+ u2_curr_nnz = ps_cur_mb_info->ps_curmb->u2_luma_csbp;
+ u2_top_horz_nnz = ps_cur_mb_info->ps_top_mb->u2_luma_csbp >> 12;
+ /* all are IBL edges then use only t_coeff of current layer*/
+ /* loop over all edges */
+ for(i4_edge = 0; i4_edge < 4; i4_edge++)
+ {
+ UWORD16 u2_curr_horz_nnz = 0;
+ WORD32 i4_bit_mask = 1;
+
+ u2_curr_horz_nnz = u2_curr_nnz & g_au4_extract_set[i4_edge];
+
+ u2_curr_horz_nnz = (u2_curr_horz_nnz >> (i4_edge * 4));
+
+ u1_left_nnz = (u1_left_mb_nnz & i4_bit_mask_edge);
+
+ for(i4_i = 0; i4_i < 4; i4_i++)
+ {
+ UWORD8 u1_curr_nnz, u1_top_nnz;
+
+ u1_curr_nnz = (u2_curr_horz_nnz & i4_bit_mask);
+ u1_top_nnz = (u2_top_horz_nnz & i4_bit_mask);
+ /* update bs horizontal */
+
+ if(!((1 == i4_horz_start) && (0 == i4_edge)))
+ {
+ u1_p_nnz = u1_top_nnz;
+ u1_q_nnz = u1_curr_nnz;
+ u1_cnd = !(u1_p_nnz || u1_q_nnz);
+ u1_bs = u1_cnd ? 0 : 1;
+ pu4_bs_table[i4_edge] = (pu4_bs_table[i4_edge] << 8) + u1_bs;
+ }
+
+ /* update bs vertical */
+ if(!((1 == i4_vertical_start) && (0 == i4_i)))
+ {
+ u1_p_nnz = u1_left_nnz;
+ u1_q_nnz = u1_curr_nnz;
+ u1_cnd = !(u1_p_nnz || u1_q_nnz);
+ u1_bs = u1_cnd ? 0 : 1;
+ pu4_bs_table[i4_i + 4] = (pu4_bs_table[i4_i + 4] << 8) + u1_bs;
+ }
+ /* store the current nnz to left nnz */
+ u1_left_nnz = u1_curr_nnz;
+ i4_bit_mask <<= 1;
+ }
+ /* store the current row nnz to top row nnz */
+ u2_top_horz_nnz = u2_curr_horz_nnz;
+ i4_bit_mask_edge <<= 1;
+ }
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_bs_non_mbaff_target_lyr_no_inter_layer */
+/* */
+/* Description : This function computes the pointers of left,top & current*/
+/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function */
+/* : for Boundary Strength Calculation */
+/* Inputs : <What inputs does the function take?> */
+/* Processing : This functions calls deblock MB in the MB increment order*/
+/* */
+/* Outputs : Produces the Boundary Strength for Current Mb */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore */
+/*****************************************************************************/
+
+void isvcd_compute_bs_non_mbaff_target_lyr_no_inter_layer(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ const UWORD16 u2_mbxn_mb)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* Mvpred and Nnz for top and Courrent */
+ mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred;
+ /* deblk_mb_t Params */
+ deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */
+ deblkmb_neighbour_t *ps_deblk_top_mb;
+
+ /* Reference Index to POC mapping*/
+ void **apv_map_ref_idx_to_poc;
+ UWORD32 u4_leftmbtype;
+
+ UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp;
+
+ /* Set of flags */
+ UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld;
+ UWORD32 u1_cur_mb_type;
+ UWORD32 *pu4_bs_table;
+
+ /* Neighbour availability */
+ /* Initialization */
+ const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx;
+ const UWORD32 u2_mby = ps_cur_mb_info->u2_mby;
+ const UWORD32 u1_pingpong = u2_mbx & 0x01;
+
+ PROFILE_DISABLE_BOUNDARY_STRENGTH()
+
+ ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx;
+
+ /* Pointer assignment for Current DeblkMB, Current Mv Pred */
+ ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb;
+ ps_cur_mv_pred = ps_dec->ps_mv_cur + (u2_mbxn_mb << 4);
+
+ apv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc + 1;
+ u1_cur_mb_type = ps_cur_mb_params->u1_mb_type;
+ u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type;
+ ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type;
+
+ ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp;
+ ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+ ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp;
+ ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+
+ /* if no deblocking required for current Mb then continue */
+ /* Check next Mbs in Mb group */
+ if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING)
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+ {
+ /* Store Parameter for Top MvPred refernce frame Address */
+
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ }
+
+ return;
+ }
+
+ /* Flag for extra left Edge */
+ ps_cur_mb_params->u1_single_call = 1;
+
+ /* Update the Left deblk_mb_t and Left MvPred Parameters */
+ if(!u2_mbx)
+ {
+ u4_leftmbtype = 0;
+
+ /* Initialize the ps_left_mv_pred with Junk but Valid Location */
+ /* to avoid invalid memory access */
+ /* this is read only pointer */
+ ps_left_mv_pred = ps_dec->ps_mv_cur + 3;
+ }
+ else
+ {
+ u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type;
+
+ /* Come to Left Most Edge of the MB */
+ ps_left_mv_pred =
+ (u2_mbxn_mb) ? ps_dec->ps_mv_cur + ((u2_mbxn_mb - 1) << 4) + 3 : ps_dec->ps_mv_left + 3;
+ }
+
+ if(!u2_mby) u1_top_mb_typ = 0;
+
+ /* MvPred Pointer Calculation */
+ ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 4) + 12;
+
+ u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB;
+ u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB);
+ /* Compute BS function */
+ pu4_bs_table = ps_cur_mb_params->u4_bs_table;
+
+ u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp;
+ u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp;
+ u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp;
+ /* Compute BS function */
+ if((ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC))
+ {
+ if(ps_cur_mb_info->u1_tran_form8x8 == 1)
+ {
+ u2_cur_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_curmb->u2_luma_csbp);
+ }
+
+ if(ps_cur_mb_info->ps_left_mb->u1_tran_form8x8 == 1)
+ {
+ u2_left_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_left_mb->u2_luma_csbp);
+ }
+
+ if(ps_cur_mb_info->ps_top_mb->u1_tran_form8x8 == 1)
+ {
+ u2_top_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_top_mb->u2_luma_csbp);
+ }
+ }
+ if(u4_cur_mb_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ pu4_bs_table[1] = 0x03030303;
+ pu4_bs_table[2] = 0x03030303;
+ pu4_bs_table[3] = 0x03030303;
+ pu4_bs_table[5] = 0x03030303;
+ pu4_bs_table[6] = 0x03030303;
+ pu4_bs_table[7] = 0x03030303;
+ }
+ else
+ {
+ UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16);
+ UWORD32 u4_is_b = ps_dec->u1_B;
+
+ ih264d_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp,
+ (const UWORD32 *) (gau4_ih264d_packed_bs2),
+ (const UWORD16 *) (gau2_ih264d_4x4_v2h_reorder));
+
+ if(u4_leftmbtype & D_INTRA_MB) pu4_bs_table[4] = 0x04040404;
+
+ if(u1_top_mb_typ & D_INTRA_MB) pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+
+ ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16](
+ ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, pu4_bs_table, ps_left_mv_pred,
+ &(ps_dec->ps_left_mvpred_addr[u1_pingpong][1]),
+ ps_cur_mb_info->ps_top_mb->u4_pic_addrress, (4 >> u4_cur_mb_fld));
+ }
+
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+ {
+ /* Store Parameter for Top MvPred refernce frame Address */
+
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ }
+ }
+
+ /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */
+ if(ps_cur_mb_info->u1_tran_form8x8)
+ {
+ pu4_bs_table[1] = 0;
+ pu4_bs_table[3] = 0;
+ pu4_bs_table[5] = 0;
+ pu4_bs_table[7] = 0;
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_bs_non_mbaff */
+/* */
+/* Description : This function computes the pointers of left,top & current*/
+/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function */
+/* : for Boundary Strength Calculation */
+/* Inputs : <What inputs does the function take?> */
+/* Processing : This functions calls deblock MB in the MB increment order*/
+/* */
+/* Outputs : Produces the Boundary Strength for Current Mb */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore */
+/*****************************************************************************/
+
+void isvcd_compute_bs_non_mbaff(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ const UWORD16 u2_mbxn_mb)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ ps_dec->pf_compute_bs(ps_dec, ps_cur_mb_info, u2_mbxn_mb);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_bs_non_mbaff_target_lyr */
+/* */
+/* Description : This function computes the pointers of left,top & current*/
+/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function */
+/* : for Boundary Strength Calculation */
+/* Inputs : <What inputs does the function take?> */
+/* Processing : This functions calls deblock MB in the MB increment order*/
+/* */
+/* Outputs : Produces the Boundary Strength for Current Mb */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore */
+/*****************************************************************************/
+
+void isvcd_compute_bs_non_mbaff_target_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, const UWORD16 u2_mbxn_mb)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* Mvpred and Nnz for top and Courrent */
+ mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred;
+ /* deblk_mb_t Params */
+ deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */
+ deblkmb_neighbour_t *ps_deblk_top_mb;
+
+ /* Reference Index to POC mapping*/
+ void **apv_map_ref_idx_to_poc;
+ UWORD32 u4_leftmbtype;
+ UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp;
+
+ /* Set of flags */
+ UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld;
+ UWORD32 u4_cur_mb_ibl;
+ UWORD32 u1_cur_mb_type;
+ UWORD32 *pu4_bs_table;
+
+ UWORD16 *pu2_curr_res_luma_csbp;
+ UWORD16 *pu2_left_res_luma_csbp;
+ UWORD16 *pu2_top_res_luma_csbp;
+
+ /* Neighbour availability */
+ /* Initialization */
+ const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx;
+ const UWORD32 u2_mby = ps_cur_mb_info->u2_mby;
+ const UWORD32 u1_pingpong = u2_mbx & 0x01;
+
+ PROFILE_DISABLE_BOUNDARY_STRENGTH()
+
+ ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx;
+
+ /* Pointer assignment for Current DeblkMB, Current Mv Pred */
+ ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb;
+ ps_cur_mv_pred = ps_dec->ps_mv_cur + (u2_mbxn_mb << 4);
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_curr_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_curr_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ pu2_left_res_luma_csbp = pu2_curr_res_luma_csbp - (ps_cur_mb_info->u2_mbx != 0);
+ pu2_top_res_luma_csbp = pu2_curr_res_luma_csbp - ((ps_cur_mb_info->u2_mby != 0) *
+ ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride);
+
+ apv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc + 1;
+ u1_cur_mb_type = ps_cur_mb_params->u1_mb_type;
+ u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type;
+ ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type;
+
+ ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp;
+ ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+ ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp;
+ ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+
+ /* if no deblocking required for current Mb then continue */
+ /* Check next Mbs in Mb group */
+ if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING)
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+
+ /* Store Parameter for Top MvPred refernce frame Address */
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+
+ return;
+ }
+
+ /* Flag for extra left Edge */
+ ps_cur_mb_params->u1_single_call = 1;
+
+ /* Update the Left deblk_mb_t and Left MvPred Parameters */
+ if(!u2_mbx)
+ {
+ u4_leftmbtype = 0;
+
+ /* Initialize the ps_left_mv_pred with Junk but Valid Location */
+ /* to avoid invalid memory access */
+ /* this is read only pointer */
+ ps_left_mv_pred = ps_dec->ps_mv_cur + 3;
+ }
+ else
+ {
+ u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type;
+
+ /* Come to Left Most Edge of the MB */
+ ps_left_mv_pred =
+ (u2_mbxn_mb) ? ps_dec->ps_mv_cur + ((u2_mbxn_mb - 1) << 4) + 3 : ps_dec->ps_mv_left + 3;
+ }
+
+ if(!u2_mby) u1_top_mb_typ = 0;
+
+ /* MvPred Pointer Calculation */
+ ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 4) + 12;
+ u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB;
+ u4_cur_mb_ibl = u1_cur_mb_type & D_INTRA_IBL;
+ u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB);
+ /* Compute BS function */
+ pu4_bs_table = ps_cur_mb_params->u4_bs_table;
+
+ u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp;
+ u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp;
+ u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp;
+ /* Compute BS function */
+ if((ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC))
+ {
+ if(ps_cur_mb_info->u1_tran_form8x8 == 1)
+ {
+ u2_cur_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_curmb->u2_luma_csbp);
+ ps_cur_mb_info->ps_curmb->u2_luma_csbp = u2_cur_csbp;
+ }
+ }
+ u2_cur_csbp |= *pu2_curr_res_luma_csbp;
+ u2_left_csbp |= *pu2_left_res_luma_csbp;
+ u2_top_csbp |= *pu2_top_res_luma_csbp;
+
+ if(u4_cur_mb_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ pu4_bs_table[1] = 0x03030303;
+ pu4_bs_table[2] = 0x03030303;
+ pu4_bs_table[3] = 0x03030303;
+ pu4_bs_table[5] = 0x03030303;
+ pu4_bs_table[6] = 0x03030303;
+ pu4_bs_table[7] = 0x03030303;
+ }
+ else
+ {
+ isvcd_fill_bs_ibl(ps_cur_mb_params, u1_top_mb_typ, u4_leftmbtype, ps_cur_mb_info,
+ pu2_curr_res_luma_csbp, pu2_left_res_luma_csbp, pu2_top_res_luma_csbp);
+
+ if(!u4_cur_mb_ibl)
+ {
+ UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16);
+ UWORD32 u4_is_b = ps_dec->u1_B;
+ UWORD32 u4_bs_0, u4_bs_4;
+
+ u4_bs_0 = pu4_bs_table[0];
+ u4_bs_4 = pu4_bs_table[4];
+
+ ih264d_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp,
+ (const UWORD32 *) (gau4_ih264d_packed_bs2),
+ (const UWORD16 *) (gau2_ih264d_4x4_v2h_reorder));
+
+ if(u4_leftmbtype & D_INTRA_MB)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ }
+ else if(u4_leftmbtype & D_INTRA_IBL)
+ {
+ pu4_bs_table[4] = u4_bs_4;
+ }
+
+ if(u1_top_mb_typ & D_INTRA_MB)
+ {
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ }
+ else if(u1_top_mb_typ & D_INTRA_IBL)
+ {
+ pu4_bs_table[0] = u4_bs_0;
+ }
+
+ ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16](
+ ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, pu4_bs_table,
+ ps_left_mv_pred, &(ps_dec->ps_left_mvpred_addr[u1_pingpong][1]),
+ ps_cur_mb_info->ps_top_mb->u4_pic_addrress, (4 >> u4_cur_mb_fld));
+ }
+ }
+
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+ /* Store Parameter for Top MvPred refernce frame Address */
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ }
+
+ /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */
+ if(ps_cur_mb_info->u1_tran_form8x8)
+ {
+ pu4_bs_table[1] = 0;
+ pu4_bs_table[3] = 0;
+ pu4_bs_table[5] = 0;
+ pu4_bs_table[7] = 0;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_bs_non_mbaff_medial_lyr */
+/* */
+/* Description : This function computes the pointers of left,top & current*/
+/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function */
+/* : for Boundary Strength Calculation */
+/* Inputs : <What inputs does the function take?> */
+/* Processing : This functions calls deblock MB in the MB increment order*/
+/* */
+/* Outputs : Produces the Boundary Strength for Current Mb */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore */
+/*****************************************************************************/
+
+void isvcd_compute_bs_non_mbaff_medial_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, const UWORD16 u2_mbxn_mb)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* deblk_mb_t Params */
+ deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */
+ deblkmb_neighbour_t *ps_deblk_top_mb;
+ UWORD32 u4_leftmbtype;
+ UWORD16 u2_cur_csbp;
+
+ /* Set of flags */
+ UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld;
+ UWORD32 u1_cur_mb_type;
+ UWORD32 *pu4_bs_table;
+ UWORD32 mb_type_intra = 0;
+
+ UWORD16 *pu2_curr_res_luma_csbp;
+ UWORD16 *pu2_left_res_luma_csbp;
+ UWORD16 *pu2_top_res_luma_csbp;
+
+ /* Neighbour availability */
+ const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx;
+ const UWORD32 u2_mby = ps_cur_mb_info->u2_mby;
+
+ PROFILE_DISABLE_BOUNDARY_STRENGTH()
+
+ ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx;
+
+ /* Pointer assignment for Current DeblkMB, Current Mv Pred */
+ ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb;
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_curr_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_curr_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ pu2_left_res_luma_csbp = pu2_curr_res_luma_csbp - (ps_cur_mb_info->u2_mbx != 0);
+ pu2_top_res_luma_csbp = pu2_curr_res_luma_csbp - ((ps_cur_mb_info->u2_mby != 0) *
+ ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride);
+
+ u1_cur_mb_type = ps_cur_mb_params->u1_mb_type;
+ u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type;
+ ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type;
+
+ ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp;
+ ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+ ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp;
+ ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+
+ /* if no deblocking required for current Mb then continue */
+ /* Check next Mbs in Mb group */
+ if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING)
+ {
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ return;
+ }
+
+ /* Flag for extra left Edge */
+ ps_cur_mb_params->u1_single_call = 1;
+
+ /* Update the Left deblk_mb_t */
+ if(!u2_mbx)
+ {
+ u4_leftmbtype = 0;
+ }
+ else
+ {
+ u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type;
+ }
+
+ if(!u2_mby) u1_top_mb_typ = 0;
+
+ u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB;
+ u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB);
+ /* Compute BS function */
+ pu4_bs_table = ps_cur_mb_params->u4_bs_table;
+
+ u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp;
+ /* Compute BS function */
+ if((ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC))
+ {
+ if(ps_cur_mb_info->u1_tran_form8x8 == 1)
+ {
+ u2_cur_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_curmb->u2_luma_csbp);
+ ps_cur_mb_info->ps_curmb->u2_luma_csbp = u2_cur_csbp;
+ }
+ }
+ u2_cur_csbp |= *pu2_curr_res_luma_csbp;
+
+ if(u4_cur_mb_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ pu4_bs_table[1] = 0x03030303;
+ pu4_bs_table[2] = 0x03030303;
+ pu4_bs_table[3] = 0x03030303;
+ pu4_bs_table[5] = 0x03030303;
+ pu4_bs_table[6] = 0x03030303;
+ pu4_bs_table[7] = 0x03030303;
+ }
+ else
+ {
+ isvcd_fill_bs_ibl(ps_cur_mb_params, u1_top_mb_typ, u4_leftmbtype, ps_cur_mb_info,
+ pu2_curr_res_luma_csbp, pu2_left_res_luma_csbp, pu2_top_res_luma_csbp);
+ }
+
+ mb_type_intra = (u1_top_mb_typ & D_INTRA_MB) || (u1_top_mb_typ & D_INTRA_IBL);
+
+ /* if Top MB or current MB is INTER */
+ if(!mb_type_intra)
+ {
+ pu4_bs_table[0] = 0;
+ /* disable the processing of top edge */
+ ps_cur_mb_params->u1_deblocking_mode |= MB_DISABLE_TOP_EDGE;
+ }
+
+ mb_type_intra = (u4_leftmbtype & D_INTRA_MB) || (u4_leftmbtype & D_INTRA_IBL);
+ /* if Left MB current MB is INTER */
+ if(!mb_type_intra)
+ {
+ pu4_bs_table[4] = 0;
+ /* disable the processing of left edge */
+ ps_cur_mb_params->u1_deblocking_mode |= MB_DISABLE_LEFT_EDGE;
+ }
+
+ /* overwrite the BS 0 values for corner cases */
+ if(0 == u2_mbx)
+ {
+ pu4_bs_table[4] = 0;
+ }
+ if(0 == u2_mby)
+ {
+ pu4_bs_table[0] = 0;
+ }
+
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+
+ /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */
+ if(ps_cur_mb_info->u1_tran_form8x8)
+ {
+ pu4_bs_table[1] = 0;
+ pu4_bs_table[3] = 0;
+ pu4_bs_table[5] = 0;
+ pu4_bs_table[7] = 0;
+ }
+}
diff --git a/decoder/svc/isvcd_deblocking.h b/decoder/svc/isvcd_deblocking.h
new file mode 100644
index 0000000..ecbe9cb
--- /dev/null
+++ b/decoder/svc/isvcd_deblocking.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_deblocking.h
+ *
+ * @brief
+ * Declarations of deblocking functions
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_DEBLOCKING_H_
+#define _ISVCD_DEBLOCKING_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+void isvcd_compute_bs_non_mbaff(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ const UWORD16 u2_mbxn_mb);
+
+void isvcd_compute_bs_non_mbaff_target_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, const UWORD16 u2_mbxn_mb);
+
+void isvcd_compute_bs_non_mbaff_medial_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, const UWORD16 u2_mbxn_mb);
+
+void isvcd_compute_bs_non_mbaff_target_lyr_no_inter_layer(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ const UWORD16 u2_mbxn_mb);
+
+#endif /*_ISVCD_DEBLOCKING_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_defs.h b/decoder/svc/isvcd_defs.h
new file mode 100644
index 0000000..4162713
--- /dev/null
+++ b/decoder/svc/isvcd_defs.h
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_defs.h
+ *
+ * @brief
+ * Type definitions used in the code
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_DEFS_H_
+#define _ISVCD_DEFS_H_
+
+#include <stdint.h>
+
+typedef enum
+{
+ ERROR_SVC_FIELD_PIC_UNSUPPORTED = 0xC1,
+ ERROR_SVC_INV_SCAN_IDX = 0xC2,
+ ERROR_SVC_INV_NAL_UNIT = 0xC3,
+ ERROR_SVC_INV_SUBSET_SPS = 0xC4
+} isvcd_decoder_error_code_t;
+
+#define FLUSH 2
+
+#define SVCD_MAX_FRAME_WIDTH 4080
+#define SVCD_MAX_FRAME_HEIGHT 4080
+#define SVCD_MAX_FRAME_SIZE (4096 * 2048)
+
+#define SVCD_MIN_FRAME_WIDTH 32
+#define SVCD_MIN_FRAME_HEIGHT 32
+
+#define SCALABLE_BASELINE_PROFILE_IDC 83
+#define SCALABLE_HIGH_PROFILE_IDC 86
+#define SCALABLE_HIGH_INTRA_IDC 118
+
+#define SPS_EXTENSION_NAL 13
+#define PREFIX_UNIT_NAL 14
+#define SUBSET_SPS_NAL 15
+#define CODED_SLICE_EXTENSION_NAL 20
+
+#define EP_SLICE 5
+#define EB_SLICE 6
+#define EI_SLICE 7
+
+#define D_INTRA_IBL 16
+
+#define CAB_INFERRED 0xFF
+
+#define MAX_TOTAL_LYRS (MAX_QUALITY_ID + 1) * (MAX_DEPENDENCY_ID + 1) * 16
+
+#define MAX_QUALITY_LYRS 5 /* ReqRename */
+/*!< Maximum number of layers with same
+ dependency id
+ */
+#define MAX_DEPENDENCY_LYRS 6 /* ReqRename */
+/*!< Maximum number of layers with
+ different dependency id
+ */
+
+/** Maximum number of layers without spatial resolution change */
+#define MAX_NUM_LYRS_IN_RES 5
+
+/** Maximum number of dependency layers in a resolution */
+#define MAX_DEP_LYRS_IN_RES 3
+
+/* Maximum number of spatial resolution layers */
+#define MAX_NUM_RES_LYRS 3
+
+/* Maximum number of layers in an access unit */
+#define MAX_NUM_LAYERS MAX_NUM_LYRS_IN_RES *MAX_NUM_RES_LYRS
+
+#define MAX_NUM_PIC_BUFS (32 + 1)
+
+/*SVC Standard Specific Macros*/
+#define MAX_QUALITY_ID 0
+#define MAX_DEPENDENCY_ID 4
+#define MAX_TEMPORAL_ID 7
+#define MAX_PRIORITY_ID 63
+#define MAX_REF_DEP_ID ((MAX_DEPENDENCY_ID << 4) | MAX_QUALITY_ID)
+
+#define BASE_LAYER 0
+#define MEDIAL_ENHANCEMENT_LAYER 1
+#define TARGET_LAYER 2
+
+#define MB_INFER 250
+
+#define SVC_INTER_MB (1 << 0) /*!< Intra MBs other than IPCM and I_BL */
+#define SVC_INTRA_MB (1 << 1) /*!< P or B MBs decoded or inferred*/
+#define SVC_IPCM_MB (1 << 2) /*!< IPCM_MB decoder or inferred*/
+#define SVC_IBL_MB (1 << 3) /*!< I_BL MB always inferred */
+#define SVC_INTRA_INTER_MB (1 << 4) /*!< Intra Inter MB */
+
+#endif /*_ISVCD_DEFS_H_*/
diff --git a/decoder/svc/isvcd_function_selector.h b/decoder/svc/isvcd_function_selector.h
new file mode 100644
index 0000000..31d3e68
--- /dev/null
+++ b/decoder/svc/isvcd_function_selector.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_function_selector.h
+ *
+ * @brief
+ * Structure definitions used in the decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_FUNCTION_SELECTOR_H_
+#define _ISVCD_FUNCTION_SELECTOR_H_
+
+void isvcd_init_function_ptr(svc_dec_lyr_struct_t *ps_codec);
+
+void isvcd_init_function_ptr_generic(svc_dec_lyr_struct_t *ps_codec);
+
+void isvcd_init_function_ptr_neonintr(svc_dec_lyr_struct_t *ps_codec);
+
+void isvcd_init_function_ptr_sse42(svc_dec_lyr_struct_t *ps_codec);
+#endif /* _ISVCD_FUNCTION_SELECTOR_H_ */
diff --git a/decoder/svc/isvcd_function_selector_generic.c b/decoder/svc/isvcd_function_selector_generic.c
new file mode 100644
index 0000000..3aeb468
--- /dev/null
+++ b/decoder/svc/isvcd_function_selector_generic.c
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_function_selector_generic.c
+ *
+ * @brief
+ * Contains functions to initialize function pointers of codec context
+ *
+ * @author
+ * kishore
+ *
+ * @par List of Functions:
+ * - isvcd_init_function_ptr_generic()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264_defs.h"
+#include "ih264_size_defs.h"
+#include "ih264_error.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "isvcd_iquant_itrans_residual_recon.h"
+#include "isvcd_iquant_itrans_residual.h"
+#include "isvcd_iquant_itrans.h"
+#include "isvcd_pred_residual_recon.h"
+#include "isvcd_structs.h"
+#include "ih264d_function_selector.h"
+#include "isvcd_function_selector.h"
+/**
+ *******************************************************************************
+ *
+ * @brief Initialize the intra/inter/transform/deblk function pointers of
+ * codec context
+ *
+ * @par Description: the current routine initializes the function pointers of
+ * codec context basing on the architecture in use for svc
+ *
+ * @param[in] ps_codec
+ * Codec context pointer
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvcd_init_function_ptr_generic(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ residual_sampling_ctxt_t *ps_resd_samp_ctx;
+ intra_sampling_ctxt_t *ps_intra_samp_ctxt;
+ dec_struct_t *ps_codec = &ps_svc_lyr_dec->s_dec;
+
+ /* call the ih264 init ptr generic fn*/
+ ih264d_init_function_ptr_generic(ps_codec);
+
+ ps_resd_samp_ctx = (residual_sampling_ctxt_t *) ps_svc_lyr_dec->pv_residual_sample_ctxt;
+ ps_intra_samp_ctxt = (intra_sampling_ctxt_t *) ps_svc_lyr_dec->pv_intra_sample_ctxt;
+
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_4x4 = isvcd_pred_residual_recon_4x4;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_8x8 = isvcd_pred_residual_recon_8x8;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_16x16 = isvcd_pred_residual_recon_16x16;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_4x4 = isvcd_pred_residual_recon_chroma_4x4;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_8x8 = isvcd_pred_residual_recon_chroma_8x8;
+
+ ps_svc_lyr_dec->pf_residual_luma_4x4 = isvcd_residual_luma_4x4;
+ ps_svc_lyr_dec->pf_residual_luma_8x8 = isvcd_residual_luma_8x8;
+ ps_svc_lyr_dec->pf_residual_luma_16x16 = isvcd_residual_luma_16x16;
+ ps_svc_lyr_dec->pf_residual_chroma_cb_cr_8x8 = isvcd_residual_chroma_cb_cr_8x8;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4 =
+ isvcd_iquant_itrans_residual_recon_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_4x4_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8 =
+ isvcd_iquant_itrans_residual_recon_8x8;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8_dc =
+ isvcd_iquant_itrans_residual_recon_8x8_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4 =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_dc;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4 = isvcd_iquant_itrans_residual_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4_dc = isvcd_iquant_itrans_residual_4x4_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8 = isvcd_iquant_itrans_residual_8x8;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8_dc = isvcd_iquant_itrans_residual_8x8_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4 = isvcd_iquant_itrans_residual_chroma_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_chroma_4x4_dc;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4 = isvcd_iquant_itrans_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4_dc = isvcd_iquant_itrans_4x4_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8 = isvcd_iquant_itrans_8x8;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8_dc = isvcd_iquant_itrans_8x8_dc;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4 = isvcd_iquant_itrans_chroma_4x4;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4_dc = isvcd_iquant_itrans_chroma_4x4_dc;
+
+ ps_intra_samp_ctxt->pf_interpolate_base_luma_dyadic = isvcd_interpolate_base_luma_dyadic;
+ ps_intra_samp_ctxt->pf_interpolate_intra_base = isvcd_interpolate_intra_base;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[0] = isvcd_vert_interpol_chroma_dyadic_1;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[1] = isvcd_vert_interpol_chroma_dyadic_2;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[2] = isvcd_vert_interpol_chroma_dyadic_3;
+
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[0] = isvcd_horz_interpol_chroma_dyadic_1;
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[1] = isvcd_horz_interpol_chroma_dyadic_2;
+
+ /*Dyadic Residual Resampling*/
+ ps_resd_samp_ctx->pf_residual_luma_dyadic = isvcd_residual_luma_dyadic;
+ ps_resd_samp_ctx->pf_residual_chroma_dyadic = isvcd_residual_chroma_dyadic;
+ ps_resd_samp_ctx->pf_residual_chroma_dyadic_alt = isvcd_residual_chroma_dyadic_alt;
+
+ /*Non-dyadic Residual Resampling*/
+ ps_resd_samp_ctx->pf_interpolate_residual = isvcd_interpolate_residual;
+
+ ps_resd_samp_ctx->pf_residual_reflayer_const_non_boundary_mb =
+ isvcd_residual_reflayer_const_non_boundary_mb;
+ ps_resd_samp_ctx->pf_residual_reflayer_const_boundary_mb =
+ isvcd_residual_reflayer_const_boundary_mb;
+
+ return;
+}
diff --git a/decoder/svc/isvcd_ii_pred.c b/decoder/svc/isvcd_ii_pred.c
new file mode 100644
index 0000000..1a89608
--- /dev/null
+++ b/decoder/svc/isvcd_ii_pred.c
@@ -0,0 +1,681 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_ii_pred.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_ii_pred_res_init()
+ * - isvcd_ii_get_ref_mb_mode()
+ * - isvcd_ii_get_ref_projections()
+ * - isvcd_ii_pred_compute_flags_mb()
+ * - isvcd_ii_pred_mb()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_defs.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "isvcd_mode_mv_resamp.h"
+#include "isvcd_ii_pred.h"
+#include "ih264_debug.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ii_pred_res_init */
+/* */
+/* Description : this function initialises the resolution level params */
+/* into the context structure */
+/* */
+/* Inputs : pv_ii_pred_ctxt: Intra inter pred handle */
+/* pi2_ref_loc_x : pointer to buffer having the */
+/* projected locations horz */
+/* pi2_ref_loc_y : pointer to buffer having the */
+/* projected location vertical */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ii_pred_res_init(void *pv_svc_dec)
+{
+ /* local vaiables */
+ intra_inter_pred_ctxt_t *ps_ii_pred_ctxt;
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ WORD32 i4_base_res_flag;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+
+ res_prms_t *ps_res_prms = &ps_svc_lyr_dec->s_res_prms;
+ ps_ii_pred_ctxt = (intra_inter_pred_ctxt_t *) ps_svc_lyr_dec->pv_ii_pred_ctxt;
+ ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
+ i4_base_res_flag = ps_svc_lyr_dec->u1_base_res_flag;
+
+ if((0 != ps_svc_lyr_dec->u1_layer_id) && (SVCD_FALSE == i4_base_res_flag))
+ {
+ /* if not first resolution layer */
+ ps_ii_pred_ctxt->i4_ref_res_lyr_wd = ps_ii_pred_ctxt->i4_cur_res_lyr_wd;
+ ps_ii_pred_ctxt->i4_ref_res_lyr_ht = ps_ii_pred_ctxt->i4_cur_res_lyr_ht;
+ }
+
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ ps_ii_pred_ctxt->pi2_ref_loc_x = ps_lyr_mem->pi2_ref_loc_x;
+ ps_ii_pred_ctxt->pi2_ref_loc_y = ps_lyr_mem->pi2_ref_loc_y;
+
+ /* Store the dimensions */
+ ps_ii_pred_ctxt->i4_cur_res_lyr_wd = ps_res_prms->i4_res_width;
+ ps_ii_pred_ctxt->i4_cur_res_lyr_ht = ps_res_prms->i4_res_height;
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ii_get_ref_mb_mode */
+/* */
+/* Description : This function is used to find the mb type of the */
+/* corresponding MB in the reference layer is INTER or */
+/* INTRA */
+/* Inputs : pu1_ref_mb_modes : ref mb modes buffer pointer */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_x_ref : reference location X */
+/* i4_y_ref : reference location Y */
+/* Globals : none */
+/* Processing : it derives the byte corresponding to reference MB and */
+/* and gets the mb type */
+/* Outputs : none */
+/* Returns : SVCD_TRUE if INTRA MB else SVCD_FALSE */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ii_get_ref_mb_mode(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_ref_mode_size, WORD32 i4_x_ref, WORD32 i4_y_ref)
+{
+ WORD32 i4_mb_x, i4_mb_y;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 i1_mb_mode;
+
+ i4_mb_x = (i4_x_ref >> MB_WIDTH_SHIFT);
+ i4_mb_y = (i4_y_ref >> MB_HEIGHT_SHIFT);
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_ref_mode_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_ref_mode_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ /* INTER */
+ return (SVCD_FALSE);
+ }
+ else
+ {
+ /* INTRA */
+ return (SVCD_TRUE);
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ii_get_ref_projections */
+/* */
+/* Description : this function projects the corners of current MB and */
+/* finds out if any point is falling into an INTRA MB in */
+/* reference layer. it also calculates the intersection */
+/* point of MB boundaries in the projected region */
+/* Inputs : ps_ctxt : Intra Inter context pointer */
+/* ps_ii_mb_ctxt : Curretn MB context pointer */
+/* ps_ref_mb_mode : reference MB mode buffer descriptor */
+/* i4_mb_x : MB_X of current MB */
+/* i4_mb_y : MB_Y of current MB */
+/* Globals : none */
+/* Processing : it derives the intra status of the corners and calculates*/
+/* the intersection point */
+/* Outputs : non */
+/* Returns : SVCD_TRUE or SVCD_FALSE */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ii_get_ref_projections(intra_inter_pred_ctxt_t *ps_ctxt,
+ intra_inter_mb_t *ps_ii_mb_ctxt, mem_element_t *ps_ref_mb_mode,
+ WORD32 i4_mb_x, WORD32 i4_mb_y)
+{
+ WORD16 *pi2_ref_loc_x;
+ WORD16 *pi2_ref_loc_y;
+ WORD8 *pi1_ref_mb_mode;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_ref_x, i4_ref_y;
+ WORD32 i4_frame_x, i4_frame_y;
+ WORD32 i4_flag;
+
+ pi2_ref_loc_x = ps_ctxt->pi2_ref_loc_x;
+ pi2_ref_loc_y = ps_ctxt->pi2_ref_loc_y;
+
+ pi1_ref_mb_mode = (WORD8 *) ps_ref_mb_mode->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode->i4_element_size;
+
+ /* get the current MB frame positions */
+ i4_frame_x = i4_mb_x << 4;
+ i4_frame_y = i4_mb_y << 4;
+
+ /* reset the flag */
+ i4_flag = SVCD_FALSE;
+
+ /* project the (0,0) of current MB and get the ref MB mode */
+ i4_ref_x = pi2_ref_loc_x[i4_frame_x];
+ i4_ref_y = pi2_ref_loc_y[i4_frame_y];
+
+ if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
+ {
+ ps_ii_mb_ctxt->u1_top_left_intra_flag = isvcd_ii_get_ref_mb_mode(
+ pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
+ }
+ else
+ {
+ /* If projection is outside the picture boundary */
+ ps_ii_mb_ctxt->u1_top_left_intra_flag = SVCD_FALSE;
+ }
+ /* project the (15,0) of current MB and get the ref MB mode */
+ i4_ref_x = pi2_ref_loc_x[i4_frame_x + 15];
+ i4_ref_y = pi2_ref_loc_y[i4_frame_y];
+
+ if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
+ {
+ ps_ii_mb_ctxt->u1_top_rt_intra_flag = isvcd_ii_get_ref_mb_mode(
+ pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
+ }
+ else
+ {
+ ps_ii_mb_ctxt->u1_top_rt_intra_flag = SVCD_FALSE;
+ }
+
+ /* project the (0,15) of current MB and get the ref MB mode */
+ i4_ref_x = pi2_ref_loc_x[i4_frame_x];
+ i4_ref_y = pi2_ref_loc_y[i4_frame_y + 15];
+
+ if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
+ {
+ ps_ii_mb_ctxt->u1_bot_left_intra_flag = isvcd_ii_get_ref_mb_mode(
+ pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
+ }
+ else
+ {
+ ps_ii_mb_ctxt->u1_bot_left_intra_flag = SVCD_FALSE;
+ }
+
+ /* project the (15,15) of current MB and get the ref MB mode */
+ i4_ref_x = pi2_ref_loc_x[i4_frame_x + 15];
+ i4_ref_y = pi2_ref_loc_y[i4_frame_y + 15];
+
+ if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
+ {
+ ps_ii_mb_ctxt->u1_bot_rt_intra_flag = isvcd_ii_get_ref_mb_mode(
+ pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
+ }
+ else
+ {
+ ps_ii_mb_ctxt->u1_bot_rt_intra_flag = SVCD_FALSE;
+ }
+
+ /* if any of the 4 cormers are falling into intra region
+ set the INTRA INTER Flag */
+ if((SVCD_TRUE == ps_ii_mb_ctxt->u1_top_left_intra_flag) ||
+ (SVCD_TRUE == ps_ii_mb_ctxt->u1_top_rt_intra_flag) ||
+ (SVCD_TRUE == ps_ii_mb_ctxt->u1_bot_left_intra_flag) ||
+ (SVCD_TRUE == ps_ii_mb_ctxt->u1_bot_rt_intra_flag))
+ {
+ i4_flag = SVCD_TRUE;
+ }
+
+ /* derive the intersection point of MB boundaries */
+ if(SVCD_TRUE == i4_flag)
+ {
+ WORD32 i4_intr_x, i4_intr_y;
+ WORD32 i4_ref_mb_init_x, i4_ref_mb_init_y;
+ WORD32 i4_ctr;
+
+ /* set the variables to initial values */
+ i4_intr_x = 0;
+ i4_intr_y = 0;
+ i4_ref_mb_init_x = pi2_ref_loc_x[i4_frame_x] >> MB_WIDTH_SHIFT;
+ i4_ref_mb_init_y = pi2_ref_loc_y[i4_frame_y] >> MB_HEIGHT_SHIFT;
+
+ /* loop until an Mb boundary is found in horizontal direction */
+ for(i4_ctr = 0; i4_ctr < MB_WIDTH; i4_ctr++)
+ {
+ i4_ref_x = pi2_ref_loc_x[i4_frame_x + i4_ctr];
+ i4_ref_x >>= MB_WIDTH_SHIFT;
+
+ /* check if the locations are falling into same MB */
+ if(i4_ref_x != i4_ref_mb_init_x)
+ {
+ break;
+ }
+ /* increment the position */
+ i4_intr_x++;
+ }
+
+ /* loop until an Mb boundary is found in vertical direction */
+ for(i4_ctr = 0; i4_ctr < MB_HEIGHT; i4_ctr++)
+ {
+ i4_ref_y = pi2_ref_loc_y[i4_frame_y + i4_ctr];
+ i4_ref_y >>= MB_HEIGHT_SHIFT;
+
+ /* check if the locations are falling into same MB */
+ if(i4_ref_y != i4_ref_mb_init_y)
+ {
+ break;
+ }
+ /* increment the position */
+ i4_intr_y++;
+ }
+ /* store the intersection points */
+ ps_ii_mb_ctxt->u1_intersection_x = i4_intr_x;
+ ps_ii_mb_ctxt->u1_intersection_y = i4_intr_y;
+ }
+ else
+ {
+ /* set to default value */
+ ps_ii_mb_ctxt->u1_intersection_x = 0;
+ ps_ii_mb_ctxt->u1_intersection_y = 0;
+ }
+
+ return (i4_flag);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ii_pred_compute_flags_mb */
+/* */
+/* Description : this function checks all the criteria for an MB to */
+/* under go Inter-Intra prediction and stores the MB mode */
+/* as INTER_INTRA for appropriate MBs */
+/* Inputs : refer to comments below */
+/* Globals : none */
+/* Processing : it checks the criteria for anMB to undergo Inter-Intra */
+/* pred process and updates the MB mode */
+/* Outputs : MB mode set for each MB with INTRA-INTER status */
+/* Returns : SVCD_EOK or SVCD_EFAIL */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ii_pred_compute_flags_mb(void *pv_ii_pred_ctxt, mem_element_t *ps_ref_mb_mode,
+ mb_coord_t *ps_coord, void *pv_mb_prms, void *pv_svc_mb_prms,
+ UWORD8 *pu1_ii_mb_mode)
+{
+ intra_inter_pred_ctxt_t *ps_ctxt;
+ WORD32 i4_mb_x, i4_mb_y;
+ dec_svc_mb_info_t *ps_svc_mb_prms;
+ UNUSED(pv_mb_prms);
+
+ if((NULL == pv_ii_pred_ctxt) || (NULL == ps_ref_mb_mode) || (NULL == ps_coord) ||
+ (NULL == pu1_ii_mb_mode))
+ {
+ return NOT_OK;
+ }
+
+ ps_ctxt = (intra_inter_pred_ctxt_t *) pv_ii_pred_ctxt;
+ ps_svc_mb_prms = (dec_svc_mb_info_t *) pv_svc_mb_prms;
+
+ /* get mb co-ordinates */
+ i4_mb_x = ps_coord->u2_mb_x;
+ i4_mb_y = ps_coord->u2_mb_y;
+
+ {
+ intra_inter_mb_t *ps_ii_mb_ctxt;
+ WORD32 i4_ii_flag;
+
+ /* get the current MB strcuture pointer */
+ ps_ii_mb_ctxt = &ps_ctxt->s_intra_inter_mb_prms;
+
+ /* reset the Intra Inter qualified flag for current MB */
+ i4_ii_flag = SVCD_FALSE;
+
+ /* check for base mode flag and Inter MB status */
+ if(1 == ps_svc_mb_prms->u1_base_mode_flag)
+ {
+ /* call the function which calculates the projections
+ and returns whether current MB has to under go
+ Inter Intra Prediction */
+ i4_ii_flag = isvcd_ii_get_ref_projections(ps_ctxt, ps_ii_mb_ctxt, ps_ref_mb_mode,
+ i4_mb_x, i4_mb_y);
+ }
+
+ /* If the current MB requires Intra Inter prediction */
+ if(SVCD_TRUE == i4_ii_flag)
+ {
+ /* set the mb mode */
+ *pu1_ii_mb_mode = SVC_INTRA_INTER_MB;
+ }
+ else
+ {
+ /* set all MB params to default values */
+ ps_ii_mb_ctxt->u1_bot_left_intra_flag = SVCD_FALSE;
+ ps_ii_mb_ctxt->u1_bot_rt_intra_flag = SVCD_FALSE;
+ ps_ii_mb_ctxt->u1_top_left_intra_flag = SVCD_FALSE;
+ ps_ii_mb_ctxt->u1_top_rt_intra_flag = SVCD_FALSE;
+ ps_ii_mb_ctxt->u1_intersection_x = 0;
+ ps_ii_mb_ctxt->u1_intersection_y = 0;
+
+ /* set the mb mode to 0 (which has no interpretation) */
+ *pu1_ii_mb_mode = 0;
+ }
+ }
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ii_pred_mb */
+/* */
+/* Description : This function performs the Intra-Inter Preduction of the */
+/* given MB */
+/* */
+/* Inputs : ps_mb_ctxt : Intra Inter mb context strcuture */
+/* ps_mb_buf : current MB buffers strcuture pointer */
+/* Globals : none */
+/* Processing : it processes all partitions based on the Intra flag */
+/* */
+/* Outputs : Intra Inter Predecited and reconstructed MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_ii_pred_mb(void *pv_svc_dec, dec_mb_info_t *ps_cur_mb_info)
+{
+ intra_inter_mb_t *ps_mb_ctxt;
+ UWORD8 *pu1_rec_y, *pu1_rec_uv;
+ UWORD8 *pu1_recon_luma;
+ WORD32 i4_recon_luma_stride;
+ UWORD8 *pu1_recon_chroma;
+ WORD32 i4_recon_chroma_stride;
+ UWORD8 *pu1_pred_luma;
+ UWORD8 *pu1_pred_chroma;
+ WORD32 i4_pred_luma_stride;
+ WORD32 i4_pred_chroma_stride;
+ WORD32 i4_intr_x, i4_intr_y;
+ intra_inter_pred_ctxt_t *ps_ctxt;
+ pic_buffer_t *ps_frame_buf;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ ps_ctxt = (intra_inter_pred_ctxt_t *) ps_svc_lyr_dec->pv_ii_pred_ctxt;
+ ps_mb_ctxt = &ps_ctxt->s_intra_inter_mb_prms;
+ ps_frame_buf = ps_dec->ps_cur_pic;
+ i4_recon_luma_stride = ps_dec->u2_frm_wd_y;
+ i4_recon_chroma_stride = ps_dec->u2_frm_wd_uv;
+
+ /* derive the intersection point */
+ i4_intr_x = ps_mb_ctxt->u1_intersection_x;
+ i4_intr_y = ps_mb_ctxt->u1_intersection_y;
+
+ pu1_rec_y = ps_frame_buf->pu1_buf1 + (ps_cur_mb_info->u2_mbx << 4) +
+ (i4_recon_luma_stride * (ps_cur_mb_info->u2_mby << 4));
+
+ pu1_rec_uv = ps_frame_buf->pu1_buf2 + (ps_cur_mb_info->u2_mbx << 3) * YUV420SP_FACTOR +
+ (i4_recon_chroma_stride * (ps_cur_mb_info->u2_mby << 3));
+
+ pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
+ pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
+ i4_pred_luma_stride = MB_SIZE;
+ i4_pred_chroma_stride = MB_SIZE;
+
+ /* get the recon and residual buffer pointer */
+ pu1_recon_luma = pu1_rec_y;
+ pu1_recon_chroma = pu1_rec_uv;
+
+ /*-----------------------------------------------------------------------*/
+ /* Reconstruct TOP_LEFT Partition */
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD32 i4_width, i4_height;
+
+ /* assign the appropriate buffer params based on Intra status */
+ if(SVCD_TRUE == ps_mb_ctxt->u1_top_left_intra_flag)
+ {
+ /* Luma Processing */
+ isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
+ i4_recon_luma_stride, i4_intr_x, i4_intr_y);
+
+ /* assign appropriate width and height for chroma */
+ i4_width = (((i4_intr_x + 1) >> 1) << 1);
+ i4_height = ((i4_intr_y + 1) & ~1);
+ i4_height >>= 1;
+ /* Chroma Processing (cb and cr interleaved) */
+ isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
+ i4_recon_chroma_stride, i4_width, i4_height);
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Reconstruct TOP_RIGHT Partition */
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD32 i4_width, i4_height;
+
+ /* assign the appropriate buffer params based on Intra status */
+ if(SVCD_TRUE == ps_mb_ctxt->u1_top_rt_intra_flag)
+ {
+ pu1_pred_luma += i4_intr_x;
+ pu1_pred_chroma += (((i4_intr_x + 1) >> 1) << 1);
+
+ /* ----------------------- Luma ------------------------ */
+ /* get the recon and residual buffer pointer */
+ pu1_recon_luma = pu1_rec_y + i4_intr_x;
+
+ /* assign appropriate width and height for luma */
+ i4_width = MB_WIDTH - i4_intr_x;
+ i4_height = i4_intr_y;
+
+ /* Luma Processing */
+ /* Luma Processing */
+ isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
+ i4_recon_luma_stride, i4_width, i4_height);
+
+ /* ----------------------- Chroma ----------------------- */
+ /* assign appropriate width and height for luma */
+ i4_width = (BLOCK_WIDTH - ((i4_intr_x + 1) >> 1)) << 1;
+
+ /* Height includes for both Cb & Cr */
+ i4_height = ((i4_intr_y + 1) & ~1);
+ i4_height >>= 1;
+ /* get the recon and residual buffer pointer */
+ pu1_recon_chroma = pu1_rec_uv;
+ {
+ WORD32 i4_temp;
+ i4_temp = (((i4_intr_x + 1) >> 1) << 1);
+ pu1_recon_chroma += i4_temp;
+ }
+
+ /* Chroma Processing (cb and cr interleaved) */
+ isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
+ i4_recon_chroma_stride, i4_width, i4_height);
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Reconstruct BOTTOM_LEFT Partition */
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD32 i4_width, i4_height;
+
+ /* assign the appropriate buffer params based on Intra status */
+ if(SVCD_TRUE == ps_mb_ctxt->u1_bot_left_intra_flag)
+ {
+ pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
+ pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
+
+ /* increment to current vertical offset */
+ pu1_pred_luma += i4_intr_y * i4_pred_luma_stride;
+ pu1_pred_chroma += (((i4_intr_y + 1) & ~1) >> 1) * i4_pred_chroma_stride;
+
+ /* ----------------------- Luma ----------------------- */
+ /* get the recon and residual buffer pointer */
+ pu1_recon_luma = pu1_rec_y;
+ pu1_recon_luma += i4_intr_y * i4_recon_luma_stride;
+
+ /* assign appropriate width and height */
+ i4_width = i4_intr_x;
+ i4_height = MB_HEIGHT - i4_intr_y;
+
+ /* Luma Processing */
+ isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
+ i4_recon_luma_stride, i4_width, i4_height);
+
+ /* ----------------------- Chroma ----------------------- */
+ pu1_recon_chroma = pu1_rec_uv;
+ {
+ WORD32 i4_temp;
+ i4_temp = ((i4_intr_y + 1) & ~1) >> 1;
+ pu1_recon_chroma += (i4_temp * i4_recon_chroma_stride);
+ }
+ /* assign appropriate width and height */
+ i4_width = ((i4_intr_x + 1) >> 1) << 1;
+ i4_height = MB_HEIGHT - (i4_intr_y & ~1);
+ i4_height >>= 1;
+ /* Chroma Processing (cb and cr interleaved) */
+ isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
+ i4_recon_chroma_stride, i4_width, i4_height);
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Reconstruct BOTTOM_RIGHT Partition */
+ /*-----------------------------------------------------------------------*/
+ {
+ WORD32 i4_width, i4_height;
+
+ /* assign the appropriate buffer params based on Intra status */
+ if(SVCD_TRUE == ps_mb_ctxt->u1_bot_rt_intra_flag)
+ {
+ pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
+ pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
+
+ /* increment to current vertical offset */
+ pu1_pred_luma += i4_intr_x;
+ pu1_pred_luma += i4_intr_y * i4_pred_luma_stride;
+ pu1_pred_chroma += (((i4_intr_y + 1) & ~1) >> 1) * i4_pred_chroma_stride;
+ pu1_pred_chroma += ((i4_intr_x + 1) >> 1) << 1;
+
+ /* ----------------------- Luma ----------------------- */
+ /* get the recon and residual buffer pointer horz */
+ pu1_recon_luma = pu1_rec_y + i4_intr_x;
+
+ /* get the recon and residual buffer pointer vertical */
+ pu1_recon_luma += (i4_intr_y * i4_recon_luma_stride);
+
+ /* assign appropriate width and height */
+ i4_width = MB_WIDTH - i4_intr_x;
+ i4_height = MB_HEIGHT - i4_intr_y;
+
+ /* Luma Processing */
+ isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
+ i4_recon_luma_stride, i4_width, i4_height);
+
+ /* ----------------------- Chroma ----------------------- */
+ /* get the recon and residual buffer pointer horz */
+ pu1_recon_chroma = pu1_rec_uv;
+ {
+ WORD32 i4_temp;
+ i4_temp = ((i4_intr_y + 1) & ~1) >> 1;
+ i4_temp *= i4_recon_chroma_stride;
+ i4_temp += (((i4_intr_x + 1) >> 1) << 1);
+ pu1_recon_chroma += i4_temp;
+ }
+
+ /* assign appropriate width and height */
+ i4_width = (BLOCK_WIDTH - ((i4_intr_x + 1) >> 1)) << 1;
+ i4_height = MB_HEIGHT - (i4_intr_y & ~1);
+ i4_height >>= 1;
+ /* Chroma Processing (cb and cr interleaved) */
+ isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
+ i4_recon_chroma_stride, i4_width, i4_height);
+ }
+ }
+ return;
+} \ No newline at end of file
diff --git a/decoder/svc/isvcd_ii_pred.h b/decoder/svc/isvcd_ii_pred.h
new file mode 100644
index 0000000..c86e54e
--- /dev/null
+++ b/decoder/svc/isvcd_ii_pred.h
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_ii_pred.h
+ *
+ * @brief
+ * Contains structures and function definitions required for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_II_PRED_H_
+#define _ISVCD_II_PRED_H_
+
+typedef struct
+{
+ /* Figure shows the projection of current MB onto reference layer
+ mapping to a certain case
+
+ MB_WIDTH
+ <--------------------------->
+ --------------------------- ^
+ | | | |
+ | TOP_L | TOP_R | |
+ | | | |
+ | | | |
+ | | | |
+ | (x,y) | | | MB_HEIGHT
+ |---------------------------| |
+ | | | |
+ | | | |
+ | BOT_L | BOT_R | |
+ | | | |
+ --------------------------- |
+ ^
+ */
+
+ UWORD8 u1_top_left_intra_flag; /*!< flag to inidicate the TOP_L
+ partition is falling in to a INTRA region
+ in base layer
+ */
+ UWORD8 u1_top_rt_intra_flag; /*!< flag to inidicate the TOP_R
+ partition is falling in to a INTRA region
+ in base layer
+ */
+ UWORD8 u1_bot_rt_intra_flag; /*!< flag to inidicate the BOT_R
+ partition is falling in to a INTRA region
+ in base layer
+ */
+ UWORD8 u1_bot_left_intra_flag; /*!< flag to inidicate the BOT_L
+ partition is falling in to a INTRA region
+ in base layer
+ */
+ UWORD8 u1_intersection_x; /*!< Horizontal point where the projection
+ falls into a different MB in reference
+ layer
+ */
+ UWORD8 u1_intersection_y; /*!< Vertical point where the projection
+ falls into a different MB in reference
+ layer
+ */
+} intra_inter_mb_t;
+
+typedef struct
+{
+ WORD16 *pi2_ref_loc_x; /*!< buffer pointer which holds
+ the projected location on reference
+ layer in horizontal direction
+ for each pixel in current layer
+ */
+ WORD16 *pi2_ref_loc_y; /*!< buffer pointer which holds
+ the projected location on reference
+ layer in vertical direction
+ for each pixel in current layer
+ */
+ intra_inter_mb_t s_intra_inter_mb_prms; /*!< array structure
+ to hold the intersection points
+ and the intra status for the
+ all 4 parts around the
+ intersection point
+ */
+ WORD32 i4_ref_res_lyr_wd; /*!< Width of reference layer */
+ WORD32 i4_ref_res_lyr_ht; /*!< Height of reference layer */
+ WORD32 i4_cur_res_lyr_wd; /*!< Width of reference layer */
+ WORD32 i4_cur_res_lyr_ht; /*!< Height of reference layer */
+
+} intra_inter_pred_ctxt_t;
+
+typedef struct
+{
+ UWORD8 *pu1_recon_luma;
+ UWORD8 *pu1_mc_pred_luma;
+ UWORD8 *pu1_intra_pred_luma;
+ WORD16 *pi2_res_luma;
+ WORD32 i4_recon_luma_stride;
+ WORD32 i4_mc_pred_luma_stride;
+ WORD32 i4_intra_pred_luma_stride;
+ WORD32 i4_res_luma_stride;
+ UWORD8 *pu1_recon_chroma;
+ UWORD8 *pu1_mc_pred_chroma;
+ UWORD8 *pu1_intra_pred_chroma;
+ WORD16 *pi2_res_chroma;
+ WORD32 i4_recon_chroma_stride;
+ WORD32 i4_mc_pred_chroma_stride;
+ WORD32 i4_intra_pred_chroma_stride;
+ WORD32 i4_res_chroma_stride;
+} intra_inter_mb_buff_t;
+
+WORD32 isvcd_ii_pred_compute_flags_mb(void *pv_ii_pred_ctxt, mem_element_t *ps_ref_mb_mode,
+ mb_coord_t *ps_coord, void *pv_mb_prms, void *pv_svc_mb_prms,
+ UWORD8 *pu1_ii_mb_mode);
+
+WORD32 isvcd_ii_pred_res_init(void *pv_svc_dec);
+#endif /* _ISVCD_II_PRED_H_ */
diff --git a/decoder/svc/isvcd_intra_resamp.c b/decoder/svc/isvcd_intra_resamp.c
new file mode 100644
index 0000000..34e3779
--- /dev/null
+++ b/decoder/svc/isvcd_intra_resamp.c
@@ -0,0 +1,5120 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_intra_resamp.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_get_ceil_log2()
+ * - isvcd_2d_memset()
+ * - isvcd_copy_data()
+ * - isvcd_copy_data_semiplanr()
+ * - isvcd_get_ref_layer_avlblty_dyadic()
+ * - isvcd_diagonal_construct_dyadic()
+ * - isvcd_left_right_padding()
+ * - isvcd_left_right_padding_chroma()
+ * - isvcd_top_bot_padding()
+ * - isvcd_top_bot_padding_chroma()
+ * - isvcd_diag_reconstruction()
+ * - isvcd_diag_reconstruction_chroma()
+ * - isvcd_diag_padding()
+ * - isvcd_diag_padding_chroma()
+ * - isvcd_corner_samp_dyadic()
+ * - isvcd_fill_non_avail_pixel()
+ * - isvcd_get_ref_layer_mbtype()
+ * - isvcd_reflayer_construction()
+ * - isvcd_reflayer_construction_dyadic()
+ * - isvcd_interpolate_base_luma_dyadic()
+ * - isvcd_vert_interpol_chroma_dyadic_1()
+ * - isvcd_vert_interpol_chroma_dyadic_2()
+ * - isvcd_vert_interpol_chroma_dyadic_3()
+ * - isvcd_horz_interpol_chroma_dyadic_1()
+ * - isvcd_horz_interpol_chroma_dyadic_2()
+ * - isvcd_intra_resamp_mb_dyadic()
+ * - isvcd_interpolate_intra_base()
+ * - isvcd_intra_resamp_mb()
+ * - isvcd_intra_resamp_generate_segment_lookup()
+ * - isvcd_intra_resamp_populate_list()
+ * - isvcd_populate_res_prms()
+ * - isvcd_crop_wnd_flag_res_int()
+ * - isvcd_intra_resamp_res_init()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264_debug.h"
+
+ftype_intra_samp_padding *gpf_lookup_fxns_luma[32] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &isvcd_left_right_padding,
+ NULL,
+ &isvcd_diag_reconstruction,
+ NULL,
+ &isvcd_left_right_padding,
+ NULL,
+ &isvcd_diag_reconstruction,
+ NULL,
+ NULL,
+ &isvcd_top_bot_padding,
+ &isvcd_diag_reconstruction,
+ NULL,
+ NULL,
+ &isvcd_top_bot_padding,
+ &isvcd_diag_reconstruction,
+ NULL,
+ &isvcd_left_right_padding,
+ &isvcd_top_bot_padding,
+ &isvcd_diag_reconstruction,
+ &isvcd_diag_padding,
+ &isvcd_left_right_padding,
+ &isvcd_top_bot_padding,
+ &isvcd_diag_reconstruction,
+};
+
+ftype_intra_samp_padding *gpf_lookup_fxns_chroma[32] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &isvcd_left_right_padding_chroma,
+ NULL,
+ &isvcd_diag_reconstruction_chroma,
+ NULL,
+ &isvcd_left_right_padding_chroma,
+ NULL,
+ &isvcd_diag_reconstruction_chroma,
+ NULL,
+ NULL,
+ &isvcd_top_bot_padding_chroma,
+ &isvcd_diag_reconstruction_chroma,
+ NULL,
+ NULL,
+ &isvcd_top_bot_padding_chroma,
+ &isvcd_diag_reconstruction_chroma,
+ NULL,
+ &isvcd_left_right_padding_chroma,
+ &isvcd_top_bot_padding_chroma,
+ &isvcd_diag_reconstruction_chroma,
+ &isvcd_diag_padding_chroma,
+ &isvcd_left_right_padding_chroma,
+ &isvcd_top_bot_padding_chroma,
+ &isvcd_diag_reconstruction_chroma,
+};
+
+const UWORD32 gu4_valid_segs_lookup[16] = {
+ 0x0F000000, 0xCF000000, 0x3F000000, 0xFF000000, 0x0F000000, 0xCF000000, 0x3F000000, 0xFF000000,
+ 0x0F000000, 0x8F000000, 0x6F000000, 0xEF000000, 0x1F000000, 0x9F000000, 0x7F000000, 0xFF000000};
+
+const WORD8 g_ai1_interp_filter_luma[64] = {
+ 0, -1, -2, -3, -3, -4, -4, -3, -3, -3, -2, -1, -1, -1, -1, -1, 32, 32, 31, 30, 28, 26,
+ 24, 22, 19, 16, 14, 11, 8, 6, 4, 2, 0, 2, 4, 6, 8, 11, 14, 16, 19, 22, 24, 26,
+ 28, 30, 31, 32, 0, -1, -1, -1, -1, -1, -2, -3, -3, -3, -4, -4, -3, -3, -2, -1};
+
+const UWORD8 g_au1_interp_filter_chroma[32] = {32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12,
+ 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10,
+ 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
+
+WORD32 ref_pos_luma[4][16] = {{10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20},
+ {10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20},
+ {2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12},
+ {2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12}};
+WORD32 ref_pos_chroma[4][8] = {{6, 7, 8, 8, 9, 10, 10, 11},
+ {6, 7, 7, 8, 9, 9, 10, 11},
+ {6, 6, 7, 8, 8, 9, 10, 10},
+ {2, 3, 4, 4, 5, 6, 6, 7}};
+
+WORD32 phase_luma[3][16] = {{13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13},
+ {8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8},
+ {3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3}};
+
+UWORD8 phase_luma_u8[3][16] = {{13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13},
+ {8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8},
+ {3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3, 13, 8, 3}};
+
+WORD8 phase_luma_x86[6][16] = {{13, 8, 3, 13, 8, 3, 13, 8, 0, 0, 0, 0, 0, 0, 0, 0},
+ {3, 13, 8, 3, 13, 8, 3, 13, 0, 0, 0, 0, 0, 0, 0, 0},
+ {8, 3, 13, 8, 3, 13, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0},
+ {13, 8, 3, 13, 8, 3, 13, 8, 0, 0, 0, 0, 0, 0, 0, 0},
+ {3, 13, 8, 3, 13, 8, 3, 13, 0, 0, 0, 0, 0, 0, 0, 0},
+ {8, 3, 13, 8, 3, 13, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+WORD32 phase_chroma[3][8] = {
+ {13, 8, 3, 13, 8, 3, 13, 8}, {3, 13, 8, 3, 13, 8, 3, 13}, {8, 3, 13, 8, 3, 13, 8, 3}};
+
+UWORD8 phase_chroma_u8[3][8] = {
+ {13, 8, 3, 13, 8, 3, 13, 8}, {3, 13, 8, 3, 13, 8, 3, 13}, {8, 3, 13, 8, 3, 13, 8, 3}};
+
+UWORD8 ref_pos_luma_mask_m48[8][16] = {{0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11},
+ {2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11},
+ {2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13},
+ {4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13},
+ {4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15},
+ {6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13, 14, 15, 14, 15},
+ {0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11},
+ {4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13}};
+
+UWORD8 ref_pos_luma_mask_m16[8][16] = {{0, 1, 2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11},
+ {0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11},
+ {2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13},
+ {2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13},
+ {4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13, 14, 15},
+ {4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15},
+ {0, 1, 2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11},
+ {2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13}};
+
+UWORD8 ref_pos_luma_mask_m32[8][16] = {{0, 1, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9},
+ {0, 1, 2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11},
+ {2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11},
+ {2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13},
+ {4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13},
+ {4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13, 14, 15},
+ {0, 1, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9},
+ {2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13}};
+
+UWORD8 ref_pos_chroma_mask_m24[2][16] = {{0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11},
+ {2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11, 12, 13}};
+UWORD8 ref_pos_chroma_mask_m8[2][16] = {{0, 1, 0, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9},
+ {2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11, 10, 11}};
+UWORD8 ref_pos_chroma_mask_m16[2][16] = {{0, 1, 2, 3, 2, 3, 4, 5, 6, 7, 6, 7, 8, 9, 10, 11},
+ {2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13}};
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_ceil_log2 */
+/* */
+/* Description : this function returns the CeilLog2 of the given number */
+/* */
+/* */
+/* Inputs : i4_input : input number */
+/* Globals : none */
+/* Processing : it calculate the bits and returns it */
+/* */
+/* Outputs : none */
+/* Returns : ceil of log to base 2 */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_ceil_log2(WORD32 i4_input)
+{
+ WORD32 i4_bits = 0;
+
+ i4_input--;
+ while(i4_input > 0)
+ {
+ i4_bits++;
+ i4_input >>= 1;
+ }
+ return (i4_bits);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_2d_memset */
+/* */
+/* Description : Function performs 2D memset operation */
+/* */
+/* */
+/* Inputs : 1. Buffer pointer */
+/* 2. width */
+/* 3. Height */
+/* 4. Stride */
+/* 5. value */
+/* Globals : None */
+/* Processing : calls memset fucntion */
+/* */
+/* Outputs : Updates the buffer */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_2d_memset(void *pv_buf, WORD32 i4_width, WORD32 i4_ht, WORD32 i4_stride, WORD32 i4_val)
+{
+ WORD32 i4_y;
+ UWORD8 *pu1_buf;
+
+ pu1_buf = (UWORD8 *) pv_buf;
+
+ for(i4_y = 0; i4_y < i4_ht; i4_y++)
+ {
+ memset(pu1_buf, i4_val, i4_width);
+ /* Increment the pointer */
+ pu1_buf += i4_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_copy_data */
+/* */
+/* Description : this module copies the data from source to destination */
+/* the amount of data to be copied is passed as input */
+/* */
+/* Inputs : pu1_src : pointer to the source buffer */
+/* u2_src_stride : source buffer stride */
+/* pu1_dst : pointer to the destination buffer */
+/* u2_dst_stride : destination buffer stride */
+/* u4_num_bytes : number of bytes to be copied */
+/* u4_num_lines : number of lines to be copied */
+/* Globals : none */
+/* Processing : it does a memcpy from source to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : both buffers are assumed to be 2-D buffers */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 29 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_copy_data(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst, WORD32 i4_dst_stride,
+ WORD32 i4_num_bytes, WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines;
+
+ /* loop for copy all the lines requried */
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ memcpy(pu1_dst, pu1_src, i4_num_bytes);
+ pu1_src += i4_src_stride;
+ pu1_dst += i4_dst_stride;
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_copy_data_semiplanr */
+/* */
+/* Description : this module copies the data from source to destination */
+/* the amount of data to be copied is passed as input */
+/* */
+/* Inputs : pu1_src : pointer to the source buffer */
+/* i4_src_stride : source buffer stride */
+/* pu1_dst1 : pointer to the destination buffer 1 */
+/* pu1_dst2 : pointer to the destination buffer 2 */
+/* i4_dst_stride : destination buffer stride */
+/* i4_num_bytes : number of bytes to be copied */
+/* i4_num_lines : number of lines to be copied */
+/* Globals : none */
+/* Processing : it does a memcpy from source to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : both buffers are assumed to be 2-D buffers */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 29 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_copy_data_semiplanr(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst1,
+ UWORD8 *pu1_dst2, WORD32 i4_dst_stride, WORD32 i4_num_bytes,
+ WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines, u4_i;
+
+ /* loop for copy all the lines requried */
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ for(u4_i = 0; u4_i < i4_num_bytes; u4_i++)
+ {
+ *(pu1_dst1 + u4_i) = *(pu1_src + (2 * u4_i));
+ *(pu1_dst2 + u4_i) = *(pu1_src + (2 * u4_i) + 1);
+ }
+
+ pu1_src += i4_src_stride;
+ pu1_dst1 += i4_dst_stride;
+ pu1_dst2 += i4_dst_stride;
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_ref_layer_avlblty_dyadic */
+/* */
+/* Description : This function is used to find the mb type of the */
+/* corresponding MB in the reference layer for dyadic cases */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra samp context */
+/* pi1_ref_mb_modes : ref mb modes buffer pointer */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_ref_mb_x : reference MB location X */
+/* i4_ref_mb_y : reference MB location Y */
+/* pi4_mb_type : pointer to store the mb type */
+/* i1_curr_slice_id : slice id of current MB */
+/* i1_cons_intr_samp_flag :constrained intra resampling flag*/
+/* Globals : none */
+/* Processing : it derives the bit corresponding to reference MB and */
+/* stores the mbtype as INTRA if the bit is set */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_get_ref_layer_avlblty_dyadic(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_ref_mb_x,
+ WORD32 i4_ref_mb_y, WORD32 *pi4_avlblty,
+ WORD8 i1_curr_slice_id, WORD8 i1_cons_intr_samp_flag)
+{
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 i1_mb_mode;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_ref_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_ref_mb_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ /* INTER */
+ *pi4_avlblty = 0;
+ }
+ else
+ {
+ /* INTRA */
+ *pi4_avlblty = 1;
+ }
+
+ /* if constrained intra flag is 1 then check for same slice id */
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ if(1 == *pi4_avlblty)
+ {
+ /* check for different slice idc */
+ if(ps_inter_lyr_mb_prms->i1_slice_id != i1_curr_slice_id)
+ {
+ /* store the mode as not available for upsampling */
+ *pi4_avlblty = 0;
+ }
+ }
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_diagonal_construct_dyadic */
+/* */
+/* Description : This function fills the unavaible pixels in the reference*/
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray : popinter to reference array */
+/* i4_refarray_wd: width of the reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : constructed pixel */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+UWORD8 isvcd_diagonal_construct_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xd_index,
+ WORD32 i4_yd_index, UWORD8 *pu1_refarray,
+ WORD32 i4_refarray_wd)
+{
+ WORD32 i4_diff_hor_ver, i4_sgn_xy;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_samp1, i4_samp2, i4_samp3;
+ WORD32 i4_result;
+ UWORD8 *pu1_tmp;
+
+ i4_diff_hor_ver = ABS(i4_xd_index) - ABS(i4_yd_index);
+ i4_sgn_xy = SIGN(i4_xd_index * i4_yd_index);
+
+ if(i4_diff_hor_ver > 0)
+ {
+ i4_xc = i4_x - (i4_sgn_xy * i4_yd_index);
+ i4_yc = i4_y - i4_yd_index;
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+ i4_samp1 = pu1_tmp[i4_xc - 1];
+ i4_samp2 = pu1_tmp[i4_xc];
+ i4_samp3 = pu1_tmp[i4_xc + 1];
+ }
+ else if(i4_diff_hor_ver < 0)
+ {
+ i4_xc = i4_x - i4_xd_index;
+ i4_yc = i4_y - (i4_sgn_xy * i4_xd_index);
+ pu1_tmp = pu1_refarray + ((i4_yc - 1) * i4_refarray_wd);
+ i4_samp1 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp2 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp3 = pu1_tmp[i4_xc];
+ }
+ else
+ {
+ WORD32 i4_ref_xd, i4_ref_yd;
+
+ i4_ref_xd = i4_x - i4_xd_index;
+ i4_ref_yd = i4_y - i4_yd_index;
+ i4_xc = i4_ref_xd + SIGN(i4_xd_index);
+ i4_yc = i4_ref_yd + SIGN(i4_yd_index);
+ pu1_tmp = pu1_refarray + (i4_ref_yd * i4_refarray_wd);
+ i4_samp1 = pu1_tmp[i4_xc];
+ i4_samp2 = pu1_tmp[i4_ref_xd];
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+ i4_samp3 = pu1_tmp[i4_ref_xd];
+ }
+
+ i4_result = (i4_samp1 + (i4_samp2 << 1) + i4_samp3 + 2) >> 2;
+ pu1_tmp = pu1_refarray + (i4_y * i4_refarray_wd);
+ /* Store the filled sample */
+ pu1_tmp[i4_x] = i4_result;
+
+ return (i4_result);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_left_right_padding */
+/* Description : This function does the left/right padding for intra */
+/* upsampling */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the left/right padding for intra */
+/* upsampling */
+/* Outputs : none */
+/* Returns : number of leading zeroes */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_left_right_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(i1_yd_index);
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + i1_xd_index;
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - i1_xd_index;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst, *pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ pu1_src += i4_refarray_stride;
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_left_right_padding_chroma */
+/* Description : This function does the left/right padding for intra */
+/* upsampling for chroma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the left/right padding for intra */
+/* upsampling for chroma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2011 Vijay creation */
+/*****************************************************************************/
+void isvcd_left_right_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i1_yd_index);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_src_cb = pu1_dst_cb + i1_xd_index;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i1_xd_index;
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_CHROMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_CHROMA);
+ pu1_dst_cb = pu1_src_cb - i1_xd_index;
+ pu1_dst_cr = pu1_src_cr - i1_xd_index;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst_cb, *pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ pu1_src_cb += i4_refarray_stride;
+ memset(pu1_dst_cr, *pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ pu1_src_cr += i4_refarray_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_top_bot_padding */
+/* Description : This function does the top/bottom padding for intra */
+/* upsampling for chroma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the top/bottom padding for intra */
+/* upsampling for chroma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_top_bot_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(i1_xd_index);
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + (i1_yd_index * i4_refarray_stride);
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - (i1_yd_index * i4_refarray_stride);
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memcpy(pu1_dst, pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_top_bot_padding */
+/* Description : This function does the top/bottom padding for intra */
+/* upsampling for chroma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the top/bottom padding for intra */
+/* upsampling for chroma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_top_bot_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i1_xd_index);
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_src_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i4_tmp;
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_CHROMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_CHROMA);
+
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_dst_cb = pu1_src_cb - i4_tmp;
+ pu1_dst_cr = pu1_src_cr - i4_tmp;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memcpy(pu1_dst_cb, pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ memcpy(pu1_dst_cr, pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_diag_reconstruction */
+/* Description : This function does the diagonal reconstuction for intra */
+/* upsampling for luma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the diagonal reconstruction for intra */
+/* upsampling for luma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_diag_reconstruction(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_i;
+ UWORD8 *pu1_src_1, *pu1_src_2, *pu1_dst;
+ UWORD8 u1_filter_delay_buf[18] = {0};
+ UWORD8 u1_out_buf[16] = {0};
+ WORD32 i4_width, i4_height;
+ WORD32 i4_x_off, i4_y_off;
+ WORD32 i4_block_size = BLOCK_WIDTH;
+
+ UNUSED(pu1_refarray_2);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src_1 = pu1_dst + i1_xd_index;
+ pu1_src_2 = pu1_dst + (i1_yd_index * i4_refarray_stride);
+
+ i4_width = MAX(u1_seg_wd, (((i4_mb_adjoin_x >> 3) ^ 1) * i4_block_size));
+ i4_height = MAX(u1_seg_ht, (((i4_mb_adjoin_y >> 4) ^ 1) * i4_block_size));
+ i4_x_off = (i4_width - u1_seg_wd);
+ i4_y_off = (i4_height - u1_seg_ht);
+
+ if(i1_xd_index < 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 1 Processing load the pixel in the filter delay buffer */
+ for(i4_i = 0; i4_i < (i4_height + 1); i4_i++)
+ {
+ u1_filter_delay_buf[i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ pu1_src_2 -= i4_x_off;
+ memcpy(&u1_filter_delay_buf[i4_i], pu1_src_2, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_i - 1] =
+ (u1_filter_delay_buf[i4_i] + u1_filter_delay_buf[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 2 Processing */
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf[0], pu1_src_2, (i4_width + 1));
+ for(i4_i = i4_height; i4_i > 0; i4_i--)
+ {
+ u1_filter_delay_buf[i4_width + i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_width] =
+ (u1_filter_delay_buf[i4_width - 1] + u1_filter_delay_buf[i4_width + 1] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_height - i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index < 0)
+ {
+ /* Quadrant 3 Processing */
+ /* load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf[0], pu1_src_2, (i4_width + 1));
+
+ pu1_src_1 -= (i4_y_off * i4_refarray_stride);
+ for(i4_i = 1; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf[i4_width + i4_i] = *pu1_src_1;
+ pu1_src_1 += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_width] =
+ (u1_filter_delay_buf[i4_width - 1] + u1_filter_delay_buf[i4_width + 1] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+ else
+ {
+ /* Quadrant 4 Processing */
+ /* load the pixel in the filter delay buffer */
+ pu1_src_1 += ((u1_seg_ht - 1) * i4_refarray_stride);
+ for(i4_i = 0; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf[i4_i] = *pu1_src_1;
+ pu1_src_1 -= i4_refarray_stride;
+ }
+
+ pu1_src_2 -= i4_x_off;
+ memcpy(&u1_filter_delay_buf[i4_i], pu1_src_2, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf[i4_i - 1] =
+ (u1_filter_delay_buf[i4_i] + u1_filter_delay_buf[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf[i4_i] = ((u1_filter_delay_buf[i4_i]) + (u1_filter_delay_buf[i4_i + 1] * 2) +
+ (u1_filter_delay_buf[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst, &u1_out_buf[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_diag_reconstruction_chroma */
+/* Description : This function does the diagonal reconstuction for intra */
+/* upsampling for chroma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the diagonal reconstruction for intra */
+/* upsampling for chroma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_diag_reconstruction_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+{
+ WORD32 i4_i;
+ UWORD8 u1_filter_delay_buf_cb[18] = {0};
+ UWORD8 u1_filter_delay_buf_cr[18] = {0};
+ UWORD8 u1_out_buf_cb[16] = {0};
+ UWORD8 u1_out_buf_cr[16] = {0};
+ WORD32 i4_width, i4_height;
+ WORD32 i4_x_off, i4_y_off;
+ WORD32 i4_block_size = BLOCK_WIDTH >> 1;
+ UWORD8 *pu1_src_1_cb, *pu1_src_2_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_1_cr, *pu1_src_2_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+
+ pu1_src_1_cb = pu1_dst_cb + i1_xd_index;
+ pu1_src_1_cr = pu1_dst_cr + i1_xd_index;
+ i4_tmp = (i1_yd_index * i4_refarray_stride);
+ pu1_src_2_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_2_cr = pu1_dst_cr + i4_tmp;
+
+ i4_width = MAX(u1_seg_wd, (((i4_mb_adjoin_x >> 3) ^ 1) * i4_block_size));
+ i4_height = MAX(u1_seg_ht, (((i4_mb_adjoin_y >> 4) ^ 1) * i4_block_size));
+ i4_x_off = (i4_width - u1_seg_wd);
+ i4_y_off = (i4_height - u1_seg_ht);
+
+ if(i1_xd_index < 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 1 Processing load the pixel in the filter delay buffer */
+ for(i4_i = 0; i4_i < (i4_height + 1); i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+ u1_filter_delay_buf_cr[i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ pu1_src_2_cb -= i4_x_off;
+ pu1_src_2_cr -= i4_x_off;
+ memcpy(&u1_filter_delay_buf_cb[i4_i], pu1_src_2_cb, i4_width);
+ memcpy(&u1_filter_delay_buf_cr[i4_i], pu1_src_2_cr, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_i - 1] =
+ (u1_filter_delay_buf_cb[i4_i] + u1_filter_delay_buf_cb[i4_i - 2] + 1) >> 1;
+
+ u1_filter_delay_buf_cr[i4_i - 1] =
+ (u1_filter_delay_buf_cr[i4_i] + u1_filter_delay_buf_cr[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_x_off + i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index > 0)
+ {
+ /* Quadrant 2 Processing load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf_cb[0], pu1_src_2_cb, (i4_width + 1));
+ memcpy(&u1_filter_delay_buf_cr[0], pu1_src_2_cr, (i4_width + 1));
+
+ for(i4_i = i4_height; i4_i > 0; i4_i--)
+ {
+ u1_filter_delay_buf_cb[i4_width + i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_width + i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_width] =
+ (u1_filter_delay_buf_cb[i4_width - 1] + u1_filter_delay_buf_cb[i4_width + 1] + 1) >>
+ 1;
+
+ u1_filter_delay_buf_cr[i4_width] =
+ (u1_filter_delay_buf_cr[i4_width - 1] + u1_filter_delay_buf_cr[i4_width + 1] + 1) >>
+ 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_height - i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_height - i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else if(i1_xd_index > 0 && i1_yd_index < 0)
+ {
+ /* Quadrant 3 Processing load the pixel in the filter delay buffer */
+ memcpy(&u1_filter_delay_buf_cb[0], pu1_src_2_cb, (i4_width + 1));
+ memcpy(&u1_filter_delay_buf_cr[0], pu1_src_2_cr, (i4_width + 1));
+
+ i4_tmp = (i4_y_off * i4_refarray_stride);
+ pu1_src_1_cb -= i4_tmp;
+ pu1_src_1_cr -= i4_tmp;
+ for(i4_i = 1; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_width + i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb += i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_width + i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr += i4_refarray_stride;
+ }
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_width] =
+ (u1_filter_delay_buf_cb[i4_width - 1] + u1_filter_delay_buf_cb[i4_width + 1] + 1) >>
+ 1;
+
+ u1_filter_delay_buf_cr[i4_width] =
+ (u1_filter_delay_buf_cr[i4_width - 1] + u1_filter_delay_buf_cr[i4_width + 1] + 1) >>
+ 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 0; i4_i < u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[i4_y_off + i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+ else
+ {
+ /* Quadrant 4 Processing load the pixel in the filter delay buffer */
+ i4_tmp = ((u1_seg_ht - 1) * i4_refarray_stride);
+ pu1_src_1_cb += i4_tmp;
+ pu1_src_1_cr += i4_tmp;
+
+ for(i4_i = 0; i4_i <= i4_height; i4_i++)
+ {
+ u1_filter_delay_buf_cb[i4_i] = *pu1_src_1_cb;
+ pu1_src_1_cb -= i4_refarray_stride;
+
+ u1_filter_delay_buf_cr[i4_i] = *pu1_src_1_cr;
+ pu1_src_1_cr -= i4_refarray_stride;
+ }
+
+ pu1_src_2_cb -= i4_x_off;
+ pu1_src_2_cr -= i4_x_off;
+ memcpy(&u1_filter_delay_buf_cb[i4_i], pu1_src_2_cb, i4_width);
+ memcpy(&u1_filter_delay_buf_cr[i4_i], pu1_src_2_cr, i4_width);
+
+ if(0 == i4_corner_pixel_available)
+ {
+ /* interpolate the unavailable corner pixel */
+ u1_filter_delay_buf_cb[i4_i - 1] =
+ (u1_filter_delay_buf_cb[i4_i] + u1_filter_delay_buf_cb[i4_i - 2] + 1) >> 1;
+
+ u1_filter_delay_buf_cr[i4_i - 1] =
+ (u1_filter_delay_buf_cr[i4_i] + u1_filter_delay_buf_cr[i4_i - 2] + 1) >> 1;
+ }
+
+ for(i4_i = 0; i4_i < (i4_width + i4_height - 1); i4_i++)
+ {
+ /* get the filtered output */
+ u1_out_buf_cb[i4_i] =
+ ((u1_filter_delay_buf_cb[i4_i]) + (u1_filter_delay_buf_cb[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cb[i4_i + 2]) + 2) >>
+ 2;
+
+ u1_out_buf_cr[i4_i] =
+ ((u1_filter_delay_buf_cr[i4_i]) + (u1_filter_delay_buf_cr[i4_i + 1] * 2) +
+ (u1_filter_delay_buf_cr[i4_i + 2]) + 2) >>
+ 2;
+ }
+
+ /* fill the segment with diagonal reconstructed output */
+ for(i4_i = 1; i4_i <= u1_seg_ht; i4_i++)
+ {
+ memcpy(pu1_dst_cb, &u1_out_buf_cb[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ memcpy(pu1_dst_cr, &u1_out_buf_cr[(u1_seg_ht + i4_x_off) - i4_i], u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_diag_padding */
+/* Description : This function does the diagonal padding for intra */
+/* upsampling for luma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the diagonal padding for intra */
+/* upsampling for luma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_diag_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available)
+
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src, *pu1_dst;
+
+ UNUSED(pu1_refarray_2);
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ pu1_dst = pu1_refarray_1 + i4_x + (i4_y * i4_refarray_stride);
+ pu1_src = pu1_dst + i1_xd_index + (i1_yd_index * i4_refarray_stride);
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+ pu1_dst = pu1_src - i1_xd_index - (i1_yd_index * i4_refarray_stride);
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst, *pu1_src, u1_seg_wd);
+ pu1_dst += i4_refarray_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_diag_padding_chroma */
+/* Description : This function does the diagonal padding for intra */
+/* upsampling for chroma */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : This function does the diagonal padding for intra */
+/* upsampling for chroma */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : none */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/*****************************************************************************/
+void isvcd_diag_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available)
+
+{
+ WORD32 i4_idx_i;
+ UWORD8 *pu1_src_cb, *pu1_dst_cb;
+ UWORD8 *pu1_src_cr, *pu1_dst_cr;
+ WORD32 i4_tmp;
+
+ UNUSED(i4_mb_adjoin_x);
+ UNUSED(i4_mb_adjoin_y);
+ UNUSED(i4_corner_pixel_available);
+
+ i4_tmp = i4_x + (i4_y * i4_refarray_stride);
+ pu1_dst_cb = pu1_refarray_1 + i4_tmp;
+ pu1_dst_cr = pu1_refarray_2 + i4_tmp;
+ i4_tmp = i1_xd_index + (i1_yd_index * i4_refarray_stride);
+ pu1_src_cb = pu1_dst_cb + i4_tmp;
+ pu1_src_cr = pu1_dst_cr + i4_tmp;
+
+ i1_xd_index = MIN(i1_xd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_wd = MIN(u1_seg_wd, MAX_PIX_FILL_LUMA);
+ i1_yd_index = MIN(i1_yd_index, MAX_PIX_FILL_LUMA);
+ u1_seg_ht = MIN(u1_seg_ht, MAX_PIX_FILL_LUMA);
+
+ i4_tmp = (i1_xd_index + (i1_yd_index * i4_refarray_stride));
+ pu1_dst_cb = pu1_src_cb - i4_tmp;
+ pu1_dst_cr = pu1_src_cr - i4_tmp;
+
+ for(i4_idx_i = 0; i4_idx_i < u1_seg_ht; i4_idx_i++)
+ {
+ memset(pu1_dst_cb, *pu1_src_cb, u1_seg_wd);
+ pu1_dst_cb += i4_refarray_stride;
+ memset(pu1_dst_cr, *pu1_src_cr, u1_seg_wd);
+ pu1_dst_cr += i4_refarray_stride;
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_corner_samp_dyadic */
+/* */
+/* Description : This function fills the corner sample in the reference */
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray_y : pointer to luma reference array */
+/* pu1_refarray_cb : pointer to Cb reference array */
+/* pu1_refarray_cr : pointer to Cr reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_corner_samp_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xD, WORD32 i4_yD,
+ UWORD8 *pu1_refarray_y, UWORD8 *pu1_refarray_cb,
+ UWORD8 *pu1_refarray_cr)
+{
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_c_xc, i4_c_yc;
+ WORD32 i4_samp1, i4_samp2;
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_ref_xD = i4_x - i4_xD;
+ i4_ref_yD = i4_y - i4_yD;
+ i4_xc = i4_ref_xD + SIGN(i4_xD);
+ i4_yc = i4_ref_yD + SIGN(i4_yD);
+
+ /* Luma */
+ pu1_tmp_src = pu1_refarray_y + (i4_yc * DYADIC_REF_W_Y);
+ i4_samp1 = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src = pu1_refarray_y + (i4_ref_yD * DYADIC_REF_W_Y);
+ i4_samp2 = pu1_tmp_src[i4_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Chroma */
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xc = i4_c_ref_xD + SIGN(i4_xD);
+ i4_c_yc = i4_c_ref_yD + SIGN(i4_yD);
+
+ /* Cb */
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Cr */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_fill_non_ava_pixel */
+/* */
+/* Description : This function does the core pixel level processing */
+/* while filling the non available pixel */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* i4_refarray_wd : width of the reference array */
+/* i4_refarray_ht : height of the reference array */
+/* ps_mb_coord : current mb coord structure */
+/* i4_chroma_flag : chroam processing flag */
+/* Globals : none */
+/* Processing : based on the map buffer values the non available pixels */
+/* are filled using border extension algorithm */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_fill_non_avail_pixel(void *pv_map_ctxt, UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, mb_coord_t *ps_mb_coord,
+ WORD32 i4_chroma_flag, UWORD8 u1_avail_map[4][4])
+{
+ /* --------------------------------------------------------------------- */
+ /* Index Variables */
+ /* --------------------------------------------------------------------- */
+ intra_samp_map_ctxt_t *ps_map_ctxt;
+ ref_mb_map_t *ps_x_off_len;
+ ref_mb_map_t *ps_y_off_len;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_corner_pixel_available;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for Segment lookup */
+ /* --------------------------------------------------------------------- */
+ seg_lookup_desc_t *ps_segments_x;
+ seg_lookup_desc_t *ps_segments_y;
+ seg_description_t *ps_seg_desc_x, *ps_seg_desc_y;
+ seg_description_t *ps_seg_x_tmp, *ps_seg_y_tmp;
+ UWORD8 u1_num_sgmts_x, u1_num_sgmts_y;
+
+ /* --------------------------------------------------------------------- */
+ /* Temp Variables for Mapping context */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refmb_wd;
+ WORD32 i4_refmb_ht;
+ WORD32 i4_mbaddr_x;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_xr_index, i4_yr_index;
+ WORD32 i4_j, i4_i;
+ WORD32 i4_cur_x;
+ UWORD32 u4_lookup_4bit, u4_lookup_5bit, u4_4thbit;
+ WORD32 i4_pad_size;
+ WORD32 i4_x_min;
+ WORD32 i4_y_min;
+ WORD32 i4_x_start_pos, i4_y_start_pos;
+ ref_min_max_map_t *ps_x_min_max;
+ ref_min_max_map_t *ps_y_min_max;
+ UWORD8 *pu1_ref_idx_x, *pu1_ref_idx_y;
+ ftype_intra_samp_padding *pf_intra_samp_padding;
+ ftype_intra_samp_padding **pf_intra_samp_lookup;
+
+ ps_map_ctxt = (intra_samp_map_ctxt_t *) pv_map_ctxt;
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+ ps_y_min_max = ps_map_ctxt->ps_y_min_max;
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+ i4_mbaddr_y = ps_mb_coord->u2_mb_y;
+ i4_mbaddr_x = ps_mb_coord->u2_mb_x;
+ i4_x_offset = ps_x_off_len[i4_mbaddr_x].i2_offset;
+ i4_y_offset = ps_y_off_len[i4_mbaddr_y].i2_offset;
+ i4_refmb_wd = (MB_WIDTH >> i4_chroma_flag) - 1;
+ i4_refmb_ht = (MB_HEIGHT >> i4_chroma_flag) - 1;
+
+ if(0 == i4_chroma_flag)
+ {
+ pf_intra_samp_lookup = gpf_lookup_fxns_luma;
+ }
+ else
+ {
+ pf_intra_samp_lookup = gpf_lookup_fxns_chroma;
+ }
+
+ /* get the min and max positions */
+ i4_x_min = ps_x_min_max[i4_mbaddr_x].i2_min_pos;
+ i4_y_min = ps_y_min_max[i4_mbaddr_y].i2_min_pos;
+
+ /* get the start position of the MB in reference layer */
+ i4_pad_size = 2 >> i4_chroma_flag;
+ i4_x_start_pos = (i4_x_min - i4_pad_size);
+ i4_y_start_pos = (i4_y_min - i4_pad_size);
+ i4_xr_index = (i4_x_start_pos + i4_x_offset) & i4_refmb_wd;
+ i4_yr_index = (i4_y_start_pos + i4_y_offset) & i4_refmb_ht;
+
+ /* Find the number of segments in x and y direction */
+ ps_segments_x = (ps_map_ctxt->ps_seg_lookup_horz + i4_xr_index);
+ ps_segments_y = (ps_map_ctxt->ps_seg_lookup_vert + i4_yr_index);
+ u1_num_sgmts_x = ps_segments_x->u1_num_segments;
+ u1_num_sgmts_y = ps_segments_y->u1_num_segments;
+ ps_seg_desc_x = ps_segments_x->s_segments;
+ ps_seg_desc_y = ps_segments_y->s_segments;
+ pu1_ref_idx_x = ps_map_ctxt->pu1_refarray_x_idx;
+ pu1_ref_idx_y = ps_map_ctxt->pu1_refarray_y_idx;
+ i4_cur_x = pu1_ref_idx_x[i4_x_start_pos];
+ u4_4thbit = ps_segments_x->u4_start_pos;
+
+ for(i4_j = 0; i4_j < u1_num_sgmts_y; i4_j++)
+ {
+ UWORD8 i4_idx_a, i4_idx_b;
+ UWORD8 u1_seg_ht, u1_seg_wd;
+ UWORD8 u1_mb_adjoin_x, u1_mb_adjoin_y;
+ WORD8 i1_nearst_mb_bdry_x, i1_nearst_mb_bdry_y;
+ UWORD32 u4_num_valid_segs;
+ WORD32 i4_idx_a_plus_ny, i4_idx_b_plus_nx, i4_index;
+ WORD8 i1_yd_index, i1_xd_index;
+
+ ps_seg_y_tmp = &ps_seg_desc_y[i4_j];
+ i4_y = i4_y_start_pos + ps_seg_y_tmp->u1_seg_off;
+ u1_seg_ht = ps_seg_y_tmp->u1_seg_dim;
+ i1_yd_index = ps_seg_y_tmp->i1_dist_idx;
+ i1_nearst_mb_bdry_y = ps_seg_y_tmp->i1_nearst_mb_bdry;
+ u1_mb_adjoin_y = ps_seg_y_tmp->u1_mb_adjoin;
+ i4_idx_a = pu1_ref_idx_y[i4_y];
+ i4_idx_a_plus_ny = (i4_idx_a + i1_nearst_mb_bdry_y);
+
+ /* Pack the availabilities of the next three horizontal MBs in 3bit
+ format and 4th bit indicating if the start position is greater than the mb_width/2 */
+ u4_lookup_4bit = u4_4thbit | u1_avail_map[i4_idx_a][i4_cur_x + 2] << 2 |
+ u1_avail_map[i4_idx_a][i4_cur_x + 1] << 1 |
+ u1_avail_map[i4_idx_a][i4_cur_x];
+
+ u4_num_valid_segs = gu4_valid_segs_lookup[u4_lookup_4bit];
+ i4_i = isvcd_left_most_bit_detect(u4_num_valid_segs);
+ u4_num_valid_segs <<= (i4_i + 1);
+
+ for(; i4_i < u1_num_sgmts_x; i4_i++)
+ {
+ ps_seg_x_tmp = &ps_seg_desc_x[i4_i];
+ i4_x = i4_x_start_pos + ps_seg_x_tmp->u1_seg_off;
+ i4_idx_b = pu1_ref_idx_x[i4_x];
+ u1_seg_wd = ps_seg_x_tmp->u1_seg_dim;
+ i1_xd_index = ps_seg_x_tmp->i1_dist_idx;
+ i1_nearst_mb_bdry_x = ps_seg_x_tmp->i1_nearst_mb_bdry;
+ u1_mb_adjoin_x = ps_seg_x_tmp->u1_mb_adjoin;
+ i4_idx_b_plus_nx = (i4_idx_b + i1_nearst_mb_bdry_x);
+
+ /* Find the avalability of (x,y-Yd),(x-Xd,y),(x-Xd,y-Yd) and pack it to 3 bits */
+ u4_lookup_5bit = u1_avail_map[i4_idx_a_plus_ny][i4_idx_b_plus_nx] << 2 |
+ u1_avail_map[i4_idx_a_plus_ny][i4_idx_b] << 1 |
+ u1_avail_map[i4_idx_a][i4_idx_b_plus_nx] | u1_mb_adjoin_x |
+ u1_mb_adjoin_y;
+
+ i4_corner_pixel_available = u1_avail_map[i4_idx_a_plus_ny][i4_idx_b_plus_nx];
+
+ /* Function pointer table from lookup to get Left,Top,Bottom,Right,Diagonal padding */
+ if(u4_lookup_5bit > 31)
+ {
+ u4_lookup_5bit = 0;
+ }
+ pf_intra_samp_padding = pf_intra_samp_lookup[u4_lookup_5bit];
+
+ if(pf_intra_samp_padding != NULL)
+ {
+ pf_intra_samp_padding(i4_x, i4_y, i1_xd_index, i1_yd_index, u1_seg_wd, u1_seg_ht,
+ pu1_refarray_1, pu1_refarray_2, i4_refarray_stride,
+ u1_mb_adjoin_x, u1_mb_adjoin_y, i4_corner_pixel_available);
+ }
+
+ /* increment to the next unavailable segment */
+ i4_index = isvcd_left_most_bit_detect(u4_num_valid_segs);
+ u4_num_valid_segs <<= (i4_index + 1);
+ i4_i += i4_index;
+
+ } /* end of loop over ref array width */
+
+ } /* end of loop over ref array height */
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_ref_layer_mbtype */
+/* */
+/* Description : This function is used to find the mb type of the */
+/* corresponding MB in the reference layer */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra samp context */
+/* pi1_ref_mb_modes : ref mb modes buffer pointer */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_x_ref : reference location X */
+/* i4_y_ref : reference location Y */
+/* pi4_mb_type : pointer to store the mb type */
+/* i4_chroma_flag : chroma flag */
+/* Globals : none */
+/* Processing : it derives the bit corresponding to reference MB and */
+/* stores the mbtype as INTRA if the bit is set */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD8 isvcd_get_ref_layer_mbtype(WORD8 *pi1_ref_mb_modes, WORD32 *pi4_mb_type,
+ WORD8 i1_curr_slice_id, WORD8 i1_cons_intr_samp_flag)
+{
+ WORD8 i1_intra_slice_id;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 i1_mb_mode;
+
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ /* INTER */
+ *pi4_mb_type = SVC_INTER_MB;
+ i1_intra_slice_id = -1;
+ }
+ else
+ {
+ /* INTRA */
+ *pi4_mb_type = SVC_INTRA_MB;
+ i1_intra_slice_id = ps_inter_lyr_mb_prms->i1_slice_id;
+
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ /* check for different slice idc */
+ if(ps_inter_lyr_mb_prms->i1_slice_id != i1_curr_slice_id)
+ {
+ /* store the mode as INTER (not available for upsampling) */
+ *pi4_mb_type = SVC_INTER_MB;
+ }
+ }
+ }
+
+ /* if contarained intra flag is 1 then check for same mb mode */
+ return (i1_intra_slice_id);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_reflayer_construction */
+/* */
+/* Description : This function constructs the reference array buffer */
+/* used for intra resampling of a component in an MB */
+/* */
+/* Inputs : pv_intra_samp_ctxt: intra sampling context */
+/* pu1_inp : input (reference layer data) */
+/* i4_inp_stride : input buffer stride */
+/* ps_ref_mb_mode_map : ref layer mb mode buffer desc */
+/* pi4_refarr_wd : pointer to store the reference array WD */
+/* pi4_refarr_ht : pointer to store the reference array HT */
+/* pi4_x_offset : pointer to store the reference X offset */
+/* pi4_y_offset : pointer to store the reference Y offset */
+/* ps_coord : mb co-ordinate structure */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it fills the reference layer data if they are falling in */
+/* INTRA MB region. If all the pixels are not filled it */
+/* calls the border extension algorithm to fill them */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/*****************************************************************************/
+WORD32 isvcd_reflayer_construction(void *pv_intra_samp_ctxt, UWORD8 *pu1_inp_1, UWORD8 *pu1_inp_2,
+ WORD32 i4_inp_stride, WORD32 i4_refarray_stride,
+ mem_element_t *ps_ref_mb_mode_map, mb_coord_t *ps_coord,
+ WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x, i4_y;
+
+ /* --------------------------------------------------------------------- */
+ /* Context and reference layer realted varaibles */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_map_ctxt_t *ps_map_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes, *pi1_ref_mb_modes_bkp_1;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ ref_mb_map_t *ps_x_off_len;
+ ref_mb_map_t *ps_y_off_len;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_mbaddr_x;
+ WORD32 i4_mb_ht, i4_mb_wd;
+ UWORD8 u1_map_buf[4][4] = {0}; /*!< 4x4 mb grid buffer to store the mb availablity */
+ /* --------------------------------------------------------------------- */
+ /* Temp Variables for Mapping context */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_ref_wd;
+ WORD32 i4_ref_ht;
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refarray_wd;
+ WORD32 i4_refarray_ht;
+ WORD32 i4_mb_type;
+ WORD8 i1_cons_intr_samp_flag;
+ WORD8 i1_slice_id = 0;
+ WORD32 i4_mb_wd_sft, i4_mb_ht_sft;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+
+ WORD32 i4_unfill_check;
+ UWORD8 *pu1_refarray_1, *pu1_refarray_2;
+
+ UNUSED(pu1_inp_2);
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode_map->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode_map->i4_element_size;
+
+ /* get the condtrained intra sampling flag */
+ i1_cons_intr_samp_flag = ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag;
+
+ if(NULL == pi1_ref_mb_modes)
+ {
+ return NOT_OK;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Based on Chroma and Luma, extracting the context information struct */
+ /* --------------------------------------------------------------------- */
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ else
+ ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
+
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+
+ /* --------------------------------------------------------------------- */
+ /* Deriving the parameters required for further processing */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_base_width = ps_lyr_ctxt->i4_ref_width;
+ WORD32 i4_base_height = ps_lyr_ctxt->i4_ref_height;
+
+ i4_ref_wd = i4_base_width >> i4_chroma_flag;
+ i4_ref_ht = i4_base_height >> i4_chroma_flag;
+ i4_mb_wd_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
+ i4_mb_ht_sft = (MB_HEIGHT_SHIFT - i4_chroma_flag);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Local variables based on the MB address */
+ /* --------------------------------------------------------------------- */
+ i4_mbaddr_y = ps_coord->u2_mb_y;
+ i4_mbaddr_x = ps_coord->u2_mb_x;
+ i4_x_offset = ps_x_off_len[i4_mbaddr_x].i2_offset;
+ i4_y_offset = ps_y_off_len[i4_mbaddr_y].i2_offset;
+ i4_refarray_wd = ps_x_off_len[i4_mbaddr_x].i2_length;
+ i4_refarray_ht = ps_y_off_len[i4_mbaddr_y].i2_length;
+ i4_mb_wd = (MB_WIDTH >> i4_chroma_flag);
+ i4_mb_ht = (MB_HEIGHT >> i4_chroma_flag);
+
+ /* --------------------------------------------------------------------- */
+ /* Derivation of ref slice MB idc */
+ /* --------------------------------------------------------------------- */
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ WORD32 i4_x_min, i4_x_max;
+ WORD32 i4_y_min, i4_y_max;
+ ref_min_max_map_t *ps_x_min_max;
+ ref_min_max_map_t *ps_y_min_max;
+
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+ ps_y_min_max = ps_map_ctxt->ps_y_min_max;
+
+ /* get the min and max positions */
+ i4_x_min = ps_x_min_max[i4_mbaddr_x].i2_min_pos;
+ i4_x_max = ps_x_min_max[i4_mbaddr_x].i2_max_pos;
+ i4_y_min = ps_y_min_max[i4_mbaddr_y].i2_min_pos;
+ i4_y_max = ps_y_min_max[i4_mbaddr_y].i2_max_pos;
+
+ /* default initialization */
+ i4_mb_type = SVC_INTER_MB;
+
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_mb_x, i4_mb_y;
+
+ i4_y_ref = (i4_y_min + 1) + i4_y_offset;
+ i4_x_ref = (i4_x_min + 1) + i4_x_offset;
+ i4_mb_x = (i4_x_ref >> i4_mb_wd_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_ht_sft);
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_element_size);
+ }
+
+ for(i4_y = (i4_y_min + 1); i4_y <= (i4_y_max - 1);)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_distleftX, i4_rangeX;
+ WORD32 i4_disttopY, i4_rangeY;
+
+ i4_y_ref = (i4_y + i4_y_offset);
+ i4_disttopY = (i4_y_ref) & (i4_mb_ht - 1);
+ i4_rangeY = (i4_mb_ht - i4_disttopY);
+
+ pi1_ref_mb_modes_bkp_1 = pi1_ref_mb_modes;
+
+ for(i4_x = (i4_x_min + 1); i4_x <= (i4_x_max - 1);)
+ {
+ i4_x_ref = (i4_x + i4_x_offset);
+ i4_distleftX = (i4_x_ref) & (i4_mb_wd - 1);
+ i4_rangeX = (i4_mb_wd - i4_distleftX);
+
+ /* get the referecne layer mb type */
+ i1_slice_id =
+ isvcd_get_ref_layer_mbtype(pi1_ref_mb_modes_bkp_1, &i4_mb_type, i1_slice_id, 0);
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ /* if an Intra MB is returned then break the loop */
+ break;
+ }
+
+ i4_x += i4_rangeX;
+ pi1_ref_mb_modes_bkp_1 += i4_element_size;
+ } /* end of loop in horizontal direction */
+
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ /* if an Intra MB is returned then break the loop */
+ break;
+ }
+
+ i4_y += i4_rangeY;
+ pi1_ref_mb_modes += (i4_ref_mode_stride * i4_element_size);
+
+ } /* end of loop in vertical direction */
+ }
+ else
+ {
+ /* set to non valid value */
+ i1_slice_id = -1;
+ }
+
+ i4_unfill_check = 0;
+
+ /* --------------------------------------------------------------------- */
+ /* Copying the data from recon buffer to refSample Array. */
+ /* NOTE: The copying of the data from recon buffer to refSample Array */
+ /* can be optimized by bring in data at N-MB level,thus taking */
+ /* advantage of the overlapping data which now gets copied every MB*/
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_x_ref_start, i4_x_ref_end;
+ WORD32 i4_y_ref_start, i4_y_ref_end;
+ WORD32 i4_rangeW, i4_rangeH;
+ WORD32 i4_offset;
+ UWORD8 *pu1_src, *pu1_dst;
+ UWORD8 *pu1_dst1, *pu1_dst2;
+
+ /* Copy (refW x refH) dimension into reference sample array */
+ i4_x_ref_start = MAX(0, MIN((i4_ref_wd - 1), i4_x_offset));
+ i4_x_ref_end = MAX(0, MIN((i4_ref_wd - 1), (i4_refarray_wd - 1) + i4_x_offset));
+ i4_y_ref_start = MAX(0, MIN((i4_ref_ht - 1), i4_y_offset));
+ i4_y_ref_end = MAX(0, MIN((i4_ref_ht - 1), (i4_refarray_ht - 1) + i4_y_offset));
+
+ /* find the actual data to be copied */
+ i4_rangeW = (i4_x_ref_end - i4_x_ref_start + 1);
+ i4_rangeH = (i4_y_ref_end - i4_y_ref_start + 1);
+
+ /* get the reconbuffer pointer and ref sample array pointer */
+ i4_offset =
+ (i4_x_ref_start - i4_x_offset) + ((i4_y_ref_start - i4_y_offset) * i4_refarray_stride);
+
+ if(0 == i4_chroma_flag)
+ {
+ pu1_refarray_1 = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_2 = NULL;
+ pu1_src = pu1_inp_1;
+ pu1_dst = pu1_refarray_1 + i4_offset;
+
+ /* Copy luma data into refsample array */
+ isvcd_copy_data(pu1_src, i4_inp_stride, pu1_dst, i4_refarray_stride, i4_rangeW,
+ i4_rangeH);
+ }
+ else
+ {
+ pu1_refarray_1 = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_2 = ps_ctxt->pu1_refarray_cb;
+ pu1_src = pu1_inp_1;
+ pu1_dst1 = pu1_refarray_1 + i4_offset;
+ pu1_dst2 = pu1_refarray_2 + i4_offset;
+ isvcd_copy_data_semiplanr(pu1_src, i4_inp_stride, pu1_dst1, pu1_dst2,
+ i4_refarray_stride, i4_rangeW, i4_rangeH);
+ }
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Loop to fill ref sample array and corresponding map for interpolation */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_i, i4_j;
+ UWORD8 *pu1_ref_idx_x, *pu1_ref_idx_y;
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_mb_x, i4_mb_y;
+
+ i4_y_ref = i4_y_offset;
+ i4_x_ref = i4_x_offset;
+ i4_mb_x = (i4_x_ref >> i4_mb_wd_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_ht_sft);
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_element_size);
+ pu1_ref_idx_x = ps_map_ctxt->pu1_refarray_x_idx;
+ pu1_ref_idx_y = ps_map_ctxt->pu1_refarray_y_idx;
+
+ i4_j = 0;
+ for(i4_y = 0; i4_y < i4_refarray_ht;)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_distleftX, i4_rangeX;
+ WORD32 i4_disttopY, i4_rangeY;
+
+ i4_y_ref = i4_y + i4_y_offset;
+ i4_disttopY = (i4_y_ref) & (i4_mb_ht - 1);
+ i4_rangeY = (i4_mb_ht - i4_disttopY);
+
+ /* find the y-index lookup */
+ memset(pu1_ref_idx_y, i4_j, i4_rangeY);
+ pu1_ref_idx_y += i4_rangeY;
+
+ i4_i = 0;
+ pi1_ref_mb_modes_bkp_1 = pi1_ref_mb_modes;
+ for(i4_x = 0; i4_x < i4_refarray_wd;)
+ {
+ i4_x_ref = i4_x + i4_x_offset;
+ i4_distleftX = (i4_x_ref) & (i4_mb_wd - 1);
+ i4_rangeX = (i4_mb_wd - i4_distleftX);
+
+ if(0 == i4_j)
+ {
+ /* find the x-index lookup */
+ memset(pu1_ref_idx_x, i4_i, i4_rangeX);
+ pu1_ref_idx_x += i4_rangeX;
+ }
+
+ /* get the referecne layer mb type */
+ isvcd_get_ref_layer_mbtype(pi1_ref_mb_modes_bkp_1, &i4_mb_type, i1_slice_id,
+ i1_cons_intr_samp_flag);
+
+ if(SVC_INTRA_MB == i4_mb_type)
+ {
+ u1_map_buf[i4_j][i4_i] = 1;
+ }
+ else
+ {
+ i4_unfill_check = 1;
+ }
+
+ i4_x = i4_x + i4_rangeX;
+ i4_i++;
+ pi1_ref_mb_modes_bkp_1 += i4_element_size;
+
+ } /* end of loop over ref array width */
+
+ i4_j++;
+ i4_y = i4_y + i4_rangeY;
+ pi1_ref_mb_modes += (i4_ref_mode_stride * i4_element_size);
+ } /* end of loop over ref array height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Calling boundary extension algorithm to fill unfilled pixels */
+ /* --------------------------------------------------------------------- */
+ if(i4_unfill_check == 1)
+ {
+ isvcd_fill_non_avail_pixel(ps_map_ctxt, pu1_refarray_1, pu1_refarray_2, i4_refarray_stride,
+ ps_coord, i4_chroma_flag, u1_map_buf);
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_reflayer_construction_dyadic */
+/* */
+/* Description : This function constructs the reference array buffer */
+/* for dyadic cases used for intra resampling of a */
+/* component in an MB */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_mb_mode_map : ref layer mb mode buffer desc */
+/* pu1_inp_luma : luma input (reference layer data) */
+/* pu1_inp_chroma : chroma input (reference layer data) */
+/* i4_inp_luma_stride : luma input buffer stride */
+/* i4_inp_chroma_stride : chroma input buffer stride */
+/* i4_top : indicates whether the core 8x8 reference block */
+/* is one of 0 and 1 or one of 2 and 3 */
+/* i4_left : indicates whether the core 8x8 ref block */
+/* is one of 0 and 2 or one of 1 and 3 */
+/* ps_ref_mb_coord : coordinates of the reference MB */
+/* Globals : none */
+/* Processing : it fills the reference layer data if they are falling in */
+/* INTRA MB region. If all the pixels are not filled it */
+/* calls the border extension algorithm to fill them */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_reflayer_construction_dyadic(void *pv_intra_samp_ctxt,
+ mem_element_t *ps_ref_mb_mode_map, UWORD8 *pu1_inp_luma,
+ UWORD8 *pu1_inp_chroma, WORD32 i4_inp_luma_stride,
+ WORD32 i4_inp_chroma_stride, WORD32 i4_top,
+ WORD32 i4_left, UWORD16 u2_mb_x, UWORD16 u2_mb_y)
+{
+ /* Index variables */
+ WORD32 i4_x, i4_y;
+ WORD32 i4_x0, i4_y0;
+ WORD32 i4_xc0, i4_yc0;
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+
+ /* --------------------------------------------------------------------- */
+ /* Context and reference layer related variables */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_mbaddr_x;
+
+ /* --------------------------------------------------------------------- */
+ /* Temp Variables for Mapping context */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_refarray_wd_luma, i4_refarray_wd_chroma;
+ WORD32 i4_refarray_ht_luma, i4_refarray_ht_chroma;
+ WORD32 i4_avlblty;
+ WORD8 i1_cons_intr_samp_flag;
+ WORD8 i1_slice_id;
+ WORD8 i1_corner_samp_avlbl_flag;
+ UWORD8 u1_ny_avlblty;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+ UWORD8 *pu1_refarray_luma;
+ UWORD8 *pu1_refarray_cb, *pu1_refarray_cr;
+
+ /* --------------------------------------------------------------------- */
+ /* Derivation of local variables */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode_map->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode_map->i4_element_size;
+
+ /* --------------------------------------------------------------------- */
+ /* get the constrained intra resampling flag */
+ /* --------------------------------------------------------------------- */
+ i1_cons_intr_samp_flag = ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag;
+ if(NULL == pi1_ref_mb_modes)
+ {
+ return NOT_OK;
+ }
+
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ /* --------------------------------------------------------------------- */
+ /* Get the coordinates of the reference layer MB */
+ /* --------------------------------------------------------------------- */
+ i4_mbaddr_x = u2_mb_x;
+ i4_mbaddr_y = u2_mb_y;
+
+ /* --------------------------------------------------------------------- */
+ /* Getting the size of the valid area of ref array to be brought in */
+ /* --------------------------------------------------------------------- */
+ i4_refarray_wd_luma = 20;
+ i4_refarray_ht_luma = 20;
+ i4_refarray_wd_chroma = i4_refarray_wd_luma >> 1;
+ i4_refarray_ht_chroma = i4_refarray_ht_luma >> 1;
+
+ /* --------------------------------------------------------------------- */
+ /* Derivation of ref slice MB idc */
+ /* --------------------------------------------------------------------- */
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 *pi1_ref_mb_mode_tmp;
+ WORD8 i1_mb_mode;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_mode_tmp = pi1_ref_mb_modes;
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_mode_tmp;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ /* The reference layer MB should be intra */
+ UNUSED(i1_mb_mode);
+
+ i1_slice_id = ps_inter_lyr_mb_prms->i1_slice_id;
+ }
+ else
+ {
+ /* set to non valid value */
+ i1_slice_id = -1;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Bring in the reference array */
+ /* --------------------------------------------------------------------- */
+ {
+ UWORD8 *pu1_src, *pu1_dst;
+ WORD32 i4_src_stride, i4_dst_stride;
+
+ /* Copy luma */
+ i4_src_stride = i4_inp_luma_stride;
+ i4_dst_stride = DYADIC_REF_W_Y;
+ pu1_src = pu1_inp_luma;
+ pu1_dst = pu1_refarray_luma;
+ isvcd_copy_data(pu1_src, i4_src_stride, pu1_dst, i4_dst_stride, i4_refarray_wd_luma,
+ i4_refarray_ht_luma);
+ // Semi planar
+ i4_src_stride = i4_inp_chroma_stride;
+ i4_dst_stride = DYADIC_REF_W_C;
+ pu1_src = pu1_inp_chroma;
+ isvcd_copy_data_semiplanr(pu1_src, i4_src_stride, pu1_refarray_cb, pu1_refarray_cr,
+ i4_dst_stride, i4_refarray_wd_chroma, i4_refarray_ht_chroma);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Get the availability of 5 neighboring MBs */
+ /* --------------------------------------------------------------------- */
+ {
+ /* mb_x + left, mb_y + top */
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty = i4_avlblty;
+
+ /* mb_x + left, mb_y */
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 1);
+
+ /* mb_x, mb_y + top */
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 2);
+
+ /* mb_x - left, mb_y + top */
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x - i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 3);
+
+ /* mb_x + left, mb_y - top */
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y - i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 4);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Filling the unavailable samples, if any */
+ /* --------------------------------------------------------------------- */
+ if(0x7 == u1_ny_avlblty)
+ {
+ /* All are available, exit */
+ return OK;
+ }
+
+ if(!(u1_ny_avlblty & 0x7))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Set the 4 corner samples to (x-xD,y-yD) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Set the corner sample of Cb and Cr to (x-xD,y-yD) */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ }
+
+ if(!(u1_ny_avlblty & 0x5))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD), ..., (x0+7,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), (x0+1,y0+1), ..., (x0+7,y0+1) */
+ i4_x0 = 2;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ }
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ for(i4_x = i4_x0; i4_x < i4_x0 + 8; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src[i4_x];
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src1[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src2[i4_x];
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x3))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0); */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1); ... ;*/
+ /* copy (ref_xD,y0+7) to (x0,y0+7) and (x0+1,y0+7) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ }
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src;
+
+ for(i4_y = i4_y0; i4_y < i4_y0 + 8; i4_y++)
+ {
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst1 += DYADIC_REF_W_Y;
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ pu1_tmp_src1 += DYADIC_REF_W_C;
+ pu1_tmp_src2 += DYADIC_REF_W_C;
+ pu1_tmp_dst1 += DYADIC_REF_W_C;
+ pu1_tmp_dst2 += DYADIC_REF_W_C;
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x4))
+ {
+ if(!(u1_ny_avlblty & 0x8))
+ {
+ /* (mb_x-left,mb_y+top) not available */
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD) and (x0+1,ref_yD) to (x0,y0) and (x0+1,y0), and */
+ /* to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+
+ } /* if (mb_x-left,mb_y+top) not available */
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride,
+ i4_element_size, i4_mbaddr_x - i4_left, i4_mbaddr_y,
+ &i4_avlblty, i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+ i4_ref_xD = i4_x0 - (i4_left * 7) - (i4_left >> 1);
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if not available */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvcd_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x2))
+ {
+ if(!(u1_ny_avlblty & 0x10))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0), (x0+1,y0), and */
+ /* copy (ref_xD,y0+1) to (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ pu1_tmp_src = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+
+ } /* if (mb_x+left,mb_y-top) not available */
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ isvcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride,
+ i4_element_size, i4_mbaddr_x, i4_mbaddr_y - i4_top,
+ &i4_avlblty, i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - (i4_top * 7) - (i4_top >> 1);
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal consrtuction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvcd_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+ }
+ }
+
+ if(u1_ny_avlblty & 1)
+ {
+ if(!(u1_ny_avlblty & 2))
+ {
+ /* (mb_x+left,mb_y) is unavailable */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 4) >> 2;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ i4_ref_yD = 1;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ i4_ref_yD = 18;
+ }
+
+ i4_ref_xD = i4_x0 - (i4_left) - (i4_left >> 1);
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if unavailable */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 8 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 (x0,y0) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0+1), ..., (x0,y0+7) and */
+ /* (x0+1,y0), ..., (x0+1,y0+6) */
+ for(i4_y = i4_y0 + 1; i4_y < i4_y0 + 8; i4_y++)
+ {
+ i4_yD++;
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ }
+
+ /* (x0+1,y0+7) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x0 + 1, i4_y0 + 7, i4_xD + 1, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 (x0+1,y0) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0 + 1, i4_y0, i4_xD + 1, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 7; i4_y++)
+ {
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ i4_yD++;
+ }
+
+ /* (x0,y0+7) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0, i4_y0 + 7, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_yD++;
+ }
+
+ } /* (mb_x+left,mb_y) is unavailable */
+
+ if(!(u1_ny_avlblty & 4))
+ {
+ /* (mb_x,mb_y+top) is unavailable */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 2) >> 1;
+ i4_y0 = 9 + (i4_top << 3) + (i4_top);
+ i4_x0 = 2;
+ i4_ref_xD = 1;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ i4_ref_xD = 18;
+ }
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ isvcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 2 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 (x0,y0) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), ..., (x0+6,y0+1) */
+ for(i4_x = i4_x0 + 1; i4_x < i4_x0 + 8; i4_x++)
+ {
+ i4_xD++;
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x - 1] = u1_filled_samp;
+ }
+
+ /* (x0+7,y0+1) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x0 + 7, i4_y0 + 1, i4_xD, i4_yD + 1, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 */
+ /* (x0,y0+1) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0, i4_y0 + 1, i4_xD, i4_yD + 1,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_x = i4_x0; i4_x < i4_x0 + 7; i4_x++)
+ {
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst[i4_x + 1] = u1_filled_samp;
+ i4_xD++;
+ }
+
+ /* (x0+7,y0) */
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x0 + 7, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = isvcd_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_xD++;
+ }
+
+ } /* (mb_x,mb_y+top) is unavailable */
+ } /* if (mb_x+left,mb_y+top) not available */
+ else
+ {
+ UWORD8 *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ if(0x02 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) available, (mb_x,mb_y+top) unavailable */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), and (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_xc0];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_xc0];
+
+ } /* if (mb_x+left,mb_y) available, (mb_x,mb_y+top) unavailable */
+ else if(0x04 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) unavailable, (mb_x,mb_y+top) available */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0) */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_tmp_src1 + DYADIC_REF_W_Y;
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src2[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src2[i4_ref_xD];
+
+ /* Copy Cb and Cr */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+
+ } /* if (mb_x+left,mb_y) unavailable, (mb_x,mb_y+top) available */
+ else if(0x6 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) available, (mb_x,mb_y+top) available */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ isvcd_diagonal_construct_dyadic(i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma,
+ DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cb,
+ DYADIC_REF_W_C);
+
+ isvcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD, pu1_refarray_cr,
+ DYADIC_REF_W_C);
+
+ } /* if (mb_x+left,mb_y) available, (mb_x,mb_y+top) available */
+ } /* (mb_x+left,mb_y+top) available */
+
+ return OK;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_base_luma_dyadic */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* intra resampling for dyadic scaling ratios */
+/* Inputs : pu1_inp_buf : ptr to the 12x12 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 12x16 buffer to hold the */
+/* vertically interpolated data */
+/* pu1_out_buf : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_base_luma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1, i4_samp_2, i4_samp_3;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ /* Filter coefficient values for phase 4 */
+ i4_coeff_0 = -3;
+ i4_coeff_1 = 28;
+ i4_coeff_2 = 8;
+ i4_coeff_3 = -1;
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 12; i4_x++)
+ {
+ /* y = 0, y_phase = 12 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_2 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_3 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase 12 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ /* Increment the output ptr */
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ }
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ /* x = 0, x_phase = 12 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+ i4_samp_2 = *pi2_tmp++;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* since x_phase 12 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_1 += 512;
+
+ i4_rslt_1 >>= 10;
+
+ /* Store the output */
+ pu1_out[0] = CLIPUCHAR(i4_rslt_1);
+
+ for(i4_x = 1; i4_x < 15; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* x_phase is 4 for odd values of x */
+ /* and 12 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_2 += 512;
+
+ i4_rslt_1 >>= 10;
+ i4_rslt_2 >>= 10;
+
+ /* Store the output */
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+ pu1_out[i4_x + 1] = CLIPUCHAR(i4_rslt_2);
+ }
+
+ /* x = 15 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_1 >>= 10;
+
+ /* Store the output */
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+
+ /* Increment the output ptr */
+ pu1_out += i4_out_stride;
+
+ } /* End of loop over y */
+} /* isvcd_interpolate_base_luma_dyadic */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_1 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 */
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* 1 2 */
+/* 2 1 */
+/* 2 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_1(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ /* y = 0, y_phase = phase_0 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase = phase_0 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Increment the output ptr */
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 7; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ } /* End of loop over x */
+} /* isvcd_vert_interpol_chroma_dyadic_1 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_2 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 */
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* 0 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_2(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ } /* End of loop over x */
+} /* isvcd_vert_interpol_chroma_dyadic_2 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_3 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 */
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_3(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+
+ } /* End of loop over x */
+} /* isvcd_vert_interpol_chroma_dyadic_3 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_1 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* horizontal intra resampling for dyadic scaling ratios for*/
+/* chroma with following ref_lyr_chroma_phase_x_plus1_flag*/
+/* and chroma_phase_x_plus1_flag: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* Inputs : pi2_tmp_filt_buf : ptr to the 6x8 buffer containing the */
+/* vertically interpolated data */
+/* pu1_out_buf : pointer to the output buffer */
+/* i4_out_stride : output buffer stride */
+/* i4_phase_0 : x phase for even values of x */
+/* i4_phase_1 : x phase for odd values of x */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_horz_interpol_chroma_dyadic_1(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y++)
+ {
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_0 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+
+ /* Store the output */
+ pu1_out[0] = i4_rslt_1;
+
+ for(i4_x = 1; i4_x < 7; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* x_phase is phase_1 for odd values of x and phase_0 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ /* Rounding to 8-bit values */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+ i4_rslt_2 += 32;
+ i4_rslt_2 >>= 6;
+
+ /* Storing the results */
+ pu1_out[2 * i4_x] = i4_rslt_1;
+ pu1_out[2 * (i4_x + 1)] = i4_rslt_2;
+
+ } /* End of loop over y */
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_1 for x = 7 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+
+ /* Store the output */
+ pu1_out[2 * 7] = i4_rslt_1;
+
+ /* Incrementing the output ptr */
+ pu1_out += i4_dst_stride;
+
+ } /* End of loop over x */
+} /* isvcd_horz_interpol_chroma_dyadic_1 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_2 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* horizontal intra resampling for dyadic scaling ratios for*/
+/* chroma with following ref_lyr_chroma_phase_x_plus1_flag*/
+/* and chroma_phase_x_plus1_flag: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* Inputs : pi2_tmp_filt_buf : ptr to the 6x8 buffer containing the */
+/* vertically interpolated data */
+/* pu1_out_buf : pointer to the output buffer */
+/* i4_out_stride : output buffer stride */
+/* i4_phase_0 : x phase for even values of x */
+/* i4_phase_1 : x phase for odd values of x */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+void isvcd_horz_interpol_chroma_dyadic_2(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf + 1;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y++)
+ {
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_1 = *pi2_tmp++;
+
+ for(i4_x = 0; i4_x < 8; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* x_phase is phase_1 for odd values of x */
+ /* and phase_0 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Rounding to 8-bit values */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+ i4_rslt_2 += 32;
+ i4_rslt_2 >>= 6;
+
+ /* Storing the results */
+ pu1_out[2 * i4_x] = i4_rslt_1;
+ pu1_out[2 * (i4_x + 1)] = i4_rslt_2;
+
+ } /* End of loop over x */
+
+ /* Incrementing the ptrs */
+ pi2_tmp += 1;
+ pu1_out += i4_dst_stride;
+
+ } /* End of loop over y */
+} /* isvcd_horz_interpol_chroma_dyadic_2 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resamp_mb_dyadic */
+/* */
+/* Description : MB level function which performs the intra resampling */
+/* of data of an MB (luma and chroma inclusive) for dyadic */
+/* scaling ratios */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_mb_mode_map : ref layer mb mode map buff desc */
+/* ps_curr_luma : current layer out luma buffer desc */
+/* ps_curr_chroma : current layer out chroma buffer desc */
+/* x,y : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interpolation function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_intra_resamp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ mb_coord_t *ps_mb_coord, void *pv_svc_dec)
+{
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ UWORD8 *pu1_inp_luma, *pu1_inp_chroma;
+ UWORD8 *pu1_out_luma, *pu1_out_chroma;
+ UWORD8 *pu1_out_cb, *pu1_out_cr;
+ UWORD8 *pu1_refarray_luma, *pu1_refarray_cb, *pu1_refarray_cr;
+ WORD16 *pi2_tmp_filt_buf;
+ WORD32 i4_inp_luma_stride, i4_inp_chroma_stride;
+ WORD32 i4_out_luma_stride, i4_out_chroma_stride;
+ UWORD16 u2_mb_x_ref, u2_mb_y_ref;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ /* --------------------------------------------------------------------- */
+ /* Intra resampling ctxt pointers */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+
+ /* --------------------------------------------------------------------- */
+ /* reference and current layer MB coordinates */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_scaled_mb_x, i4_scaled_mb_y;
+ WORD32 i4_top, i4_left;
+ WORD32 ret;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ /* --------------------------------------------------------------------- */
+ /* Pointer derivation */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ /* --------------------------------------------------------------------- */
+ /* MB coordinate derivation */
+ /* --------------------------------------------------------------------- */
+ i4_scaled_mb_x =
+ ps_mb_coord->u2_mb_x - (ps_svc_slice_params->i4_scaled_ref_layer_left_offset >> 4);
+ i4_scaled_mb_y =
+ ps_mb_coord->u2_mb_y - (ps_svc_slice_params->i4_scaled_ref_layer_top_offset >> 4);
+
+ if(i4_scaled_mb_x & 0x1)
+ {
+ i4_left = 1;
+ }
+ else
+ {
+ i4_left = -1;
+ }
+ if(i4_scaled_mb_y & 0x1)
+ {
+ i4_top = 1;
+ }
+ else
+ {
+ i4_top = -1;
+ }
+
+ u2_mb_x_ref = (i4_scaled_mb_x >> 1);
+ u2_mb_y_ref = (i4_scaled_mb_y >> 1);
+
+ /* --------------------------------------------------------------------- */
+ /* Reference Array Consrtuction - luma and chroma */
+ /* --------------------------------------------------------------------- */
+ pu1_inp_luma = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_inp_chroma = (UWORD8 *) ps_ref_chroma->pv_buffer;
+ i4_inp_luma_stride = ps_ref_luma->i4_num_element_stride;
+ i4_inp_chroma_stride = ps_ref_chroma->i4_num_element_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_reflayer_construction_dyadic(
+ pv_intra_samp_ctxt, ps_ref_mb_mode_map, pu1_inp_luma, pu1_inp_chroma, i4_inp_luma_stride,
+ i4_inp_chroma_stride, i4_top, i4_left, u2_mb_x_ref, u2_mb_y_ref);
+
+ if(ret != OK)
+ {
+ return NOT_OK;
+ }
+ /* --------------------------------------------------------------------- */
+ /* LUMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ if(1 == i4_top)
+ {
+ pu1_refarray_luma += (DYADIC_REF_W_Y << 3);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_luma += 8;
+ }
+ pu1_out_luma = (UWORD8 *) ps_curr_luma->pv_buffer;
+ i4_out_luma_stride = ps_curr_luma->i4_num_element_stride;
+ pi2_tmp_filt_buf = (WORD16 *) ps_ctxt->pi4_temp_interpolation_buffer;
+
+ ps_ctxt->pf_interpolate_base_luma_dyadic(pu1_refarray_luma, pi2_tmp_filt_buf, pu1_out_luma,
+ i4_out_luma_stride);
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_out_chroma = (UWORD8 *) ps_curr_chroma->pv_buffer;
+ i4_out_chroma_stride = ps_curr_chroma->i4_num_element_stride;
+
+ /* CB */
+ pu1_out_cb = pu1_out_chroma;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cb += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cb += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_chroma_interpol(pu1_refarray_cb, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_chroma_interpol(pi2_tmp_filt_buf, pu1_out_cb, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+
+ /* CR */
+ pu1_out_cr = pu1_out_chroma + 1;
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cr += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cr += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_chroma_interpol(pu1_refarray_cr, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_chroma_interpol(pi2_tmp_filt_buf, pu1_out_cr, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_intra_base */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* interpolation of a component to find the intra */
+/* resampled value */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* pu1_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_intra_base(void *pv_intra_samp_ctxt, UWORD8 *pu1_out, WORD32 i4_out_stride,
+ WORD32 i4_refarray_wd, WORD32 i4_mb_x, WORD32 i4_mb_y,
+ WORD32 i4_chroma_flag, WORD32 i4_refarray_flag)
+{
+ /* --------------------------------------------------------------------- */
+ /* Index Parameters */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_map_ctxt_t *ps_map_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ WORD32 i4_temp_array_ht;
+ WORD32 *pi4_interp_buff;
+ WORD32 *pi4_interp_buff_temp;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD32 i4_x_min, i4_x_max;
+ ref_min_max_map_t *ps_x_min_max;
+ UWORD8 *pu1_refarray = NULL;
+
+ /* --------------------------------------------------------------------- */
+ /* Extracting pointers from the context */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ if(0 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_buffer;
+ }
+ else if(1 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_cb;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA or CHROMA */
+ /* --------------------------------------------------------------------- */
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &(ps_lyr_ctxt->s_chroma_map_ctxt);
+ else
+ ps_map_ctxt = &(ps_lyr_ctxt->s_luma_map_ctxt);
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+ i4_frm_mb_y = i4_mb_y * i4_mb_ht;
+ i4_frm_mb_x = i4_mb_x * i4_mb_wd;
+
+ /* get the min and max positions */
+ i4_x_min = ps_x_min_max[i4_mb_x].i2_min_pos;
+ i4_x_max = ps_x_min_max[i4_mb_x].i2_max_pos;
+
+ /* --------------------------------------------------------------------- */
+ /* Projected frame level pointers */
+ /* --------------------------------------------------------------------- */
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointers and Dimenstion of the temporary buffer */
+ /* --------------------------------------------------------------------- */
+ i4_temp_array_ht = i4_mb_ht;
+ pi4_interp_buff = ps_ctxt->pi4_temp_interpolation_buffer;
+ pi4_interp_buff_temp = pi4_interp_buff;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation in vertical direction */
+ /* --------------------------------------------------------------------- */
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ for(i4_x = (i4_x_min - 1); i4_x <= (i4_x_max + 2); i4_x++)
+ {
+ UWORD8 *pu1_refarray_temp;
+ WORD32 i4_y_ref;
+ WORD32 i4_y_phase;
+ /* ------------------------------------------------------------ */
+ /* Finding the offset */
+ /* ------------------------------------------------------------ */
+ i4_y_ref = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos;
+ i4_y_phase = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ pu1_refarray_temp = pu1_refarray + i4_x + (i4_y_ref * i4_refarray_wd);
+
+ /* ------------------------------------------------------------ */
+ /* Check for Luma/Chroma Processing */
+ /* ------------------------------------------------------------ */
+ if(0 == i4_chroma_flag)
+ {
+ *(pi4_interp_buff + i4_x) =
+ (g_ai1_interp_filter_luma[i4_y_phase]) *
+ (*(pu1_refarray_temp - i4_refarray_wd)) +
+
+ (g_ai1_interp_filter_luma[16 + i4_y_phase]) * (*(pu1_refarray_temp)) +
+
+ (g_ai1_interp_filter_luma[32 + i4_y_phase]) *
+ (*(pu1_refarray_temp + i4_refarray_wd)) +
+
+ (g_ai1_interp_filter_luma[48 + i4_y_phase]) *
+ (*(pu1_refarray_temp + (2 * i4_refarray_wd)));
+ }
+ else
+ {
+ *(pi4_interp_buff + i4_x) =
+ (g_au1_interp_filter_chroma[i4_y_phase]) * (*(pu1_refarray_temp)) +
+
+ (g_au1_interp_filter_chroma[16 + i4_y_phase]) *
+ (*(pu1_refarray_temp + i4_refarray_wd));
+ }
+
+ } /* end of loop over array width */
+ pi4_interp_buff = pi4_interp_buff + i4_refarray_wd;
+ } /* end of loop over temp array height*/
+
+ pi4_interp_buff = pi4_interp_buff_temp;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation in horizontal direction */
+ /* --------------------------------------------------------------------- */
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_x_phase;
+ /* ------------------------------------------------------------- */
+ /* Finding the offset */
+ /* ------------------------------------------------------------- */
+ i4_x_ref = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ i4_x_phase = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ pi4_interp_buff_temp = pi4_interp_buff + i4_x_ref;
+
+ /* ------------------------------------------------------------- */
+ /* Check for Luma/Chroma Processing */
+ /* ------------------------------------------------------------- */
+ if(0 == i4_chroma_flag)
+ {
+ *(pu1_out + i4_x + (i4_y * i4_out_stride)) =
+
+ CLIPUCHAR(
+ ((g_ai1_interp_filter_luma[i4_x_phase]) * (*(pi4_interp_buff_temp - 1)) +
+ (g_ai1_interp_filter_luma[16 + i4_x_phase]) * (*(pi4_interp_buff_temp)) +
+ (g_ai1_interp_filter_luma[32 + i4_x_phase]) *
+ (*(pi4_interp_buff_temp + 1)) +
+ (g_ai1_interp_filter_luma[48 + i4_x_phase]) *
+ (*(pi4_interp_buff_temp + 2)) +
+ 512) >>
+ 10);
+ }
+ else
+ {
+ *(pu1_out + (2 * i4_x) + (i4_y * i4_out_stride)) = CLIPUCHAR(
+ ((g_au1_interp_filter_chroma[i4_x_phase]) * (*(pi4_interp_buff_temp)) +
+ (g_au1_interp_filter_chroma[16 + i4_x_phase]) * (*(pi4_interp_buff_temp + 1)) +
+ 512) >>
+ 10);
+ }
+
+ } /* end of loop over array width */
+ pi4_interp_buff = pi4_interp_buff + i4_refarray_wd;
+ } /* end of loop over MB height */
+
+ return;
+} /* End of Interpolation Function */
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resamp_mb */
+/* */
+/* Description : MB level function whcih perform the intra resampling */
+/* of data of an MB (luma and chroma insclusive) */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_mb_mode_map : ref layer mb mode map buff desc */
+/* ps_curr_luma : current layer out luma buffer desc */
+/* ps_curr_chroma : current layer out chroma buffer desc */
+/* ps_mb_coord : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interpolation function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_intra_resamp_mb(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ mb_coord_t *ps_mb_coord)
+{
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ UWORD8 *pu1_inp_luma, *pu1_inp_cb, *pu1_inp_cr;
+ UWORD8 *pu1_out_luma, *pu1_out_cb, *pu1_out_cr;
+ WORD32 i4_inp_stride;
+ WORD32 i4_out_stride;
+ WORD32 i4_refarray_stride;
+
+ /* --------------------------------------------------------------------- */
+ /* ref sample array and corresponding parametrs */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_chroma_flag, ret;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ /* needs to be populated at proper place */
+ i4_refarray_stride = ps_ctxt->i4_refarray_stride;
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ pu1_inp_luma = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_out_luma = (UWORD8 *) ps_curr_luma->pv_buffer;
+ i4_inp_stride = ps_ref_luma->i4_num_element_stride;
+ i4_out_stride = ps_curr_luma->i4_num_element_stride;
+ i4_chroma_flag = 0;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_reflayer_construction(pv_intra_samp_ctxt, pu1_inp_luma, NULL, i4_inp_stride,
+ i4_refarray_stride, ps_ref_mb_mode_map, ps_mb_coord,
+ i4_chroma_flag);
+
+ if(ret != OK)
+ {
+ return NOT_OK;
+ }
+ /* ---- Interpolation process for Intra_Base prediction ------ */
+ ps_ctxt->pf_interpolate_intra_base(pv_intra_samp_ctxt, pu1_out_luma, i4_out_stride,
+ i4_refarray_stride, ps_mb_coord->u2_mb_x,
+ ps_mb_coord->u2_mb_y, i4_chroma_flag, 0);
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ /* CB */
+ i4_inp_stride = ps_ref_chroma->i4_num_element_stride;
+ pu1_inp_cb = (UWORD8 *) ps_ref_chroma->pv_buffer;
+ pu1_inp_cr = pu1_inp_cb + 1;
+ i4_chroma_flag = 1;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_reflayer_construction(pv_intra_samp_ctxt, pu1_inp_cb, pu1_inp_cr, i4_inp_stride,
+ i4_refarray_stride, ps_ref_mb_mode_map, ps_mb_coord,
+ i4_chroma_flag);
+
+ if(ret != OK)
+ {
+ return NOT_OK;
+ }
+ i4_out_stride = ps_curr_chroma->i4_num_element_stride;
+ pu1_out_cb = (UWORD8 *) ps_curr_chroma->pv_buffer;
+ pu1_out_cr = pu1_out_cb + 1;
+
+ /* ---- Cb Interpolation process for Intra_Base prediction ------ */
+ ps_ctxt->pf_interpolate_intra_base(pv_intra_samp_ctxt, pu1_out_cb, i4_out_stride,
+ i4_refarray_stride, ps_mb_coord->u2_mb_x,
+ ps_mb_coord->u2_mb_y, i4_chroma_flag, 0);
+
+ /* ---- Cr Interpolation process for Intra_Base prediction ------ */
+ ps_ctxt->pf_interpolate_intra_base(pv_intra_samp_ctxt, pu1_out_cr, i4_out_stride,
+ i4_refarray_stride, ps_mb_coord->u2_mb_x,
+ ps_mb_coord->u2_mb_y, i4_chroma_flag, 1);
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resamp_generate_segment_lookup */
+/* */
+/* Description : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* */
+/* Inputs : pv_lookup_table : look up table */
+/* i4_dimension : dimension of the block which is used in*/
+/* resampling process. */
+/* i4_mb_size : size of the mb */
+/* Globals : None */
+/* Processing : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Creation */
+/* */
+/*****************************************************************************/
+void isvcd_intra_resamp_generate_segment_lookup(seg_lookup_desc_t *ps_seg_lookup_table,
+ WORD32 i4_dimension, WORD32 i4_mb_size,
+ WORD32 i4_shift_val)
+{
+ WORD32 i4_x;
+ WORD32 i4_position, i4_dist_prev_mb, i4_dist_next_mb;
+ UWORD8 u1_seg_dim;
+ UWORD8 u1_num_sgmts;
+ WORD32 i4_block_size = i4_mb_size >> 1;
+ UWORD8 u1_offset = 0;
+ seg_lookup_desc_t *ps_segments;
+ seg_description_t *ps_seg_desc;
+
+ memset(ps_seg_lookup_table, 0, i4_mb_size * sizeof(seg_lookup_desc_t));
+
+ for(i4_x = 0; i4_x < i4_mb_size; i4_x++)
+ {
+ ps_segments = &ps_seg_lookup_table[i4_x];
+ ps_seg_desc = ps_segments->s_segments;
+ i4_position = i4_x;
+
+ if(i4_x >= i4_block_size)
+ {
+ /* set the fourth bit so that later it can be directly OR ed */
+ ps_segments->u4_start_pos = 8;
+ }
+ else
+ {
+ ps_segments->u4_start_pos = 0;
+ }
+
+ u1_num_sgmts = 0;
+ u1_offset = 0;
+
+ while(i4_position < (i4_x + i4_dimension))
+ {
+ /* check and fill the nearest mb boundry flag */
+ if((i4_position & (i4_mb_size - 1)) < i4_block_size)
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = -1;
+ }
+ else
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = 1;
+ }
+
+ /* find the distance from the previous MB for start of segment*/
+ i4_dist_prev_mb = (i4_position & (i4_mb_size - 1));
+
+ ps_seg_desc->i1_dist_idx =
+ ((i4_dist_prev_mb >= i4_mb_size >> 1) ? (i4_mb_size - i4_dist_prev_mb)
+ : -(i4_dist_prev_mb + 1));
+
+ /* find the size of the segment */
+ u1_seg_dim = (i4_block_size - (i4_position & (i4_block_size - 1)));
+ i4_position += u1_seg_dim;
+ if(i4_position > (i4_x + i4_dimension))
+ {
+ i4_position = (i4_x + i4_dimension);
+ u1_seg_dim = (i4_position & (i4_block_size - 1));
+ }
+
+ /* find the distance from the next MB for end of segment */
+ i4_dist_next_mb = (i4_position & (i4_mb_size - 1));
+ ps_seg_desc->u1_seg_dim = u1_seg_dim;
+ ps_seg_desc->u1_seg_off = u1_offset;
+
+ /* check if the segment has a adjoining MB edge */
+ if(i4_dist_prev_mb == 0)
+ {
+ if(0 == u1_num_sgmts)
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else if(i4_dist_next_mb == 0)
+ {
+ if(i4_position == (i4_x + i4_dimension))
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+
+ /* Updations */
+ u1_offset += u1_seg_dim;
+ u1_num_sgmts++;
+ ps_seg_desc++;
+ }
+
+ /* fill the number of segments for this position */
+ ps_segments->u1_num_segments = u1_num_sgmts;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resamp_populate_list */
+/* */
+/* Description : This is a seq or frame level init function which fills */
+/* all offsets, projected locations arrays based on */
+/* the two resolutions and cropping parameters */
+/* Inputs : refer ot doxygen comments below */
+/* Globals : none */
+/* Processing : it projects the locations and computes the values */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_intra_resamp_populate_list(intra_samp_map_ctxt_t *ps_map_ctxt,
+ res_prms_t *ps_curr_res_prms, res_prms_t *ps_ref_res_prms,
+ WORD32 i4_chroma_flag, svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ /* --------------------------------------------------------------------- */
+ /* Local variables required for finding the mapping between the layers */
+ /* --------------------------------------------------------------------- */
+ UWORD32 i4_shift_x, i4_shift_y, i4_scale_x, i4_scale_y;
+ WORD32 i4_offset_x, i4_offset_y;
+ WORD32 i4_add_x, i4_add_y, i4_delta_x, i4_delta_y, i4_refphase_x, i4_refphase_y;
+ WORD32 i4_phase_x, i4_phase_y, i4_sub_wd, i4_sub_ht, i4_mb_wd, i4_mb_ht;
+ WORD32 i4_horz_dim, i4_vert_dim, i4_tmp;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+ ref_mb_map_t *ps_x_off_len, *ps_y_off_len;
+ UWORD32 i4_ref_wd, i4_ref_ht, i4_scaled_wd, i4_scaled_ht, i4_curr_lyr_width, i4_curr_lyr_height;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Flag Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_ref_layer_field_pic_flag, i4_field_pic_flag, i4_frame_mbs_only_flag;
+ WORD32 i4_ref_layer_frame_Mbs_only_flag, i4_field_Mb_flag, i4_bot_field_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Cropping Parameters Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_scaled_ref_layer_left_offset, i4_scaled_ref_layer_top_offset;
+ WORD32 i4_scaled_ref_layer_right_offset, i4_scaled_ref_layer_bottom_offset;
+ dec_seq_params_t *ps_sps;
+ dec_svc_seq_params_t *ps_subset_sps;
+ ps_sps = ps_dec->ps_cur_sps;
+ ps_subset_sps = ps_svc_lyr_dec->ps_cur_subset_sps;
+
+ /* --------------------------------------------------------------------- */
+ /* Hardcoding flag information (assuming no field support) */
+ /* --------------------------------------------------------------------- */
+ i4_ref_layer_field_pic_flag = SVCD_FALSE;
+ i4_field_pic_flag = SVCD_FALSE;
+ i4_frame_mbs_only_flag = SVCD_TRUE;
+ i4_field_Mb_flag = SVCD_FALSE;
+ i4_bot_field_flag = SVCD_FALSE;
+ i4_ref_layer_frame_Mbs_only_flag = SVCD_TRUE;
+ i4_horz_dim = 0;
+ i4_vert_dim = 0;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointer and Paramater are intialized - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_base_width;
+ WORD32 i4_base_height;
+ WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
+ WORD32 i4_ref_layer_chroma_phase_y_plus1;
+ WORD32 i4_chroma_phase_x_plus1_flag;
+ WORD32 i4_chroma_phase_y_plus1;
+
+ /* ------------------------------------------------------------- */
+ /* HARD CODED FOR 420 */
+ /* ------------------------------------------------------------- */
+ WORD32 i4_sub_wd_chroma = 2;
+ WORD32 i4_sub_ht_chroma = 2;
+
+ i4_base_width = ps_ref_res_prms->i4_res_width;
+ i4_base_height = ps_ref_res_prms->i4_res_height;
+
+ i4_ref_layer_chroma_phase_x_plus1_flag =
+ ps_curr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+
+ i4_ref_layer_chroma_phase_y_plus1 = ps_curr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_phase_x_plus1_flag = ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag;
+ i4_chroma_phase_y_plus1 = ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1;
+ i4_scaled_ref_layer_bottom_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_bot;
+ i4_scaled_ref_layer_left_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
+ i4_scaled_ref_layer_top_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
+ i4_scaled_ref_layer_right_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_rt;
+
+ /* ----------------------------------------------------------------- */
+ /* Computing Effective Frame Dimensions */
+ /* ------------------------------------------------------------------*/
+ i4_ref_wd = (i4_base_width >> i4_chroma_flag);
+ i4_ref_ht = (i4_base_height >> i4_chroma_flag) * (1 + i4_ref_layer_field_pic_flag);
+
+ i4_scaled_wd = ps_curr_res_prms->u2_scaled_ref_width;
+ i4_scaled_ht = ps_curr_res_prms->u2_scaled_ref_height;
+ i4_scaled_wd = (i4_scaled_wd >> i4_chroma_flag);
+ i4_scaled_ht = (i4_scaled_ht >> i4_chroma_flag) * (1 + i4_field_pic_flag);
+
+ if(1 == i4_chroma_flag)
+ {
+ i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1_flag - 1;
+ i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
+ i4_phase_x = i4_chroma_phase_x_plus1_flag - 1;
+ i4_phase_y = i4_chroma_phase_y_plus1 - 1;
+ i4_sub_wd = i4_sub_wd_chroma;
+ i4_sub_ht = i4_sub_ht_chroma;
+ i4_mb_wd = MB_WIDTH >> 1;
+ i4_mb_ht = MB_HEIGHT >> 1;
+ }
+ else
+ {
+ i4_refphase_x = 0;
+ i4_refphase_y = 0;
+ i4_phase_x = 0;
+ i4_phase_y = 0;
+ i4_sub_wd = 1;
+ i4_sub_ht = 1;
+ i4_mb_wd = MB_WIDTH;
+ i4_mb_ht = MB_HEIGHT;
+ }
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Derive shift x and y based on level idd */
+ /* --------------------------------------------------------------------- */
+ if(ps_sps->u1_level_idc <= 30)
+ {
+ i4_shift_x = 16;
+ i4_shift_y = 16;
+ }
+ else
+ {
+ i4_shift_x = 31 - isvcd_get_ceil_log2(i4_ref_wd);
+ i4_shift_y = 31 - isvcd_get_ceil_log2(i4_ref_ht);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* The following condition is not true in our case for time being */
+ /* --------------------------------------------------------------------- */
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) || (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_phase_y = i4_phase_y + 4 * i4_bot_field_flag;
+
+ if(1 == i4_ref_layer_frame_Mbs_only_flag)
+ i4_refphase_y = (2 * i4_refphase_y) + 2;
+ else
+ i4_refphase_y = i4_refphase_y + (4 * i4_bot_field_flag);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Dx and Dy Computation - Ratio of the base and enhance layer width */
+ /* --------------------------------------------------------------------- */
+ i4_scale_x = ((i4_ref_wd << i4_shift_x) + (i4_scaled_wd >> 1)) / (i4_scaled_wd);
+ i4_scale_y = ((i4_ref_ht << i4_shift_y) + (i4_scaled_ht >> 1)) / (i4_scaled_ht);
+
+ i4_offset_x = i4_scaled_ref_layer_left_offset / i4_sub_wd;
+ i4_add_x = (((i4_ref_wd * (2 + i4_phase_x)) << (i4_shift_x - 2)) + (i4_scaled_wd >> 1)) /
+ i4_scaled_wd +
+ (1 << (i4_shift_x - 5));
+ i4_delta_x = 4 * (2 + i4_refphase_x);
+
+ if((SVCD_TRUE == i4_frame_mbs_only_flag) && (SVCD_TRUE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / i4_sub_ht;
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (i4_shift_y - 2)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (i4_shift_y - 5));
+ i4_delta_y = 4 * (2 + i4_refphase_y);
+ }
+ else
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / (2 * i4_sub_ht);
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (i4_shift_y - 3)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (i4_shift_y - 5));
+ i4_delta_y = 2 * (2 + i4_refphase_y);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Intializing Local Pointers - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+ i4_curr_lyr_width = ps_curr_res_prms->i4_res_width >> i4_chroma_flag;
+ i4_curr_lyr_height = ps_curr_res_prms->i4_res_height >> i4_chroma_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Dyadic Scaling Ratios Handling */
+ /* --------------------------------------------------------------------- */
+ if(1 == ps_curr_res_prms->u1_dyadic_flag)
+ {
+ WORD32 i4_refarray_wd, i4_x_offset;
+ WORD32 i4_refarray_ht, i4_y_offset;
+ WORD32 i4_crp_wd_lt, i4_crp_ht_top;
+ WORD32 i4_crp_wd_rt, i4_crp_ht_bot;
+ WORD32 i4_ref_lyr_wd, i4_ref_lyr_ht;
+ WORD32 i4_ref_x, i4_ref_y;
+ WORD32 i4_ofst;
+ WORD32 i4_i, i4_j;
+
+ /* Hard coded for dyadic case */
+ i4_refarray_wd = 20 >> i4_chroma_flag;
+ i4_ofst = -2 >> i4_chroma_flag;
+ i4_crp_wd_lt = i4_scaled_ref_layer_left_offset >> i4_chroma_flag;
+ i4_crp_wd_rt = i4_scaled_ref_layer_right_offset >> i4_chroma_flag;
+ i4_ref_lyr_wd = (i4_curr_lyr_width >> 1);
+
+ i4_ref_x = 0;
+ for(i4_i = 0; i4_i < (WORD32) i4_curr_lyr_width; i4_i += (i4_mb_wd << 1))
+ {
+ i4_x_offset = MAX(i4_ofst, (i4_ref_x + i4_ofst));
+ i4_x_offset = MIN(i4_x_offset, (i4_ref_lyr_wd - i4_ofst));
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+ ps_x_off_len++;
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+ ps_x_off_len++;
+ if(i4_i >= i4_crp_wd_lt)
+ {
+ if(i4_i <= (WORD32) (i4_curr_lyr_width - i4_crp_wd_rt))
+ {
+ i4_ref_x += i4_mb_wd;
+ }
+ }
+ }
+
+ i4_refarray_ht = 20 >> i4_chroma_flag;
+ i4_crp_ht_top = i4_scaled_ref_layer_top_offset >> i4_chroma_flag;
+ i4_crp_ht_bot = i4_scaled_ref_layer_bottom_offset >> i4_chroma_flag;
+ i4_ref_lyr_ht = (i4_curr_lyr_height >> 1);
+
+ i4_ref_y = 0;
+ for(i4_j = 0; i4_j < (WORD32) i4_curr_lyr_height; i4_j += (i4_mb_ht << 1))
+ {
+ i4_y_offset = MAX(i4_ofst, (i4_ref_y + i4_ofst));
+ i4_y_offset = MIN(i4_y_offset, (i4_ref_lyr_ht - i4_ofst));
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+ ps_y_off_len++;
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+ ps_y_off_len++;
+ if(i4_j >= i4_crp_ht_top)
+ {
+ if(i4_j <= (WORD32) (i4_curr_lyr_height - i4_crp_ht_bot))
+ {
+ i4_ref_y += i4_mb_ht;
+ }
+ }
+ }
+ /* No need to process further, return */
+ return;
+ } /* If dyadic path */
+
+ /* Proposed Algo for Optimization */
+ {
+ WORD32 i4_max, i4_min;
+ ref_min_max_map_t *ps_x_min_max;
+ ref_min_max_map_t *ps_y_min_max;
+ WORD32 i4_i, i4_j;
+
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+ ps_y_min_max = ps_map_ctxt->ps_y_min_max;
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetX refArrayW Xmin and Xmax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_i = 0; i4_i < (WORD32) i4_curr_lyr_width; i4_i = i4_i + i4_mb_wd)
+ {
+ WORD32 i4_refarray_wd, i4_xr_index;
+ WORD32 i4_x_refmin16;
+ WORD32 i4_x_refmax16;
+ WORD32 i4_x_offset;
+
+ i4_x_refmin16 = (WORD64) (((WORD64) (i4_i - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ ((WORD32) (i4_shift_x - 4))) -
+ i4_delta_x;
+
+ i4_x_refmax16 =
+ (WORD64) (((WORD64) (i4_i + i4_mb_wd - 1 - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ ((WORD32) (i4_shift_x - 4))) -
+ i4_delta_x;
+
+ /* ------------------------------------------------------------- */
+ /* Modified AC205 */
+ /* Minimum width required - So adding 2 pixels on each side */
+ /* ------------------------------------------------------------- */
+ i4_refarray_wd = ((i4_x_refmax16 + 15) >> 4) - (i4_x_refmin16 >> 4) + 1 + 4;
+
+ /* ------------------------------------------------------------- */
+ /* Setting the offset 2 pixels before */
+ /* ------------------------------------------------------------- */
+ i4_x_offset = (i4_x_refmin16 >> 4) - 2;
+
+ /* ------------------------------------------------------------- */
+ /* Modifying the values based on the location */
+ /* ------------------------------------------------------------- */
+ i4_min = i4_x_offset;
+ i4_xr_index = i4_min - ((i4_min / i4_mb_wd) * i4_mb_wd);
+
+ if(i4_xr_index < (i4_mb_wd >> 1))
+ {
+ i4_refarray_wd = i4_refarray_wd + (i4_mb_wd >> 1);
+ i4_x_offset = i4_x_offset - (i4_mb_wd >> 1);
+ }
+
+ i4_max = ((i4_x_refmax16 + 15) >> 4) + 2;
+ i4_xr_index = i4_max - ((i4_max / i4_mb_wd) * i4_mb_wd);
+
+ if(i4_xr_index >= (i4_mb_wd >> 1)) i4_refarray_wd = i4_refarray_wd + (i4_mb_wd >> 1);
+
+ /* ------------------------------------------------------------- */
+ /* Filling the arrays with offset, min, max and refArray dim */
+ /* ------------------------------------------------------------- */
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+
+ ps_x_min_max->i2_min_pos = (i4_x_refmin16 >> 4) - i4_x_offset;
+ ps_x_min_max->i2_max_pos = ((i4_x_refmax16 + 15) >> 4) - i4_x_offset;
+
+ i4_tmp = (WORD32) (ps_x_min_max->i2_max_pos - ps_x_min_max->i2_min_pos) +
+ (4 >> i4_chroma_flag);
+ if(i4_tmp > i4_horz_dim)
+ {
+ i4_horz_dim = i4_tmp;
+ }
+
+ /* increment the pointer */
+ ps_x_off_len++;
+ ps_x_min_max++;
+ } /* end of loop over scaled width */
+
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetY refArrayH Ymin and Ymax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_j = 0; i4_j < (WORD32) i4_curr_lyr_height; i4_j = i4_j + i4_mb_ht)
+ {
+ WORD32 i4_refarray_ht, i4_yr_index;
+ WORD32 i4_y_refmin16;
+ WORD32 i4_y_refmax16;
+ WORD32 i4_y_offset;
+
+ i4_y_refmin16 = (WORD64) (((WORD64) (i4_j - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ ((WORD32) (i4_shift_y - 4))) -
+ i4_delta_y;
+
+ i4_y_refmax16 =
+ (WORD64) (((WORD64) (i4_j + i4_mb_ht - 1 - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ ((WORD32) (i4_shift_y - 4))) -
+ i4_delta_y;
+
+ /* ------------------------------------------------------------- */
+ /* Modified AC205 */
+ /* Minimum width required - So adding 2 pixels on each side */
+ /* ------------------------------------------------------------- */
+ i4_refarray_ht = ((i4_y_refmax16 + 15) >> 4) - (i4_y_refmin16 >> 4) + 1 + 4;
+
+ /* ------------------------------------------------------------- */
+ /* Setting the offset 2 pixels before */
+ /* ------------------------------------------------------------- */
+ i4_y_offset = (i4_y_refmin16 >> 4) - 2;
+
+ /* ------------------------------------------------------------- */
+ /* Modifying the values based on the location */
+ /* ------------------------------------------------------------- */
+ i4_min = i4_y_offset;
+ i4_yr_index = i4_min - ((i4_min / i4_mb_ht) * i4_mb_ht);
+ if(i4_yr_index < (i4_mb_ht >> 1))
+ {
+ i4_refarray_ht = i4_refarray_ht + (i4_mb_ht >> 1);
+ i4_y_offset = i4_y_offset - (i4_mb_ht >> 1);
+ }
+
+ i4_max = ((i4_y_refmax16 + 15) >> 4) + 2;
+ i4_yr_index = i4_max - ((i4_max / i4_mb_ht) * i4_mb_ht);
+ if(i4_yr_index >= (i4_mb_ht >> 1)) i4_refarray_ht = i4_refarray_ht + (i4_mb_ht >> 1);
+
+ /* ------------------------------------------------------------- */
+ /* Filling the arrays with offset, min, max and refArray dim */
+ /* ------------------------------------------------------------- */
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+ ps_y_min_max->i2_min_pos = (i4_y_refmin16 >> 4) - i4_y_offset;
+ ps_y_min_max->i2_max_pos = ((i4_y_refmax16 + 15) >> 4) - i4_y_offset;
+
+ i4_tmp = (WORD32) (ps_y_min_max->i2_max_pos - ps_y_min_max->i2_min_pos) +
+ (4 >> i4_chroma_flag);
+ if(i4_tmp > i4_vert_dim)
+ {
+ i4_vert_dim = i4_tmp;
+ }
+
+ /* increment the pointer */
+ ps_y_off_len++;
+ ps_y_min_max++;
+ } /* end of loop over scaled height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Xref and Xphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+
+ {
+ ref_pixel_map_t *ps_x_pos_phase;
+ WORD32 i4_xc;
+ WORD32 i4_offset_x_index;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+
+ for(i4_xc = 0; i4_xc < (WORD32) i4_curr_lyr_width; i4_xc++)
+ {
+ WORD32 i4_x_offset;
+ WORD32 i4_x_ref16;
+
+ i4_offset_x_index = i4_xc / i4_mb_wd;
+
+ i4_x_offset = ps_x_off_len[i4_offset_x_index].i2_offset;
+
+ i4_x_ref16 = (WORD64) (((WORD64) (i4_xc - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ ((WORD32) (i4_shift_x - 4))) -
+ i4_delta_x;
+
+ /* store the values */
+ ps_x_pos_phase->i2_ref_pos = (i4_x_ref16 >> 4) - i4_x_offset;
+ ps_x_pos_phase->i2_phase = i4_x_ref16 & 15;
+
+ /* increment the pointer */
+ ps_x_pos_phase++;
+
+ } /* end of loop over scaled width */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Yref and Yphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_yc;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ for(i4_yc = 0; i4_yc < (WORD32) i4_curr_lyr_height; i4_yc++)
+ {
+ WORD32 i4_y_offset;
+ WORD32 i4_y_ref16;
+ WORD32 i4_offset_y_index;
+
+ i4_offset_y_index = i4_yc / i4_mb_ht;
+
+ i4_y_offset = ps_y_off_len[i4_offset_y_index].i2_offset;
+
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) ||
+ (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - i4_field_Mb_flag);
+ }
+
+ i4_y_ref16 = (WORD64) (((WORD64) (i4_yc - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ ((WORD32) (i4_shift_y - 4))) -
+ i4_delta_y;
+ ps_y_pos_phase->i2_ref_pos = (i4_y_ref16 >> 4) - i4_y_offset;
+ ps_y_pos_phase->i2_phase = i4_y_ref16 & 15;
+
+ /* increment the pointer */
+ ps_y_pos_phase++;
+
+ } /* end of loop over scaled height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Corresponding Diagonal Location */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD16 *pi2_xd_index;
+ WORD16 *pi2_yd_index;
+ WORD16 *pi2_ya_index;
+ WORD32 i4_i, i4_j;
+
+ pi2_xd_index = ps_map_ctxt->pi2_xd_index;
+ pi2_yd_index = ps_map_ctxt->pi2_yd_index;
+ pi2_ya_index = ps_map_ctxt->pi2_ya_index;
+
+ for(i4_i = 0; i4_i < i4_mb_wd; i4_i++)
+ {
+ *(pi2_xd_index + i4_i) = ((i4_i >= i4_mb_wd >> 1) ? (i4_i - i4_mb_wd) : (i4_i + 1));
+
+ } /* end of loop over MB width */
+
+ for(i4_j = 0; i4_j < i4_mb_ht; i4_j++)
+ {
+ *(pi2_yd_index + i4_j) = ((i4_j >= i4_mb_ht >> 1) ? (i4_j - i4_mb_ht) : (i4_j + 1));
+
+ *(pi2_ya_index + i4_j) =
+ *(pi2_yd_index + i4_j) - (((i4_mb_ht >> 1) + 1) * (SIGN(*(pi2_yd_index + i4_j))));
+
+ } /* end of loop over MB height */
+ }
+
+ /* generate the lookup to generate horizontal segments */
+ isvcd_intra_resamp_generate_segment_lookup(ps_map_ctxt->ps_seg_lookup_horz, i4_horz_dim,
+ i4_mb_wd, 3);
+
+ /* generate the lookup to generate vertical segments */
+ isvcd_intra_resamp_generate_segment_lookup(ps_map_ctxt->ps_seg_lookup_vert, i4_vert_dim,
+ i4_mb_ht, 4);
+
+ return;
+} /* end of function "isvcd_intra_resamp_populate_list"*/
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_populate_res_prms */
+/* */
+/* Description :this function populates the current layer params */
+/* from the base layer and decoder context */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_populate_res_prms(void *pv_svc_dec)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ res_prms_t *ps_curr_lyr_res_prms;
+ svc_dec_lyr_struct_t *ps_svc_ref_lyr_dec;
+ ps_svc_ref_lyr_dec = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
+ ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
+
+ ps_curr_lyr_res_prms->i4_res_width = ps_dec->u2_pic_wd;
+ ps_curr_lyr_res_prms->i4_res_height = ps_dec->u2_pic_ht;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset << 1;
+ ps_curr_lyr_res_prms->u2_scaled_ref_width =
+ (ps_dec->u2_frm_wd_in_mbs << 4) - (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt);
+
+ ps_curr_lyr_res_prms->u2_scaled_ref_height =
+ (ps_dec->u2_frm_ht_in_mbs << 4) - (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot);
+
+ ps_curr_lyr_res_prms->u1_cropping_change_flag = 0;
+ if(2 == ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc)
+ {
+ ps_curr_lyr_res_prms->u1_cropping_change_flag = 1;
+
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_scaled_ref_layer_left_offset << 1;
+
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_scaled_ref_layer_top_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_scaled_ref_layer_right_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_scaled_ref_layer_bottom_offset << 1;
+ ps_curr_lyr_res_prms->u2_scaled_ref_width =
+ (ps_dec->u2_frm_wd_in_mbs << 4) -
+ (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt);
+
+ ps_curr_lyr_res_prms->u2_scaled_ref_height =
+ (ps_dec->u2_frm_ht_in_mbs << 4) -
+ (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot);
+
+ return NOT_OK;
+ }
+
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_TRUE;
+
+ ps_curr_lyr_res_prms->u1_disable_inter_lyr_dblk_filter_idc =
+ ps_svc_lyr_dec->s_svc_slice_params.u4_disable_inter_layer_deblk_filter_idc;
+ ps_curr_lyr_res_prms->i1_inter_lyr_alpha_c0_offset =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_inter_layer_slice_alpha_c0_offset_div2;
+ ps_curr_lyr_res_prms->i1_inter_lyr_beta_offset =
+ ps_svc_lyr_dec->s_svc_slice_params.i4_inter_layer_slice_beta_offset_div2;
+ ps_curr_lyr_res_prms->i1_constrained_intra_rsmpl_flag =
+ ps_svc_lyr_dec->s_svc_slice_params.u1_constrained_intra_resampling_flag;
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1 =
+ ps_svc_lyr_dec->ps_cur_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
+ ps_curr_lyr_res_prms->u1_direct_8x8_inference_flag =
+ ps_dec->ps_cur_sps->u1_direct_8x8_inference_flag;
+
+ ps_curr_lyr_res_prms->u1_remap_req_flag = 1;
+ ps_curr_lyr_res_prms->u1_dyadic_flag = ps_svc_lyr_dec->u1_dyadic_flag;
+
+ /* Derive the reference layer width and height */
+
+ if(SVCD_TRUE != ps_svc_lyr_dec->u1_base_res_flag)
+ {
+ WORD32 i4_ref_lyr_width;
+ WORD32 i4_ref_lyr_ht;
+ WORD32 i4_dyadic_flag = SVCD_FALSE;
+ i4_ref_lyr_width = ps_svc_ref_lyr_dec->s_res_prms.i4_res_width;
+ i4_ref_lyr_ht = ps_svc_ref_lyr_dec->s_res_prms.i4_res_height;
+
+ /* set the Restricted Spatial Resolution change flag */
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_TRUE;
+
+ if(0 == ((ps_curr_lyr_res_prms->u2_scaled_ref_width == i4_ref_lyr_width) ||
+ (ps_curr_lyr_res_prms->u2_scaled_ref_width == (i4_ref_lyr_width << 1))))
+ {
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_FALSE;
+ }
+
+ if(0 == ((ps_curr_lyr_res_prms->u2_scaled_ref_height == i4_ref_lyr_ht) ||
+ (ps_curr_lyr_res_prms->u2_scaled_ref_height == (i4_ref_lyr_ht << 1))))
+ {
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_FALSE;
+ }
+
+ if(0 != (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left & 15))
+ {
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_FALSE;
+ }
+
+ if(0 != (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top & 15))
+ {
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_FALSE;
+ }
+
+ /* populate the dyadic status */
+
+ if((ps_curr_lyr_res_prms->u2_scaled_ref_width == (i4_ref_lyr_width << 1)) &&
+ (ps_curr_lyr_res_prms->u2_scaled_ref_height == (i4_ref_lyr_ht << 1)))
+ {
+ i4_dyadic_flag = SVCD_TRUE;
+ }
+ else if((ps_curr_lyr_res_prms->u2_scaled_ref_width != ((i4_ref_lyr_width * 3) >> 1)) ||
+ (ps_curr_lyr_res_prms->u2_scaled_ref_height != ((i4_ref_lyr_ht * 3) >> 1)))
+ {
+ ps_curr_lyr_res_prms->u1_dyadic_flag = i4_dyadic_flag;
+ ps_svc_lyr_dec->u1_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
+ return NOT_OK;
+ }
+
+ /* check if cropping is MB aligned */
+ if(SVCD_TRUE == i4_dyadic_flag)
+ {
+ if((0 != (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left & 15)) ||
+ (0 != (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top & 15)))
+ {
+ i4_dyadic_flag = SVCD_FALSE;
+ }
+ }
+
+ ps_curr_lyr_res_prms->u1_dyadic_flag = i4_dyadic_flag;
+ ps_svc_lyr_dec->u1_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
+ }
+
+ {
+ inter_lyr_mb_prms_t *ps_tmp_prms, *ps_tmp_prms_2;
+ inter_lyr_mb_prms_t *ps_ref_mb_prms;
+ WORD32 i4_stride;
+ WORD32 i4_ht_in_mbs, i4_wd_in_mbs;
+ WORD32 i4_i;
+
+ /* Derive the reference mb mode map */
+
+ ps_ref_mb_prms = ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start;
+ i4_stride = ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride;
+
+ i4_ht_in_mbs = ps_dec->u2_frm_ht_in_mbs;
+ i4_wd_in_mbs = ps_dec->u2_frm_wd_in_mbs;
+
+ /* Set the first border row to 0xFF */
+ ps_tmp_prms = (ps_ref_mb_prms - 1 - i4_stride);
+
+ memset(ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base, -1,
+ ps_svc_lyr_dec->u4_inter_lyr_mb_prms_size);
+ memset(ps_svc_lyr_dec->pu1_svc_base_mode_flag, 0,
+ ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_size);
+
+ for(i4_i = 0; i4_i < (i4_wd_in_mbs + 2); i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += 1;
+ }
+
+ /* Set the left and right border pixels of each row to 0 */
+ ps_tmp_prms = ps_ref_mb_prms - 1;
+
+ for(i4_i = 0; i4_i < i4_ht_in_mbs; i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms_2 = ps_tmp_prms + (i4_wd_in_mbs + 1);
+ ps_tmp_prms_2->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += i4_stride;
+ }
+
+ /* Set the last border row to 0xFF */
+ for(i4_i = 0; i4_i < (i4_wd_in_mbs + 2); i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += 1;
+ }
+ }
+
+ /* reset residual luma, chroma buffer*/
+ memset(ps_svc_lyr_dec->pi2_il_residual_resample_luma_base, 0,
+ ps_svc_lyr_dec->u4_residual_resample_luma_size);
+ memset(ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base, 0,
+ ps_svc_lyr_dec->u4_residual_resample_chroma_size);
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_crop_wnd_flag_res_int */
+/* */
+/* Description : This routine computes the crop window flag for entire */
+/* dependency layer and places it in the crop window flag */
+/* buffer */
+/* Inputs : 1. ECD context structure */
+/* 2. Crop offset structure */
+/* Globals : None */
+/* Processing : For Mbs within the crop window, flag set to 1 and for */
+/* others it is set to 0 */
+/* */
+/* Outputs : Updates crop window flag buffer */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_crop_wnd_flag_res_int(void *pv_svc_dec)
+{
+ UWORD8 *pu1_crop_wnd_flag;
+ WORD32 i4_num_mbs;
+ WORD32 i4_crop_mbs_x;
+ WORD32 i4_crop_mbs_y;
+ WORD32 i4_cnt;
+ WORD32 i4_left_offset, i4_rt_offset;
+ WORD32 i4_top_offset, i4_bot_offset;
+ WORD32 i4_frm_wd_in_mbs;
+ WORD32 i4_frm_ht_in_mbs;
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ res_prms_t *ps_res_prms;
+
+ ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+ ps_res_prms = &ps_svc_lyr_dec->s_res_prms;
+ i4_frm_wd_in_mbs = ps_dec->u2_frm_wd_in_mbs;
+ i4_frm_ht_in_mbs = ps_dec->u2_frm_ht_in_mbs;
+
+ /* Initializations */
+ pu1_crop_wnd_flag = ps_svc_lyr_dec->pu1_crop_wnd_flag;
+ i4_num_mbs = i4_frm_wd_in_mbs * i4_frm_ht_in_mbs;
+
+ /* bottom most layer in a resolution */
+ if(ps_res_prms->s_ref_lyr_scaled_offset.i2_left >= 0)
+ {
+ /* check for offset greater than 0 */
+ i4_left_offset = (ps_res_prms->s_ref_lyr_scaled_offset.i2_left + 15) >> 4;
+ }
+ else
+ {
+ /* if negative set it to 0*/
+ i4_left_offset = 0;
+ }
+
+ if(ps_res_prms->s_ref_lyr_scaled_offset.i2_rt >= 0)
+ {
+ /* check for offset greater than 0 */
+ i4_rt_offset =
+ (ps_res_prms->i4_res_width - ps_res_prms->s_ref_lyr_scaled_offset.i2_rt) >> 4;
+ }
+ else
+ {
+ /* if negative set it to framewidth in MBs */
+ i4_rt_offset = (ps_res_prms->i4_res_width >> 4);
+ }
+
+ if(ps_res_prms->s_ref_lyr_scaled_offset.i2_top >= 0)
+ {
+ /* check for offset greater than 0 */
+ i4_top_offset = (ps_res_prms->s_ref_lyr_scaled_offset.i2_top + 15) >> 4;
+ }
+ else
+ {
+ /* if negative set it to 0 */
+ i4_top_offset = 0;
+ }
+
+ if(ps_res_prms->s_ref_lyr_scaled_offset.i2_bot >= 0)
+ {
+ /* check for offset greater than 0 */
+ i4_bot_offset =
+ (ps_res_prms->i4_res_height - ps_res_prms->s_ref_lyr_scaled_offset.i2_bot) >> 4;
+ }
+ else
+ {
+ /* if negative set it to frameheight in MBs */
+ i4_bot_offset = (ps_res_prms->i4_res_height >> 4);
+ }
+
+ i4_crop_mbs_x = i4_rt_offset - i4_left_offset;
+ i4_crop_mbs_y = i4_bot_offset - i4_top_offset;
+
+ /* Set crop window flag to 0 for all mbs */
+ memset(pu1_crop_wnd_flag, 0, i4_num_mbs);
+
+ pu1_crop_wnd_flag += (i4_frm_wd_in_mbs * i4_top_offset);
+ pu1_crop_wnd_flag += i4_left_offset;
+ /* Loop over MBs in crop window */
+ for(i4_cnt = 0; i4_cnt < i4_crop_mbs_y; i4_cnt++)
+ {
+ memset(pu1_crop_wnd_flag, 1, i4_crop_mbs_x);
+ pu1_crop_wnd_flag += i4_frm_wd_in_mbs;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_intra_resamp_res_init */
+/* */
+/* Description : this function calculates the scale factors and initialise*/
+/* the context structure */
+/* */
+/* Inputs : pv_intra_samp_ctxt: handle to private structure */
+/* ps_curr_lyr_res_prms: pointer to current resolution */
+/* params */
+/* ps_ref_lyr_res_prms : pointer to ref resolution params */
+/* Globals : none */
+/* Processing : it stores the layer dimensions */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 08 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_intra_resamp_res_init(void *pv_svc_dec)
+{
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ dec_svc_seq_params_t *ps_cur_subset_sps;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ void *pv_intra_samp_ctxt = ps_svc_lyr_dec->pv_intra_sample_ctxt;
+ res_prms_t *ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
+ ref_mb_map_t **pps_luma_map_horz = &ps_svc_lyr_dec->ps_intsam_luma_map_horz;
+ ref_mb_map_t **pps_chroma_map_horz = &ps_svc_lyr_dec->ps_intsam_chroma_map_horz;
+ ref_mb_map_t **pps_luma_map_vert = &ps_svc_lyr_dec->ps_intsam_luma_map_vert;
+ ref_mb_map_t **pps_chroma_map_vert = &ps_svc_lyr_dec->ps_intsam_chroma_map_vert;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_cur_subset_sps = ps_svc_lyr_dec->ps_cur_subset_sps;
+
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+
+ /* if called for base resolution store default values */
+ if(SVCD_TRUE == ps_svc_lyr_dec->u1_base_res_flag)
+ {
+ *pps_luma_map_horz = NULL;
+ *pps_chroma_map_horz = NULL;
+ *pps_luma_map_vert = NULL;
+ *pps_chroma_map_vert = NULL;
+ ps_ctxt->i4_res_lyr_id = -1;
+ ps_ctxt->i4_ref_width = ps_dec->u2_pic_wd;
+ ps_ctxt->i4_ref_height = ps_dec->u2_pic_ht;
+
+ /* Note: The stride option is provided for bringing in data at NMB */
+ /* level. Hence to set a NMB level stride refSample array buffer */
+ /* have to be increased */
+ ps_ctxt->i4_refarray_stride = REF_ARRAY_WIDTH;
+ return OK;
+ }
+
+ /* derive the current sps */
+ /* store the res id appropriately */
+ ps_ctxt->i4_res_lyr_id = ps_svc_lyr_dec->u1_layer_id - 1;
+
+ /* store the resolution params */
+ ps_ctxt->ps_res_prms = ps_curr_lyr_res_prms;
+
+ /* get the current layer ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_svc_lyr_dec->u1_layer_id - 1];
+
+ ps_ctxt->i4_res_lyr_id = ps_svc_lyr_dec->u1_layer_id - 1;
+ /* get the width and heights */
+ ps_lyr_ctxt->i4_curr_width = ps_dec->u2_pic_wd;
+ ps_lyr_ctxt->i4_curr_height = ps_dec->u2_pic_ht;
+ ps_lyr_ctxt->i4_ref_width = ps_ctxt->i4_ref_width;
+ ps_lyr_ctxt->i4_ref_height = ps_ctxt->i4_ref_height;
+ ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag =
+ ps_svc_slice_params->u1_constrained_intra_resampling_flag;
+
+ /* store the structure pointer containing projected locations */
+ *pps_luma_map_horz = ps_lyr_ctxt->s_luma_map_ctxt.ps_x_offset_length;
+ *pps_chroma_map_horz = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_offset_length;
+ *pps_luma_map_vert = ps_lyr_ctxt->s_luma_map_ctxt.ps_y_offset_length;
+ *pps_chroma_map_vert = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_offset_length;
+
+ /* check for recomputation of mapping required */
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ res_prms_t s_ref_res_prms = {0};
+ WORD32 i4_chroma_x_phase, i4_chroma_y_phase;
+ WORD32 i4_ref_chroma_x_phase, i4_ref_chroma_y_phase;
+ WORD32 i4_x_phase_0, i4_x_phase_1;
+ WORD32 i4_y_phase_0, i4_y_phase_1;
+ WORD32 i4_vert_flag;
+
+ /* store the reference layer resolution width and height */
+ s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
+ s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
+
+ /* call the frame level projections calculation function */
+ isvcd_intra_resamp_populate_list(&ps_lyr_ctxt->s_luma_map_ctxt, ps_curr_lyr_res_prms,
+ &s_ref_res_prms, 0, ps_svc_lyr_dec);
+
+ isvcd_intra_resamp_populate_list(&ps_lyr_ctxt->s_chroma_map_ctxt, ps_curr_lyr_res_prms,
+ &s_ref_res_prms, 1, ps_svc_lyr_dec);
+
+ /* Compute the chroma xPhase and yPhase values */
+ if(1 == ps_curr_lyr_res_prms->u1_dyadic_flag)
+ {
+ i4_ref_chroma_x_phase = ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+ i4_ref_chroma_y_phase = ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_x_phase = ps_cur_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag;
+ i4_chroma_y_phase = ps_cur_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1;
+
+ i4_x_phase_0 = i4_chroma_x_phase - (i4_ref_chroma_x_phase << 1);
+ i4_x_phase_1 = (3 + i4_x_phase_0) & 0x7;
+ i4_x_phase_0 += 7;
+ i4_x_phase_0 &= 0x7;
+ i4_y_phase_0 = i4_chroma_y_phase - (i4_ref_chroma_y_phase << 1);
+ i4_y_phase_1 = (3 + i4_y_phase_0) & 0x7;
+ i4_y_phase_0 += 7;
+ i4_y_phase_0 &= 0x7;
+
+ ps_lyr_ctxt->i4_x_phase_0 = i4_x_phase_0;
+ ps_lyr_ctxt->i4_x_phase_1 = i4_x_phase_1;
+ ps_lyr_ctxt->i4_y_phase_0 = i4_y_phase_0;
+ ps_lyr_ctxt->i4_y_phase_1 = i4_y_phase_1;
+
+ /* Choose the appropriate chroma interpolation functions */
+ if((0 == i4_ref_chroma_x_phase) && (1 == i4_chroma_x_phase))
+ {
+ ps_lyr_ctxt->pf_horz_chroma_interpol = ps_ctxt->pf_horz_chroma_interpol[1];
+ }
+ else
+ {
+ ps_lyr_ctxt->pf_horz_chroma_interpol = ps_ctxt->pf_horz_chroma_interpol[0];
+ }
+
+ i4_vert_flag = 0;
+ if(0 == i4_ref_chroma_y_phase)
+ {
+ if((1 == i4_chroma_y_phase) || (2 == i4_chroma_y_phase))
+ {
+ i4_vert_flag = 1;
+ }
+ }
+ else if((2 == i4_ref_chroma_y_phase) && (0 == i4_chroma_y_phase))
+ {
+ i4_vert_flag = 2;
+ }
+
+ if(1 == i4_vert_flag)
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = ps_ctxt->pf_vert_chroma_interpol[1];
+ }
+ else if(2 == i4_vert_flag)
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = ps_ctxt->pf_vert_chroma_interpol[2];
+ }
+ else
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = ps_ctxt->pf_vert_chroma_interpol[0];
+ }
+ }
+ }
+ else
+ {
+ /* should take false value */
+ if(SVCD_FALSE != ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ return NOT_OK;
+ }
+ }
+
+ /* store the current layer width and height to context */
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+
+ return OK;
+} \ No newline at end of file
diff --git a/decoder/svc/isvcd_intra_resamp.h b/decoder/svc/isvcd_intra_resamp.h
new file mode 100644
index 0000000..9b15a6d
--- /dev/null
+++ b/decoder/svc/isvcd_intra_resamp.h
@@ -0,0 +1,631 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_intra_resamp.h
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_INTRA_RESAMPLE_H_
+#define _ISVCD_INTRA_RESAMPLE_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+#define SVCD_FALSE 0
+#define SVCD_TRUE 1
+
+#define MAP_BUFF_WIDTH 48
+#define MAP_BUFF_HEIGHT 48
+#define INTERMEDIATE_BUFF_WIDTH 48
+#define INTERMEDIATE_BUFF_HEIGHT (MB_HEIGHT + 4)
+
+#define MAX_REF_ARR_WD_HT 48
+
+#define MAX_REF_IDX_ARRAY (MAX_REF_ARR_WD_HT + MB_WIDTH)
+#define DYADIC_REF_W_Y 20
+#define DYADIC_REF_H_Y 20
+#define DYADIC_REF_W_C 10
+#define DYADIC_REF_H_C 10
+
+#define SUB_BLOCK_WIDTH 4
+#define SUB_BLOCK_HEIGHT 4
+#define SUB_BLOCK_SIZE (SUB_BLOCK_WIDTH * SUB_BLOCK_HEIGHT)
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
+#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
+#define MB_WIDTH 16
+#define MB_HEIGHT 16
+#define CLIPUCHAR(x) CLIP3(0, 255, (x))
+#define MB_WIDTH_SHIFT 4
+#define MB_HEIGHT_SHIFT 4
+
+#define REF_ARRAY_WIDTH 48
+#define REF_ARRAY_HEIGHT 48
+#define MAX_PIX_FILL_LUMA 4
+#define MAX_PIX_FILL_CHROMA 2
+
+extern const WORD8 g_ai1_interp_filter_luma[64];
+extern const UWORD8 g_au1_interp_filter_chroma[32];
+extern WORD32 ref_pos_luma[4][16];
+extern WORD32 ref_pos_chroma[4][8];
+extern WORD32 phase_luma[3][16];
+extern UWORD8 phase_luma_u8[3][16];
+extern WORD8 phase_luma_x86[6][16];
+extern WORD32 phase_chroma[3][8];
+extern UWORD8 phase_chroma_u8[3][8];
+extern UWORD8 ref_pos_luma_mask_m48[8][16];
+extern UWORD8 ref_pos_luma_mask_m16[8][16];
+extern UWORD8 ref_pos_luma_mask_m32[8][16];
+extern UWORD8 ref_pos_chroma_mask_m24[2][16];
+extern UWORD8 ref_pos_chroma_mask_m8[2][16];
+extern UWORD8 ref_pos_chroma_mask_m16[2][16];
+
+void isvcd_copy_data(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst, WORD32 i4_dst_stride,
+ WORD32 i4_num_bytes, WORD32 i4_num_lines);
+
+static __inline int isvcd_left_most_bit_detect(UWORD32 u4_num)
+{
+ WORD32 i4_number = 0;
+ if(0xff == u4_num)
+ {
+ return 32;
+ }
+
+ do
+ {
+ if(0 == (u4_num & 0x80000000))
+ {
+ return i4_number;
+ }
+ u4_num <<= 1;
+ i4_number++;
+ } while(1);
+}
+
+typedef void i264_vert_interpol_chroma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1);
+
+typedef void i264_horz_interpol_chroma_dyadic(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1);
+
+typedef void (*pf_vert_interpol_chroma_dyadic)(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1);
+
+typedef void (*pf_horz_interpol_chroma_dyadic)(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1);
+
+typedef void(ftype_intra_samp_padding)(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available);
+void isvcd_left_right_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+void isvcd_left_right_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+void isvcd_top_bot_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available);
+
+void isvcd_top_bot_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+void isvcd_diag_padding(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available);
+
+void isvcd_diag_padding_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+void isvcd_diag_reconstruction(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index, WORD8 i1_yd_index,
+ UWORD8 u1_seg_wd, UWORD8 u1_seg_ht, UWORD8 *pu1_refarray_1,
+ UWORD8 *pu1_refarray_2, WORD32 i4_refarray_stride,
+ WORD32 i4_mb_adjoin_x, WORD32 i4_mb_adjoin_y,
+ WORD32 i4_corner_pixel_available);
+
+void isvcd_diag_reconstruction_chroma(WORD32 i4_x, WORD32 i4_y, WORD8 i1_xd_index,
+ WORD8 i1_yd_index, UWORD8 u1_seg_wd, UWORD8 u1_seg_ht,
+ UWORD8 *pu1_refarray_1, UWORD8 *pu1_refarray_2,
+ WORD32 i4_refarray_stride, WORD32 i4_mb_adjoin_x,
+ WORD32 i4_mb_adjoin_y, WORD32 i4_corner_pixel_available);
+
+typedef void i264_interpolate_base_luma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride);
+
+typedef void i264_interpolate_intra_base(void *pv_intra_samp_ctxt, UWORD8 *pu1_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd,
+ WORD32 u2_mb_x, WORD32 u2_mb_y, WORD32 i4_chroma_flag,
+ WORD32 i4_refarray_flag);
+
+/*C Declarations*/
+i264_interpolate_base_luma_dyadic isvcd_interpolate_base_luma_dyadic;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_1;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_2;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_3;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_1;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_2;
+
+/*ARM Declarations*/
+i264_interpolate_base_luma_dyadic isvcd_interpolate_base_luma_dyadic_neonintr;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_1_neonintr;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_2_neonintr;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_3_neonintr;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_1_neonintr;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_2_neonintr;
+
+i264_interpolate_intra_base isvcd_interpolate_intra_base;
+i264_interpolate_intra_base isvcd_interpolate_intra_base_sse42;
+i264_interpolate_intra_base isvcd_interpolate_intra_base_neonintr;
+
+/*x86 Declarations*/
+i264_interpolate_base_luma_dyadic isvcd_interpolate_base_luma_dyadic_sse42;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_1_sse42;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_2_sse42;
+i264_vert_interpol_chroma_dyadic isvcd_vert_interpol_chroma_dyadic_3_sse42;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_1_sse42;
+i264_horz_interpol_chroma_dyadic isvcd_horz_interpol_chroma_dyadic_2_sse42;
+
+typedef struct
+{
+ UWORD16 u2_mb_x; /*!< MB X of the MB which has to
+ be processed
+ */
+ UWORD16 u2_mb_y; /*!< MB Y of the MB which has to
+ be processed
+ */
+} mb_coord_t;
+
+typedef struct
+{
+ void *pv_buffer; /*!< Buffer pointer */
+ WORD32 i4_element_size; /*!< size of the structure or unit */
+ WORD32 i4_num_element_stride; /*!< Stride of buffer in terms of number
+ of elements. */
+} mem_element_t;
+
+typedef struct
+{
+ void *pv_buffer1; /*!< Buffer pointer */
+ void *pv_buffer2; /*!< Buffer pointer */
+ WORD32 i4_element_size; /*!< size of the structure or unit */
+ WORD32 i4_num_element_stride; /*!< Stride of buffer in terms of number
+ of elements.
+ */
+} mem_element_2_t;
+typedef struct
+{
+ UWORD8 u1_seg_dim; /*!< describes segment dimension */
+ UWORD8 u1_seg_off; /*!< describes offset from start */
+ UWORD8 u1_mb_adjoin; /*!< describes whether mb is adjoining
+ the segment 0 => not adjoining
+ 1 => adjoining */
+
+ WORD8 i1_dist_idx; /*!< distance to nearest MB */
+
+ WORD8 i1_nearst_mb_bdry; /*!< describes the nearest mb boundary
+ +1 => rightMB/bottomMB
+ -1 => leftMB/topMB */
+} seg_description_t;
+
+typedef struct
+{
+ UWORD8 u1_num_segments; /*!< place holder to store the number of
+ segments */
+
+ UWORD8 u4_start_pos; /*!< this variable indicates where is
+ start locatiion of the segment with
+ respect to less the block_width or
+ greater than block width */
+
+ seg_description_t s_segments[4]; /*!< place holder to store per segment
+ description */
+} seg_lookup_desc_t;
+typedef struct
+{
+ WORD16 i2_min_pos; /*!< place holder to store the projected
+ MIN referecne position for a MB in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+ WORD16 i2_max_pos; /*!< place holder to store the projected
+ MAX referecne position for a MB in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+} ref_min_max_map_t;
+
+typedef struct
+{
+ WORD16 i2_left; /*!< Horizontal offset of upper left luma sample
+ after resampling process on reference
+ layer with respect to upper left luma
+ sample of current layer.
+ */
+ WORD16 i2_top; /*!< Vertical offset of upper left luma pixel
+ after resampling process on reference
+ layer
+ */
+ WORD16 i2_rt; /*!< Horizontal offset of bottom right luma
+ sample after resampling process on
+ reference layer with respect to bottom
+ right luma sample.
+ */
+ WORD16 i2_bot; /*!< Vertical offset of bottom right luma
+ pixel after resampling process on
+ reference layer
+ */
+} ref_lyr_scaled_offset_t;
+
+typedef struct
+{
+ UWORD8 i2_ref_pos; /*!< place holder to store the projected
+ referecne position for a pixel in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+ UWORD8 i2_phase; /*!< place holder to store the projected
+ phase for a pixel in current layer.
+ can be used to store either
+ horizontal or vertical phase
+ */
+} ref_pixel_map_t;
+
+typedef struct
+{
+ WORD16 i2_offset; /*!< place holder to store the projected
+ start point of reference window
+ for each MB in current layer.can be
+ used to store either horizontal or
+ vertical offset
+ */
+ WORD16 i2_length; /*!< place holder to store reference array
+ length of the reference window
+ for each MB in current layer.can be
+ used to store either horizontal width
+ or vertical height
+ */
+} ref_mb_map_t;
+
+typedef struct
+{
+ WORD32 i4_res_width; /*!< Frame width of top most layer in the
+ resolution. It's expressed in terms
+ of luma samples.
+ */
+ WORD32 i4_res_height; /*!< Frame height of top most layer in the
+ resolution. It's expressed in terms
+ of luma samples.
+ */
+ ref_lyr_scaled_offset_t s_ref_lyr_scaled_offset; /*!< Scaled offset
+ parameters of reference layer considering
+ bottom most layer of the resolution as
+ current layer. Offsets are with respect
+ to upper left luma samples in top most
+ layer in the resolution.
+ */
+ UWORD16 u2_scaled_ref_width; /*!< Considering bottom most layer of the
+ resolution as current layer, scaled
+ width of reference layer in terms of
+ luma pixels. It's inferred parameter
+ based on reference layer offsets.
+ */
+ UWORD16 u2_scaled_ref_height; /*!< Considering bottom most layer of the
+ resolution as current layer, scaled
+ height of reference layer in terms of
+ luma pixels. It's inferred parameter
+ based on reference layer offsets.
+ */
+ UWORD8 u1_rstrct_res_change_flag; /*!< restrictedResolutionChangeFlag for
+ bottom most layer of the resolution. It's
+ a inferred parameter.
+ */
+ UWORD8 u1_cropping_change_flag; /*!< croppingChangeFlag for bottom most
+ layer of the resolution. It's a inferred
+ parameter.
+ */
+ UWORD8 u1_disable_inter_lyr_dblk_filter_idc; /*!< Mode of operation for
+ inter layer de-blocking. It shall be
+ set for bottom most layer of the top
+ resolution. By top resolution, it
+ referes to the resolution just above
+ the current spatial resolution. This
+ shall be valid for all resolutions
+ except target resolution.
+ */
+ WORD8 i1_inter_lyr_alpha_c0_offset; /*!< specifies the offset used in
+ accessing the alpha and tC0 deblocking
+ filter tables for filtering operations
+ in inter layer de-blocking. Applicable
+ for bottom most layer of the top
+ resolution. By top resolution, it referes
+ to the resolution just above the current
+ spatial resolution. This shall be valid
+ for resolutions except target resolution.
+ */
+ WORD8 i1_inter_lyr_beta_offset; /*!< specifies the offset used in
+ accessing the beta deblocking filter table
+ for filtering operations in inter layer
+ de-blocking. Applicable for bottom most
+ layer of the top resolution. By top
+ resolution, it referes to the resolution
+ just above the current spatial resolution.
+ This shall be valid for resolutions
+ except target resolution.
+ */
+ WORD8 i1_constrained_intra_rsmpl_flag; /*!< Constrained intra resampling
+ flag. Range is [0,1].
+ */
+ WORD8 i1_ref_lyr_chroma_phase_x_plus1_flag; /*!< specifies the horizontal
+ phase shift of the chroma components in
+ units of half luma samples of a layer
+ frame for the layer pictures that may be
+ used for inter-layer prediction
+ */
+
+ WORD8 i1_ref_lyr_chroma_phase_y_plus1; /*!< specifies the vertical phase
+ shift of the chroma components in units of
+ half luma samples of a layer frame for the
+ layer pictures that may be used for
+ inter-layer prediction
+ */
+ UWORD8 u1_direct_8x8_inference_flag; /*!< Direct 8x8 inference flag
+ . Range is [0,1].
+ */
+
+ UWORD8 u1_remap_req_flag; /*!< this flag signifies to the
+ upsampling modules whether the Map
+ buffers have to recomputed for current
+ access unit or to retain the previous
+ access units values
+ */
+ UWORD8 u1_dyadic_flag; /*!< this flag signifies the scaling
+ ratios are 2 in both directions
+ and the cropping is MB aligned
+ */
+} res_prms_t;
+
+typedef struct
+{
+ ref_pixel_map_t *ps_x_pos_phase; /*!< buffers to store the projected
+ referecne X and phase X for each
+ pixel in current layer in
+ horizontal direction
+ */
+ ref_pixel_map_t *ps_y_pos_phase; /*!< buffers to store the projected
+ referecne Y and phase Y for each
+ pixel in current layer in
+ vertical direction
+ */
+ ref_mb_map_t *ps_x_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array width in
+ horizontal direction for each MB in
+ current layer
+ */
+ ref_mb_map_t *ps_y_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array height in
+ vertical direction for each MB in
+ current layer
+ */
+ ref_min_max_map_t *ps_x_min_max;
+ /*!< Buffer to store the projected
+ MIN and MAX referecne position for a
+ MB in current layer in
+ horizontal direction
+ */
+
+ ref_min_max_map_t *ps_y_min_max;
+ /*!< Buffer to store the projected
+ MIN and MAX referecne position for a
+ MB in current layer in
+ Vertical direction
+ */
+
+ WORD16 *pi2_xd_index; /*!< buffers to store the projected
+ XD for each pixel in an MB
+ */
+ WORD16 *pi2_yd_index; /*!< buffers to store the projected
+ YD for each pixel in an MB
+ */
+ WORD16 *pi2_ya_index; /*!< buffers to store the projected
+ YA for each pixel in an MB
+ */
+
+ seg_lookup_desc_t *ps_seg_lookup_horz; /*!< buffers to store lookup for
+ horizontal segment description */
+
+ seg_lookup_desc_t *ps_seg_lookup_vert; /*!< buffers to store lookup for
+ vertical segment description */
+
+ UWORD8 *pu1_refarray_x_idx; /*!< buffers to store lookup for
+ x indexes to get availability
+ from 4x4 availability grid */
+
+ UWORD8 *pu1_refarray_y_idx; /*!< buffers to store lookup for
+ y indexes to get availability
+ from 4x4 availability grid */
+} intra_samp_map_ctxt_t;
+
+typedef struct
+{
+ intra_samp_map_ctxt_t s_luma_map_ctxt; /*!< map structure for luma
+ projected locations
+ for curr resolution layer
+ */
+ intra_samp_map_ctxt_t s_chroma_map_ctxt; /*!< map structure for chroma
+ projected locations
+ for curr resolution layer
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ WORD32 i4_curr_width; /*!< current layer width in
+ terms luma samples
+ */
+ WORD32 i4_curr_height; /*!< current layer height in
+ terms luma samples
+ */
+ WORD8 i1_constrained_intra_rsmpl_flag; /*!< Constrained intra resampling
+ flag. Range is [0,1].
+ */
+ WORD32 i4_x_phase_0; /*!< Chroma xPhase for even
+ values of x for dyadic cases
+ */
+ WORD32 i4_x_phase_1; /*!< Chroma xPhase for odd
+ values of x for dyadic cases
+ */
+ WORD32 i4_y_phase_0; /*!< Chroma yPhase for even
+ values of y for dyadic cases
+ */
+ WORD32 i4_y_phase_1; /*!< Chroma yPhase for odd
+ values of y for dyadic cases
+ */
+
+ pf_vert_interpol_chroma_dyadic pf_vert_chroma_interpol;
+ /*!< Vertical interpolation
+ function for chroma
+ */
+ pf_horz_interpol_chroma_dyadic pf_horz_chroma_interpol;
+ /*!< Horizontal interpolation
+ function for chroma
+ */
+} intra_samp_lyr_ctxt;
+typedef struct
+{
+ intra_samp_lyr_ctxt as_res_lyrs[MAX_NUM_RES_LYRS]; /*!< Array of resolution
+ layer ctxt.
+ The first strcuture in the
+ array will be used for storing
+ the "second resolution" map in
+ an access unit w.r.t to its
+ base resolution, and for base
+ resolution nothing will be
+ computed or stored
+ */
+ void *ps_sps; /*!< pointer to array of SPS
+ */
+
+ UWORD8 *pu1_refarray_buffer; /*!< buffer to store the reference
+ layer data before intra
+ sampling
+ */
+ UWORD8 *pu1_refarray_cb; /*!< buffer to hold the reference
+ layer Cb data before intra
+ resampling (used for dyadic
+ cases only)
+ */
+ UWORD8 *pu1_refarray_cr; /*!< buffer to hold the reference
+ layer Cr data before intra
+ resampling (used for dyadic
+ cases only)
+ */
+ WORD32 *pi4_temp_interpolation_buffer; /*!< intermideate buffer
+ for interpolation
+ */
+
+ WORD32 i4_res_lyr_id; /*!< resolution id of the layer
+ which is to be processed
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_refarray_stride; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ res_prms_t *ps_res_prms; /*!< Current resolution params
+ */
+
+ i264_interpolate_base_luma_dyadic *pf_interpolate_base_luma_dyadic;
+ i264_interpolate_intra_base *pf_interpolate_intra_base;
+
+ /*!< Vertical interpolation
+ function for chroma
+ */
+ i264_vert_interpol_chroma_dyadic *pf_vert_chroma_interpol[3];
+
+ /*!< Horizontal interpolation
+ function for chroma
+ */
+ i264_horz_interpol_chroma_dyadic *pf_horz_chroma_interpol[2];
+
+} intra_sampling_ctxt_t;
+
+WORD32 isvcd_get_ceil_log2(WORD32 i4_x);
+
+void isvcd_2d_memset(void *pv_buf, WORD32 i4_width, WORD32 i4_ht, WORD32 i4_stride, WORD32 i4_val);
+
+WORD32 isvcd_intra_resamp_mb(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ mb_coord_t *ps_mb_coord);
+
+WORD32 isvcd_intra_resamp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ mb_coord_t *ps_mb_coord, void *ps_svc_dec);
+
+WORD32 isvcd_populate_res_prms(void *ps_svc_dec);
+
+void isvcd_crop_wnd_flag_res_int(void *ps_svc_dec);
+
+WORD32 isvcd_intra_resamp_res_init(void *ps_svc_dec);
+
+#endif /* _ISVCD_INTRA_RESAMPLE_H_ */
diff --git a/decoder/svc/isvcd_iquant_itrans.c b/decoder/svc/isvcd_iquant_itrans.c
new file mode 100644
index 0000000..a54d873
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans.c
@@ -0,0 +1,714 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_iquant_itrans.c
+*
+* @brief
+* Contains definition of functions for h264 inverse quantization inverse
+transformation and resd comp
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_iquant_itrans_4x4()
+* - isvcd_iquant_itrans_8x8()
+* - isvcd_iquant_itrans_4x4_dc()
+* - isvcd_iquant_itrans_8x8_dc()
+* - isvcd_iquant_itrans_chroma_4x4()
+* - isvcd_iquant_itrans_chroma_4x4_dc()
+
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_iquant_itrans_4x4(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ if(i == 0 && iq_start_idx == 1)
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_out = pi2_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x1 + x2;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x1 - x2;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x0 - x3;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_tmp_ptr++;
+ pi2_out_ptr++;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4_dc */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_iquant_itrans_4x4_dc(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD32 q0;
+ WORD16 i_macro, i;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+ i_macro = CLIP_RSD((q0 + 32) >> 6);
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_out = pi2_out_ptr;
+
+ /* inverse prediction */
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+ *pi2_out = i_macro;
+ pi2_out_ptr++;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_iquant_itrans_chroma_4x4(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ if(i == 0)
+ {
+ q0 = pi2_dc_src[0];
+ }
+ else
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_out = pi2_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x1 + x2;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x1 - x2;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_out += out_strd;
+
+ i_macro = x0 - x3;
+ *pi2_out = CLIP_RSD((i_macro + 32) >> 6);
+ pi2_tmp_ptr++;
+ pi2_out_ptr += 2; // Interleaved store for output
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4_dc */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_chroma_4x4_dc(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD32 q0;
+ WORD16 i_macro, i;
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = CLIP_RSD((q0 + 32) >> 6);
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_out = pi2_out_ptr;
+
+ /* inverse prediction */
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+
+ pi2_out_ptr += 2;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function performs inverse quant and Inverse transform type Ci4 for 8x8
+*block
+*
+* @par Description:
+* Performs inverse transform Ci8 and adds the residue to get the
+* reconstructed block
+*
+* @param[in] pi2_src
+* Input 8x8coefficients
+*
+* @param[in] pu1_pred
+* Prediction 8x8 block
+*
+* @param[out] pu1_recon
+* Output 8x8 block
+*
+* @param[in] q_div
+* QP/6
+*
+* @param[in] q_rem
+* QP%6
+*
+* @param[in] q_lev
+* Quantizer level
+*
+* @param[in] src_strd
+* Input stride
+*
+* @param[in] pred_strd,
+* Prediction stride
+*
+* @param[in] out_strd
+* Output Stride
+*
+* @param[in] pi4_tmp
+* temporary buffer of size 1*16 we dont need a bigger blcok since we reuse
+* the tmp for each block
+*
+* @param[in] pu4_iquant_mat
+* Pointer to the inverse quantization matrix
+*
+* @returns Void
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+void isvcd_iquant_itrans_8x8_dc(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 i, i_macro;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+ i_macro = CLIP_RSD((q + 32) >> 6);
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pi2_out = pi2_out_ptr;
+
+ *pi2_out = i_macro;
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+ pi2_out += out_strd;
+
+ *pi2_out = i_macro;
+
+ pi2_out_ptr++;
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_8x8 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_8x8(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 i_z0, i_z1, i_z2, i_z3, i_z4, i_z5, i_z6, i_z7;
+ WORD16 i_y0, i_y1, i_y2, i_y3, i_y4, i_y5, i_y6, i_y7;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* De quantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ for(i = 0; i < (SUB_BLK_WIDTH_8x8 * SUB_BLK_WIDTH_8x8); i++)
+ {
+ q = pi2_src[i];
+ INV_QUANT(q, pu2_iscale_mat[i], pu2_weigh_mat[i], qp_div, rnd_fact, 6);
+ pi2_tmp_ptr[i] = q;
+ }
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ /* y2 = w0 - w4 */
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ /* y4 = (w2 >> 1) - w6 */
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ /* y6 = w2 + (w6 >> 1) */
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4]);
+
+ i_y1 =
+ ((WORD32) (-pi2_tmp_ptr[3]) + pi2_tmp_ptr[5] - pi2_tmp_ptr[7] - (pi2_tmp_ptr[7] >> 1));
+
+ i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4]);
+
+ i_y3 = ((WORD32) pi2_tmp_ptr[1] + pi2_tmp_ptr[7] - pi2_tmp_ptr[3] - (pi2_tmp_ptr[3] >> 1));
+
+ i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6]);
+
+ i_y5 =
+ ((WORD32) (-pi2_tmp_ptr[1]) + pi2_tmp_ptr[7] + pi2_tmp_ptr[5] + (pi2_tmp_ptr[5] >> 1));
+
+ i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+
+ i_y7 = ((WORD32) pi2_tmp_ptr[3] + pi2_tmp_ptr[5] + pi2_tmp_ptr[1] + (pi2_tmp_ptr[1] >> 1));
+
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ /* z1 = y1 + (y7 >> 2) */
+ /* z2 = y2 + y4 */
+ /* z3 = y3 + (y5 >> 2) */
+ /* z4 = y2 - y4 */
+ /* z5 = (y3 >> 2) - y5 */
+ /* z6 = y0 - y6 */
+ /* z7 = y7 - (y1 >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ /* x1 = z2 + z5 */
+ /* x2 = z4 + z3 */
+ /* x3 = z6 + z1 */
+ /* x4 = z6 - z1 */
+ /* x5 = z4 - z3 */
+ /* x6 = z2 - z5 */
+ /* x7 = z0 - z7 */
+ /*------------------------------------------------------------------*/
+ pi2_tmp_ptr[0] = i_z0 + i_z7;
+ pi2_tmp_ptr[1] = i_z2 + i_z5;
+ pi2_tmp_ptr[2] = i_z4 + i_z3;
+ pi2_tmp_ptr[3] = i_z6 + i_z1;
+ pi2_tmp_ptr[4] = i_z6 - i_z1;
+ pi2_tmp_ptr[5] = i_z4 - i_z3;
+ pi2_tmp_ptr[6] = i_z2 - i_z5;
+ pi2_tmp_ptr[7] = i_z0 - i_z7;
+
+ /* move to the next row */
+ // pi2_src_ptr += SUB_BLK_WIDTH_8x8;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_8x8;
+ }
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pi2_out = pi2_out_ptr;
+ /*------------------------------------------------------------------*/
+ /* y0j = w0j + w4j */
+ /* y1j = -w3j + w5j -w7j -(w7j >> 1) */
+ /* y2j = w0j -w4j */
+ /* y3j = w1j + w7j -w3j -(w3j >> 1) */
+ /* y4j = ( w2j >> 1 ) -w6j */
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ /* y6j = w2j + ( w6j >> 1 ) */
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = pi2_tmp_ptr[0] + pi2_tmp_ptr[32];
+
+ i_y1 = (WORD32) (-pi2_tmp_ptr[24]) + pi2_tmp_ptr[40] - pi2_tmp_ptr[56] -
+ (pi2_tmp_ptr[56] >> 1);
+
+ i_y2 = pi2_tmp_ptr[0] - pi2_tmp_ptr[32];
+
+ i_y3 = (WORD32) pi2_tmp_ptr[8] + pi2_tmp_ptr[56] - pi2_tmp_ptr[24] - (pi2_tmp_ptr[24] >> 1);
+
+ i_y4 = (pi2_tmp_ptr[16] >> 1) - pi2_tmp_ptr[48];
+
+ i_y5 =
+ (WORD32) (-pi2_tmp_ptr[8]) + pi2_tmp_ptr[56] + pi2_tmp_ptr[40] + (pi2_tmp_ptr[40] >> 1);
+
+ i_y6 = pi2_tmp_ptr[16] + (pi2_tmp_ptr[48] >> 1);
+
+ i_y7 = (WORD32) pi2_tmp_ptr[24] + pi2_tmp_ptr[40] + pi2_tmp_ptr[8] + (pi2_tmp_ptr[8] >> 1);
+
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ /* z1j = y1j + (y7j >> 2) */
+ /* z2j = y2j + y4j */
+ /* z3j = y3j + (y5j >> 2) */
+ /* z4j = y2j -y4j */
+ /* z5j = (y3j >> 2) -y5j */
+ /* z6j = y0j -y6j */
+ /* z7j = y7j -(y1j >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ /* x1j = z2j + z5j */
+ /* x2j = z4j + z3j */
+ /* x3j = z6j + z1j */
+ /* x4j = z6j -z1j */
+ /* x5j = z4j -z3j */
+ /* x6j = z2j -z5j */
+ /* x7j = z0j -z7j */
+ /*------------------------------------------------------------------*/
+ *pi2_out = CLIP_RSD((i_z0 + i_z7 + 32) >> 6);
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z2 + i_z5 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z4 + i_z3 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z6 + i_z1 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z6 - i_z1 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z4 - i_z3 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z2 - i_z5 + 32) >> 6);
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD((i_z0 - i_z7 + 32) >> 6);
+
+ pi2_tmp_ptr++;
+ pi2_out_ptr++;
+ }
+}
diff --git a/decoder/svc/isvcd_iquant_itrans.h b/decoder/svc/isvcd_iquant_itrans.h
new file mode 100644
index 0000000..9e09846
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans.h
+ *
+ * @brief
+ * Contains declarations for forward and inverse transform paths for SVC
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef ISVCD_ITRANS_IQUANT_
+#define ISVCD_ITRANS_IQUANT_
+
+/*Function prototype declarations*/
+
+typedef void ih264_iquant_itrans_ft(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr);
+
+typedef void ih264_iquant_itrans_chroma_ft(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src);
+
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4_dc;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8_dc;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4_dc;
+
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4_dc_neonintr;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8_dc_neonintr;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4_neonintr;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8_neonintr;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4_dc_neonintr;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4_neonintr;
+
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4_dc_sse42;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8_dc_sse42;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_4x4_sse42;
+ih264_iquant_itrans_ft isvcd_iquant_itrans_8x8_sse42;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4_dc_sse42;
+ih264_iquant_itrans_chroma_ft isvcd_iquant_itrans_chroma_4x4_sse42;
+
+#endif /* ISVCD_ITRANS_IQUANT_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_iquant_itrans_residual.c b/decoder/svc/isvcd_iquant_itrans_residual.c
new file mode 100644
index 0000000..4fb63d1
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans_residual.c
@@ -0,0 +1,809 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual.c
+ *
+ * @brief
+ * Contains definition of functions for h264 inverse quantization inverse
+ *transformation and resd comp
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_residual_4x4()
+ * - isvcd_iquant_itrans_residual_8x8()
+ * - isvcd_iquant_itrans_residual_4x4_dc()
+ * - isvcd_iquant_itrans_residual_8x8_dc()
+ * - isvcd_iquant_itrans_residual_chroma_4x4()
+ * - isvcd_iquant_itrans_residual_chroma_4x4_dc()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans_residual.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_4x4(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ WORD32 i4_nnz = 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ if(i == 0 && iq_start_idx == 1)
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+
+ pi2_tmp_ptr++;
+ pi2_out_ptr++;
+ pi2_pred++;
+ }
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4_dc */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_4x4_dc(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD32 q0;
+ WORD16 i_macro, i;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+ i_macro = ((q0 + 32) >> 6);
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+
+ /* inverse prediction */
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+
+ pi2_out_ptr++;
+ pi2_pred++;
+ }
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0, i4_nnz_H = 0, i4_nnz_L = 0;
+ WORD32 i;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 i_z0, i_z1, i_z2, i_z3, i_z4, i_z5, i_z6, i_z7;
+ WORD16 i_y0, i_y1, i_y2, i_y3, i_y4, i_y5, i_y6, i_y7;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* De quantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ for(i = 0; i < (SUB_BLK_WIDTH_8x8 * SUB_BLK_WIDTH_8x8); i++)
+ {
+ q = pi2_src[i];
+ INV_QUANT(q, pu2_iscale_mat[i], pu2_weigh_mat[i], qp_div, rnd_fact, 6);
+ pi2_tmp_ptr[i] = q;
+ }
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ /* y2 = w0 - w4 */
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ /* y4 = (w2 >> 1) - w6 */
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ /* y6 = w2 + (w6 >> 1) */
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4]);
+
+ i_y1 =
+ ((WORD32) (-pi2_tmp_ptr[3]) + pi2_tmp_ptr[5] - pi2_tmp_ptr[7] - (pi2_tmp_ptr[7] >> 1));
+
+ i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4]);
+ i_y3 = ((WORD32) pi2_tmp_ptr[1] + pi2_tmp_ptr[7] - pi2_tmp_ptr[3] - (pi2_tmp_ptr[3] >> 1));
+ i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6]);
+
+ i_y5 =
+ ((WORD32) (-pi2_tmp_ptr[1]) + pi2_tmp_ptr[7] + pi2_tmp_ptr[5] + (pi2_tmp_ptr[5] >> 1));
+
+ i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+ i_y7 = ((WORD32) pi2_tmp_ptr[3] + pi2_tmp_ptr[5] + pi2_tmp_ptr[1] + (pi2_tmp_ptr[1] >> 1));
+
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ /* z1 = y1 + (y7 >> 2) */
+ /* z2 = y2 + y4 */
+ /* z3 = y3 + (y5 >> 2) */
+ /* z4 = y2 - y4 */
+ /* z5 = (y3 >> 2) - y5 */
+ /* z6 = y0 - y6 */
+ /* z7 = y7 - (y1 >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ /* x1 = z2 + z5 */
+ /* x2 = z4 + z3 */
+ /* x3 = z6 + z1 */
+ /* x4 = z6 - z1 */
+ /* x5 = z4 - z3 */
+ /* x6 = z2 - z5 */
+ /* x7 = z0 - z7 */
+ /*------------------------------------------------------------------*/
+ pi2_tmp_ptr[0] = i_z0 + i_z7;
+ pi2_tmp_ptr[1] = i_z2 + i_z5;
+ pi2_tmp_ptr[2] = i_z4 + i_z3;
+ pi2_tmp_ptr[3] = i_z6 + i_z1;
+ pi2_tmp_ptr[4] = i_z6 - i_z1;
+ pi2_tmp_ptr[5] = i_z4 - i_z3;
+ pi2_tmp_ptr[6] = i_z2 - i_z5;
+ pi2_tmp_ptr[7] = i_z0 - i_z7;
+
+ /* move to the next row */
+ // pi2_src_ptr += SUB_BLK_WIDTH_8x8;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_8x8;
+ }
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+ /*------------------------------------------------------------------*/
+ /* y0j = w0j + w4j */
+ /* y1j = -w3j + w5j -w7j -(w7j >> 1) */
+ /* y2j = w0j -w4j */
+ /* y3j = w1j + w7j -w3j -(w3j >> 1) */
+ /* y4j = ( w2j >> 1 ) -w6j */
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ /* y6j = w2j + ( w6j >> 1 ) */
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = pi2_tmp_ptr[0] + pi2_tmp_ptr[32];
+
+ i_y1 = (WORD32) (-pi2_tmp_ptr[24]) + pi2_tmp_ptr[40] - pi2_tmp_ptr[56] -
+ (pi2_tmp_ptr[56] >> 1);
+
+ i_y2 = pi2_tmp_ptr[0] - pi2_tmp_ptr[32];
+ i_y3 = (WORD32) pi2_tmp_ptr[8] + pi2_tmp_ptr[56] - pi2_tmp_ptr[24] - (pi2_tmp_ptr[24] >> 1);
+ i_y4 = (pi2_tmp_ptr[16] >> 1) - pi2_tmp_ptr[48];
+
+ i_y5 =
+ (WORD32) (-pi2_tmp_ptr[8]) + pi2_tmp_ptr[56] + pi2_tmp_ptr[40] + (pi2_tmp_ptr[40] >> 1);
+
+ i_y6 = pi2_tmp_ptr[16] + (pi2_tmp_ptr[48] >> 1);
+ i_y7 = (WORD32) pi2_tmp_ptr[24] + pi2_tmp_ptr[40] + pi2_tmp_ptr[8] + (pi2_tmp_ptr[8] >> 1);
+
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ /* z1j = y1j + (y7j >> 2) */
+ /* z2j = y2j + y4j */
+ /* z3j = y3j + (y5j >> 2) */
+ /* z4j = y2j -y4j */
+ /* z5j = (y3j >> 2) -y5j */
+ /* z6j = y0j -y6j */
+ /* z7j = y7j -(y1j >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ /* x1j = z2j + z5j */
+ /* x2j = z4j + z3j */
+ /* x3j = z6j + z1j */
+ /* x4j = z6j -z1j */
+ /* x5j = z4j -z3j */
+ /* x6j = z2j -z5j */
+ /* x7j = z0j -z7j */
+ /*------------------------------------------------------------------*/
+ *pi2_out = CLIP_RSD(((i_z0 + i_z7 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z2 + i_z5 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z4 + i_z3 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z6 + i_z1 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z6 - i_z1 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z4 - i_z3 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z2 - i_z5 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(((i_z0 - i_z7 + 32) >> 6) + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+
+ pi2_tmp_ptr++;
+ pi2_out_ptr++;
+ pi2_pred++;
+ if(i == 3)
+ {
+ i4_nnz = i4_nnz_H | (i4_nnz_L << 4);
+ i4_nnz_L = 0;
+ i4_nnz_H = 0;
+ }
+ }
+ i4_nnz |= (i4_nnz_H << 1) | (i4_nnz_L << 5);
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8_dc */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8_dc(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0, i4_nnz_H = 0, i4_nnz_L = 0;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 i, i_macro;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+ i_macro = (q + 32) >> 6;
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_H |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz_L |= !!(*pi2_out);
+
+ pi2_out_ptr++;
+ pi2_pred++;
+ if(i == 3)
+ {
+ i4_nnz = i4_nnz_H | (i4_nnz_L << 4);
+ i4_nnz_L = 0;
+ i4_nnz_H = 0;
+ }
+ }
+ i4_nnz |= (i4_nnz_H << 1) | (i4_nnz_L << 5);
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD32 i4_nnz = 0;
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ if(i == 0)
+ {
+ q0 = pi2_dc_src[0];
+ }
+ else
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!i_macro;
+ *pi2_out = i_macro;
+
+ pi2_tmp_ptr++;
+ pi2_out_ptr += 2; // Interleaved store for output
+ pi2_pred += 2; // Interleaved load for pred buffer
+ }
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4_dc */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4_dc(WORD16 *pi2_src, WORD16 *pi2_pred,
+ WORD16 *pi2_out, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD32 i4_nnz = 0;
+ WORD16 *pi2_pred_ptr = pi2_pred;
+ WORD16 *pi2_out_ptr = pi2_out;
+ WORD32 q0;
+ WORD16 i_macro, i;
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = ((q0 + 32) >> 6);
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pi2_pred_ptr = pi2_pred;
+ pi2_out = pi2_out_ptr;
+
+ /* inverse prediction */
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+ pi2_pred_ptr += pred_strd;
+ pi2_out += out_strd;
+
+ *pi2_out = CLIP_RSD(i_macro + (*pi2_pred_ptr));
+ i4_nnz |= !!(*pi2_out);
+
+ pi2_out_ptr += 2;
+ pi2_pred += 2;
+ }
+ return i4_nnz;
+}
diff --git a/decoder/svc/isvcd_iquant_itrans_residual.h b/decoder/svc/isvcd_iquant_itrans_residual.h
new file mode 100644
index 0000000..3b729c1
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans_residual.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual.h
+ *
+ * @brief
+ * Contains declarations for forward and inverse transform paths and residual
+ * computation
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef ISVCD_ITRANS_IQUANT_RESD_
+#define ISVCD_ITRANS_IQUANT_RESD_
+
+/*Function prototype declarations*/
+
+typedef WORD32 ih264_iquant_itrans_residual_ft(WORD16 *pi2_src, WORD16 *pi2_rsd, WORD16 *pi2_out,
+ WORD32 rsd_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr);
+
+typedef WORD32 ih264_iquant_itrans_residual_chroma_ft(WORD16 *pi2_src, WORD16 *pi2_rsd,
+ WORD16 *pi2_out, WORD32 rsd_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp,
+ WORD16 *pi2_dc_src);
+
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4_dc;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8_dc;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4_dc;
+
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4_dc_sse42;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4_sse42;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8_sse42;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8_dc_sse42;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4_sse42;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4_dc_sse42;
+
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4_dc_neonintr;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_4x4_neonintr;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8_neonintr;
+ih264_iquant_itrans_residual_ft isvcd_iquant_itrans_residual_8x8_dc_neonintr;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4_neonintr;
+ih264_iquant_itrans_residual_chroma_ft isvcd_iquant_itrans_residual_chroma_4x4_dc_neonintr;
+
+#endif /* ISVCD_ITRANS_IQUANT_RESD_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_iquant_itrans_residual_recon.c b/decoder/svc/isvcd_iquant_itrans_residual_recon.c
new file mode 100644
index 0000000..5096d61
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans_residual_recon.c
@@ -0,0 +1,908 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_recon.c
+ *
+ * @brief
+ * Contains definition of functions for h264 inverse quantization inverse
+ *transformation and recon
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_residual_recon_4x4()
+ * - isvcd_iquant_itrans_residual_recon_8x8()
+ * - isvcd_iquant_itrans_residual_recon_4x4_dc()
+ * - isvcd_iquant_itrans_residual_recon_8x8_dc()
+ * - isvcd_iquant_itrans_residual_recon_chroma_4x4()
+ * - isvcd_iquant_itrans_residual_recon_chroma_4x4_dc()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans_residual_recon.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4(WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd, WORD32 rsd_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0;
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ if(i == 0 && iq_start_idx == 1)
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i4_nnz |= !!i_macro;
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr++;
+ pi2_rsd++;
+ pu1_pred++;
+ }
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4_dc */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4_dc(WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd, WORD32 rsd_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD32 q0;
+ WORD16 x, i_macro, i;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+ i_macro = ((q0 + 32) >> 6);
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ /* inverse prediction */
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+
+ pu1_out_ptr++;
+ pu1_pred++;
+ pi2_rsd++;
+ }
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ WORD16 *pi2_src_ptr = pi2_src;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 x0, x1, x2, x3, i;
+ WORD32 q0, q1, q2, q3;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ /* inverse quant */
+ /*horizontal inverse transform */
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ if(i == 0)
+ {
+ q0 = pi2_dc_src[0];
+ }
+ else
+ {
+ q0 = pi2_src_ptr[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+
+ q2 = pi2_src_ptr[2];
+ INV_QUANT(q2, pu2_iscal_mat[2], pu2_weigh_mat[2], u4_qp_div_6, rnd_fact, 4);
+
+ x0 = q0 + q2;
+ x1 = q0 - q2;
+
+ q1 = pi2_src_ptr[1];
+ INV_QUANT(q1, pu2_iscal_mat[1], pu2_weigh_mat[1], u4_qp_div_6, rnd_fact, 4);
+
+ q3 = pi2_src_ptr[3];
+ INV_QUANT(q3, pu2_iscal_mat[3], pu2_weigh_mat[3], u4_qp_div_6, rnd_fact, 4);
+
+ x2 = (q1 >> 1) - q3;
+ x3 = q1 + (q3 >> 1);
+
+ pi2_tmp_ptr[0] = x0 + x3;
+ pi2_tmp_ptr[1] = x1 + x2;
+ pi2_tmp_ptr[2] = x1 - x2;
+ pi2_tmp_ptr[3] = x0 - x3;
+
+ pi2_src_ptr += SUB_BLK_WIDTH_4x4;
+ pi2_tmp_ptr += SUB_BLK_WIDTH_4x4;
+ pu2_iscal_mat += SUB_BLK_WIDTH_4x4;
+ pu2_weigh_mat += SUB_BLK_WIDTH_4x4;
+ }
+
+ /* vertical inverse transform */
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ x0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[8]);
+ x1 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[8]);
+ x2 = (pi2_tmp_ptr[4] >> 1) - pi2_tmp_ptr[12];
+ x3 = pi2_tmp_ptr[4] + (pi2_tmp_ptr[12] >> 1);
+
+ /* inverse prediction */
+ i_macro = x0 + x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x1 + x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x1 - x2;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = x0 - x3;
+ i_macro = ((i_macro + 32) >> 6);
+ i_macro = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr += 2; // Interleaved store for output
+ pu1_pred += 2; // Interleaved load for pred buffer
+ pi2_rsd += 2;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4_dc */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4_dc(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD32 q0;
+ WORD16 x, i_macro, i;
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = ((q0 + 32) >> 6);
+
+ for(i = 0; i < SUB_BLK_WIDTH_4x4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ /* inverse prediction */
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+
+ pu1_out_ptr += 2;
+ pu1_pred += 2;
+ pi2_rsd += 2;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8(WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd, WORD32 rsd_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0, i4_nnz_H = 0, i4_nnz_L = 0;
+ WORD32 i;
+ WORD16 *pi2_tmp_ptr = pi2_tmp;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i_z0, i_z1, i_z2, i_z3, i_z4, i_z5, i_z6, i_z7;
+ WORD16 i_y0, i_y1, i_y2, i_y3, i_y4, i_y5, i_y6, i_y7;
+ WORD16 i_macro;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* De quantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ for(i = 0; i < (SUB_BLK_WIDTH_8x8 * SUB_BLK_WIDTH_8x8); i++)
+ {
+ q = pi2_src[i];
+ INV_QUANT(q, pu2_iscale_mat[i], pu2_weigh_mat[i], qp_div, rnd_fact, 6);
+ pi2_tmp_ptr[i] = q;
+ }
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ /* y2 = w0 - w4 */
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ /* y4 = (w2 >> 1) - w6 */
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ /* y6 = w2 + (w6 >> 1) */
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = (pi2_tmp_ptr[0] + pi2_tmp_ptr[4]);
+
+ i_y1 =
+ ((WORD32) (-pi2_tmp_ptr[3]) + pi2_tmp_ptr[5] - pi2_tmp_ptr[7] - (pi2_tmp_ptr[7] >> 1));
+
+ i_y2 = (pi2_tmp_ptr[0] - pi2_tmp_ptr[4]);
+
+ i_y3 = ((WORD32) pi2_tmp_ptr[1] + pi2_tmp_ptr[7] - pi2_tmp_ptr[3] - (pi2_tmp_ptr[3] >> 1));
+
+ i_y4 = ((pi2_tmp_ptr[2] >> 1) - pi2_tmp_ptr[6]);
+
+ i_y5 =
+ ((WORD32) (-pi2_tmp_ptr[1]) + pi2_tmp_ptr[7] + pi2_tmp_ptr[5] + (pi2_tmp_ptr[5] >> 1));
+
+ i_y6 = (pi2_tmp_ptr[2] + (pi2_tmp_ptr[6] >> 1));
+
+ i_y7 = ((WORD32) pi2_tmp_ptr[3] + pi2_tmp_ptr[5] + pi2_tmp_ptr[1] + (pi2_tmp_ptr[1] >> 1));
+
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ /* z1 = y1 + (y7 >> 2) */
+ /* z2 = y2 + y4 */
+ /* z3 = y3 + (y5 >> 2) */
+ /* z4 = y2 - y4 */
+ /* z5 = (y3 >> 2) - y5 */
+ /* z6 = y0 - y6 */
+ /* z7 = y7 - (y1 >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ /* x1 = z2 + z5 */
+ /* x2 = z4 + z3 */
+ /* x3 = z6 + z1 */
+ /* x4 = z6 - z1 */
+ /* x5 = z4 - z3 */
+ /* x6 = z2 - z5 */
+ /* x7 = z0 - z7 */
+ /*------------------------------------------------------------------*/
+ pi2_tmp_ptr[0] = i_z0 + i_z7;
+ pi2_tmp_ptr[1] = i_z2 + i_z5;
+ pi2_tmp_ptr[2] = i_z4 + i_z3;
+ pi2_tmp_ptr[3] = i_z6 + i_z1;
+ pi2_tmp_ptr[4] = i_z6 - i_z1;
+ pi2_tmp_ptr[5] = i_z4 - i_z3;
+ pi2_tmp_ptr[6] = i_z2 - i_z5;
+ pi2_tmp_ptr[7] = i_z0 - i_z7;
+
+ /* move to the next row */
+ pi2_tmp_ptr += SUB_BLK_WIDTH_8x8;
+ }
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ pi2_tmp_ptr = pi2_tmp;
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+ /*------------------------------------------------------------------*/
+ /* y0j = w0j + w4j */
+ /* y1j = -w3j + w5j -w7j -(w7j >> 1) */
+ /* y2j = w0j -w4j */
+ /* y3j = w1j + w7j -w3j -(w3j >> 1) */
+ /* y4j = ( w2j >> 1 ) -w6j */
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ /* y6j = w2j + ( w6j >> 1 ) */
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ /*------------------------------------------------------------------*/
+ i_y0 = pi2_tmp_ptr[0] + pi2_tmp_ptr[32];
+
+ i_y1 = (WORD32) (-pi2_tmp_ptr[24]) + pi2_tmp_ptr[40] - pi2_tmp_ptr[56] -
+ (pi2_tmp_ptr[56] >> 1);
+
+ i_y2 = pi2_tmp_ptr[0] - pi2_tmp_ptr[32];
+
+ i_y3 = (WORD32) pi2_tmp_ptr[8] + pi2_tmp_ptr[56] - pi2_tmp_ptr[24] - (pi2_tmp_ptr[24] >> 1);
+
+ i_y4 = (pi2_tmp_ptr[16] >> 1) - pi2_tmp_ptr[48];
+
+ i_y5 =
+ (WORD32) (-pi2_tmp_ptr[8]) + pi2_tmp_ptr[56] + pi2_tmp_ptr[40] + (pi2_tmp_ptr[40] >> 1);
+
+ i_y6 = pi2_tmp_ptr[16] + (pi2_tmp_ptr[48] >> 1);
+
+ i_y7 = (WORD32) pi2_tmp_ptr[24] + pi2_tmp_ptr[40] + pi2_tmp_ptr[8] + (pi2_tmp_ptr[8] >> 1);
+
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ /* z1j = y1j + (y7j >> 2) */
+ /* z2j = y2j + y4j */
+ /* z3j = y3j + (y5j >> 2) */
+ /* z4j = y2j -y4j */
+ /* z5j = (y3j >> 2) -y5j */
+ /* z6j = y0j -y6j */
+ /* z7j = y7j -(y1j >> 2) */
+ /*------------------------------------------------------------------*/
+ i_z0 = i_y0 + i_y6;
+ i_z1 = i_y1 + (i_y7 >> 2);
+ i_z2 = i_y2 + i_y4;
+ i_z3 = i_y3 + (i_y5 >> 2);
+ i_z4 = i_y2 - i_y4;
+ i_z5 = (i_y3 >> 2) - i_y5;
+ i_z6 = i_y0 - i_y6;
+ i_z7 = i_y7 - (i_y1 >> 2);
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ /* x1j = z2j + z5j */
+ /* x2j = z4j + z3j */
+ /* x3j = z6j + z1j */
+ /* x4j = z6j -z1j */
+ /* x5j = z4j -z3j */
+ /* x6j = z2j -z5j */
+ /* x7j = z0j -z7j */
+ /*------------------------------------------------------------------*/
+ i_macro = CLIP_RSD(((i_z0 + i_z7 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z2 + i_z5 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z4 + i_z3 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z6 + i_z1 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z6 - i_z1 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z4 - i_z3 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z2 - i_z5 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ i_macro = CLIP_RSD(((i_z0 - i_z7 + 32) >> 6) + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+
+ pi2_tmp_ptr++;
+ pu1_out_ptr++;
+ pi2_rsd++;
+ pu1_pred++;
+ if(i == 3)
+ {
+ i4_nnz = i4_nnz_H | (i4_nnz_L << 4);
+ i4_nnz_L = 0;
+ i4_nnz_H = 0;
+ }
+ }
+ i4_nnz |= (i4_nnz_H << 1) | (i4_nnz_L << 5);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8_dc */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8_dc(WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd,
+ UWORD8 *pu1_out, WORD32 pred_strd, WORD32 rsd_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0, i4_nnz_H = 0, i4_nnz_L = 0;
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 x, i, i_macro;
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+ i_macro = (q + 32) >> 6;
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+ for(i = 0; i < SUB_BLK_WIDTH_8x8; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ /* Change uc_recBuffer to Point to next element in the same column*/
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_H |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+
+ x = CLIP_RSD(i_macro + (*pi2_rsd_ptr));
+ i4_nnz_L |= !!x;
+ x += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(x);
+
+ pu1_out_ptr++;
+ pu1_pred++;
+ pi2_rsd++;
+ if(i == 3)
+ {
+ i4_nnz = i4_nnz_H | (i4_nnz_L << 4);
+ i4_nnz_L = 0;
+ i4_nnz_H = 0;
+ }
+ }
+ i4_nnz |= (i4_nnz_H << 1) | (i4_nnz_L << 5);
+ return i4_nnz;
+}
diff --git a/decoder/svc/isvcd_iquant_itrans_residual_recon.h b/decoder/svc/isvcd_iquant_itrans_residual_recon.h
new file mode 100644
index 0000000..510895e
--- /dev/null
+++ b/decoder/svc/isvcd_iquant_itrans_residual_recon.h
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_recon.h
+ *
+ * @brief
+ * Contains declarations for forward and inverse transform paths for SVC Target
+ * Layer
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef ISVCD_ITRANS_IQUANT_RESD_RECON_
+#define ISVCD_ITRANS_IQUANT_RESD_RECON_
+
+/*Function prototype declarations*/
+typedef WORD32 ih264_iquant_itrans_residual_recon_ft(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_stride, WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr);
+
+typedef void ih264_iquant_itrans_residual_recon_chroma_ft(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_stride, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src);
+
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4_dc;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8_dc;
+ih264_iquant_itrans_residual_recon_chroma_ft isvcd_iquant_itrans_residual_recon_chroma_4x4;
+ih264_iquant_itrans_residual_recon_chroma_ft isvcd_iquant_itrans_residual_recon_chroma_4x4_dc;
+
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4_dc_neonintr;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8_dc_neonintr;
+ih264_iquant_itrans_residual_recon_chroma_ft
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_neonintr;
+
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4_neonintr;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8_neonintr;
+ih264_iquant_itrans_residual_recon_chroma_ft isvcd_iquant_itrans_residual_recon_chroma_4x4_neonintr;
+
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4_dc_sse42;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8_dc_sse42;
+ih264_iquant_itrans_residual_recon_chroma_ft isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_sse42;
+
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_4x4_sse42;
+ih264_iquant_itrans_residual_recon_ft isvcd_iquant_itrans_residual_recon_8x8_sse42;
+ih264_iquant_itrans_residual_recon_chroma_ft isvcd_iquant_itrans_residual_recon_chroma_4x4_sse42;
+
+#endif /* ISVCD_ITRANS_IQUANT_RESD_RECON_ */
diff --git a/decoder/svc/isvcd_mb_utils.c b/decoder/svc/isvcd_mb_utils.c
new file mode 100644
index 0000000..4844be1
--- /dev/null
+++ b/decoder/svc/isvcd_mb_utils.c
@@ -0,0 +1,364 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_mb_utils.c
+ *
+ * @brief
+ * Contains utitlity functions needed for Macroblock decoding
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_get_mb_info_cabac_nonmbaff()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_parse_mb_header.h"
+#include "ih264d_cabac.h"
+#include "ih264d_defs.h"
+#include "ih264d_tables.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_mb_info_cabac */
+/* */
+/* Description : This function sets the following information of cur MB */
+/* (a) mb_x and mb_y */
+/* (b) Neighbour availablity */
+/* (c) Macroblock location in the frame buffer */
+/* (e) leftMb parama and TopMb params of curMB */
+/* (f) For Mbaff case leftMb params and TopMb params of */
+/* bottomMb are also set if curMB is top */
+/* (g) For mbaff predicts field/frame u4_flag for topMb */
+/* and sets the field/frame for botMb. This is */
+/* written in ps_dec->u1_cur_mb_fld_dec_flag */
+/* */
+/* Inputs : pointer to decstruct */
+/* pointer to current mb info */
+/* currentMbaddress */
+/* */
+/* Processing : leftMb and TopMb params are used by DecMbskip and */
+/* DecCtxMbfield modules so that these modules do not */
+/* check for neigbour availability and then find the */
+/* neigbours for context increments */
+/* */
+/* Returns : OK */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+UWORD32 isvcd_get_mb_info_cabac_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip)
+{
+ WORD32 mb_x;
+ WORD32 mb_y;
+ UWORD32 u1_mb_ngbr_avail = 0;
+ UWORD32 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_top_mb = 1;
+ WORD32 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx;
+ UWORD32 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE;
+ UWORD32 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE;
+ ctxt_inc_mb_info_t *const p_ctx_inc_mb_map = ps_dec->p_ctxt_inc_mb_map;
+
+ /*--------------------------------------------------------------------*/
+ /* Calculate values of mb_x and mb_y */
+ /*--------------------------------------------------------------------*/
+ mb_x = (WORD16) ps_dec->u2_mbx;
+ mb_y = (WORD16) ps_dec->u2_mby;
+ ps_dec->u2_cur_mb_addr = u2_cur_mb_address;
+
+ mb_x++;
+ if((UWORD32) mb_x == u2_frm_width_in_mb)
+ {
+ mb_x = 0;
+ mb_y++;
+ if(mb_y >= ps_dec->u2_frm_ht_in_mbs)
+ {
+ mb_y = ps_dec->u2_frm_ht_in_mbs - 1;
+ }
+ }
+ /*********************************************************************/
+ /* Cabac Context Initialisations */
+ /*********************************************************************/
+ ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + mb_x;
+ ps_dec->p_left_ctxt_mb_info = p_ctx_inc_mb_map - 1;
+ ps_dec->p_top_ctxt_mb_info = p_ctx_inc_mb_map - 1;
+
+ /********************************************************************/
+ /* neighbour availablility */
+ /********************************************************************/
+ if(mb_y > ps_dec->i2_prev_slice_mby)
+ {
+ /* if not in the immemdiate row of prev slice end then top will be available */
+ if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1;
+
+ if(mb_x > i2_prev_slice_mbx)
+ {
+ u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK;
+ u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE;
+ u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE;
+ ps_dec->p_top_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info;
+ }
+ if((mb_x > (i2_prev_slice_mbx - 1)) && ((UWORD32) mb_x != (u2_frm_width_in_mb - 1)))
+ {
+ u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK;
+ u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE;
+ }
+
+ if(mb_x > (i2_prev_slice_mbx + 1))
+ {
+ u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK;
+ u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE;
+ }
+ /* Next row */
+ i2_prev_slice_mbx = -1;
+ }
+ /* Same row */
+ if(mb_x > (i2_prev_slice_mbx + 1))
+ {
+ u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK;
+ u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE;
+ ps_dec->p_left_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info - 1;
+ }
+ {
+ mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row;
+ mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row;
+ /* copy the parameters of topleft Mb */
+ ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype;
+ /* Neighbour pointer assignments*/
+ ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x;
+ ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1;
+ ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x;
+ ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1;
+
+ /* Update the parameters of topleftmb*/
+ ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type;
+ }
+
+ ps_dec->u2_mby = mb_y;
+ ps_dec->u2_mbx = mb_x;
+ ps_cur_mb_info->u2_mbx = mb_x;
+ ps_cur_mb_info->u2_mby = mb_y;
+ ps_cur_mb_info->u1_topmb = u1_top_mb;
+ ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
+ ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
+ ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
+ ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag;
+ ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag;
+ ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask;
+ ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask;
+
+ /*********************************************************************/
+ /* Assign the neigbours */
+ /*********************************************************************/
+ if(u4_mbskip)
+ {
+ UWORD8 u1_a, u1_b;
+ UWORD32 u4_ctx_inc;
+
+ u1_a = (ps_dec->p_top_ctxt_mb_info->u1_mb_type != CAB_INFERRED)
+ ? (!!(ps_dec->p_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK))
+ : 0;
+ u1_b = (ps_dec->p_left_ctxt_mb_info->u1_mb_type != CAB_INFERRED)
+ ? (!!(ps_dec->p_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK))
+ : 0;
+ u4_ctx_inc = 2 - (u1_a + u1_b);
+
+ u4_mbskip = ih264d_decode_bin(u4_ctx_inc, ps_dec->p_mb_skip_flag_t, ps_dec->ps_bitstrm,
+ &ps_dec->s_cab_dec_env);
+
+ if(!u4_mbskip)
+ {
+ if(!(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK))
+ {
+ UWORD32 *pu4_buf;
+ UWORD8 *pu1_buf;
+
+ pu1_buf = ps_dec->pu1_left_nnz_y;
+ pu4_buf = (UWORD32 *) pu1_buf;
+ *pu4_buf = 0;
+ pu1_buf = ps_dec->pu1_left_nnz_uv;
+ pu4_buf = (UWORD32 *) pu1_buf;
+ *pu4_buf = 0;
+
+ *(ps_dec->pu1_left_yuv_dc_csbp) = 0;
+ MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
+ *(UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc = 0;
+ }
+ if(!(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK))
+ {
+ MEMSET_16BYTES(ps_dec->ps_curr_ctxt_mb_info->u1_mv, 0);
+ memset(ps_dec->ps_curr_ctxt_mb_info->i1_ref_idx, 0, 4);
+ }
+ }
+ }
+ return (u4_mbskip);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_mb_info_cavlc_nonmbaff */
+/* */
+/* Description : This function sets the following information of cur MB */
+/* (a) mb_x and mb_y */
+/* (b) Neighbour availablity */
+/* (c) Macroblock location in the frame buffer */
+/* (e) For mbaff predicts field/frame u4_flag for topMb */
+/* and sets the field/frame for botMb. This is */
+/* written in ps_dec->u1_cur_mb_fld_dec_flag */
+/* */
+/* Inputs : pointer to decstruct */
+/* pointer to current mb info */
+/* currentMbaddress */
+/* */
+/* Processing : leftMb and TopMb params are used by DecMbskip and */
+/* DecCtxMbfield modules so that these modules do not */
+/* check for neigbour availability and then find the */
+/* neigbours for context increments */
+/* */
+/* Returns : OK */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 01 2023 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+UWORD32 isvcd_get_mb_info_cavlc_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip_run)
+{
+ WORD32 mb_x;
+ WORD32 mb_y;
+ UWORD8 u1_mb_ngbr_avail = 0;
+ UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs;
+ WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx;
+ UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE;
+ UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE;
+ UNUSED(u4_mbskip_run);
+ /*--------------------------------------------------------------------*/
+ /* Calculate values of mb_x and mb_y */
+ /*--------------------------------------------------------------------*/
+ mb_x = (WORD16) ps_dec->u2_mbx;
+ mb_y = (WORD16) ps_dec->u2_mby;
+
+ ps_dec->u2_cur_mb_addr = u2_cur_mb_address;
+
+ mb_x++;
+
+ if(mb_x == u2_frm_width_in_mb)
+ {
+ mb_x = 0;
+ mb_y++;
+ if(mb_y >= ps_dec->u2_frm_ht_in_mbs)
+ {
+ mb_y = ps_dec->u2_frm_ht_in_mbs - 1;
+ }
+ }
+ if(mb_y > ps_dec->i2_prev_slice_mby)
+ {
+ /* if not in the immemdiate row of prev slice end then top
+ will be available */
+ if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1;
+
+ if(mb_x > i2_prev_slice_mbx)
+ {
+ u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK;
+ u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE;
+ u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE;
+ }
+
+ if((mb_x > (i2_prev_slice_mbx - 1)) && (mb_x != (u2_frm_width_in_mb - 1)))
+ {
+ u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK;
+ u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE;
+ }
+
+ if(mb_x > (i2_prev_slice_mbx + 1))
+ {
+ u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK;
+ u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE;
+ }
+
+ /* Next row Left will be available*/
+ i2_prev_slice_mbx = -1;
+ }
+
+ /* Same row */
+ if(mb_x > (i2_prev_slice_mbx + 1))
+ {
+ u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK;
+ u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE;
+ }
+
+ {
+ mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row;
+ mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row;
+
+ /* copy the parameters of topleft Mb */
+ ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype;
+ /* Neighbour pointer assignments*/
+ ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x;
+ ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1;
+ ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x;
+ ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1;
+
+ /* Update the parameters of topleftmb*/
+ ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type;
+ }
+
+ ps_dec->u2_mby = mb_y;
+ ps_dec->u2_mbx = mb_x;
+ ps_cur_mb_info->u2_mbx = mb_x;
+ ps_cur_mb_info->u2_mby = mb_y;
+ ps_cur_mb_info->u1_topmb = 1;
+ ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
+ ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
+ ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
+ ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag;
+ ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag;
+ ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask;
+ ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask;
+ return (OK);
+}
diff --git a/decoder/svc/isvcd_mb_utils.h b/decoder/svc/isvcd_mb_utils.h
new file mode 100644
index 0000000..0275f13
--- /dev/null
+++ b/decoder/svc/isvcd_mb_utils.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_mb_utils.h
+ *
+ * @brief
+ * Contains declarations of the utility functions needed to decode SVCD MB
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_MB_UTILS_H_
+#define _ISVCD_MB_UTILS_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+UWORD32 isvcd_get_mb_info_cabac_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip);
+
+UWORD32 isvcd_get_mb_info_cavlc_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip_run);
+
+#endif /* _ISVCD_MB_UTILS_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_mode_mv_resamp.c b/decoder/svc/isvcd_mode_mv_resamp.c
new file mode 100644
index 0000000..322dbec
--- /dev/null
+++ b/decoder/svc/isvcd_mode_mv_resamp.c
@@ -0,0 +1,3211 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_mode_mv_resamp.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_ref_lyr_part_idc()
+ * - isvcd_check_motion()
+ * - isvcd_get_min_positive()
+ * - isvcd_motion_scale_crop_wdw_change()
+ * - isvcd_interlyr_motion_scale()
+ * - isvcd_store_motion_map()
+ * - isvcd_check_mv_diff()
+ * - isvcd_interlyr_motion_submbmode_pred()
+ * - isvcd_interlyr_mbmode_pred_bmb()
+ * - isvcd_populate_ref_idx()
+ * - isvcd_interlyr_mbmode_pred()
+ * - isvcd_compute_interlyr_motion_mode()
+ * - isvcd_interlyr_motion_mode_pred_dyadic()
+ * - isvcd_compute_scaled_offsets()
+ * - isvcd_comp_mode_mv_res_init()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_defs.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "isvcd_mode_mv_resamp.h"
+#include "ih264_debug.h"
+
+const WORD32 g_i4_dpb_size[16] = {
+ 396, 396, 900, 2376, 2376, 2376, 4752, 8100,
+ 8100, 18000, 20480, 32768, 32768, 34816, 110400, 184320,
+};
+
+/*****************************************************************************/
+/* total_coeff and trailing 1's decode table */
+/*****************************************************************************/
+
+/*-----------------------------------------------------------------------*/
+/* This table consists of info about the NNZ and t1 table */
+/*-----------------------------------------------------------------------*/
+
+const UWORD16 g_au2_nnz_tbl_offsets[9] = {0, 0, 120, 120, 224, 224, 224, 224, 224};
+
+/*-----------------------------------------------------------------------*/
+/* For given bits in the bitstream, this table consists of 3 parts */
+/* | tcoeff(4) | t1s(2) | suffix(2)| */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_codegx_avc[312] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24,
+ 24, 24, 24, 24, 24, 24, 22, 22, 2, 2, 45, 45, 45, 45, 78, 78, 42, 42,
+ 61, 61, 61, 61, 94, 94, 58, 58, 38, 38, 18, 18, 110, 110, 74, 74, 54, 54,
+ 34, 34, 126, 126, 90, 90, 70, 70, 50, 50, 142, 142, 106, 106, 86, 86, 66, 66,
+ 115, 139, 119, 99, 159, 123, 103, 83, 191, 171, 151, 147, 175, 155, 135, 131, 223, 203,
+ 183, 179, 207, 187, 167, 163, 255, 235, 231, 211, 239, 219, 215, 195, 242, 242, 250, 250,
+ 246, 246, 226, 226, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 5, 5, 5, 5, 1, 1, 1, 1, 62, 62, 46, 46, 25, 25, 25, 25, 95, 43,
+ 39, 3, 78, 78, 22, 22, 110, 110, 58, 58, 54, 54, 18, 18, 126, 126, 74, 74,
+ 70, 70, 34, 34, 66, 66, 90, 90, 86, 86, 50, 50, 142, 142, 106, 106, 102, 102,
+ 82, 82, 175, 139, 135, 115, 159, 123, 119, 99, 163, 171, 167, 147, 191, 155, 151, 131,
+ 223, 203, 199, 195, 207, 187, 183, 179, 231, 227, 235, 215, 218, 218, 210, 210, 254, 254,
+ 250, 250, 246, 246, 242, 242, 236, 236, 236, 236, 236, 236, 236, 236,
+
+ 111, 95, 79, 63, 47, 27, 7, 0, 71, 75, 55, 59, 39, 127, 43, 23, 35, 107,
+ 103, 19, 143, 91, 87, 3, 99, 83, 139, 67, 159, 123, 119, 51, 191, 171, 151, 131,
+ 175, 155, 135, 115, 179, 203, 183, 163, 207, 187, 167, 147, 231, 211, 223, 219, 215, 195,
+ 198, 198, 246, 246, 226, 226, 238, 238, 234, 234, 253, 253, 253, 253, 249, 249, 249, 249,
+ 240, 240, 240, 240, 240, 240, 240, 240};
+
+/*-----------------------------------------------------------------------*/
+/* For given bits in the bitstream the decoded codeword consists of 2 */
+/* fields: */
+/* | targetcoefftokenidx(6) | suffix(2) | */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_codegx_svc[312] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 22, 22, 18, 18, 13, 13, 13, 13, 34, 34, 30, 30, 25, 25,
+ 25, 25, 50, 50, 46, 46, 42, 42, 38, 38, 66, 66, 62, 62, 58, 58, 54, 54, 82,
+ 82, 78, 78, 74, 74, 70, 70, 98, 98, 94, 94, 90, 90, 86, 86, 131, 127, 123, 119,
+ 115, 111, 107, 103, 163, 159, 155, 151, 147, 143, 139, 135, 195, 191, 187, 183, 179, 175, 171,
+ 167, 231, 227, 223, 219, 215, 211, 207, 203, 246, 246, 242, 242, 238, 238, 234, 234, 196, 196,
+ 196, 196, 196, 196, 196, 196, 5, 5, 5, 5, 29, 29, 29, 29, 18, 18, 14, 14, 9,
+ 9, 9, 9, 43, 39, 35, 31, 26, 26, 22, 22, 58, 58, 54, 54, 50, 50, 46, 46,
+ 74, 74, 70, 70, 66, 66, 62, 62, 90, 90, 86, 86, 82, 82, 78, 78, 106, 106, 102,
+ 102, 98, 98, 94, 94, 139, 135, 131, 127, 123, 119, 115, 111, 171, 167, 163, 159, 155, 151,
+ 147, 143, 203, 199, 195, 191, 187, 183, 179, 175, 227, 223, 231, 219, 210, 210, 206, 206, 234,
+ 234, 246, 246, 242, 242, 238, 238, 212, 212, 212, 212, 212, 212, 212, 212, 31, 27, 23, 19,
+ 15, 11, 7, 64, 63, 59, 55, 51, 47, 43, 39, 35, 95, 91, 87, 83, 79, 75, 71,
+ 67, 127, 123, 119, 115, 111, 107, 103, 99, 159, 155, 151, 147, 143, 139, 135, 131, 191, 187,
+ 183, 179, 175, 171, 167, 163, 219, 215, 211, 207, 203, 199, 194, 194, 234, 234, 230, 230, 226,
+ 226, 222, 222, 241, 241, 241, 241, 237, 237, 237, 237, 244, 244, 244, 244, 244, 244, 244, 244,
+ 64, 64, 64, 64, 64, 64, 64, 64
+
+};
+
+/*---------------------------------------------------------------------------*/
+/* A lookup table, when nC>=8, to get the targetcoefftokenidx */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_target_coeff_token_idx[68] = {
+ 0, 0, 0, 0, 16, 1, 1, 1, 20, 8, 2, 2, 23, 11, 9, 3, 24, 13, 12, 4, 28, 15, 14,
+ 5, 30, 17, 18, 6, 31, 21, 22, 7, 32, 25, 26, 10, 36, 33, 29, 19, 40, 37, 34, 27, 44, 41,
+ 38, 35, 47, 45, 42, 39, 49, 48, 46, 43, 53, 50, 51, 52, 57, 54, 55, 56, 61, 58, 59, 60};
+
+/*---------------------------------------------------------------------------*/
+/* A lookup table for invTotalCoeff( coeffTokenIdx) and */
+/* invTrailingOnes( coeffTokenIdx ) */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_inv_tcoeff_t1[186] = {
+ 0, 5, 10, 15, 4, 9, 19, 14, 23, 8, 13, 18, 27, 12, 17, 22, 31, 16, 21, 26, 35,
+ 20, 25, 30, 39, 24, 29, 34, 43, 28, 33, 38, 32, 36, 37, 42, 47, 40, 41, 46, 51, 44,
+ 45, 50, 55, 48, 49, 54, 59, 53, 52, 57, 58, 63, 56, 61, 62, 67, 60, 65, 66, 64,
+
+ 0, 5, 10, 15, 19, 9, 23, 4, 13, 14, 27, 8, 17, 18, 31, 12, 21, 22, 35, 16, 25,
+ 26, 20, 24, 29, 30, 39, 28, 33, 34, 43, 32, 37, 38, 47, 36, 41, 42, 51, 40, 45, 46,
+ 44, 48, 49, 50, 55, 52, 53, 54, 59, 56, 58, 63, 57, 60, 61, 62, 67, 64, 65, 66,
+
+ 0, 5, 10, 15, 19, 23, 27, 31, 9, 14, 35, 13, 18, 17, 22, 21, 4, 25, 26, 39, 8,
+ 29, 30, 12, 16, 33, 34, 43, 20, 38, 24, 28, 32, 37, 42, 47, 36, 41, 46, 51, 40, 45,
+ 50, 55, 44, 49, 54, 48, 53, 52, 57, 58, 59, 56, 61, 62, 63, 60, 65, 66, 67, 64};
+
+/*---------------------------------------------------------------------------*/
+/* A lookup table for decoding the chroma nnz's and trailing 1's */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_chroma_dc_nnz_t1[28] = {4, 4, 4, 4, 0, 0, 0, 0, 24, 24, 24, 24, 18, 46,
+ 22, 2, 49, 49, 33, 33, 41, 41, 37, 37, 57, 57, 53, 53};
+
+/*****************************************************************************/
+/* Total zeroes table */
+/*****************************************************************************/
+
+/*-----------------------------------------------------------------------*/
+/* Contains information about tz table. Each entry consists of 3 fields */
+/* | table offset (8) | max zeroes(4) | bit offset(2) | */
+/*-----------------------------------------------------------------------*/
+
+const UWORD16 g_au2_tz_tbl_offsets[27] = {0, 37, 1178, 2778, 4374, 5718, 7066,
+ 8666, 10265, 11097, 11925, 12625, 13200, 13516,
+ 13768, 13956, 14092, 14344, 14532, 14677, 15374,
+ 16206, 17034, 17609, 17928, 18116, 18240};
+
+/*-----------------------------------------------------------------------*/
+/* Total zero table */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_tz_tbl[285] = {
+ 0, 0, 9, 5, 17, 13, 25, 21, 33, 29, 41, 37, 49, 45, 57, 53, 60, 60,
+
+ 14, 10, 6, 2, 26, 22, 17, 17, 33, 33, 29, 29, 41, 41, 37, 37, 49, 49, 45, 45, 52, 52, 52,
+ 52, 56, 26, 14, 10, 6, 18, 2, 29, 29, 33, 33, 21, 21, 41, 41, 37, 37, 48, 48, 48, 48, 44,
+ 44, 44, 44, 52, 26, 22, 18, 6, 14, 10, 33, 33, 37, 37, 29, 29, 41, 41, 1, 1, 44, 44, 44,
+ 44, 48, 26, 22, 18, 14, 6, 2, 29, 29, 33, 33, 9, 9, 40, 40, 40, 40, 36, 36, 36, 36, 44,
+ 22, 18, 14, 10, 29, 29, 25, 25, 36, 36, 36, 36, 32, 32, 32, 32, 4, 4, 4, 4, 0, 0, 0,
+ 0, 40, 14, 10, 21, 21, 25, 25, 17, 17, 32, 32, 32, 32, 28, 28, 28, 28, 4, 4, 4, 4, 0,
+ 0, 0, 0, 36, 21, 17, 25, 13, 28, 28, 4, 4, 8, 8, 0, 0, 32,
+
+ 17, 13, 24, 24, 20, 20, 8, 8, 28, 28, 0, 0, 4,
+
+ 17, 13, 20, 20, 8, 8, 24, 24, 0, 0, 4,
+
+ 16, 16, 13, 21, 8, 8, 4, 4, 0,
+
+ 12, 8, 16, 4, 0,
+
+ 8, 12, 4, 0,
+
+ 8, 4, 0,
+
+ 4, 0,
+
+ 0, 4, 8, 12,
+
+ 0, 4, 8,
+
+ 0, 4,
+
+ 0, 0, 5, 9, 13, 17, 20, 20, 24, 24, 28, /*11*/
+
+ 14, 18, 22, 26, 4, 4, 4, 4, 8, 8, 8, 8, 0, /*13*/
+
+ 13, 13, 18, 22, 8, 8, 8, 8, 4, 4, 4, 4, 0, /*13*/
+
+ 13, 13, 2, 18, 8, 8, 8, 8, 4, /*9*/
+
+ 9, 13, 4, 4, 0, /*5*/
+
+ 8, 4, 0, /*3*/
+
+ 4, 0 /*2*/
+};
+
+/*****************************************************************************/
+/* Run before table */
+/*****************************************************************************/
+
+const UWORD8 g_au1_run_bef_tbl[64] = {0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 1, 1,
+ 10, 10, 6, 6, 1, 1, 1, 1, 14, 14, 10, 10, 6, 6, 2, 2,
+ 19, 15, 10, 10, 6, 6, 2, 2, 23, 19, 15, 11, 6, 6, 2, 2,
+ 7, 11, 19, 15, 27, 23, 2, 2, 27, 27, 23, 19, 15, 11, 7, 3};
+
+/*****************************************************************************/
+/* CBP table */
+/*****************************************************************************/
+
+/*-----------------------------------------------------------------------*/
+/* Contains both inter and intra tables */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_intra_cbp[48] = {47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
+ 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
+ 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41};
+
+const UWORD8 g_au1_inter_cbp[48] = {0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
+ 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
+ 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41};
+
+/*---------------------------------------------------------------------------*/
+/* Contains the cbp table for intra16x16 mb type */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_intra16x16_cbp[6] = {0, 16, 32, 15, 31, 47};
+
+/*****************************************************************************/
+/* Inverse scan table */
+/*****************************************************************************/
+
+/*-----------------------------------------------------------------------*/
+/* Regular inverse scan tables */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_regular_inv_scan[16] = {0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15};
+
+const UWORD8 g_au1_regular_inv_scan_field[16] = {0, 4, 1, 8, 12, 5, 9, 13,
+ 2, 6, 10, 14, 3, 7, 11, 15};
+
+const UWORD8 g_au1_regular_inv_scan8x8[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48,
+ 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23,
+ 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
+
+UWORD8 const g_au1_subblk_8x8_offsets[16] = {0, 0, 0, 0, 64, 64, 64, 64,
+ 128, 128, 128, 128, 192, 192, 192, 192};
+
+/*---------------------------------------------------------------------------*/
+/* 8x8 inverse scan tables */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_prog_deinter_inv_scan[4][16] = {
+ {0, 9, 17, 18, 12, 40, 27, 7, 35, 57, 29, 30, 58, 38, 53, 47}, /* for First subblock */
+ {1, 2, 24, 11, 19, 48, 20, 14, 42, 50, 22, 37, 59, 31, 60, 55}, /* for second subblock */
+ {8, 3, 32, 4, 26, 41, 13, 21, 49, 43, 15, 44, 52, 39, 61, 62}, /* for third subblock */
+ {16, 10, 25, 5, 33, 34, 6, 28, 56, 36, 23, 51, 45, 46, 54, 63} /* for fourth subblock */
+};
+
+const UWORD8 g_au1_prog_8x8_inv_scan[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48,
+ 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23,
+ 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
+
+/*****************************************************************************/
+/* SUBMB partition tables */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Number of sub Mb's in 8x8 partition mode */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_num_sub_mb_part[4] = {1, 2, 2, 4};
+
+/*---------------------------------------------------------------------------*/
+/* Width and height of submb's in terms of 4x4 (for 8x8 partition mode) */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_sub_mb_part_wd[4] = {2, 2, 1, 1};
+
+const UWORD8 g_au1_sub_mb_part_ht[4] = {2, 1, 2, 1};
+
+/*---------------------------------------------------------------------------*/
+/* SubMB mc mode table */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_sub_mb_mc_mode[20] = {SUBMB_8x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4, SUBMB_8x8,
+ SUBMB_8x8, SUBMB_8x8, SUBMB_8x8, SUBMB_8x4, SUBMB_4x8,
+ SUBMB_8x4, SUBMB_4x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4,
+ SUBMB_4x4, SUBMB_4x4,
+ /* Self defined modes B DIRECT8x8 */
+ SUBMB_4x4, SUBMB_4x4, SUBMB_4x4};
+
+/*---------------------------------------------------------------------------*/
+/* SubMb prediciton mode table */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_sub_mb_pred_mode[20] = {
+ PRED_L0,
+ PRED_L0,
+ PRED_L0,
+ PRED_L0,
+ B_DIRECT,
+ PRED_L0,
+ PRED_L1,
+ BI_PRED,
+ PRED_L0,
+ PRED_L0,
+ PRED_L1,
+ PRED_L1,
+ BI_PRED,
+ BI_PRED,
+ PRED_L0,
+ PRED_L1,
+ BI_PRED,
+ /* Self defined modes for B DIRECT8x8 */
+ BI_PRED,
+ PRED_L0,
+ PRED_L1,
+};
+
+/*****************************************************************************/
+/* MB partition tables */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Number of MB partitions */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_num_mb_part[5] = {1, 2, 2, 4, 4};
+
+/*---------------------------------------------------------------------------*/
+/* MB partitions width and height in terms of submbs */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_mb_part_wd[5] = {4, 4, 2, 2, 2};
+
+const UWORD8 g_au1_mb_part_ht[5] = {4, 2, 4, 2, 2};
+
+/*---------------------------------------------------------------------------*/
+/* MB MC mode of mb partitions */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_mb_mc_mode[31] = {
+ PRED_16x16, PRED_16x8, PRED_8x16, PRED_8x8, PRED_8x8R0, PRED_16x16, PRED_16x16, PRED_16x16,
+ PRED_16x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8,
+ PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8,
+ PRED_8x16, PRED_16x8, PRED_8x16, PRED_8x8,
+ /* Self defined modes for B_SKIP and DIRECT16x16 */
+ PRED_8x8, PRED_8x8, PRED_8x8};
+
+/*---------------------------------------------------------------------------*/
+/* MB prediciton mode table */
+/*---------------------------------------------------------------------------*/
+
+const WORD8 g_au1_mb_pred_mode[2][32] = {
+ {
+ PRED_L0,
+ PRED_L0,
+ PRED_L0,
+ PRED_INVALID,
+ PRED_INVALID,
+ B_DIRECT,
+ PRED_L0,
+ PRED_L1,
+ BI_PRED,
+ PRED_L0,
+ PRED_L0,
+ PRED_L1,
+ PRED_L1,
+ PRED_L0,
+ PRED_L0,
+ PRED_L1,
+ PRED_L1,
+ PRED_L0,
+ PRED_L0,
+ PRED_L1,
+ PRED_L1,
+ BI_PRED,
+ BI_PRED,
+ BI_PRED,
+ BI_PRED,
+ BI_PRED,
+ BI_PRED,
+ PRED_INVALID,
+ /* Self defined modes for B_SKIP and DIRECT16x16 */
+ BI_PRED,
+ PRED_L0,
+ PRED_L1,
+ },
+ {PRED_INVALID, PRED_L0, PRED_L0, PRED_INVALID, PRED_INVALID, PRED_INVALID, PRED_INVALID,
+ PRED_INVALID, PRED_INVALID, PRED_L0, PRED_L0, PRED_L1, PRED_L1, PRED_L1, PRED_L1, PRED_L0,
+ PRED_L0, BI_PRED, BI_PRED, BI_PRED, BI_PRED, PRED_L0, PRED_L0, PRED_L1, PRED_L1, BI_PRED,
+ BI_PRED, PRED_INVALID,
+ /* Self defined modes for B_SKIP and DIRECT16x16 */
+ PRED_INVALID, PRED_INVALID, PRED_INVALID}};
+
+/*---------------------------------------------------------------------------*/
+/* Neighbour partition address offsets table */
+/*---------------------------------------------------------------------------*/
+
+const UWORD8 g_au1_neighbors_addr_offset[2][16 * 4] = {
+ /* Each row has current, left, top, top right */
+ /* Each row corresponds to sub_mb_num */
+
+ /* Partition width 4 */
+ {
+ 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 2, 3, 3, 2, 3, 5, 4, 1, 0, 1, 5, 4,
+ 1, 0, 6, 5, 2, 3, 7, 6, 3, 2, 8, 2, 4, 5, 9, 8, 5, 6, 10, 9, 6, 7,
+ 11, 10, 7, 6, 12, 3, 8, 9, 13, 12, 9, 8, 14, 13, 10, 11, 15, 14, 11, 10,
+ },
+ /* Partition width 8 */
+ {/* Only alternate rows are valid */
+ 0, 0, 0, 2, 0, 0, 0, 0, 2, 1, 2, 4, 0, 0, 0, 0, 4, 1, 0, 2, 0, 0,
+ 0, 0, 6, 5, 2, 1, 0, 0, 0, 0, 8, 2, 4, 6, 0, 0, 0, 0, 10, 9, 6, 5,
+ 0, 0, 0, 0, 12, 3, 8, 10, 0, 0, 0, 0, 14, 13, 10, 9, 0, 0, 0, 0}};
+
+/*---------------------------------------------------------------------------*/
+/* Reference index comparison map table */
+/*---------------------------------------------------------------------------*/
+const UWORD8 g_au1_ref_idx_comp_map[16 * 2 * 16] = {
+ /* SUB MB NUMBER 0 */
+ 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 4, 5, 6, 7, /* Partition width 4 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 1 */
+ 1, 1, 7, 7, 5, 5, 7, 7, 1, 1, 3, 3, 1, 1, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 2 */
+ 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 3 */
+ 1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 3, 3, 5, 5, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 4 */
+ 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
+ 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 5 */
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 6 */
+ 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
+ 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 7 */
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 8 */
+ 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 9 */
+ 1, 1, 3, 3, 5, 5, 7, 7, 1, 1, 3, 3, 5, 5, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 10 */
+ 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, 0, 1, 6, 7, /* Partition width 4 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 11 */
+ 1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 7, 7, 1, 1, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 12 */
+ 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
+ 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 13 */
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Partition width 8 */
+
+ /* SUB MB NUMBER 14 */
+ 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, /* Partition width 4 */
+ 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, 2, 7, /* Partition width 8 */
+
+ /* SUB MB NUMBER 15 */
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* Partition width 4 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* Partition width 8 */
+
+};
+
+/*-----------------------------------------------------------------------*/
+/* SUB MB index */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_sub_mb_idx_mod[16] = {
+ 0, 0, /* 16x16 */
+ 0, 8, /* 16x8 */
+ 0, 2, /* 8x16 */
+ 0, 0, /* 8x8 */
+ 0, 4, /* 8x4 */
+ 0, 1, /* 4x8 */
+ 0, 1, 3, 1 /* 4x4 */
+};
+
+/*****************************************************************************/
+/* Raster scan offset table */
+/*****************************************************************************/
+
+const UWORD8 g_au1_sub_blk_rast_scan_offsets[16] = {0, 1, 4, 5, 2, 3, 6, 7,
+ 8, 9, 12, 13, 10, 11, 14, 15};
+
+/*****************************************************************************/
+/*Motion and mode computation tables */
+/*****************************************************************************/
+
+/* B MB TYPES */
+const UWORD8 g_au1_eb_mb_type[36] = {
+ B_L0_16x16, B_L0_16x16, B_L0_16x16, B_L1_16x16, B_L1_16x16, B_L1_16x16,
+ B_BI_16x16, B_BI_16x16, B_BI_16x16, B_L0_L0_16x8, B_L0_L1_16x8, B_L0_BI_16x8,
+ B_L1_L0_16x8, B_L1_L1_16x8, B_L1_BI_16x8, B_BI_L0_16x8, B_BI_L1_16x8, B_BI_BI_16x8,
+ B_L0_L0_8x16, B_L0_L1_8x16, B_L0_BI_8x16, B_L1_L0_8x16, B_L1_L1_8x16, B_L1_BI_8x16,
+ B_BI_L0_8x16, B_BI_L1_8x16, B_BI_BI_8x16, B_8x8, B_8x8, B_8x8,
+ B_8x8, B_8x8, B_8x8, B_8x8, B_8x8, B_8x8};
+
+/* P MB TYPES */
+const UWORD8 g_au1_ep_mb_type[4] = {P_L0_16x16, P_L0_L0_16x8, P_L0_L0_8x16, P_8x8};
+
+/* P SUB MB TYPES */
+const UWORD8 g_au1_ep_submb_type[4] = {P_L0_8x8, P_L0_8x4, P_L0_4x8, P_L0_4x4};
+
+/* B SUB MB TYPES */
+const UWORD8 g_au1_eb_submb_type[12] = {B_L0_8x8, B_L1_8x8, B_BI_8x8, B_L0_8x4, B_L1_8x4, B_BI_8x4,
+ B_L0_4x8, B_L1_4x8, B_BI_4x8, B_L0_4x4, B_L1_4x4, B_BI_4x4};
+
+/*****************************************************************************/
+/* Deblocking related tables */
+/*****************************************************************************/
+
+/* chroma QP values luma Qp is used to index to this table */
+const UWORD8 g_au1_qp_scale_chroma[52] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35,
+ 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39};
+
+/* alpha table used in deblocking */
+const UWORD8 g_au1_alpha_table[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13,
+ 15, 17, 20, 22, 25, 28, 32, 36, 40, 45, 50, 56, 63,
+ 71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, 255, 255};
+
+/* clip table used in deblcoking */
+const UWORD8 g_au1_clip_table_deblk[75] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51};
+
+/* Beta table used in deblocking*/
+const UWORD8 g_au1_beta_table[52] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
+ 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18};
+
+/* clip table used baed on index BS and other vakues */
+const UWORD8 g_au1_clip_table[52][4] = {
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1},
+ {0, 0, 0, 1}, {0, 0, 1, 1}, {0, 0, 1, 1}, {0, 1, 1, 1}, {0, 1, 1, 1},
+ {0, 1, 1, 1}, {0, 1, 1, 1}, {0, 1, 1, 2}, {0, 1, 1, 2}, {0, 1, 1, 2},
+ {0, 1, 1, 2}, {0, 1, 2, 3}, {0, 1, 2, 3}, {0, 2, 2, 3}, {0, 2, 2, 4},
+ {0, 2, 3, 4}, {0, 2, 3, 4}, {0, 3, 3, 5}, {0, 3, 4, 6}, {0, 3, 4, 6},
+ {0, 4, 5, 7}, {0, 4, 5, 8}, {0, 4, 6, 9}, {0, 5, 7, 10}, {0, 6, 8, 11},
+ {0, 6, 8, 13}, {0, 7, 10, 14}, {0, 8, 11, 16}, {0, 9, 12, 18}, {0, 10, 13, 20},
+ {0, 11, 15, 23}, {0, 13, 17, 25}};
+
+/*****************************************************************************/
+/* QUANTIZATION TABLES */
+/*****************************************************************************/
+
+const UWORD8 g_au1_luma_to_chroma_qp_map[52] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35,
+ 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39};
+
+const UWORD8 g_au1_scale_factor_table[6] = {8, 9, 10, 11, 13, 14};
+
+/*****************************************************************************/
+/* SCALING MATRICIES TABLE */
+/*****************************************************************************/
+
+/* Default table used for INTRA 4x4 blocks */
+const WORD16 g_ai2_default_intra4x4[16] = {6, 13, 13, 20, 20, 20, 28, 28,
+ 28, 28, 32, 32, 32, 37, 37, 42};
+
+/* Default table used for INTER 4x4 blocks */
+const WORD16 g_ai2_default_inter4x4[16] = {10, 14, 14, 20, 20, 20, 24, 24,
+ 24, 24, 27, 27, 27, 30, 30, 34};
+
+/* Flat table used for 4x4 blocks */
+const WORD16 g_ai2_flat_4x4[16] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
+
+/* Flat table used for 4x4 blocks */
+const WORD16 g_ai2_flat_8x8[64] = {16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
+
+/* Default table used for INTRA 8x8 blocks */
+const WORD16 g_ai2_default_intra8x8[64] = {
+ 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25,
+ 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31,
+ 31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42};
+
+/* Default table used for INTER 8x8 blocks */
+const WORD16 g_ai2_default_inter8x8[64] = {
+ 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22,
+ 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27,
+ 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35};
+
+/* V(qp%6) table */
+const WORD8 g_ai1_scale_quant_matrix[6][16] = {
+ {10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16},
+ {11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18},
+ {13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20},
+ {14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23},
+ {16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25},
+ {18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29}};
+
+/* V(qp%6) table for 8x8 */
+const UWORD8 g_ai1_8x8_scale_quant_matrix[6][64] = {
+ {20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25,
+ 18, 25, 18, 25, 18, 25, 19, 24, 24, 19, 19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24,
+ 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18},
+ {22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28,
+ 19, 28, 19, 28, 19, 28, 21, 26, 26, 21, 21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26,
+ 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19},
+ {26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33,
+ 23, 33, 23, 33, 23, 33, 24, 31, 31, 24, 24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31,
+ 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23},
+ {28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35,
+ 25, 35, 25, 35, 25, 35, 26, 33, 33, 26, 26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33,
+ 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25},
+ {32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40,
+ 28, 40, 28, 40, 28, 40, 30, 38, 38, 30, 30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38,
+ 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28},
+ {36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46,
+ 32, 46, 32, 46, 32, 46, 34, 43, 43, 34, 34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43,
+ 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32}
+
+};
+
+/*****************************************************************************/
+/* CABAC engine tables */
+/*****************************************************************************/
+
+const UWORD8 g_au1_sig_coeff_ctxt_inc[64] = {
+ 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3,
+ 6, 7, 7, 7, 8, 9, 10, 9, 8, 7, 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10,
+ 9, 8, 6, 11, 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11, 14, 10, 12, 255};
+
+const UWORD8 g_au1_last_coeff_ctxt_inc[64] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 255};
+
+/*-----------------------------------------------------------------------*/
+/* Range table */
+/*-----------------------------------------------------------------------*/
+
+const UWORD8 g_au1_cabac_rtab[64][4] = {
+ {128, 176, 208, 240}, {128, 167, 197, 227}, {128, 158, 187, 216}, {123, 150, 178, 205},
+ {116, 142, 169, 195}, {111, 135, 160, 185}, {105, 128, 152, 175}, {100, 122, 144, 166},
+ {95, 116, 137, 158}, {90, 110, 130, 150}, {85, 104, 123, 142}, {81, 99, 117, 135},
+ {77, 94, 111, 128}, {73, 89, 105, 122}, {69, 85, 100, 116}, {66, 80, 95, 110},
+ {62, 76, 90, 104}, {59, 72, 86, 99}, {56, 69, 81, 94}, {53, 65, 77, 89},
+ {51, 62, 73, 85}, {48, 59, 69, 80}, {46, 56, 66, 76}, {43, 53, 63, 72},
+ {41, 50, 59, 69}, {39, 48, 56, 65}, {37, 45, 54, 62}, {35, 43, 51, 59},
+ {33, 41, 48, 56}, {32, 39, 46, 53}, {30, 37, 43, 50}, {29, 35, 41, 48},
+ {27, 33, 39, 45}, {26, 31, 37, 43}, {24, 30, 35, 41}, {23, 28, 33, 39},
+ {22, 27, 32, 37}, {21, 26, 30, 35}, {20, 24, 29, 33}, {19, 23, 27, 31},
+ {18, 22, 26, 30}, {17, 21, 25, 28}, {16, 20, 23, 27}, {15, 19, 22, 25},
+ {14, 18, 21, 24}, {14, 17, 20, 23}, {13, 16, 19, 22}, {12, 15, 18, 21},
+ {12, 14, 17, 20}, {11, 14, 16, 19}, {11, 13, 15, 18}, {10, 12, 15, 17},
+ {10, 12, 14, 16}, {9, 11, 13, 15}, {9, 11, 12, 14}, {8, 10, 12, 14},
+ {8, 9, 11, 13}, {7, 9, 11, 12}, {7, 9, 10, 12}, {7, 8, 10, 11},
+ {6, 8, 9, 11}, {6, 7, 9, 10}, {6, 7, 8, 9}, {2, 2, 2, 2}};
+
+/*-----------------------------------------------------------------------*/
+/* Next state MPS_LPS table */
+/*-----------------------------------------------------------------------*/
+
+const UWORD16 g_au2_cabac_next_state_mps_lps[64] = {
+ 0x100, 0x200, 0x301, 0x402, 0x502, 0x604, 0x704, 0x805, 0x906, 0xa07, 0xb08,
+ 0xc09, 0xd09, 0xe0b, 0xf0b, 0x100c, 0x110d, 0x120d, 0x130f, 0x140f, 0x1510, 0x1610,
+ 0x1712, 0x1812, 0x1913, 0x1a13, 0x1b15, 0x1c15, 0x1d16, 0x1e16, 0x1f17, 0x2018, 0x2118,
+ 0x2219, 0x231a, 0x241a, 0x251b, 0x261b, 0x271c, 0x281d, 0x291d, 0x2a1e, 0x2b1e, 0x2c1e,
+ 0x2d1f, 0x2e20, 0x2f20, 0x3021, 0x3121, 0x3221, 0x3322, 0x3422, 0x3523, 0x3623, 0x3723,
+ 0x3824, 0x3924, 0x3a24, 0x3b25, 0x3c25, 0x3d25, 0x3e26, 0x3e26, 0x3f3f};
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ref_lyr_part_idc */
+/* */
+/* Description : this function computes the reference layer partition map */
+/* for all the 4x4 partitions of the current MB */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : mode motion handle */
+/* ai4_ref_part_idc : pointer to reference layer partition */
+/* indentification */
+/* pi4_intra_flag : pointer to store the intra flag */
+/* i4_mb_addr : current MB address */
+/* Globals : none */
+/* Processing : it projects the each 4x4 block onto the refernce layer */
+/* and gets the co-located location. it checks the MB mode */
+/* of the reference layer MB for INTRA and performs actions */
+/* appropriately. it modifies the intra declared partitions */
+/* for non-dydaic cases */
+/* Outputs : packed offset x and offset y in the refernce layer array */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_ref_lyr_part_idc(void *pv_comp_mode_mv_ctxt, WORD32 ai4_ref_part_idc[4][4],
+ WORD32 *pi4_intra_flag, void *pv_mb_params)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. runs loops over the 16 4x4 blocks and gets teh reference layer
+ patition information by projecting the 1,1 locations of
+ each block */
+ /*! 2. if the projected partition is in INTRA MB then its stores -1
+ to the partition idc array */
+ /*! 3. if projected partition is in INTER MB then it packs and stores
+ the offsets form the starting pointer in the part_idc array */
+ /*! 4. IN non dyaydic cases. the part idc having -1 are replaced by
+ neighbours if the current MB projected is not INTRA */
+ /*! 5. the -1 values are replaced first on a 4x4 inside an 8x8 basis */
+ /*! 6. in second iteration -1 are replaced at an 8x8 basis */
+ /*! 7. stores the intra MB status in the location given */
+
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD32 i4_blk_y, i4_blk_x;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_intra_mb_flag;
+ WORD32 i4_inter_lyr_mb_prms_stride;
+ dec_mb_info_t *ps_mb_params;
+
+ ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ /* ref layer mb mode */
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_lyr_mem->s_ref_mb_mode.pv_buffer;
+ i4_inter_lyr_mb_prms_stride = ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride;
+
+ /* derive the MB_X and MB_Y for the current MB */
+ i4_mb_x = ps_mb_params->u2_mbx;
+ i4_mb_y = ps_mb_params->u2_mby;
+
+ /* set the intra MB flag to default TRUE */
+ i4_intra_mb_flag = SVCD_TRUE;
+
+ /*-----------------------------------------------------------------------*/
+ /* derive the reference layer part idc for all 16 partitions */
+ /*-----------------------------------------------------------------------*/
+ for(i4_blk_y = 0; i4_blk_y < NUM_SUB_MB_PARTS; i4_blk_y++)
+ {
+ for(i4_blk_x = 0; i4_blk_x < NUM_SUB_MB_PARTS; i4_blk_x++)
+ {
+ WORD32 i4_curr_x, i4_curr_y;
+ WORD32 i4_ref_x, i4_ref_y;
+ WORD32 i4_ref_mb_x, i4_ref_mb_y;
+ WORD8 i1_ref_mb_mode;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms_temp;
+
+ i4_curr_x = (i4_mb_x << 4) + (i4_blk_x << 2) + 1;
+ i4_curr_y = (i4_mb_y << 4) + (i4_blk_y << 2) + 1;
+
+ /* get the colocated position in the refernce layer */
+ i4_ref_x = ps_lyr_mem->pi2_ref_loc_x[i4_curr_x];
+ i4_ref_y = ps_lyr_mem->pi2_ref_loc_y[i4_curr_y];
+
+ i4_ref_x = CLIP3(0, ((ps_lyr_mem->i4_ref_width) - 1), i4_ref_x);
+
+ i4_ref_y = CLIP3(0, ((ps_lyr_mem->i4_ref_height) - 1), i4_ref_y);
+
+ /* get the reference mb x and y */
+ i4_ref_mb_x = (i4_ref_x >> 4);
+ i4_ref_mb_y = (i4_ref_y >> 4);
+
+ /* get the appropriate mb params in reference layer */
+ ps_inter_lyr_mb_prms_temp = ps_inter_lyr_mb_prms + i4_ref_mb_x;
+ ps_inter_lyr_mb_prms_temp += i4_ref_mb_y * i4_inter_lyr_mb_prms_stride;
+
+ i1_ref_mb_mode = ps_inter_lyr_mb_prms_temp->i1_mb_mode;
+
+ /* check if the MB mode of the refernce MB is Intra*/
+ if(i1_ref_mb_mode > SVC_INTER_MB)
+ {
+ /* store the -1 value */
+ ai4_ref_part_idc[i4_blk_y][i4_blk_x] = -1;
+ }
+ else
+ {
+ /* pack and store the reference x and y */
+ ai4_ref_part_idc[i4_blk_y][i4_blk_x] = (i4_ref_y << 16) + i4_ref_x;
+ i4_intra_mb_flag = SVCD_FALSE;
+ }
+
+ } /* end of block x loop */
+
+ } /* end of block y loop */
+
+ /*************************************************************************/
+ /* if the restricted spatial resolution change flag is 0 */
+ /* modify the part_idc for all the partitions */
+ /*************************************************************************/
+ if(SVCD_FALSE == (ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) &&
+ (SVCD_FALSE == i4_intra_mb_flag))
+ {
+ /* replace values of "-1" on a 4x4 block basis */
+ WORD32 i4_xp, i4_yp;
+ WORD32 i4_indx_x, i4_indx_y;
+ WORD32 ai4_flag_8x8[2][2] = {SVCD_FALSE};
+
+ /* loop over (4) 8x8 partitions */
+ for(i4_yp = 0; i4_yp < 2; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 2; i4_xp++)
+ {
+ WORD32 i4_xs, i4_ys;
+ WORD32 ai4_flag_4x4[2][2] = {SVCD_FALSE};
+
+ /* loop over (4) 4x4 partitions */
+ for(i4_ys = 0; i4_ys < 2; i4_ys++)
+ {
+ for(i4_xs = 0; i4_xs < 2; i4_xs++)
+ {
+ /* index to the exact 4x4 block */
+ i4_indx_y = (i4_yp << 1) + i4_ys;
+ i4_indx_x = (i4_xp << 1) + i4_xs;
+
+ /* check if the current part idc is -1*/
+ if(ai4_ref_part_idc[i4_indx_y][i4_indx_x] == -1)
+ {
+ WORD32 i4_temp_x = 1 - i4_xs;
+ WORD32 i4_temp_y = 1 - i4_ys;
+ WORD32 i4_temp_part_y = (i4_yp << 1) + i4_temp_y;
+
+ WORD32 i4_temp_part_x = (i4_xp << 1) + i4_temp_x;
+
+ ai4_flag_4x4[i4_ys][i4_xs] = SVCD_TRUE;
+
+ /* replace with appropriate values */
+ if((SVCD_FALSE == ai4_flag_4x4[i4_ys][i4_temp_x]) &&
+ (ai4_ref_part_idc[i4_indx_y][i4_temp_part_x] != -1))
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_indx_y][i4_temp_part_x];
+ }
+ else if((SVCD_FALSE == ai4_flag_4x4[i4_temp_y][i4_xs]) &&
+ (ai4_ref_part_idc[i4_temp_part_y][i4_indx_x] != -1))
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_temp_part_y][i4_indx_x];
+ }
+ else if((SVCD_FALSE == ai4_flag_4x4[i4_temp_y][i4_temp_x]) &&
+ (ai4_ref_part_idc[i4_temp_part_y][i4_temp_part_x] != -1))
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_temp_part_y][i4_temp_part_x];
+ }
+ } /* end of part idc equal to -1 check */
+
+ } /* end of sub partition xs loop */
+
+ } /* end of sub partition ys loop */
+
+ } /* end of partition xp loop */
+
+ } /* end of partition yp loop */
+
+ /* replace values of "-1" on an 8x8 block basis */
+
+ /* loop over (4) 8x8 partitions */
+ for(i4_yp = 0; i4_yp < 2; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 2; i4_xp++)
+ {
+ WORD32 i4_yp_inv = 1 - i4_yp;
+ WORD32 i4_xp_inv = 1 - i4_xp;
+ WORD32 i4_xo_inv = (2 - i4_xp);
+ WORD32 i4_yo_inv = (2 - i4_yp);
+ i4_indx_x = (i4_xp << 1);
+ i4_indx_y = (i4_yp << 1);
+
+ /* check if the current part idc is -1*/
+ if(ai4_ref_part_idc[i4_indx_y][i4_indx_x] == -1)
+ {
+ ai4_flag_8x8[i4_yp][i4_xp] = SVCD_TRUE;
+
+ /* replace the -1 with appropriate values */
+ if(SVCD_FALSE == ai4_flag_8x8[i4_yp][i4_xp_inv] &&
+ ai4_ref_part_idc[i4_indx_y][i4_xo_inv] != -1)
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_indx_y][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
+ ai4_ref_part_idc[i4_indx_y + 1][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_indx_y][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_indx_y + 1][i4_xo_inv];
+ }
+ else if(SVCD_FALSE == ai4_flag_8x8[i4_yp_inv][i4_xp] &&
+ ai4_ref_part_idc[i4_yo_inv][i4_indx_x] != -1)
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_yo_inv][i4_indx_x];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
+ ai4_ref_part_idc[i4_yo_inv][i4_indx_x];
+
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_yo_inv][i4_indx_x + 1];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_yo_inv][i4_indx_x + 1];
+ }
+ else if(SVCD_FALSE == ai4_flag_8x8[i4_yp_inv][i4_xp_inv] &&
+ ai4_ref_part_idc[i4_yo_inv][i4_xo_inv] != -1)
+ {
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x] =
+ ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x] =
+ ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
+
+ ai4_ref_part_idc[i4_indx_y + 1][i4_indx_x + 1] =
+ ai4_ref_part_idc[i4_yo_inv][i4_xo_inv];
+ }
+ } /* end of part idc equal to -1 check */
+
+ } /* end of partition xp loop */
+
+ } /* end of partition yp loop */
+
+ } /* end of refinement of part idc for non dyadic case*/
+
+ /* store the intra flag in the location provided */
+ *pi4_intra_flag = i4_intra_mb_flag;
+
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_check_motion */
+/* */
+/* Description :this function calculates the MV diff b/w to motion vectors*/
+/* and returns 1 if it is under threshold equal to 0 */
+/* */
+/* Inputs : pv_motion_prm_mb_part_a : pointer to motion struct part A*/
+/* pv_motion_prm_mb_part_b : pointer to motion struct part B*/
+/* i4_listx : lists to be checked */
+/* Globals : none */
+/* Processing : it compares reference indcies fo given number of lists */
+/* it calculates the mv diff and compares it with 0 */
+/* it does the above for given number of lists */
+/* Outputs : none */
+/* Returns : 1 if matching 0 if not matching */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_check_motion(void *pv_motion_prm_mb_part_a, void *pv_motion_prm_mb_part_b,
+ WORD32 i4_listx)
+{
+ mv_pred_t *ps_part_a;
+ mv_pred_t *ps_part_b;
+ WORD32 i4_cntr;
+ WORD32 i4_mv_treshold;
+ WORD32 i4_flag = 0;
+
+ ps_part_a = (mv_pred_t *) pv_motion_prm_mb_part_a;
+ ps_part_b = (mv_pred_t *) pv_motion_prm_mb_part_b;
+
+ for(i4_cntr = 0; i4_cntr < i4_listx; i4_cntr++)
+ {
+ /* calculate the absolute diff of both components */
+ i4_mv_treshold = ABS((ps_part_a->i2_mv[2 * i4_cntr]) - (ps_part_b->i2_mv[2 * i4_cntr]));
+ i4_mv_treshold +=
+ ABS((ps_part_a->i2_mv[1 + 2 * i4_cntr]) - (ps_part_b->i2_mv[1 + 2 * i4_cntr]));
+
+ if((0 == i4_mv_treshold) &&
+ (ps_part_a->i1_ref_frame[i4_cntr] == ps_part_b->i1_ref_frame[i4_cntr]))
+ {
+ i4_flag = 1;
+ }
+ else
+ {
+ i4_flag = 0;
+ return (i4_flag);
+ }
+
+ } /* end of loop over lists */
+
+ return (i4_flag);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_min_positive */
+/* */
+/* Description : this utility return the minimum positive b/w the given */
+/* inputs */
+/* */
+/* Inputs : i4_input_1: value A , i4_input_2: value B */
+/* Globals : none */
+/* Processing : if A & B are greater than -1 thenit returns MIN(A<B) */
+/* otherwise return MAX(A<B) */
+/* Outputs : none */
+/* Returns : minimum positive of the two inputs */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_min_positive(WORD32 i4_input_1, WORD32 i4_input_2)
+{
+ UWORD32 u4_x, u4_y;
+ WORD32 i4_min_positive;
+
+ /* get positive values */
+ u4_x = (UWORD32) i4_input_1;
+ u4_y = (UWORD32) i4_input_2;
+
+ /* logic and desired output
+
+ u4_x magnitude compare u4_y o/p
+ + > + u4_y
+ + < + u4_x
+ + = + u4_x
+ - > - u4_y
+ - < - u4_x
+ - = - u4_x
+ 0 = 0 u4_x
+ - n/a + u4_y
+ + n/a - u4_x
+
+ */
+
+ if((u4_y < u4_x) && (0 <= i4_input_2))
+ {
+ i4_min_positive = i4_input_2;
+ }
+ else
+ {
+ i4_min_positive = i4_input_1;
+ }
+ return (i4_min_positive);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_motion_scale_crop_wdw_change */
+/* */
+/* Description : This function does the up scaling of motion vectors and */
+/* for crop window change cases */
+/* Inputs : pv_comp_mode_mv_ctxt : mode motion handle */
+/* ps_lyr_mem : pointer current layer memory */
+/* ps_mb_params : pointer to mb params structure */
+/* ps_ref_mv : pointer to reference MVs */
+/* ps_motion_pred : pointer to current 4x4 part mv pred */
+/* i4_listx : lists to be processed */
+/* i4_part_frm_x: horz location in the picture of the */
+/* current sub partition */
+/* i4_part_frm_y: vertical location in the picture of the */
+/* current sub partition */
+/* Globals : */
+/* Processing : it takes care of cropping */
+/* change flag */
+/* Outputs : it stores the interlayer MV pred in the structure */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_motion_scale_crop_wdw_change(mode_motion_ctxt_t *ps_ctxt,
+ mode_motion_lyr_ctxt *ps_lyr_mem,
+ dec_mb_info_t *ps_mb_params, mv_pred_t *ps_ref_mv,
+ mv_pred_t *ps_motion_pred, WORD32 i4_lists,
+ WORD32 i4_part_frm_x, WORD32 i4_part_frm_y,
+ void **ppv_map_ref_idx_to_poc, UWORD8 u1_list_x)
+{
+ ref_lyr_scaled_offset_t *ps_curr_lyr_offset;
+ ref_lyr_scaled_offset_t *ps_ref_pic_lyr_offset;
+ WORD32 i4_ref_lyr_width, i4_ref_lyr_height;
+ WORD32 i4_curr_lyr_width, i4_curr_lyr_height;
+ WORD32 i4_ref_indx;
+ WORD32 i4_mv_x, i4_mv_y;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_dox, i4_doy, i4_dsw, i4_dsh;
+ WORD32 i4_scale_x, i4_scale_y;
+ WORD8 *pi1_ref_idx_map;
+
+ UNUSED(ps_ctxt);
+ UNUSED(ps_mb_params);
+
+ /* get the reference index */
+ i4_ref_indx = ps_motion_pred->i1_ref_frame[u1_list_x];
+
+ i4_mv_x = (WORD32) ps_ref_mv->i2_mv[2 * u1_list_x];
+ i4_mv_y = (WORD32) ps_ref_mv->i2_mv[1 + 2 * u1_list_x];
+
+ /* get the Map buffer pointer */
+ if(0 == i4_lists)
+ {
+ pi1_ref_idx_map = (WORD8 *) ppv_map_ref_idx_to_poc;
+ }
+ else
+ {
+ pi1_ref_idx_map = (WORD8 *) (ppv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF);
+ }
+
+ /* get the Ref layer width and height */
+ i4_ref_lyr_width = ps_lyr_mem->i4_ref_width;
+ i4_ref_lyr_height = ps_lyr_mem->i4_ref_height;
+
+ /* get the Scaled ref layer width and height */
+ i4_curr_lyr_width = ps_lyr_mem->ps_curr_lyr_res_prms->u2_scaled_ref_width;
+ i4_curr_lyr_height = ps_lyr_mem->ps_curr_lyr_res_prms->u2_scaled_ref_height;
+
+ /* get the offset stucture pointer */
+ ps_curr_lyr_offset = &ps_lyr_mem->ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset;
+
+ /* get the reference offset structure pointer */
+ ps_ref_pic_lyr_offset = ps_lyr_mem->ps_ref_pic_lyr_offsets + pi1_ref_idx_map[i4_ref_indx];
+
+ /* calculate the correction variables */
+ i4_dox = ps_curr_lyr_offset->i2_left - ps_ref_pic_lyr_offset->i2_left;
+ i4_doy = ps_curr_lyr_offset->i2_top - ps_ref_pic_lyr_offset->i2_top;
+ i4_dsw = ps_curr_lyr_offset->i2_rt - ps_ref_pic_lyr_offset->i2_rt + i4_dox;
+ i4_dsh = ps_curr_lyr_offset->i2_bot - ps_ref_pic_lyr_offset->i2_bot + i4_doy;
+
+ i4_scale_x =
+ (((i4_curr_lyr_width + i4_dsw) << 16) + (i4_ref_lyr_width >> 1)) / i4_ref_lyr_width;
+
+ i4_scale_y =
+ (((i4_curr_lyr_height + i4_dsh) << 16) + (i4_ref_lyr_height >> 1)) / i4_ref_lyr_height;
+
+ /* scale the motion vectors */
+ i4_mv_x = (i4_mv_x * i4_scale_x + 32768) >> 16;
+ i4_mv_y = (i4_mv_y * i4_scale_y + 32768) >> 16;
+
+ /* subtract the offsets */
+ i4_x = i4_part_frm_x - ps_lyr_mem->i4_offset_x;
+ i4_y = i4_part_frm_y - ps_lyr_mem->i4_offset_y;
+
+ /* get the scale factors */
+ i4_scale_x = (((4 * i4_dsw) << 16) + (i4_curr_lyr_width >> 1)) / i4_curr_lyr_width;
+ i4_scale_y = (((4 * i4_dsh) << 16) + (i4_curr_lyr_height >> 1)) / i4_curr_lyr_height;
+
+ /* add the correction */
+ i4_mv_x += ((i4_x * i4_scale_x + 32768) >> 16) - 4 * i4_dox;
+ i4_mv_y += ((i4_y * i4_scale_y + 32768) >> 16) - 4 * i4_doy;
+
+ /* store the final motion vectors */
+ ps_motion_pred->i2_mv[2 * u1_list_x] = i4_mv_x;
+ ps_motion_pred->i2_mv[1 + 2 * u1_list_x] = i4_mv_y;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interlayer_motion_scale */
+/* */
+/* Description : This function does the up scaling of motion vectors and */
+/* and stores the inter layer MV and reference indices */
+/* in the mv prediction structure for a 4x4 part */
+/* Inputs : pv_comp_mode_mv_ctxt : mode motion handle */
+/* pi4_ref_part_idc : pointer current 4x4 part ref_idc */
+/* pv_motion_pred : pointer to current 4x4 part mv pred */
+/* i4_listx : lists to be processed */
+/* i4_part_frm_x: horz location in the picture of the */
+/* current sub partition */
+/* i4_part_frm_y: vertical location in the picture of the */
+/* current sub partition */
+/* Globals : */
+/* Processing : it stores the default values if the refernce indx of */
+/* ref lyr partiton is -1. if not it upscales the motion */
+/* vectors based on scale factors. it takes care of cropping*/
+/* change flag */
+/* Outputs : it stores the interlayer MV pred in the structure */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_interlyr_motion_scale(void *pv_comp_mode_mv_ctxt, WORD32 *pi4_ref_part_idc,
+ dec_mb_info_t *ps_mb_params, void *pv_motion_pred,
+ WORD32 i4_listx, WORD32 i4_part_frm_x, WORD32 i4_part_frm_y,
+ void **ppv_map_ref_idx_to_poc)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. derive the offsets form part idc */
+ /*! 2. takes the motion vector and scales it based on scale factor */
+ /*! 3. adds the correction factors for crop window change cases */
+ /*! 4. store the default motion params for intra projected blocks */
+
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ mv_pred_t *ps_motion_pred;
+ mv_pred_t *ps_ref_mv;
+ WORD32 i4_lists;
+ WORD32 i4_ref_16x16_flag = 0;
+ WORD32 i4_scale_x, i4_scale_y;
+ WORD16 i2_max_mv_x, i2_max_mv_y;
+
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ /* ----------- Get the reference layer MV structure ---------- */
+ {
+ mv_pred_t *ps_ref_lyr_motion_prms;
+ WORD32 i4_ref_x, i4_ref_y;
+ WORD32 i4_ref_mb_x, i4_ref_mb_y;
+ WORD32 i4_ref_width;
+
+ ps_ref_lyr_motion_prms = (mv_pred_t *) ps_lyr_mem->pv_ref_mv_bank_l0;
+ i4_ref_width = ps_lyr_mem->i4_ref_width;
+ i2_max_mv_x = i4_ref_width << 2;
+ i2_max_mv_y = ps_lyr_mem->i4_ref_height << 2;
+
+ /* extract the reference x and y positions */
+ i4_ref_x = (*pi4_ref_part_idc) & 0xFFFF;
+ i4_ref_y = (*pi4_ref_part_idc) >> 16;
+
+ /* get the reference mb x and y */
+ i4_ref_mb_x = (i4_ref_x >> 4);
+ i4_ref_mb_y = (i4_ref_y >> 4);
+
+ /* get the reference layer motion struct pointing */
+ /* to first 4x4 partition of the refernce layer MB */
+ ps_ref_mv = ps_ref_lyr_motion_prms + (i4_ref_mb_x << 4);
+ ps_ref_mv += (i4_ref_mb_y * i4_ref_width);
+
+ /* if reference layer mb type is non 16x16 */
+ if(0 == i4_ref_16x16_flag)
+ {
+ /* increment the pointer to appropaite 4x4 */
+ ps_ref_mv += ((i4_ref_x >> 2) & 0x03);
+ ps_ref_mv += (((i4_ref_y >> 2) & 0x03) << 2);
+ }
+ }
+
+ /* motion pred structure */
+ ps_motion_pred = pv_motion_pred;
+
+ /* retrive the scale factors */
+ i4_scale_x = ps_lyr_mem->i4_scale_mv_x;
+ i4_scale_y = ps_lyr_mem->i4_scale_mv_y;
+
+ /* loop on the lists given as input */
+ for(i4_lists = 0; i4_lists < i4_listx; i4_lists++)
+ {
+ WORD32 i4_mv_x, i4_mv_y;
+ WORD16 i2_mv_x, i2_mv_y;
+
+ /* if the refernce index is -1 set the default values */
+ if(-1 == ps_ref_mv->i1_ref_frame[i4_lists])
+ {
+ ps_motion_pred->i1_ref_frame[i4_lists] = -1;
+ ps_motion_pred->i2_mv[2 * i4_lists] = 0;
+ ps_motion_pred->i2_mv[1 + 2 * i4_lists] = 0;
+ }
+ else
+ {
+ /* field MB and field pictures modification are present */
+ /* currently not implemented */
+ ps_motion_pred->i1_ref_frame[i4_lists] = ps_ref_mv->i1_ref_frame[i4_lists];
+
+ i2_mv_x = ps_ref_mv->i2_mv[2 * i4_lists];
+ i2_mv_y = ps_ref_mv->i2_mv[1 + 2 * i4_lists];
+ i2_mv_x = CLIP3(-i2_max_mv_x, i2_max_mv_x, i2_mv_x);
+ i2_mv_y = CLIP3(-i2_max_mv_y, i2_max_mv_y, i2_mv_y);
+ /* scale the motion vectors */
+ i4_mv_x = (i2_mv_x * i4_scale_x + 32768) >> 16;
+ i4_mv_y = (i2_mv_y * i4_scale_y + 32768) >> 16;
+
+ /* store the final motion vectors */
+ ps_motion_pred->i2_mv[2 * i4_lists] = i4_mv_x;
+ ps_motion_pred->i2_mv[1 + 2 * i4_lists] = i4_mv_y;
+
+ /* if cropping change flag is present */
+ if(SVCD_TRUE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_cropping_change_flag)
+ {
+ /* over write the motion vectors x and y */
+ isvcd_motion_scale_crop_wdw_change(ps_ctxt, ps_lyr_mem, ps_mb_params, ps_ref_mv,
+ ps_motion_pred, i4_listx, i4_part_frm_x,
+ i4_part_frm_y, ppv_map_ref_idx_to_poc, i4_lists);
+ }
+ }
+ } /* end of lists loop */
+
+ return (i4_ref_16x16_flag);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_store_motion_map */
+/* */
+/* Description : this fucntion copies the souce structure contents to */
+/* destination entires of part width x part height */
+/* */
+/* Inputs : pv_motion_pred : pointer to the source structure */
+/* ps_curr_lyr_motion_map : pointer to the destination */
+/* in the map */
+/* i4_src_stride : source stride */
+/* i4_dst_stride : destination stride */
+/* i4_part_width : width to be copied in terms of sub mbs */
+/* i4_part_height : height to be copied */
+/* i4_src_update_flag : source update flag */
+/* Globals : none */
+/* Processing : it copies the src contents to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_store_motion_map(void *pv_motion_pred, void *pv_curr_lyr_motion_map,
+ WORD32 i4_src_stride, WORD32 i4_dst_stride, WORD32 i4_part_width,
+ WORD32 i4_part_height, WORD32 i4_src_update_flag)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. loops over part_width and part_height */
+ /*! 2. copies the src params toi destination */
+ /*! 3. updates the source pointer if src_update flag is set to 1 */
+
+ WORD32 i4_i, i4_j;
+ mv_pred_t *ps_mv_pred_src;
+ mv_pred_t *ps_mv_map_dst;
+
+ ps_mv_pred_src = (mv_pred_t *) pv_motion_pred;
+ ps_mv_map_dst = (mv_pred_t *) pv_curr_lyr_motion_map;
+
+ /* store the current motion pred to all the motion map structures */
+ for(i4_i = 0; i4_i < i4_part_height; i4_i++)
+ {
+ for(i4_j = 0; i4_j < i4_part_width; i4_j++)
+ {
+ /* copy form source to destination */
+ *(ps_mv_map_dst + i4_j) = *(ps_mv_pred_src + (i4_src_update_flag * i4_j));
+
+ } /* end of loop over partition width */
+
+ ps_mv_map_dst += i4_dst_stride;
+ ps_mv_pred_src += (i4_src_stride * i4_src_update_flag);
+
+ } /* end of loop over partition height */
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_check_mv_diff */
+/* */
+/* Description :this function calculates the MV diff b/w to motion vectors*/
+/* and returns 1 if it is under threshold */
+/* */
+/* Inputs : pv_motion_prm_a : pointer to motion struct part A */
+/* pv_motion_prm_b : pointer to motion struct part B */
+/* i4_listx : lists to be checked */
+/* i4_actual_threshold : threshold with which the mv diff */
+/* is to be compared with */
+/* Globals : none */
+/* Processing : it calculates the mv diff and compares it with threshold */
+/* returns 1 if under threshold */
+/* Outputs : none */
+/* Returns : 1 if under threshold 0 if not under threshold */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_check_mv_diff(void *pv_motion_prm_a, void *pv_motion_prm_b, WORD32 i4_listx,
+ WORD32 i4_actual_threshold)
+{
+ mv_pred_t *ps_part_a;
+ mv_pred_t *ps_part_b;
+ WORD32 i4_cntr;
+ WORD32 i4_mv_treshold;
+ WORD32 i4_flag;
+
+ ps_part_a = (mv_pred_t *) pv_motion_prm_a;
+ ps_part_b = (mv_pred_t *) pv_motion_prm_b;
+
+ i4_flag = 1;
+ for(i4_cntr = 0; i4_cntr < i4_listx; i4_cntr++)
+ {
+ /* calculate the absolute diff of both components */
+ i4_mv_treshold = ABS((ps_part_a->i2_mv[2 * i4_cntr]) - (ps_part_b->i2_mv[2 * i4_cntr]));
+ i4_mv_treshold +=
+ ABS((ps_part_a->i2_mv[1 + (2 * i4_cntr)]) - (ps_part_b->i2_mv[1 + (2 * i4_cntr)]));
+
+ if(i4_actual_threshold < i4_mv_treshold)
+ {
+ i4_flag = 0;
+ break;
+ }
+
+ } /* end of loop over lists */
+ return (i4_flag);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interlayer_motion_submbmode_pred */
+/* */
+/* Description : this function does the inter layer motion predcition for */
+/* all sub partitions of a macro block */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : motion mode handle */
+/* pv_mb_params : pointer to MB params structure */
+/* ai4_ref_part_idc : ref partitons idc of all 4x4 blocks */
+/* pi4_sub_mb_mode : pointer to store the sub mb modes */
+/* i4_mb_addr : current mb address */
+/* pi4_intra_flag : location to store the intra status */
+/* Globals : none */
+/* Processing : it computes the motion vectors and futher modifictaion is*/
+/* done for NON -DYAdic cases */
+/* Outputs : inter layer predicted motion vectors and ref indices */
+/* sub mbmodes of the 4 mb partitions */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interlyr_motion_submbmode_pred(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, WORD32 ai4_ref_part_idc[4][4],
+ WORD32 *pi4_sub_mb_mode, void *pv_dec)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. if dyadic case it calculates the motion vectors based on dyadic
+ scale factor and loop counts calculated at layer level */
+ /*! 2. if non dyadic then it calculates the motion vectors based on
+ reference layer part idc */
+ /*! 3. does the motion vector modification for non dyayic cases, by
+ calculating the minimum positive of reference indices of 4 4x4
+ blocks and getiing a single reference index for 8x8 */
+ /*! 4. if direct 8x8 inference is present and current slice is
+ B OR EB, then it stores the corner motion vectors for each 8x8 */
+ /*! 5. does the sub mb mode prediction and merging of motion vectors
+ which are closely related by setting appropriate thresholds
+ for MVs */
+ /*! 6. stores the sub mb modes in the array given as input */
+
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ mv_pred_t *ps_motion_pred;
+ dec_mb_info_t *ps_mb_params;
+ dec_svc_mb_info_t *ps_svc_mb_params;
+ WORD32 i4_blk_y, i4_blk_x;
+ WORD32 i4_i;
+ WORD32 i4_listx;
+ WORD32 i4_mv_treshold;
+ WORD32 ai4_temp_ref_indx[NUM_REF_LISTS][NUM_MB_PARTS] = {0};
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_mb_pic_x, i4_mb_pic_y;
+ dec_struct_t *ps_dec;
+
+ ps_dec = (dec_struct_t *) pv_dec;
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+ ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
+ ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
+
+ i4_listx = ps_ctxt->i4_listx;
+
+ /* derive the MB_X and MB_Y for the current MB */
+ i4_mb_x = ps_mb_params->u2_mbx;
+ i4_mb_y = ps_mb_params->u2_mby;
+
+ /* convert into picture units */
+ i4_mb_pic_x = i4_mb_x << 4;
+ i4_mb_pic_y = i4_mb_y << 4;
+
+ /* compute the motion vectors and reference indices of all part */
+ for(i4_blk_y = 0; i4_blk_y < NUM_SUB_MB_PARTS; i4_blk_y++)
+ {
+ for(i4_blk_x = 0; i4_blk_x < NUM_SUB_MB_PARTS; i4_blk_x++)
+ {
+ isvcd_interlyr_motion_scale(pv_comp_mode_mv_ctxt, &ai4_ref_part_idc[i4_blk_y][i4_blk_x],
+ ps_mb_params, (ps_motion_pred + (4 * i4_blk_y) + i4_blk_x),
+ i4_listx, (i4_mb_pic_x + (i4_blk_x << 2) + 1),
+ (i4_mb_pic_y + (i4_blk_y << 2) + 1),
+ ps_dec->ppv_map_ref_idx_to_poc);
+
+ } /* end of blk x loop */
+ } /* end of blk y loop */
+
+ /********************************************************/
+ /* get the final reference index into a temparory array */
+ /********************************************************/
+
+ /* set reference indices */
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ ai4_temp_ref_indx[i4_i][0] = ps_motion_pred[0].i1_ref_frame[i4_i];
+ ai4_temp_ref_indx[i4_i][1] = ps_motion_pred[2].i1_ref_frame[i4_i];
+ ai4_temp_ref_indx[i4_i][2] = ps_motion_pred[8].i1_ref_frame[i4_i];
+ ai4_temp_ref_indx[i4_i][3] = ps_motion_pred[10].i1_ref_frame[i4_i];
+
+ } /* end of loop over lists */
+
+ /* if restricted spatial resolution change is not set */
+ if(SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag)
+ {
+ WORD32 i4_xp, i4_yp;
+ WORD32 i4_xs, i4_ys;
+
+ /* merge reference indices and modify the motion vectors */
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ for(i4_yp = 0; i4_yp < 2; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 2; i4_xp++)
+ {
+ /* get the minimum positive of the refernce index */
+ for(i4_ys = 0; i4_ys < 2; i4_ys++)
+ {
+ for(i4_xs = 0; i4_xs < 2; i4_xs++)
+ {
+ mv_pred_t *ps_temp;
+ ps_temp = ps_motion_pred + (i4_xp << 1) + i4_xs;
+ ps_temp += 4 * ((i4_yp << 1) + i4_ys);
+
+ /* get the minimum positive */
+ ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] =
+ isvcd_get_min_positive(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp],
+ ps_temp->i1_ref_frame[i4_i]);
+ }
+ }
+ /* update motion vectors */
+ for(i4_ys = 0; i4_ys < 2; i4_ys++)
+ {
+ for(i4_xs = 0; i4_xs < 2; i4_xs++)
+ {
+ mv_pred_t *ps_temp;
+ ps_temp = ps_motion_pred + (i4_xp << 1) + i4_xs;
+ ps_temp += 4 * ((i4_yp << 1) + i4_ys);
+
+ /* check if the current part reference index is */
+ /* not choosen as the final reference index */
+ /* if not copy the neighbours MV */
+ if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] !=
+ ps_temp->i1_ref_frame[i4_i])
+ {
+ mv_pred_t *ps_temp_1;
+ WORD32 i4_updated_flag = SVCD_FALSE;
+
+ ps_temp_1 = ps_motion_pred + (i4_xp << 1) + (1 - i4_xs);
+ ps_temp_1 += 4 * ((i4_yp << 1) + i4_ys);
+
+ /* store the appropriate neighbours */
+ if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] ==
+ ps_temp_1->i1_ref_frame[i4_i])
+ {
+ ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
+
+ ps_temp->i2_mv[1 + (2 * i4_i)] =
+ ps_temp_1->i2_mv[1 + (2 * i4_i)];
+ i4_updated_flag = SVCD_TRUE;
+ }
+
+ if(SVCD_FALSE == i4_updated_flag)
+ {
+ ps_temp_1 = ps_motion_pred + (i4_xp << 1) + i4_xs;
+
+ ps_temp_1 += 4 * ((i4_yp << 1) + 1 - i4_ys);
+
+ if(ai4_temp_ref_indx[i4_i][2 * i4_yp + i4_xp] ==
+ ps_temp_1->i1_ref_frame[i4_i])
+ {
+ ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
+
+ ps_temp->i2_mv[1 + (2 * i4_i)] =
+ ps_temp_1->i2_mv[1 + (2 * i4_i)];
+ i4_updated_flag = SVCD_TRUE;
+ }
+ }
+ if(SVCD_FALSE == i4_updated_flag)
+ {
+ ps_temp_1 = ps_motion_pred + (i4_xp << 1) + (1 - i4_xs);
+ ps_temp_1 += 4 * ((i4_yp << 1) + 1 - i4_ys);
+
+ ps_temp->i2_mv[2 * i4_i] = ps_temp_1->i2_mv[2 * i4_i];
+
+ ps_temp->i2_mv[1 + (2 * i4_i)] =
+ ps_temp_1->i2_mv[1 + (2 * i4_i)];
+
+ i4_updated_flag = SVCD_TRUE;
+ }
+ } /* end of replacement of mv based on ref indx */
+ } /* end of loop over sub partition xs */
+ } /* end of loop over sub partition ys */
+ } /* end of loop over partition xp */
+ } /* end of loop over partition yp */
+ } /* end of loop over lists */
+ }
+
+ /************************************************************************/
+ /* if restircted saptial resolution change flag is 0 */
+ /* modify the reference indixes and motion vectors */
+ /************************************************************************/
+ if((SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) &&
+ (2 == i4_listx) && (SVCD_TRUE == ps_ctxt->u1_direct_8x8_inference_flag))
+ {
+ /* only applicable for EB Slice */
+ /* store the corner 4x4 motion vectors to the whole block */
+ /* 2 lists and 4 partitions */
+ mot_vec_t s_temp_mv[2][4];
+ WORD32 i4_xp, i4_yp;
+ memset(&s_temp_mv[0][0], 0, sizeof(s_temp_mv));
+
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ s_temp_mv[i4_i][0].i2_mv_x = ps_motion_pred[0].i2_mv[2 * i4_i];
+ s_temp_mv[i4_i][0].i2_mv_y = ps_motion_pred[0].i2_mv[1 + (2 * i4_i)];
+
+ s_temp_mv[i4_i][1].i2_mv_x = ps_motion_pred[3].i2_mv[2 * i4_i];
+ s_temp_mv[i4_i][1].i2_mv_y = ps_motion_pred[3].i2_mv[1 + (2 * i4_i)];
+
+ s_temp_mv[i4_i][2].i2_mv_x = ps_motion_pred[12].i2_mv[2 * i4_i];
+ s_temp_mv[i4_i][2].i2_mv_y = ps_motion_pred[12].i2_mv[1 + (2 * i4_i)];
+
+ s_temp_mv[i4_i][3].i2_mv_x = ps_motion_pred[15].i2_mv[2 * i4_i];
+ s_temp_mv[i4_i][3].i2_mv_y = ps_motion_pred[15].i2_mv[1 + (2 * i4_i)];
+
+ } /* end of loop over lists */
+
+ /* replace the motion vectors */
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ for(i4_yp = 0; i4_yp < 4; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 4; i4_xp++)
+ {
+ mv_pred_t *ps_temp;
+ ps_temp = ps_motion_pred + i4_xp;
+ ps_temp += 4 * i4_yp;
+
+ ps_temp->i2_mv[2 * i4_i] =
+ s_temp_mv[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)].i2_mv_x;
+
+ ps_temp->i2_mv[1 + (2 * i4_i)] =
+ s_temp_mv[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)].i2_mv_y;
+
+ } /* end of loop over sub partitions xp */
+ } /* end of loop over sub partitions yp */
+ } /* end of loop over lists */
+ }
+
+ /* store the final reference index for all sub partitions */
+ /* approporiate reference index is stored for each 4x4 belonging to 8x8 */
+ {
+ WORD32 i4_xp, i4_yp;
+
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ for(i4_yp = 0; i4_yp < 4; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 4; i4_xp++)
+ {
+ mv_pred_t *ps_temp;
+ ps_temp = ps_motion_pred + i4_xp;
+ ps_temp += 4 * i4_yp;
+
+ ps_temp->i1_ref_frame[i4_i] =
+ ai4_temp_ref_indx[i4_i][2 * (i4_yp >> 1) + (i4_xp >> 1)];
+
+ } /* end of loop over partition xp */
+ } /* end of loop over partition yp */
+ } /* end of loop over lists */
+ }
+
+ /********************************************************************/
+ /* modify the motion vectors for non dyadic cases, set the mv */
+ /* threshold appropraitely to derive the sub MB type */
+ /********************************************************************/
+ if(SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag)
+ {
+ /* non dyadic cases set the mv treshold to 1 */
+ i4_mv_treshold = 1;
+ }
+ else
+ {
+ /* dyadic cases set the mv treshold to 0 */
+ i4_mv_treshold = 0;
+ }
+
+ /* modify the motion vectors and get sub mb mode if base mode flag is 1 */
+ if((SVCD_FALSE == ps_lyr_mem->ps_curr_lyr_res_prms->u1_rstrct_res_change_flag) ||
+ (1 == ps_svc_mb_params->u1_base_mode_flag))
+ {
+ WORD32 i4_xp, i4_yp;
+ for(i4_yp = 0; i4_yp < 2; i4_yp++)
+ {
+ for(i4_xp = 0; i4_xp < 2; i4_xp++)
+ {
+ mv_pred_t *ps_temp;
+ WORD32 i4_part_size = 0;
+ WORD32 i4_horz1_match, i4_vert1_match;
+ WORD32 i4_horz2_match, i4_vert2_match;
+ WORD32 i4_diag_match;
+
+ WORD32 i4_8x8_match, i4_horz_match, i4_vert_match;
+ WORD32 i4_mv_x, i4_mv_y;
+
+ ps_temp = ps_motion_pred + (i4_xp << 1);
+ ps_temp += 4 * ((i4_yp << 1));
+
+ /* default init */
+ i4_8x8_match = i4_horz_match = i4_vert_match = SVCD_TRUE;
+
+ /* check if the mv diff in horz direction is under threshold*/
+ i4_horz1_match =
+ isvcd_check_mv_diff(ps_temp, (ps_temp + 1), i4_listx, i4_mv_treshold);
+
+ i4_horz2_match =
+ isvcd_check_mv_diff((ps_temp + 4), (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
+
+ /* check if the mv diff in horz direction is under threshold*/
+ i4_vert1_match =
+ isvcd_check_mv_diff(ps_temp, (ps_temp + 4), i4_listx, i4_mv_treshold);
+
+ i4_vert2_match =
+ isvcd_check_mv_diff((ps_temp + 1), (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
+
+ /* check if in diagonal direction is under threshold*/
+ i4_diag_match =
+ isvcd_check_mv_diff(ps_temp, (ps_temp + 4 + 1), i4_listx, i4_mv_treshold);
+
+ /* calculate the excat matching points*/
+ i4_8x8_match = i4_8x8_match && i4_horz1_match && i4_vert1_match && i4_diag_match;
+ i4_horz_match = i4_horz_match && i4_horz1_match && i4_horz2_match;
+ i4_vert_match = i4_vert_match && i4_vert1_match && i4_vert2_match;
+
+ /* modify the motion vectors appropriately */
+
+ for(i4_i = 0; i4_i < i4_listx; i4_i++)
+ {
+ /* 8x8 mode all the 4 blocks are under threshold */
+ if(SVCD_TRUE == i4_8x8_match)
+ {
+ /* calculate the avarage */
+ i4_mv_x =
+ ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[1].i2_mv[2 * i4_i]) +
+ (ps_temp[4].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 2)) >>
+ 2;
+
+ i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[1].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[4].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 2)) >>
+ 2;
+
+ /* store the modified motion vectors */
+ ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+
+ ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+
+ /* store the sub mb partition size */
+ i4_part_size = SUBMB_8x8;
+ }
+ /* 8x4 mode */
+ else if(SVCD_TRUE == i4_horz_match)
+ {
+ /* horizontal directional merging */
+ /* calculate the average of first two and store back*/
+ i4_mv_x =
+ ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[1].i2_mv[2 * i4_i] + 1)) >> 1;
+
+ i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[1].i2_mv[1 + (2 * i4_i)] + 1)) >>
+ 1;
+
+ ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+
+ ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+
+ /* calculate the average of next two and store back*/
+ i4_mv_x =
+ ((ps_temp[4].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 1)) >> 1;
+
+ i4_mv_y = ((ps_temp[4].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 1)) >>
+ 1;
+
+ ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+
+ ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ /* store the sub mb partition size */
+ i4_part_size = SUBMB_8x4;
+ }
+ /* 4x8 mode all the 4 blocks are under threshold */
+ else if(SVCD_TRUE == i4_vert_match)
+ {
+ /* vertical directional merging */
+ i4_mv_x =
+ ((ps_temp[0].i2_mv[2 * i4_i]) + (ps_temp[4].i2_mv[2 * i4_i] + 1)) >> 1;
+
+ i4_mv_y = ((ps_temp[0].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[4].i2_mv[1 + (2 * i4_i)] + 1)) >>
+ 1;
+
+ ps_temp[0].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[4].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+
+ ps_temp[0].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[4].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+
+ /* calculate the average of next two and store back*/
+ i4_mv_x =
+ ((ps_temp[1].i2_mv[2 * i4_i]) + (ps_temp[5].i2_mv[2 * i4_i] + 1)) >> 1;
+
+ i4_mv_y = ((ps_temp[1].i2_mv[1 + (2 * i4_i)]) +
+ (ps_temp[5].i2_mv[1 + (2 * i4_i)] + 1)) >>
+ 1;
+
+ ps_temp[1].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+ ps_temp[5].i2_mv[2 * i4_i] = (WORD16) i4_mv_x;
+
+ ps_temp[1].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ ps_temp[5].i2_mv[1 + (2 * i4_i)] = (WORD16) i4_mv_y;
+ /* store the sub mb partition size */
+ i4_part_size = SUBMB_4x8;
+ }
+ else
+ {
+ /* store the sub mb partition size */
+ i4_part_size = SUBMB_4x4;
+ }
+
+ } /* end of loop over lists */
+
+ /* store the sub MB type B slice */
+ if(2 == i4_listx)
+ {
+ WORD32 i4_part_mode_a;
+ WORD32 i4_indx;
+
+ i4_part_mode_a = 0;
+ /* check the 0th partiton reference indices */
+ if(0 <= ps_temp[0].i1_ref_frame[0])
+ {
+ i4_part_mode_a += 1;
+ }
+ if(0 <= ps_temp[0].i1_ref_frame[1])
+ {
+ i4_part_mode_a += 2;
+ }
+ i4_indx = 3 * i4_part_size + (i4_part_mode_a - 1);
+
+ pi4_sub_mb_mode[2 * i4_yp + i4_xp] = g_au1_eb_submb_type[i4_indx];
+ }
+ /* P slice */
+ else
+ {
+ pi4_sub_mb_mode[2 * i4_yp + i4_xp] = g_au1_ep_submb_type[i4_part_size];
+ }
+ } /* end of loop over partition xp */
+
+ } /* end of loop over partition yp */
+ }
+
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interlyr_mbmode_pred_bmb */
+/* */
+/* Description : this module does the mode predcition for base mode B_MB */
+/* */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : motion mode hanldle */
+/* Globals : none */
+/* Processing : it checks the sub MB type derived motion prediction. if */
+/* all partitions are 8x8 then it goes further matching */
+/* finally it stores the MB type using a look up table */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interlyr_mbmode_pred_bmb(mode_motion_ctxt_t *ps_ctxt, mv_pred_t *ps_motion_pred,
+ WORD32 i4_cur_mot_stride, WORD32 i4_part_size,
+ WORD32 *pi4_sub_mb_mode, void *pv_mb_params, void *pv_part,
+ UWORD8 *pu1_col_info)
+{
+ WORD32 i4_part_mode_a, i4_part_mode_b;
+ WORD32 i4_idx;
+ dec_mb_info_t *ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+ parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
+
+ UNUSED(ps_ctxt);
+
+ i4_part_mode_a = 0;
+
+ /* check the 0th partiton reference indices */
+ if(PRED_8x8 != i4_part_size)
+ {
+ if(0 <= ps_motion_pred[0].i1_ref_frame[0])
+ {
+ i4_part_mode_a += 1;
+ }
+ if(0 <= ps_motion_pred[0].i1_ref_frame[1])
+ {
+ i4_part_mode_a += 2;
+ }
+ }
+
+ /* check the 15th partiton reference indices */
+ /* this done since all the reference indices will be replicated */
+ i4_part_mode_b = 0;
+
+ if((PRED_16x8 == i4_part_size) || (PRED_8x16 == i4_part_size))
+ {
+ ps_motion_pred += (3 * i4_cur_mot_stride) + 3;
+
+ if(0 <= ps_motion_pred[0].i1_ref_frame[0])
+ {
+ i4_part_mode_b += 1;
+ }
+ if(0 <= ps_motion_pred[0].i1_ref_frame[1])
+ {
+ i4_part_mode_b += 2;
+ }
+ }
+ /* update the pred modes for B cases */
+ /* If partition size is not equal to 8x8 */
+ /* then update the prediciton mode of */
+ /* partitions */
+ if(PRED_8x8 != i4_part_size)
+ {
+ UWORD8 u1_pred_mode_part0;
+ UWORD8 u1_pred_mode_part1;
+
+ i4_idx = 3 * i4_part_size;
+ i4_idx += 3 * (i4_part_mode_a - 1);
+ i4_part_mode_b = (i4_part_mode_b > 0) ? i4_part_mode_b : 1;
+ i4_idx += (i4_part_mode_b - 1);
+ i4_idx = (i4_idx < 0) ? 0 : i4_idx;
+ /* Get the mb type */
+ /* From mb type - get prediciton modes */
+ /* of parttions */
+ /* Update the prediciton mode parma of */
+ /* mb param structure */
+
+ ps_mb_params->u1_mb_type = g_au1_eb_mb_type[i4_idx + (6 * i4_part_size)];
+ u1_pred_mode_part0 = g_au1_mb_pred_mode[0][5 + ps_mb_params->u1_mb_type];
+ u1_pred_mode_part1 = g_au1_mb_pred_mode[1][5 + ps_mb_params->u1_mb_type];
+ ps_part[0].u1_pred_mode = u1_pred_mode_part0;
+ ps_part[1].u1_pred_mode = u1_pred_mode_part1;
+ }
+ else
+ {
+ WORD32 i4_i, i4_ctr, i4_num_submb_part;
+ UWORD8 u1_sub_mb_type, u1_sub_mb_mc_mode;
+ UWORD8 u1_pred_mode;
+
+ ps_mb_params->u1_mb_type = B_8x8;
+
+ for(i4_i = 0; i4_i < NUM_MB_PARTS; i4_i++)
+ {
+ u1_sub_mb_type = (UWORD8) pi4_sub_mb_mode[i4_i];
+
+ u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[4 + u1_sub_mb_type];
+ i4_num_submb_part = g_au1_num_sub_mb_part[u1_sub_mb_mc_mode];
+ *pu1_col_info |= (u1_sub_mb_mc_mode << 4);
+ pu1_col_info++;
+ u1_pred_mode = g_au1_sub_mb_pred_mode[4 + u1_sub_mb_type];
+ for(i4_ctr = 0; i4_ctr < i4_num_submb_part; i4_ctr++)
+ {
+ ps_part->u1_pred_mode = u1_pred_mode;
+ ps_part++;
+ }
+ }
+ }
+
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_populate_ref_idx */
+/* */
+/* Description : this module populates the reference idx based on the */
+/* motion prediction flags */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_populate_ref_idx(dec_mb_info_t *ps_mb_params, dec_svc_mb_info_t *ps_svc_mb_params,
+ mv_pred_t *ps_motion_pred, parse_pmbarams_t *ps_mb_part_info,
+ WORD32 i4_listx)
+{
+ UWORD8 u1_mot_pred_flag;
+ WORD32 i4_lx;
+
+ for(i4_lx = 0; i4_lx < i4_listx; i4_lx++)
+ {
+ u1_mot_pred_flag = ps_svc_mb_params->au1_motion_pred_flag[i4_lx];
+
+ if((PRED_16x16 == ps_mb_params->u1_mb_mc_mode) && (u1_mot_pred_flag & 0x1))
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
+ }
+ else if((PRED_8x16 == ps_mb_params->u1_mb_mc_mode))
+ {
+ if(u1_mot_pred_flag & 0x01)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
+ }
+ if(u1_mot_pred_flag & 0x02)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[2].i1_ref_frame[i4_lx];
+ }
+ }
+ else if((PRED_16x8 == ps_mb_params->u1_mb_mc_mode))
+ {
+ if(u1_mot_pred_flag & 0x01)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
+ }
+ if(u1_mot_pred_flag & 0x02)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[8].i1_ref_frame[i4_lx];
+ }
+ }
+ else if((PRED_8x8 == ps_mb_params->u1_mb_mc_mode))
+ {
+ if(u1_mot_pred_flag & 0x01)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][0] = ps_motion_pred[0].i1_ref_frame[i4_lx];
+ }
+ if(u1_mot_pred_flag & 0x02)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][1] = ps_motion_pred[2].i1_ref_frame[i4_lx];
+ }
+ if(u1_mot_pred_flag & 0x04)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][2] = ps_motion_pred[8].i1_ref_frame[i4_lx];
+ }
+ if(u1_mot_pred_flag & 0x08)
+ {
+ ps_mb_part_info->i1_ref_idx[i4_lx][3] = ps_motion_pred[10].i1_ref_frame[i4_lx];
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_interlayer_mbmode_pred */
+/* */
+/* Description : this module does the mode predcition for base mode MB */
+/* */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : motion mode hanldle */
+/* pv_mb_params : pointer to MB params structure */
+/* pi4_sub_mb_mode: pointer to sub mbmodes predicted */
+/* Globals : none */
+/* Processing : it checks the sub MB type derived motion prediction. if */
+/* all partitions are 8x8 then it goes further matching */
+/* finally it stores the MB type using a look up table */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interlyr_mbmode_pred(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ WORD32 *pi4_sub_mb_mode, WORD32 *pi4_mb_mode, void *pv_dec,
+ void *pv_mb_part_info, void *pv_part)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. it checks if all the sub mb modes are 8x8 modes */
+ /*! 2. it matches the motion vectors at 8x8 level and computes the
+ partiton size. store the same in the part type of mb params */
+ /*! 3. stores the pred modes based on slcie type and reference indices */
+ /*! 4. stores the sub mb type in the mb params if teh part size is 8x8 */
+ mode_motion_ctxt_t *ps_ctxt;
+ mv_pred_t *ps_motion_pred;
+ dec_mb_info_t *ps_mb_params;
+ WORD32 i4_listx;
+ WORD32 i4_part_size;
+ WORD32 i4_mb_mode_flag;
+ WORD32 i4_i;
+ WORD32 i4_blk_mode;
+ parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
+ parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
+ UWORD8 *pu1_col_info = ps_mb_part_info->u1_col_info;
+ UNUSED(pv_dec);
+
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+ ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
+ ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+
+ /*********** store the MB mode as inter *************************/
+ *pi4_mb_mode = SVC_INTER_MB;
+
+ /***********************************************************************/
+ /* derivation of part type */
+ /***********************************************************************/
+ i4_listx = ps_ctxt->i4_listx;
+
+ /* set the mb mode derivation flag to false */
+ i4_mb_mode_flag = SVCD_FALSE;
+
+ /* for B and P slice different blk mod treshold */
+ if(2 == i4_listx)
+ {
+ i4_blk_mode = B_BI_8x8;
+ }
+ else
+ {
+ i4_blk_mode = P_L0_8x8;
+ }
+
+ /* set the mode derivation flag to true base on conditions */
+ if((i4_blk_mode >= pi4_sub_mb_mode[0]) && (i4_blk_mode >= pi4_sub_mb_mode[1]) &&
+ (i4_blk_mode >= pi4_sub_mb_mode[2]) && (i4_blk_mode >= pi4_sub_mb_mode[3]))
+ {
+ i4_mb_mode_flag = SVCD_TRUE;
+ }
+
+ /* store the default 8x8 mode */
+ ps_mb_part_info->u1_num_part = 4;
+ i4_part_size = PRED_8x8;
+
+ /* further check is present if all are 8x8 mode */
+ if(SVCD_TRUE == i4_mb_mode_flag)
+ {
+ WORD32 i4_horz_match, i4_vert_match;
+
+ /* check if the motion in horz direction are same*/
+ i4_horz_match = isvcd_check_motion(ps_motion_pred, (ps_motion_pred + 2), i4_listx);
+ i4_horz_match += isvcd_check_motion((ps_motion_pred + 8), (ps_motion_pred + 10), i4_listx);
+
+ /* check if the motion in vertical direction is same */
+ i4_vert_match = isvcd_check_motion(ps_motion_pred, (ps_motion_pred + 8), i4_listx);
+ i4_vert_match += isvcd_check_motion((ps_motion_pred + 2), (ps_motion_pred + 10), i4_listx);
+
+ /* decide the partition size based on the results of matching */
+ if((2 == i4_horz_match) && (2 == i4_vert_match))
+ {
+ ps_mb_params->u1_mb_type = P_L0_16x16;
+ i4_part_size = PRED_16x16;
+ ps_mb_part_info->u1_num_part = 1;
+ *pu1_col_info++ = (PRED_16x16 << 6);
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ if(2 == i4_listx) ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+
+ ps_part->u1_partwidth = 4; // interms of 4x4
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+ }
+ else if(2 == i4_horz_match)
+ {
+ i4_part_size = PRED_16x8;
+ ps_mb_params->u1_mb_type = P_L0_L0_16x8;
+ ps_mb_part_info->u1_num_part = 2;
+ *pu1_col_info++ = (PRED_16x8 << 6);
+ *pu1_col_info++ = (PRED_16x8 << 6);
+
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[8].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[8].i1_ref_frame[1];
+ }
+ ps_part->u1_partwidth = 4; // interms of 4x4
+ ps_part->u1_partheight = 2;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+
+ ps_part++;
+ ps_part->u1_partwidth = 4;
+ ps_part->u1_partheight = 2;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 8;
+ }
+ else if(2 == i4_vert_match)
+ {
+ ps_mb_params->u1_mb_type = P_L0_L0_8x16;
+ i4_part_size = PRED_8x16;
+ ps_mb_part_info->u1_num_part = 2;
+ *pu1_col_info++ = (PRED_8x16 << 6);
+ *pu1_col_info++ = (PRED_8x16 << 6);
+
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
+ }
+ ps_part->u1_partwidth = 2; // interms of 4x4
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+
+ ps_part++;
+ ps_part->u1_partwidth = 2;
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 2;
+ }
+ }
+
+ /* store the part size to the mb params */
+ ps_mb_params->u1_mb_mc_mode = i4_part_size;
+
+ /* in case of slice derive the partition modes */
+
+ {
+ /* store the sub MB modes if 8x8 mode is choosen */
+ if(PRED_8x8 == i4_part_size)
+ {
+ UWORD8 u1_sub_mb_type, u1_sub_mb_mc_mode = 0;
+
+ /* for P_MB sub part type is same as sub mb type */
+ ps_mb_params->u1_mb_type = P_8x8;
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred[0].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][2] = ps_motion_pred[8].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][3] = ps_motion_pred[10].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred[0].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][2] = ps_motion_pred[8].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][3] = ps_motion_pred[10].i1_ref_frame[1];
+ }
+
+ ps_mb_part_info->u1_num_part = 0;
+ for(i4_i = 0; i4_i < NUM_MB_PARTS; i4_i++)
+ {
+ WORD32 i4_num_submb_part, i4_part_width, i4_part_height, i4_ctr;
+ u1_sub_mb_type = (UWORD8) pi4_sub_mb_mode[i4_i];
+
+ if(1 == i4_listx)
+ {
+ u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[u1_sub_mb_type];
+ }
+ else if(2 == i4_listx)
+ {
+ u1_sub_mb_mc_mode = gau1_ih264d_submb_mc_mode[4 + u1_sub_mb_type];
+ }
+ i4_num_submb_part = g_au1_num_sub_mb_part[u1_sub_mb_mc_mode];
+
+ ps_mb_part_info->u1_num_part += i4_num_submb_part;
+
+ i4_part_width = g_au1_sub_mb_part_wd[u1_sub_mb_mc_mode];
+ i4_part_height = g_au1_sub_mb_part_ht[u1_sub_mb_mc_mode];
+ *pu1_col_info++ = (PRED_8x8 << 6) | (u1_sub_mb_mc_mode << 4);
+ for(i4_ctr = 0; i4_ctr < i4_num_submb_part; i4_ctr++)
+ {
+ ps_part->u1_partwidth = i4_part_width; // interms of 4x4
+ ps_part->u1_partheight = i4_part_height;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = (i4_i & 0x01) * 2 + (i4_i >> 1) * 8;
+ if(i4_num_submb_part == 2)
+ {
+ ps_part->u1_sub_mb_num +=
+ i4_ctr ? (((i4_part_width - 1) << 2) + (i4_part_height - 1)) : 0;
+ }
+ else if(i4_num_submb_part == 4)
+ {
+ ps_part->u1_sub_mb_num += ((i4_ctr >> 1) << 2) + (i4_ctr & 0x01);
+ }
+
+ ps_part++;
+ }
+ }
+ }
+ if(2 == i4_listx)
+ {
+ ps_part = (parse_part_params_t *) pv_part;
+ pu1_col_info = ps_mb_part_info->u1_col_info;
+ /* B_MBs */
+ isvcd_interlyr_mbmode_pred_bmb(ps_ctxt, ps_motion_pred, 4, i4_part_size,
+ pi4_sub_mb_mode, ps_mb_params, ps_part, pu1_col_info);
+ }
+ }
+
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_interlayer_motion_mode */
+/* */
+/* Description : this function does the inter layer motion and mode */
+/* prediction. of the current MB */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : mode motion handle */
+/* pv_ref_layer_motion_mem_elements : pointer to memory */
+/* elements of reference layer motion params */
+/* pv_mb_params : pointer to mb params structure */
+/* Globals : none */
+/* Processing : it calls the module for cal ref part idc and intra flag */
+/* if not intra it calls the motion prediction module */
+/* if base mdoe flag then it call teh mode prediction module*/
+/* Outputs : inter layer predicted parameters */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_compute_interlyr_motion_mode(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, void *pv_dec,
+ void *pv_mb_part_info, void *pv_part)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. if dyaydic case then it sets the sub mb mode to 8x8 */
+ /*! 2. else it call the ref part idc comute fucntion */
+ /*! 3. it calls the motion vectors and submb mode derive function.
+ if the current mb is not inffered as INTRA */
+ /*! 4. it calls the mode predcition module if base mode flag is 1 */
+
+ mode_motion_ctxt_t *ps_ctxt;
+ WORD32 i4_intra_flag;
+ WORD32 ai4_sub_mb_mode[NUM_MB_PARTS] = {0};
+ dec_mb_info_t *ps_mb_params;
+ dec_svc_mb_info_t *ps_svc_mb_params;
+ dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
+ WORD32 i4_mb_mode = -1;
+ parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
+ parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
+
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+ ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+ ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
+
+ i4_intra_flag = SVCD_FALSE;
+
+ isvcd_ref_lyr_part_idc(pv_comp_mode_mv_ctxt, ps_ctxt->ai4_ref_part_idc, &i4_intra_flag,
+ pv_mb_params);
+
+ /* If base is Intra */
+ if(SVCD_TRUE == i4_intra_flag)
+ {
+ if(1 == ps_svc_mb_params->u1_base_mode_flag)
+ {
+ i4_mb_mode = SVC_IBL_MB;
+ ps_svc_mb_params->u1_residual_prediction_flag = 0;
+ }
+ }
+ else
+ {
+ /* derive the motion and reference index by inter layer predcition */
+ isvcd_interlyr_motion_submbmode_pred(pv_comp_mode_mv_ctxt, ps_mb_params, ps_svc_mb_params,
+ ps_ctxt->ai4_ref_part_idc, ai4_sub_mb_mode, pv_dec);
+
+ /* derive the MB mode */
+ if(1 == ps_svc_mb_params->u1_base_mode_flag)
+ {
+ isvcd_interlyr_mbmode_pred(pv_comp_mode_mv_ctxt, pv_mb_params, ai4_sub_mb_mode,
+ &i4_mb_mode, ps_dec, ps_mb_part_info, ps_part);
+ }
+ else
+ {
+ isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_ctxt->ps_motion_pred_struct,
+ ps_mb_part_info, ps_ctxt->i4_listx);
+ }
+ }
+
+ return i4_mb_mode;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interlyr_motion_mode_pred_dyadic */
+/* */
+/* Description : this function does the inter layer motion predcition for */
+/* dyadic cases */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt : motion mode handle */
+/* pv_ref_layer_motion_mem_elements : pointer to memory */
+/* elements of reference layer motion params */
+/* pv_mb_params : pointer to MB params structure */
+/* ai4_ref_part_idc : ref partitons idc of all 4x4 blocks */
+/* pi4_sub_mb_mode : pointer to store the sub mb modes */
+/* i4_mb_addr : current mb address */
+/* pi4_intra_flag : location to store the intra status */
+/* Globals : none */
+/* Processing : it computes the motion vectors and */
+/* Outputs : inter layer predicted motion vectors and ref indices */
+/* sub mbmodes of the 4 mb partitions */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_interlyr_motion_mode_pred_dyadic(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, void *pv_dec,
+ void *pv_mb_part_info, void *pv_part)
+{
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ dec_mb_info_t *ps_mb_params;
+ dec_svc_mb_info_t *ps_svc_mb_params;
+ WORD32 i4_listx;
+ WORD32 i4_mb_pic_x, i4_mb_pic_y;
+ WORD32 i4_ref_x, i4_ref_y;
+ UWORD8 u1_base_mode_flag;
+ dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
+ WORD32 i4_mb_mode = -1;
+ parse_pmbarams_t *ps_mb_part_info = (parse_pmbarams_t *) pv_mb_part_info;
+ UWORD8 *pu1_col_info = ps_mb_part_info->u1_col_info;
+ parse_part_params_t *ps_part = (parse_part_params_t *) pv_part;
+
+ ps_ctxt = (mode_motion_ctxt_t *) pv_comp_mode_mv_ctxt;
+
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ ps_mb_params = (dec_mb_info_t *) pv_mb_params;
+ ps_svc_mb_params = (dec_svc_mb_info_t *) pv_svc_mb_params;
+ i4_listx = ps_ctxt->i4_listx;
+
+ {
+ WORD32 i4_mb_x, i4_mb_y;
+ /* derive the MB_X and MB_Y for the current MB */
+ i4_mb_x = ps_mb_params->u2_mbx;
+ i4_mb_y = ps_mb_params->u2_mby;
+
+ /* get the colocated position in the refernce layer */
+ i4_ref_x = ps_lyr_mem->pi2_ref_loc_x[i4_mb_x << 4];
+ i4_ref_y = ps_lyr_mem->pi2_ref_loc_y[i4_mb_y << 4];
+ i4_ref_x = CLIP3(0, ((ps_lyr_mem->i4_ref_width) - 1), i4_ref_x);
+ i4_ref_y = CLIP3(0, ((ps_lyr_mem->i4_ref_height) - 1), i4_ref_y);
+
+ /* convert into picture units */
+ i4_mb_pic_x = i4_mb_x << 4;
+ i4_mb_pic_y = i4_mb_y << 4;
+ }
+
+ /* ref layer mb mode */
+ {
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD32 i4_inter_lyr_mb_prms_stride;
+ WORD32 i4_ref_mb_x, i4_ref_mb_y;
+ WORD8 i1_ref_mb_mode;
+
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_lyr_mem->s_ref_mb_mode.pv_buffer;
+ i4_inter_lyr_mb_prms_stride = ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride;
+
+ /* get the reference mb x and y */
+ i4_ref_mb_x = (i4_ref_x >> 4);
+ i4_ref_mb_y = (i4_ref_y >> 4);
+
+ /* get the appropriate mb params in reference layer */
+ ps_inter_lyr_mb_prms += i4_ref_mb_x;
+ ps_inter_lyr_mb_prms += i4_ref_mb_y * i4_inter_lyr_mb_prms_stride;
+ i1_ref_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+ u1_base_mode_flag = ps_svc_mb_params->u1_base_mode_flag;
+
+ /* check if the MB mode of the refernce MB is Intra*/
+ if(i1_ref_mb_mode > SVC_INTER_MB)
+ {
+ if(1 == u1_base_mode_flag)
+ {
+ i4_mb_mode = SVC_IBL_MB;
+ ps_svc_mb_params->u1_residual_prediction_flag = 0;
+ }
+ return i4_mb_mode;
+ }
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Inter MB upsampling process */
+ /*-----------------------------------------------------------------------*/
+ {
+ mv_pred_t *ps_motion_pred;
+ WORD32 i4_16x16_flag;
+ WORD32 i4_part_idc;
+ WORD32 i4_blk_idx;
+ WORD32 i4_curr_mot_stride;
+
+ /* choose the appropriate mv bank pointer and stride */
+ if(1 == u1_base_mode_flag)
+ {
+ i4_mb_mode = SVC_INTER_MB;
+ }
+
+ ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
+ i4_curr_mot_stride = 4;
+
+ /* call the motion upsampling for 1st 4x4 */
+ i4_part_idc = (i4_ref_y << 16) + i4_ref_x;
+ i4_16x16_flag = isvcd_interlyr_motion_scale(
+ pv_comp_mode_mv_ctxt, &i4_part_idc, ps_mb_params, ps_motion_pred, i4_listx,
+ (i4_mb_pic_x + 1), (i4_mb_pic_y + 1), ps_dec->ppv_map_ref_idx_to_poc);
+
+ /* ---------- reference layer MB is 16x16 ------------------*/
+ if(i4_16x16_flag)
+ {
+ if(1 == u1_base_mode_flag)
+ {
+ ps_mb_params->u1_mb_type = P_L0_16x16;
+ ps_mb_params->u1_mb_mc_mode = PRED_16x16;
+ ps_mb_part_info->u1_num_part = 1;
+ *pu1_col_info++ = (PRED_16x16 << 6);
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+
+ ps_part->u1_partwidth = 4; // interms of 4x4
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+
+ if(2 == i4_listx)
+ {
+ WORD32 i4_part_mode_a = 0;
+ WORD32 i4_temp;
+
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+ if(0 <= ps_motion_pred[0].i1_ref_frame[0])
+ {
+ i4_part_mode_a += 1;
+ }
+ if(0 <= ps_motion_pred[0].i1_ref_frame[1])
+ {
+ i4_part_mode_a += 2;
+ }
+
+ i4_temp = 3 * PRED_16x16;
+ i4_temp += (3 * (i4_part_mode_a - 1) - 1);
+ i4_temp = (i4_temp < 0) ? 0 : i4_temp;
+ i4_temp = g_au1_eb_mb_type[i4_temp];
+ ps_mb_params->u1_mb_type = i4_temp;
+ ps_part->u1_pred_mode = g_au1_mb_pred_mode[0][5 + i4_temp];
+ }
+ }
+ else
+ {
+ /* motion prediction flag cases replicate the motion vectors for entire MB */
+ isvcd_store_motion_map(ps_motion_pred, (ps_motion_pred), 0, i4_curr_mot_stride,
+ NUM_MB_PARTS, NUM_MB_PARTS, SVCD_FALSE);
+
+ isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_motion_pred,
+ ps_mb_part_info, i4_listx);
+ }
+ return i4_mb_mode;
+ }
+ /* ---------- reference layer MB is non 16x16 ------------------ */
+ else
+ {
+ WORD32 ai4_sub_mb_mode[NUM_MB_PARTS] = {0};
+
+ /* replicate the motion vectors for 8x8 */
+ isvcd_store_motion_map(ps_motion_pred, ps_motion_pred, 0, i4_curr_mot_stride, 2, 2,
+ SVCD_FALSE);
+
+ if(2 == i4_listx)
+ {
+ WORD32 i4_indx = 0;
+
+ /* replicate the motion vectors for 8x8 */
+ /* check the 0th partiton reference indices */
+ if(0 <= ps_motion_pred[0].i1_ref_frame[0])
+ {
+ i4_indx += 1;
+ }
+ if(0 <= ps_motion_pred[0].i1_ref_frame[1])
+ {
+ i4_indx += 2;
+ }
+
+ i4_indx = 3 * PRED_8x8 + (i4_indx - 1);
+ ai4_sub_mb_mode[0] = g_au1_eb_submb_type[i4_indx];
+ }
+
+ /* derive the motion vectors and reference indices of 3 rem partitions */
+ for(i4_blk_idx = 1; i4_blk_idx < NUM_MB_PARTS; i4_blk_idx++)
+ {
+ WORD32 i4_blk_y, i4_blk_x;
+ mv_pred_t *ps_temp;
+
+ i4_blk_x = i4_blk_idx & 1;
+ i4_blk_y = i4_blk_idx >> 1;
+
+ ps_temp = ps_motion_pred + (i4_blk_x << 1);
+ ps_temp += (i4_blk_y * i4_curr_mot_stride << 1);
+
+ /* store the reference layer positions */
+ i4_part_idc = ((i4_ref_y + (i4_blk_y << 2)) << 16) + (i4_ref_x + (i4_blk_x << 2));
+ isvcd_interlyr_motion_scale(pv_comp_mode_mv_ctxt, &i4_part_idc, ps_mb_params,
+ ps_temp, i4_listx, (i4_mb_pic_x + (i4_blk_x << 2) + 1),
+ (i4_mb_pic_y + (i4_blk_y << 2) + 1),
+ ps_dec->ppv_map_ref_idx_to_poc);
+
+ /* replicate the motion vectors for 8x8 */
+ isvcd_store_motion_map(ps_temp, ps_temp, 0, i4_curr_mot_stride, 2, 2, SVCD_FALSE);
+
+ if(2 == i4_listx)
+ {
+ WORD32 i4_indx = 0;
+
+ /* check the 0th partiton reference indices */
+ if(0 <= ps_temp[0].i1_ref_frame[0])
+ {
+ i4_indx += 1;
+ }
+ if(0 <= ps_temp[0].i1_ref_frame[1])
+ {
+ i4_indx += 2;
+ }
+
+ i4_indx = 3 * PRED_8x8 + (i4_indx - 1);
+
+ ai4_sub_mb_mode[i4_blk_idx] = g_au1_eb_submb_type[i4_indx];
+ }
+ }
+
+ /* if MB mode has to derivied */
+ if(1 == u1_base_mode_flag)
+ {
+ WORD32 i4_horz_match, i4_vert_match;
+ WORD32 i4_part_size = PRED_8x8;
+
+ mv_pred_t *ps_motion_1;
+ mv_pred_t *ps_motion_2;
+ mv_pred_t *ps_motion_3;
+
+ ps_motion_1 = ps_motion_pred + 2;
+ ps_motion_2 = ps_motion_pred + (i4_curr_mot_stride << 1);
+ ps_motion_3 = ps_motion_2 + 2;
+
+ /* check if the motion in horz direction are same*/
+ i4_horz_match = isvcd_check_motion(ps_motion_pred, ps_motion_1, i4_listx);
+ i4_horz_match += isvcd_check_motion(ps_motion_2, ps_motion_3, i4_listx);
+
+ /* check if the motion in vertical direction is same */
+ i4_vert_match = isvcd_check_motion(ps_motion_pred, ps_motion_2, i4_listx);
+ i4_vert_match += isvcd_check_motion(ps_motion_1, ps_motion_3, i4_listx);
+
+ ps_mb_part_info->u1_num_part = 4;
+
+ /* decide the partition size based on the results of matching */
+ if((2 == i4_horz_match) && (2 == i4_vert_match))
+ {
+ ps_mb_params->u1_mb_type = P_L0_16x16;
+ i4_part_size = PRED_16x16;
+ ps_mb_part_info->u1_num_part = 1;
+ *pu1_col_info++ = (PRED_16x16 << 6);
+
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ if(2 == i4_listx)
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+
+ ps_part->u1_partwidth = 4; // interms of 4x4
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+ }
+ else if(2 == i4_horz_match)
+ {
+ ps_mb_params->u1_mb_type = P_L0_L0_16x8;
+ i4_part_size = PRED_16x8;
+ ps_mb_part_info->u1_num_part = 2;
+ *pu1_col_info++ = (PRED_16x8 << 6);
+ *pu1_col_info++ = (PRED_16x8 << 6);
+
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[8].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[8].i1_ref_frame[1];
+ }
+ ps_part->u1_partwidth = 4; // interms of 4x4
+ ps_part->u1_partheight = 2;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+
+ ps_part++;
+ ps_part->u1_partwidth = 4;
+ ps_part->u1_partheight = 2;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 8;
+ }
+ else if(2 == i4_vert_match)
+ {
+ ps_mb_params->u1_mb_type = P_L0_L0_8x16;
+ i4_part_size = PRED_8x16;
+ ps_mb_part_info->u1_num_part = 2;
+ *pu1_col_info++ = (PRED_8x16 << 6);
+ *pu1_col_info++ = (PRED_8x16 << 6);
+
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred->i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred->i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
+ }
+ ps_part->u1_partwidth = 2; // interms of 4x4
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 0;
+
+ ps_part++;
+ ps_part->u1_partwidth = 2;
+ ps_part->u1_partheight = 4;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = 2;
+ }
+
+ /* store the part size to the mb params */
+ ps_mb_params->u1_mb_mc_mode = i4_part_size;
+
+ /* store the sub partition size */
+ if(PRED_8x8 == i4_part_size)
+ {
+ UWORD8 u1_ctr;
+ /* for P_MB sub part type is P_L0_8x8*/
+
+ ps_mb_params->u1_mb_type = P_8x8;
+ ps_mb_part_info->i1_ref_idx[0][0] = ps_motion_pred[0].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][1] = ps_motion_pred[2].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][2] = ps_motion_pred[8].i1_ref_frame[0];
+ ps_mb_part_info->i1_ref_idx[0][3] = ps_motion_pred[10].i1_ref_frame[0];
+ if(2 == i4_listx)
+ {
+ ps_mb_part_info->i1_ref_idx[1][0] = ps_motion_pred[0].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][1] = ps_motion_pred[2].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][2] = ps_motion_pred[8].i1_ref_frame[1];
+ ps_mb_part_info->i1_ref_idx[1][3] = ps_motion_pred[10].i1_ref_frame[1];
+ }
+
+ for(u1_ctr = 0; u1_ctr < 4; u1_ctr++)
+ {
+ *pu1_col_info++ = (PRED_8x8 << 6);
+
+ ps_part->u1_partwidth = 2; // interms of 4x4
+ ps_part->u1_partheight = 2;
+ ps_part->u1_pred_mode = PRED_L0;
+ ps_part->u1_is_direct = 0;
+ ps_part->u1_sub_mb_num = (u1_ctr & 0x01) * 2 + (u1_ctr >> 1) * 8;
+ ps_part++;
+ }
+ }
+
+ if(2 == i4_listx)
+ {
+ ps_part = (parse_part_params_t *) pv_part;
+ pu1_col_info = ps_mb_part_info->u1_col_info;
+ isvcd_interlyr_mbmode_pred_bmb(ps_ctxt, ps_motion_pred, i4_curr_mot_stride,
+ i4_part_size, &ai4_sub_mb_mode[0], ps_mb_params,
+ ps_part, pu1_col_info);
+ }
+ } /* end of mode derivation */
+ else
+ {
+ isvcd_populate_ref_idx(ps_mb_params, ps_svc_mb_params, ps_motion_pred,
+ ps_mb_part_info, i4_listx);
+
+ } /* non 16x16 mv mode derivation */
+ }
+ }
+ return i4_mb_mode;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_scaled_offsets */
+/* */
+/* Description : this module does the projection of the current layer */
+/* points (x,0) and (0,y) on to the reference layer and */
+/* gets the 1/16 sample of the reference location */
+/* x ranges from 0 - frame width */
+/* y ranges from 0 - frame height */
+/* this projection is done for LUMA only */
+/* Inputs : ps_curr_lyr_slice_prms: pointer to current layer slice */
+/* parameters */
+/* ps_ref_lyr_slice_prms: pointer to ref layer slice prms */
+/* pi2_offset_x : pointer to store x projected */
+/* pi2_offset_y : pointer to store y projected */
+/* Globals : none */
+/* Processing : it store the projected values for those points in the */
+/* crop window */
+/* Outputs : projected locations */
+/* Returns : none */
+/* */
+/* Issues : assumes that outside crop window no projection */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_compute_scaled_offsets(res_prms_t *ps_curr_res_prms, res_prms_t *ps_ref_res_prms,
+ WORD16 *pi2_offset_x, WORD16 *pi2_offset_y, UWORD8 u1_level_idc)
+{
+ WORD32 i4_offset_x, i4_offset_y;
+ UWORD32 i4_scaled_ref_lyr_width;
+ UWORD32 i4_scaled_ref_lyr_height;
+ UWORD32 i4_ref_lyr_width;
+ UWORD32 i4_ref_lyr_height;
+ UWORD32 i4_shift_x, i4_shift_y;
+ UWORD32 i4_scale_x, i4_scale_y;
+ WORD32 i4_cntr;
+ WORD32 i4_scale_add_x, i4_scale_add_y;
+ WORD32 i4_curr_lyr_width, i4_curr_lyr_height;
+
+ if((NULL == ps_curr_res_prms) || (NULL == ps_ref_res_prms) || (NULL == pi2_offset_x) ||
+ (NULL == pi2_offset_y))
+ {
+ return NOT_OK;
+ }
+ /* initial calculation */
+ i4_offset_x = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
+ i4_offset_y = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
+
+ /* get the width and height */
+ i4_scaled_ref_lyr_width = ps_curr_res_prms->u2_scaled_ref_width;
+ i4_scaled_ref_lyr_height = ps_curr_res_prms->u2_scaled_ref_height;
+ i4_ref_lyr_width = ps_ref_res_prms->i4_res_width;
+ i4_ref_lyr_height = ps_ref_res_prms->i4_res_height;
+ i4_curr_lyr_width = ps_curr_res_prms->i4_res_width;
+ i4_curr_lyr_height = ps_curr_res_prms->i4_res_height;
+
+ /* derive shift x and y based on level idd */
+ if(u1_level_idc <= 30)
+ {
+ i4_shift_x = 16;
+ i4_shift_y = 16;
+ }
+ else
+ {
+ i4_shift_x = 31 - isvcd_get_ceil_log2(i4_ref_lyr_width);
+ i4_shift_y = 31 - isvcd_get_ceil_log2(i4_ref_lyr_height);
+ }
+
+ /* assert on max ranges of width and shift values */
+ if((i4_ref_lyr_width > H264_MAX_FRAME_WIDTH) ||
+ (i4_scaled_ref_lyr_width > H264_MAX_FRAME_WIDTH) ||
+ (i4_ref_lyr_height > H264_MAX_FRAME_HEIGHT) ||
+ (i4_scaled_ref_lyr_height > H264_MAX_FRAME_HEIGHT) ||
+ (i4_curr_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_curr_lyr_height > H264_MAX_FRAME_HEIGHT))
+ {
+ return NOT_OK;
+ }
+
+ /* calculate scale factor x and y */
+ i4_scale_x = (((UWORD32) i4_ref_lyr_width << i4_shift_x) + (i4_scaled_ref_lyr_width >> 1)) /
+ i4_scaled_ref_lyr_width;
+
+ i4_scale_y = (((UWORD32) i4_ref_lyr_height << i4_shift_y) + (i4_scaled_ref_lyr_height >> 1)) /
+ i4_scaled_ref_lyr_height;
+
+ /* calcualte the values to be added based on left and top offset */
+ i4_scale_add_x = (1 << (i4_shift_x - 1)) - (i4_offset_x * (WORD32) i4_scale_x);
+ i4_scale_add_y = (1 << (i4_shift_y - 1)) - (i4_offset_y * (WORD32) i4_scale_y);
+
+ /* derive the projected locations in the reference layer */
+ for(i4_cntr = 0; i4_cntr < i4_curr_lyr_width; i4_cntr++)
+ {
+ WORD32 i4_ref_x;
+ i4_ref_x = (i4_cntr * i4_scale_x + i4_scale_add_x) >> i4_shift_x;
+ *pi2_offset_x++ = (WORD16) i4_ref_x;
+ }
+
+ /* derive the projected locations in the reference layer */
+ for(i4_cntr = 0; i4_cntr < i4_curr_lyr_height; i4_cntr++)
+ {
+ WORD32 i4_ref_y;
+ i4_ref_y = (i4_cntr * i4_scale_y + i4_scale_add_y) >> i4_shift_y;
+ *pi2_offset_y++ = (WORD16) i4_ref_y;
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_comp_mode_mv_res_init */
+/* */
+/* Description : this function calculates the scale factors and initialise*/
+/* the context structure */
+/* */
+/* Inputs : pv_comp_mode_mv_ctxt: handle to private structure */
+/* ps_curr_lyr_res_prms: pointer to current resolution */
+/* params */
+/* pi2_ref_loc_x : pointer to buffer having the */
+/* projected locations horz */
+/* pi2_ref_loc_y : pointer to buffer having the */
+/* projected location vertical */
+/* Globals : none */
+/* Processing : it calculates the scale factors and stores it */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_comp_mode_mv_res_init(void *pv_svc_dec)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. calculates the scale factors for dyadic cases */
+ /*! 2. calculaets the loop counts and part width and height based on
+ dyadic scale factor */
+ /*! 2. calculate the MV scale factors */
+ /*! 3. initialises the default mv ped structure with deafult values */
+
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+ dec_seq_params_t *ps_sps;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ svc_dec_lyr_struct_t *ps_svc_dec_ref_layer;
+ WORD32 ret;
+ WORD32 i4_scaled_ref_lyr_width;
+ WORD32 i4_scaled_ref_lyr_height;
+ WORD32 i4_ref_lyr_width;
+ WORD32 i4_ref_lyr_height;
+ res_prms_t *ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
+
+ ps_svc_dec_ref_layer = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
+ if(NULL == ps_curr_lyr_res_prms)
+ {
+ return NOT_OK;
+ }
+
+ ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
+ ps_ctxt->u1_direct_8x8_inference_flag = ps_curr_lyr_res_prms->u1_direct_8x8_inference_flag;
+
+ /* if called for base resolution store deafult values */
+ if(SVCD_TRUE == ps_svc_lyr_dec->u1_base_res_flag)
+ {
+ ps_ctxt->i4_res_id = -1;
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+ return OK;
+ }
+
+ /* call the function which populates the projected ref locations */
+ ps_sps = ps_dec->ps_cur_sps;
+
+ /* store the res id appropriately */
+ ps_ctxt->i4_res_id = ps_svc_lyr_dec->u1_layer_id - 1;
+
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ /* store the current and reference res params to the context */
+ ps_lyr_mem->ps_curr_lyr_res_prms = ps_curr_lyr_res_prms;
+
+ /* store the reference layer mv bank pointer */
+ ps_lyr_mem->pv_ref_mv_bank_l0 = ps_svc_dec_ref_layer->s_dec.s_cur_pic.ps_mv;
+
+ /* store the reference layer mb mode pointer */
+ ps_lyr_mem->s_ref_mb_mode.pv_buffer = ps_svc_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
+ ps_lyr_mem->s_ref_mb_mode.i4_num_element_stride =
+ ps_svc_dec_ref_layer->u2_inter_lyr_mb_prms_stride;
+ ps_lyr_mem->s_ref_mb_mode.i4_element_size = sizeof(inter_lyr_mb_prms_t);
+
+ /* check for recomputation of mapping required */
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ res_prms_t s_ref_res_prms = {0};
+
+ /* store the reference layer resolution width and height */
+ s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
+ s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
+
+ /* call projection map calculation function */
+ ret = isvcd_compute_scaled_offsets(ps_curr_lyr_res_prms, &s_ref_res_prms,
+ ps_lyr_mem->pi2_ref_loc_x, ps_lyr_mem->pi2_ref_loc_y,
+ ps_sps->u1_level_idc);
+ if(OK != ret)
+ {
+ return NOT_OK;
+ }
+
+ /* derive the scaling variables */
+ ps_lyr_mem->i4_offset_x = ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left;
+
+ ps_lyr_mem->i4_offset_y = ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top;
+
+ /* get the width and heights */
+ i4_scaled_ref_lyr_width = ps_curr_lyr_res_prms->u2_scaled_ref_width;
+ i4_scaled_ref_lyr_height = ps_curr_lyr_res_prms->u2_scaled_ref_height;
+ i4_ref_lyr_width = ps_ctxt->i4_ref_width;
+ i4_ref_lyr_height = ps_ctxt->i4_ref_height;
+
+ /*store the reference layer width adn height */
+ ps_lyr_mem->i4_ref_width = ps_ctxt->i4_ref_width;
+ ps_lyr_mem->i4_ref_height = ps_ctxt->i4_ref_height;
+
+ if((i4_ref_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_ref_lyr_width <= 0)) return NOT_OK;
+ if((i4_scaled_ref_lyr_width > H264_MAX_FRAME_WIDTH) || (i4_scaled_ref_lyr_width <= 0))
+ return NOT_OK;
+ if((i4_ref_lyr_height > H264_MAX_FRAME_HEIGHT) || (i4_ref_lyr_height <= 0)) return NOT_OK;
+ if((i4_scaled_ref_lyr_height > H264_MAX_FRAME_HEIGHT) || (i4_scaled_ref_lyr_height <= 0))
+ return NOT_OK;
+
+ /* derivation of variables for dyadic cases cropping should be MB aligned */
+ /* default values for flags */
+ ps_lyr_mem->pf_inter_lyr_pred = &isvcd_compute_interlyr_motion_mode;
+
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_dyadic_flag)
+ {
+ ps_lyr_mem->pf_inter_lyr_pred = &isvcd_interlyr_motion_mode_pred_dyadic;
+ }
+
+ /* Store the Dyadic flag */
+ ps_lyr_mem->i4_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
+
+ /* derive the scaling factors for motion upscaling */
+ /* this is derived assuming no crop change flag is present */
+ ps_lyr_mem->i4_scale_mv_x =
+ ((i4_scaled_ref_lyr_width << 16) + (i4_ref_lyr_width >> 1)) / i4_ref_lyr_width;
+
+ ps_lyr_mem->i4_scale_mv_y =
+ ((i4_scaled_ref_lyr_height << 16) + (i4_ref_lyr_height >> 1)) / i4_ref_lyr_height;
+ }
+ else
+ {
+ /* should take false value */
+ if(SVCD_FALSE != ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ return NOT_OK;
+ }
+ }
+
+ /* store the current layer width and height to context */
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_mode_mv_resamp.h b/decoder/svc/isvcd_mode_mv_resamp.h
new file mode 100644
index 0000000..1edd918
--- /dev/null
+++ b/decoder/svc/isvcd_mode_mv_resamp.h
@@ -0,0 +1,170 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#ifndef _ISVCD_MODE_MV_RESAMPLE_H_
+#define _ISVCD_MODE_MV_RESAMPLE_H_
+
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_mode_mv_resamp.h
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+#define MAX_NEIGHBORS 3 /*!< left top and top right neighbours */
+
+#define LEFT \
+ 0 /*!<Index for accessing the left MB in the \
+ MV predictor array */
+
+#define TOP \
+ 1 /*!< Index for accessing the top MB in the \
+ MV predictor array */
+
+#define TOP_R \
+ 2 /*!< Index for accessing the top right MB \
+ in the MV predictor array */
+
+#define MB_SKIP 255
+
+typedef void ftype_comp_mode_mv_mb(void *pv_comp_mode_mv_hdl, void *pv_mb_params,
+ void *pv_curr_mb_motion_mem_elements,
+ void *pv_top_mb_motion_mem_elements, WORD32 i4_lyr_id);
+
+typedef void(ftype_pred_direct)(void *pv_comp_mode_mv_ctxt, void *pv_top_mb_motion_l0,
+ void *pv_top_mb_motion_l1, void *pv_curr_part_motion_pred_l0,
+ void *pv_curr_part_motion_pred_l1,
+ void *pv_curr_part_motion_params_l0,
+ void *pv_curr_part_motion_params_l1,
+ WORD32 i4_curr_mb_motion_stride, WORD32 i4_availability,
+ WORD32 i4_part_width, WORD32 i4_num_mb_parts,
+ UWORD16 u2_col_zero_flag);
+
+typedef WORD32 ftype_inter_lyr_motion_pred(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, void *ps_dec,
+ void *ps_mb_part_info, void *pv_part);
+
+WORD32 isvcd_interlyr_motion_mode_pred_dyadic(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, void *ps_dec,
+ void *ps_mb_part_info, void *pv_part);
+
+WORD32 isvcd_compute_interlyr_motion_mode(void *pv_comp_mode_mv_ctxt, void *pv_mb_params,
+ void *pv_svc_mb_params, void *ps_dec,
+ void *ps_mb_part_info, void *pv_part);
+
+WORD32 isvcd_comp_mode_mv_res_init(void *pv_svc_dec);
+typedef struct
+{
+ res_prms_t *ps_curr_lyr_res_prms; /*!< pointer to current layer
+ resolution parameters */
+
+ WORD32 i4_offset_x; /*!< scaled ref layer left offset. will
+ be used during mv calculation for crop window change case */
+
+ WORD32 i4_offset_y; /*!< scaled ref layer top offset. will
+ be used during mv calculation for crop window change case */
+
+ WORD32 i4_scale_mv_x; /*!< scale factor x for motion upscaling*/
+
+ WORD32 i4_scale_mv_y; /*!< scale factor y for motion upscaling*/
+
+ WORD32 i4_dyadic_flag; /*!< flag inidcates the
+ dyadic upscaling or non - dyadic upscaling */
+
+ /* projected location pointers */
+ WORD16 *pi2_ref_loc_x; /*!< pointer to the bufer having the
+ projected locations on horizontal direction.This used as look up
+ during calculation of reference locations */
+
+ WORD16 *pi2_ref_loc_y; /*!< pointer to the bufer having the
+ projected locations on vertical direction.This used as look up
+ during calculation of reference locations */
+
+ ref_lyr_scaled_offset_t *ps_ref_pic_lyr_offsets; /*!<
+ array of structure pointer for MAX_NUM_RES - 1 to hold the scaled ref
+ offset of reference picture for each resolution */
+
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms of luma samples */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms of luma samples */
+
+ ftype_inter_lyr_motion_pred *pf_inter_lyr_pred; /*!< function pointer
+ for dyadic optimization*/
+
+ void *pv_ref_mv_bank_l0; /*!< pointer to reference layer MV bank List 0*/
+
+ mem_element_t s_ref_mb_mode; /*!< pointer to reference layer mb mode */
+
+} mode_motion_lyr_ctxt;
+
+typedef struct
+{
+ mv_pred_t *ps_motion_pred_struct; /*!< temporary motion structure
+ array for 16 sub partitions used in both inter layer and spatial
+ MV prediction */
+
+ UWORD8 u1_direct_8x8_inference_flag;
+ /*!< flag to indicate
+ the corner mv have to be inherited in B slice */
+
+ WORD32 i4_listx; /*!< number of lists to be procesed. this
+ is set on B_SLICE or PSLICE */
+
+ /* array to store the ref layer part idc */
+ WORD32 ai4_ref_part_idc[4][4]; /*!< reference layer partition
+ identifications stored of all 16 sub partitions */
+
+ /*!< default mv pred used to store
+ default motion params for intra cases in motion map */
+
+ mode_motion_lyr_ctxt as_res_lyr_mem[MAX_NUM_RES_LYRS]; /*!< array of
+ strcuture each structure for a pair of resolution except the base layer */
+
+ WORD32 i4_res_id; /*!< resolution ID used to access the
+ Layer presistant memory */
+
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples */
+
+ WORD32 ai4_dqid[MAX_NUM_LYRS_IN_RES]; /*! Array of DQID of all the layers in
+ the resolution */
+
+} mode_motion_ctxt_t;
+
+#endif /* _ISVCD_MODE_MV_RESAMPLE_H_ */
diff --git a/decoder/svc/isvcd_nal.c b/decoder/svc/isvcd_nal.c
new file mode 100644
index 0000000..a41c242
--- /dev/null
+++ b/decoder/svc/isvcd_nal.c
@@ -0,0 +1,1256 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal.c
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*****************************************************************************/
+/* */
+/* File Name : isvcd_nal.c */
+/* */
+/* Description : Contains fucntions which help in NAL extraction from */
+/* the bitstream */
+/* */
+/* List of Functions : isvcd_nal_find_start_code, */
+/* isvcd_get_annex_b_nal_unit, */
+/* isvcd_get_rfc_nal_unit, */
+/* isvcd_nal_rbsp_to_sodb, */
+/* isvcd_reset_emulation_ctxt, */
+/* isvcd_nal_byte_swap_emulation, */
+/* isvcd_set_default_nal_header_prms, */
+/* isvcd_dec_nal_hdr, */
+/* isvcd_parse_part_slice_hdr, */
+/* isvcd_get_int_tgt_lyr_attr, */
+/* isvcd_discard_nal */
+/* */
+/* Issues / Problems : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 14 09 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stddef.h>
+#include <assert.h>
+
+/* standard interface include files */
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_tables.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264d_defs.h"
+#include "ih264_debug.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_inter_pred.h"
+#include "isvcd_structs.h"
+#include "ih264d_nal.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_defs.h"
+
+/*****************************************************************************/
+/*Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Global Variable Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Static Global Variable Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Static function Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_reset_nal_buf */
+/* */
+/* Description : Performs the reset of NAL buffer structure */
+/* Inputs : 1. Pointer to NAL buffer structure */
+/* Globals : None */
+/* Processing : Updates different fields of the structure */
+/* Outputs : None */
+/* Returns : */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_nal_buf_reset(void *pv_nal_buf)
+{
+ nal_buf_t *ps_nal_buf = pv_nal_buf;
+
+ ps_nal_buf->i4_valid_flag = SVCD_FALSE;
+ ps_nal_buf->i4_buf_size = 0;
+ ps_nal_buf->u4_max_bits = 0;
+ ps_nal_buf->pu1_buf = NULL;
+}
+/*****************************************************************************/
+/* */
+/* Function Name :svcd_nal_find_start_code */
+/* */
+/* Description : Finds the position of the start code in the stream */
+/* */
+/* */
+/* Inputs : 1. Pointer to buffer start */
+/* 2. start position */
+/* 3. Maximum number of bytes in the buffer */
+/* 4. pointer to zero byte count */
+/* 5. pointer to bytes consumed variable */
+/* Globals : */
+/* Processing : Searches for the start code in the bitstream and updates */
+/* consumed variable */
+/* */
+/* Outputs : Bytes consumed variable */
+/* Returns : If start code is found then it returns SC_FOUND otherwise*/
+/* it returns SC_NOT_FOUND */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_nal_find_start_code(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
+ WORD32 *pi4_zero_cnt, UWORD32 *pu4_bytes_consumed)
+{
+ UWORD8 *pu1_buf = pu1_buf_start + i4_cur_pos;
+ WORD32 i4_i;
+
+ for(i4_i = 0; i4_i < (i4_max_num_bytes - i4_cur_pos); i4_i++)
+ {
+ /*-------------------------------------------------------------------*/
+ /* If zero increment the zero byte counter */
+ /*-------------------------------------------------------------------*/
+ if(0 == *pu1_buf)
+ {
+ (*pi4_zero_cnt)++;
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* If start code found then increment the byte consumed and return */
+ /*-------------------------------------------------------------------*/
+ else if(0x01 == *pu1_buf && *pi4_zero_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE)
+ {
+ (*pu4_bytes_consumed)++;
+ return (SC_FOUND);
+ }
+ /*-------------------------------------------------------------------*/
+ /* If non zero byte and value is not equal to 1 a then reset zero */
+ /* byte counter */
+ /*-------------------------------------------------------------------*/
+ else
+ {
+ *pi4_zero_cnt = 0;
+ }
+
+ (*pu4_bytes_consumed)++;
+ pu1_buf++;
+ }
+
+ return (SC_NOT_FOUND);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_first_start_code */
+/* */
+/* Description : Searches for the first start code in the bitstream */
+/* */
+/* */
+/* Inputs : 1. input buffer structure */
+/* 2. Bytes consumed variable */
+/* Globals : None */
+/* Processing : None */
+/* */
+/* Outputs : Updates bytes consumed variable */
+/* Returns : Start code is found or not */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_get_first_start_code(UWORD8 *pu1_stream_buffer, UWORD32 *pu4_bytes_consumed,
+ UWORD32 *pu4_num_bytes)
+{
+ WORD32 i4_zero_cnt = 0, i4_status;
+ UWORD32 u4_bytes_consumed_temp = 0;
+
+ i4_status = isvcd_nal_find_start_code(pu1_stream_buffer, 0, *pu4_num_bytes, &i4_zero_cnt,
+ &u4_bytes_consumed_temp);
+
+ /*-----------------------------------------------------------------------*/
+ /* If start code is not found then return and start searching for it */
+ /* again in the next process call. This process is repeated till we */
+ /* get a start code */
+ /*-----------------------------------------------------------------------*/
+ if(SC_NOT_FOUND == i4_status)
+ {
+ *pu4_bytes_consumed += u4_bytes_consumed_temp;
+ return (i4_status);
+ }
+ else
+ {
+ /*-------------------------------------------------------------------*/
+ /* If start code found then proceed with bitstream extraction */
+ /*-------------------------------------------------------------------*/
+ *pu4_bytes_consumed += u4_bytes_consumed_temp;
+ return (i4_status);
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_annex_b_nal_unit */
+/* */
+/* Description : This function gets one NAL unit from the Annex B based */
+/* input bitstream */
+/* */
+/* */
+/* Inputs : 1. Input buffer pointer */
+/* 2. Current position in the input buffer */
+/* 3. Input buffer size */
+/* 4. Pointer to state of NAL boundary detection variable */
+/* 5. Pointer to bytes consumed variable */
+/* 6. pointer to nal structure */
+/* Globals : */
+/* Processing : This fucntion searches for start code from the current */
+/* position and once gets one start code it searches for */
+/* another start code to get a NAL unit. */
+/* */
+/* Outputs : Updates the state of NAL boundary detection logic */
+/* Updates the bytes consumed variable from 0 to bytes */
+/* consumed in this call */
+/* Returns : start of nal flag */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_get_annex_b_nal_unit(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
+ WORD32 *pi4_state, WORD32 *pi4_zero_byte_cnt,
+ UWORD32 *pu4_bytes_consumed, void *pv_nal_unit,
+ WORD32 *pi4_more_data_flag)
+{
+ nal_unit_t *ps_nal_unit = (nal_unit_t *) pv_nal_unit;
+ WORD32 i4_status, i4_nal_start_flag = SVCD_FALSE;
+
+ /*-----------------------------------------------------------------------*/
+ /* Initialization */
+ /*-----------------------------------------------------------------------*/
+ *pu4_bytes_consumed = 0;
+ *pi4_more_data_flag = SVCD_TRUE;
+
+ /*------------------------ check ----------------------------------------*/
+ /* Assumptions is that this fucntion should not be called with this state*/
+ /* hence it is responsibility of the caller to reset the state after the */
+ /* NAL_END. */
+ /*-----------------------------------------------------------------------*/
+ if(NAL_END == *pi4_state)
+ {
+ return i4_nal_start_flag;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* ps_nal_unit->apu1_bufs[0] is expected to point to start of buffer of */
+ /* current NAL unit of the current process call. If a NAL unit is frag- */
+ /* -mented across multiple process call then this buffer should point to */
+ /* start address of buffers. But when start of NAL is present in the */
+ /* buffer of current process call then ps_nal_unit->apu1_bufs[0] is */
+ /* expected to point to start adress of NAL unit (should be pointing to) */
+ /* NAL header) */
+ /*-----------------------------------------------------------------------*/
+ ps_nal_unit->pu1_bufs = pu1_buf_start + i4_cur_pos;
+
+ if(NAL_START == *pi4_state)
+ {
+ if(0 != *pi4_zero_byte_cnt)
+ {
+ return i4_nal_start_flag;
+ }
+ i4_nal_start_flag = SVCD_TRUE;
+ ps_nal_unit->i4_num_bufs = 1;
+ ps_nal_unit->i4_buf_sizes = 0;
+ *pi4_state = FIND_NAL_END;
+ }
+
+ i4_status = isvcd_nal_find_start_code(pu1_buf_start, i4_cur_pos, i4_max_num_bytes,
+ pi4_zero_byte_cnt, pu4_bytes_consumed);
+
+ if(SC_NOT_FOUND == i4_status)
+ {
+ /*-------------------------------------------------------------------*/
+ /* If start code is not found then there are 2 possibilities */
+ /* 1. We are in the middle of decoding the start code. This means */
+ /* that we might have decoded the one or 2 zeroes of the start */
+ /* code. In such cases, we should not consume these bytes. Though */
+ /* doing so we might encounter spurious cases where 0's are not */
+ /* actually corresponds to start code but these will not harm us */
+ /* 2. Not of above case. Straightforward one */
+ /*-------------------------------------------------------------------*/
+ ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed;
+ *pi4_more_data_flag = SVCD_FALSE;
+
+ return (i4_nal_start_flag);
+ }
+ else
+ {
+ /*-------------------------------------------------------------------*/
+ /* If NAL END is found then increment the bytes consumed appropriatly*/
+ /* reset the zero byte counter */
+ /*-------------------------------------------------------------------*/
+ *pi4_state = NAL_END;
+ ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed - 1;
+ *pi4_zero_byte_cnt = 0;
+ return (i4_nal_start_flag);
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_rbsp_to_sodb */
+/* */
+/* Description : Converts the RBSP data to SODB data */
+/* */
+/* */
+/* Inputs : 1. Input buffer containing the NAL unit */
+/* 2. Length of NAL unit (in bytes) */
+/* Globals : None */
+/* Processing : Finds the RBSP stop bit, if present then finds the length*/
+/* of SODB data */
+/* */
+/* Outputs : */
+/* Returns : Number of bits in the SODB data */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+UWORD32 isvcd_nal_rbsp_to_sodb(UWORD8 *pu1_buf, WORD32 i4_nal_len_in_bytes, UWORD8 u1_ecd_mode)
+{
+ UWORD32 u4_last_word_pos;
+ UWORD32 u4_word, u4_max_bit_offset;
+ UWORD8 i4_num_bits;
+ WORD32 i4_i;
+ WORD64 i8_nal_len;
+ UWORD32 *pu4_buf;
+
+ if(0 >= i4_nal_len_in_bytes)
+ {
+ return (0);
+ }
+
+ /* Get offset in bits */
+ i8_nal_len = (WORD64) i4_nal_len_in_bytes << 3;
+ u4_max_bit_offset = (UWORD32) i8_nal_len;
+
+ /* If NAL is coded in CABAC then SODB */
+ /* length has to account for CABAC */
+ /* ZERO WORDS also */
+ if(1 == u1_ecd_mode)
+ {
+ return (u4_max_bit_offset);
+ }
+
+ /* Calculate the position of last word */
+ u4_last_word_pos = i4_nal_len_in_bytes >> 2;
+
+ /* Load the last word */
+ i4_i = i4_nal_len_in_bytes & 0x03;
+ if(0 != i4_i)
+ {
+ pu4_buf = (UWORD32 *) pu1_buf;
+ pu4_buf += u4_last_word_pos;
+ u4_word = *pu4_buf;
+ i4_num_bits = i4_i << 3;
+ u4_word >>= (32 - i4_num_bits);
+ }
+ else
+ {
+ pu4_buf = (UWORD32 *) pu1_buf;
+ pu4_buf += (u4_last_word_pos - 1);
+ u4_word = *pu4_buf;
+ i4_num_bits = 32;
+ }
+
+ /* Search for RBSP stop bit */
+ do
+ {
+ for(i4_i = 0; (i4_i < i4_num_bits) && !CHECKBIT(u4_word, i4_i); i4_i++)
+ ;
+
+ u4_max_bit_offset -= i4_i;
+
+ /* RBSP stop bit is found then */
+ /* come out of the loop */
+ if(0 != CHECKBIT(u4_word, i4_i))
+ {
+ /* Remove RBSP stop bit */
+ u4_max_bit_offset -= 1;
+ break;
+ }
+
+ pu4_buf -= 1;
+ u4_word = *pu4_buf;
+ i4_num_bits = 32;
+ } while(u4_max_bit_offset > 0);
+
+ return (u4_max_bit_offset);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_reset_emulation_ctxt */
+/* */
+/* Description : Resets the emulation prevention context structure */
+/* */
+/* Inputs : pv_emulation_ctxt - pointer to emulation prevention */
+/* context structure */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+void isvcd_reset_emulation_ctxt(void *pv_emulation_ctxt)
+{
+ emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
+
+ /*! Reset the emulation prevention context */
+ ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
+ ps_emulation_ctxt->i4_zeroes_cnt = 0;
+ ps_emulation_ctxt->u4_bytes_in_word = 0;
+ ps_emulation_ctxt->u4_word = 0;
+}
+
+/****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_byte_swap_emulation */
+/* */
+/* Description : This function is does byte swap or emulation or both */
+/* in the stream. */
+/* */
+/* Inputs : pu4_out_stream : Pointer to bitstream out buffer */
+/* pu4_out_len : Pointer to variable for out len */
+/* pu1_in_stream : Pointer to bitstream in buffer */
+/* u4_in_len : Input bitstream buffer length */
+/* u4_prev_0s : In case of fragemented NAL 0s in last */
+/* fragmented unit */
+/* u4_0s_bfr_sc : Number of zeros before start code */
+/* u4_bytes : Number of bytes in last fragmented */
+/* word */
+/* u4_word : Last fragmented word */
+/* */
+/* Globals : None */
+/* */
+/* Processing : It has three mode of operations */
+/* 1. Byte Swap and Emulation for H.264 WMV9 AP DEC */
+/* supports both fragmented and non fragmented packets */
+/* set u4_prev_0s = last valid zeros for this operation*/
+/* 2. Byte Swap only for MPEG2 and MPEG4 WMV9 MP DEC */
+/* supports both fragmented and non fragmented packets */
+/* set u4_prev_0s = 0 and u4_0s_bfr_sc = u4_in_len */
+/* 3. Annex B stream */
+/* only non fragmented */
+/* set u4_prev_0s = 0 for this operation */
+/* Outputs : pu4_out_len output length of the bit stream */
+/* */
+/* Returns : Number of zeros in case of framented start code */
+/* */
+/* Known Issues : */
+/* */
+/* Revision History */
+/* */
+/* DD MM YY Author Changes */
+/* 06 09 2021 Vijay */
+/****************************************************************************/
+UWORD32 isvcd_nal_byte_swap_emulation(UWORD32 *pu4_out_stream, UWORD32 *pu4_out_len,
+ UWORD8 *pu1_in_stream, UWORD32 u4_in_len, WORD32 i4_0s_bfr_sc,
+ void *pv_emulation_ctxt)
+{
+ UWORD32 u4_i, u4_num_bytes, u4_offset;
+ UWORD8 u1_cur_byte;
+ emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
+
+ u4_offset = ps_emulation_ctxt->u4_bytes_in_word;
+ u4_num_bytes = ps_emulation_ctxt->u4_bytes_in_word;
+
+ for(u4_i = 0; u4_i < u4_in_len; u4_i++)
+ {
+ UWORD8 u1_cur_byte_emu, u1_cur_byte_sc;
+ UWORD64 u8_sft_word;
+
+ u1_cur_byte = *pu1_in_stream++;
+ u1_cur_byte_emu = (EMULATION_PREVENTION_BYTE == u1_cur_byte);
+ u1_cur_byte_sc = (START_CODE_BYTE == u1_cur_byte);
+
+ if((ps_emulation_ctxt->i4_zeroes_cnt >= i4_0s_bfr_sc) & (u1_cur_byte_emu | u1_cur_byte_sc) &
+ (NOT_STUFFED_BYTE == ps_emulation_ctxt->i4_state))
+ {
+ if(u1_cur_byte_sc)
+ {
+ break;
+ }
+ ps_emulation_ctxt->i4_zeroes_cnt = 0;
+ ps_emulation_ctxt->i4_state = STUFFED_BYTE;
+ continue;
+ }
+
+ u8_sft_word = (UWORD64) ps_emulation_ctxt->u4_word << 8;
+ ps_emulation_ctxt->u4_word = (UWORD32) (u8_sft_word | u1_cur_byte);
+ ps_emulation_ctxt->u4_bytes_in_word++;
+ u4_num_bytes++;
+ ps_emulation_ctxt->i4_zeroes_cnt++;
+ if(u1_cur_byte != 0x00)
+ {
+ ps_emulation_ctxt->i4_zeroes_cnt = 0;
+ }
+
+ if((u4_num_bytes & 0x03) == 0x00)
+ {
+ *pu4_out_stream = ps_emulation_ctxt->u4_word;
+ ps_emulation_ctxt->u4_bytes_in_word = 0;
+ pu4_out_stream++;
+ }
+
+ ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
+ }
+
+ if(ps_emulation_ctxt->u4_bytes_in_word)
+ {
+ UWORD64 temp_out_stream = (UWORD64) ps_emulation_ctxt->u4_word
+ << ((4 - ps_emulation_ctxt->u4_bytes_in_word) << 3);
+ *pu4_out_stream = (UWORD32) temp_out_stream;
+ }
+
+ *pu4_out_len = (u4_num_bytes - u4_offset);
+ return ((u4_num_bytes & 0xFFFFFFFC));
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_set_default_nal_header_prms */
+/* */
+/* Description : Sets the members of NAL header structures to default */
+/* values */
+/* */
+/* Inputs : pv_nal_prms - pointer nal header prms structure */
+/* i4_temp_id - default value of temporal id */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_set_default_nal_prms(void *pv_nal_prms)
+{
+ nal_prms_t *ps_nal_prms;
+ ps_nal_prms = (nal_prms_t *) pv_nal_prms;
+
+ /* Set default values */
+ ps_nal_prms->i4_dependency_id = 0;
+ ps_nal_prms->i4_derived_nal_type = 0xFF;
+ ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
+ ps_nal_prms->i4_nal_header_len = 0;
+ ps_nal_prms->i4_nal_ref_idc = 0xFF;
+ ps_nal_prms->i4_nal_unit_type = 0xFF;
+ ps_nal_prms->i4_no_int_lyr_pred = 1;
+ ps_nal_prms->i4_priority_id = 0;
+ ps_nal_prms->i4_quality_id = 0;
+ ps_nal_prms->i4_discard_flag = 0;
+ ps_nal_prms->i4_dqid = 0;
+ ps_nal_prms->i4_use_ref_base_pic_flag = 0;
+ ps_nal_prms->i4_temporal_id = 0;
+ ps_nal_prms->i4_idr_pic_num = 0;
+ ps_nal_prms->u2_frm_num = 0;
+ ps_nal_prms->i4_poc_lsb = 0;
+ ps_nal_prms->i4_delta_poc_bot = 0;
+ ps_nal_prms->ai4_delta_poc[0] = 0;
+ ps_nal_prms->ai4_delta_poc[1] = 0;
+ ps_nal_prms->u1_pps_id = 0;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_dec_nal_hdr */
+/* */
+/* Description : None */
+/* */
+/* Inputs : pv_buf_ptr - Pointer to buffer constaining start of NAL */
+/* pv_nal_header_buf - Temporray working buffer */
+/* pv_nal_prms - Pointer to nal header prms */
+/* structure */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_dec_nal_hdr(void *pv_buf_ptr, WORD32 i4_buf_size, void *pv_nal_header_buf,
+ void *pv_nal_prms, void *pv_prefix_nal_buf, void *pv_prefix_nal_prms,
+ UWORD32 *pu4_err_code)
+{
+ nal_prms_t *ps_nal_prms;
+ nal_prms_t *ps_prefix_nal_prms;
+ nal_buf_t *ps_prefix_nal_buf;
+ dec_bit_stream_t s_stream_ctxt = {0};
+ WORD32 i4_forbidden_zero_bit;
+
+ /* byte swapping */
+ UWORD8 *pu1_buf = (UWORD8 *) pv_nal_header_buf;
+ UWORD8 *pu1_src = (UWORD8 *) pv_buf_ptr;
+
+ ps_nal_prms = (nal_prms_t *) pv_nal_prms;
+ ps_prefix_nal_prms = (nal_prms_t *) pv_prefix_nal_prms;
+ ps_prefix_nal_buf = (nal_buf_t *) pv_prefix_nal_buf;
+
+ /* The NAL header syntax elements are read through bitstream fucntions. */
+ /* Hence bitstream context structure initializaton is needed before */
+ /* parsing from the bitstream */
+ /* Also bitstream fucntions assume the buffer is byteswapped. Hence the */
+ /* byte swapping is also done for 4 bytes */
+ s_stream_ctxt.u4_ofst = 0;
+ s_stream_ctxt.pu4_buffer = pv_nal_header_buf;
+ s_stream_ctxt.u4_max_ofst = (i4_buf_size << 3);
+
+ *pu4_err_code = 0;
+
+ /* Check the size of bitstream buffer */
+ if(s_stream_ctxt.u4_max_ofst < 8)
+ {
+ *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
+ return;
+ }
+
+ if(s_stream_ctxt.u4_max_ofst >= 32)
+ {
+ *pu1_buf++ = *(pu1_src + 3);
+ *pu1_buf++ = *(pu1_src + 2);
+ *pu1_buf++ = *(pu1_src + 1);
+ *pu1_buf++ = *pu1_src;
+ }
+ else
+ {
+ *pu1_buf++ = *pu1_src;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /*! Parse the NAL header and update the NAL header structure members */
+ /*-----------------------------------------------------------------------*/
+ /* Read forbidden 0 bit */
+ i4_forbidden_zero_bit = ih264d_get_bit_h264(&s_stream_ctxt);
+
+ if(0 != i4_forbidden_zero_bit)
+ {
+ *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
+ return;
+ }
+
+ /*---------------- Read NAL ref idc -----------------------------*/
+ ps_nal_prms->i4_nal_ref_idc = ih264d_get_bits_h264(&s_stream_ctxt, 2);
+
+ /*----------------- Read NAL type -------------------------------*/
+ ps_nal_prms->i4_nal_unit_type = ih264d_get_bits_h264(&s_stream_ctxt, 5);
+ if(ps_nal_prms->i4_nal_unit_type > CODED_SLICE_EXTENSION_NAL)
+ {
+ *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
+ return;
+ }
+ if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
+ {
+ ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
+ return;
+ }
+
+ /* set idr pic flag */
+ if(IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
+ }
+ else
+ {
+ ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
+ }
+
+ /*----------------- Read SVC extension NAL header ---------------*/
+ if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
+ PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ WORD32 i4_svc_extension_flag, i4_idr_flag;
+
+ /* check the size of the buffer */
+ if(s_stream_ctxt.u4_max_ofst < 32)
+ {
+ *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
+ return;
+ }
+
+ i4_svc_extension_flag = ih264d_get_bit_h264(&s_stream_ctxt);
+ UNUSED(i4_svc_extension_flag);
+
+ i4_idr_flag = ih264d_get_bit_h264(&s_stream_ctxt);
+
+ /* Set idr pic flag based on idr flag */
+ if(1 == i4_idr_flag)
+ {
+ ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
+ }
+ else
+ {
+ ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
+ }
+
+ /* parse priorit id */
+ ps_nal_prms->i4_priority_id = ih264d_get_bits_h264(&s_stream_ctxt, 6);
+
+ /* parse the no inter layer prediction flag */
+ ps_nal_prms->i4_no_int_lyr_pred = ih264d_get_bit_h264(&s_stream_ctxt);
+
+ /* parse dependency id */
+ ps_nal_prms->i4_dependency_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
+
+ /* parse quality id */
+ ps_nal_prms->i4_quality_id = ih264d_get_bits_h264(&s_stream_ctxt, 4);
+
+ if((ps_nal_prms->i4_quality_id > 0) || (ps_nal_prms->i4_dependency_id > 2))
+ {
+ *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
+ return;
+ }
+ /* parse temporal id */
+ ps_nal_prms->i4_temporal_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
+
+ /* parse use ref base pic flag */
+ ps_nal_prms->i4_use_ref_base_pic_flag = ih264d_get_bit_h264(&s_stream_ctxt);
+
+ if(0 != ps_nal_prms->i4_use_ref_base_pic_flag)
+ {
+ *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
+ return;
+ }
+ /* parse discrad flag */
+ ps_nal_prms->i4_discard_flag = ih264d_get_bit_h264(&s_stream_ctxt);
+
+ /* parse the reserved bits */
+ ih264d_get_bits_h264(&s_stream_ctxt, 3);
+ }
+
+ /* update NAL hedaer length in bytes */
+ ps_nal_prms->i4_nal_header_len = s_stream_ctxt.u4_ofst >> 3;
+
+ /*************************************************************************/
+ /* PREFIX NAL UNIT ASSOCIATION WITH ASSOCIATED NAL UNIT */
+ /*************************************************************************/
+
+ /* if current NAL is not a AVC NAL unit then */
+ /* discard the prefix NAL unit if present */
+ if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ isvcd_nal_buf_reset(ps_prefix_nal_buf);
+ }
+
+ if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
+ {
+ /* Copy the required parameters from the prefix NAL unit */
+ ps_nal_prms->i4_dependency_id = ps_prefix_nal_prms->i4_dependency_id;
+ ps_nal_prms->i4_quality_id = ps_prefix_nal_prms->i4_quality_id;
+ ps_nal_prms->i4_priority_id = ps_prefix_nal_prms->i4_priority_id;
+ ps_nal_prms->i4_temporal_id = ps_prefix_nal_prms->i4_temporal_id;
+ ps_nal_prms->i4_no_int_lyr_pred = ps_prefix_nal_prms->i4_no_int_lyr_pred;
+ ps_nal_prms->i4_use_ref_base_pic_flag = ps_prefix_nal_prms->i4_use_ref_base_pic_flag;
+ ps_nal_prms->i4_discard_flag = ps_prefix_nal_prms->i4_discard_flag;
+ }
+
+ /*-----------------------------------------------------------------------*/
+ /* Set the derived NAL unit type and also update the DQID for VCL NAL */
+ /* units */
+ /*-----------------------------------------------------------------------*/
+ if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
+ SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
+ IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
+ PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ ps_nal_prms->i4_derived_nal_type = VCL_NAL;
+
+ /* calculate the DQID and modified DQID */
+ ps_nal_prms->i4_dqid = (ps_nal_prms->i4_dependency_id << 4) + ps_nal_prms->i4_quality_id;
+ }
+ else
+ {
+ ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_part_slice_hdr */
+/* */
+/* Description : This routine parses the slice till POC parameters */
+/* */
+/* Inputs : 1. Pointer to input bitstream */
+/* 2. Temporary input buffer */
+/* 3. PPS start buffer */
+/* 4. SPS start buffer */
+/* 5. Pointer to NAL paramter structure */
+/* 6. Place holder for error code */
+/* Globals : None */
+/* Processing : Parses the slice header */
+/* */
+/* Outputs : Updated NAL prms structure */
+/* Updated error code */
+/* Returns : status */
+/* */
+/* Issues : Does not support interlaced content */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_part_slice_hdr(UWORD8 *pu1_input_buf, WORD32 i4_input_buf_size,
+ UWORD8 *pu1_temp_buf, void *pv_sps, void *pv_pps,
+ nal_prms_t *ps_nal_prms, UWORD32 *pu4_err_code,
+ WORD32 *pi4_sps_pps_status)
+{
+ UWORD32 u4_slice_type;
+ dec_seq_params_t *ps_sps = (dec_seq_params_t *) pv_sps;
+ dec_pic_params_t *ps_pps = (dec_pic_params_t *) pv_pps;
+ dec_bit_stream_t s_stream_ctxt = {0};
+ dec_bit_stream_t *ps_stream_ctxt;
+ UWORD32 *pu4_bitstrm_buf;
+ UWORD32 *pu4_bitstrm_ofst;
+
+ *pi4_sps_pps_status = NAL_CORRUPT_DATA;
+ /* Perform the emulation prevention and byte swap */
+ {
+ emulation_prevent_ctxt_t s_emulation_ctxt = {0};
+ WORD32 i4_size, i4_temp;
+
+ isvcd_reset_emulation_ctxt((void *) &s_emulation_ctxt);
+ i4_size = MIN(i4_input_buf_size, HEADER_BUFFER_LEN_BEFORE_EP);
+
+ isvcd_nal_byte_swap_emulation((UWORD32 *) pu1_temp_buf, (UWORD32 *) &i4_temp, pu1_input_buf,
+ (UWORD32) i4_size, NUM_OF_ZERO_BYTES_BEFORE_START_CODE,
+ &s_emulation_ctxt);
+
+ /* Initialize the stream context structure */
+ s_stream_ctxt.pu4_buffer = (UWORD32 *) pu1_temp_buf;
+ s_stream_ctxt.u4_ofst = 0;
+ s_stream_ctxt.u4_max_ofst = (i4_size << 3);
+ }
+
+ ps_stream_ctxt = &s_stream_ctxt;
+
+ /* Parse the first mb address in slice */
+ pu4_bitstrm_buf = ps_stream_ctxt->pu4_buffer;
+ pu4_bitstrm_ofst = &ps_stream_ctxt->u4_ofst;
+ ps_nal_prms->u4_first_mb_addr = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ps_nal_prms->u4_first_mb_addr >= (MAX_MBS_LEVEL_51))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ /* Parse slice type */
+ u4_slice_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_slice_type > 9) return ERROR_INV_SLC_TYPE_T;
+
+ /* Check the validity of slice prms */
+ switch(u4_slice_type)
+ {
+ case 0:
+ case 5:
+ u4_slice_type = P_SLICE;
+ /* P slice */
+ break;
+ case 1:
+ case 6:
+ u4_slice_type = B_SLICE;
+ /* B slice */
+ break;
+ case 2:
+ case 7:
+ /* I slice */
+ u4_slice_type = I_SLICE;
+ break;
+ default:
+ break;
+ }
+
+ /* Parse the pps id */
+ ps_nal_prms->u1_pps_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ps_nal_prms->u1_pps_id & MASK_ERR_PIC_SET_ID) return ERROR_INV_SLICE_HDR_T;
+
+ /* validate pps id */
+ ps_pps += ps_nal_prms->u1_pps_id;
+ if(0 == ps_pps->u1_is_valid)
+ {
+ return NOT_OK;
+ }
+ /* Derive sps id */
+ ps_sps = ps_pps->ps_sps;
+
+ ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
+ if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ ps_sps += MAX_NUM_SEQ_PARAMS;
+ ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
+ ps_nal_prms->u1_sps_id += MAX_NUM_SEQ_PARAMS;
+ }
+
+ if(NULL == ps_sps)
+ {
+ return NOT_OK;
+ }
+ if(FALSE == ps_sps->u1_is_valid)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ if(ps_nal_prms->u4_first_mb_addr > (ps_sps->u2_frm_ht_in_mbs * ps_sps->u2_frm_wd_in_mbs))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ *pi4_sps_pps_status = 0;
+
+ /* Parse frame number */
+ ps_nal_prms->u2_frm_num = ih264d_get_bits_h264(ps_stream_ctxt, ps_sps->u1_bits_in_frm_num);
+
+ /* IDR picture number */
+ if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
+ {
+ ps_nal_prms->i4_idr_pic_num = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_nal_prms->i4_idr_pic_num > 65535) return ERROR_INV_SLICE_HDR_T;
+ }
+
+ /* Poc lsb */
+ if(0 == ps_sps->u1_pic_order_cnt_type)
+ {
+ ps_nal_prms->i4_poc_lsb =
+ ih264d_get_bits_h264(ps_stream_ctxt, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
+
+ if(ps_nal_prms->i4_poc_lsb < 0 ||
+ ps_nal_prms->i4_poc_lsb >= ps_sps->i4_max_pic_order_cntLsb)
+ return ERROR_INV_SLICE_HDR_T;
+ if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
+ {
+ ps_nal_prms->i4_delta_poc_bot = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+ else if((1 == ps_sps->u1_pic_order_cnt_type) && (!ps_sps->u1_delta_pic_order_always_zero_flag))
+ {
+ ps_nal_prms->ai4_delta_poc[0] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
+ {
+ ps_nal_prms->ai4_delta_poc[1] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ }
+ }
+
+ *pu4_err_code = 0;
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_int_tgt_lyr_attr */
+/* */
+/* Description : This routine returns the target layer attributes */
+/* (dependency id, temporal id and quality id) */
+/* */
+/* Inputs : 1. Application attributes */
+/* 2. Internal attributes (input and output) */
+/* 3. Nal prms structure */
+/* Globals : None */
+/* Processing : */
+/* */
+/* Outputs : Updated internal target layer attributes */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_int_tgt_lyr_attr(target_lyr_attr_t *ps_app_attr, target_lyr_attr_t *ps_int_attr,
+ nal_prms_t *ps_nal_prms)
+{
+ WORD32 i4_dep_id;
+ WORD32 i4_quality_id;
+ WORD32 i4_temp_id;
+ WORD32 i4_prior_id;
+
+ /* sanity checks */
+ if((NULL == ps_app_attr) || (NULL == ps_int_attr) || (NULL == ps_nal_prms))
+ {
+ return NOT_OK;
+ }
+
+ i4_dep_id = ps_int_attr->i4_dependency_id;
+ i4_quality_id = ps_int_attr->i4_quality_id;
+ i4_temp_id = ps_int_attr->i4_temporal_id;
+ i4_prior_id = ps_int_attr->i4_priority_id;
+
+ /* check for idr pic flag */
+ /* dependency & temporal id is updated only for IDR picture */
+ if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
+ {
+ if(ps_int_attr->i4_dependency_id < ps_app_attr->i4_dependency_id)
+ {
+ /* update the internal attributes only if */
+ /* current dep_id -1 == highest dep id decoded so far */
+ /* and quality id is equal to 0 */
+ if((ps_nal_prms->i4_dependency_id - 1 == ps_int_attr->i4_dependency_id) &&
+ (0 == ps_nal_prms->i4_quality_id))
+ {
+ /* Set revised target dependency id */
+ i4_dep_id = ps_nal_prms->i4_dependency_id;
+ i4_temp_id = ps_app_attr->i4_temporal_id;
+ i4_prior_id = ps_app_attr->i4_priority_id;
+ }
+ }
+ else
+ {
+ /* cases when the curr dep is greater than or equal to app dep */
+ i4_dep_id = ps_app_attr->i4_dependency_id;
+ i4_temp_id = ps_app_attr->i4_temporal_id;
+ i4_prior_id = ps_app_attr->i4_priority_id;
+ }
+ }
+
+ /* Set quality id */
+ if(i4_dep_id == ps_app_attr->i4_dependency_id)
+ {
+ i4_quality_id = ps_app_attr->i4_quality_id;
+ }
+ else
+ {
+ i4_quality_id = MAX_QUALITY_ID;
+ }
+
+ /* Update the internal attributes */
+ ps_int_attr->i4_dependency_id = i4_dep_id;
+ ps_int_attr->i4_quality_id = i4_quality_id;
+ ps_int_attr->i4_temporal_id = i4_temp_id;
+ ps_int_attr->i4_priority_id = i4_prior_id;
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_discard_nal */
+/* */
+/* Description : Determines whether current NAL unit has to be discarded */
+/* or not */
+/* */
+/* Inputs : pv_nal_prms - Pointer to NAL header prms */
+/* structure */
+/* pv_app_lyr_attr - Pointer to application target layer */
+/* attributes structure */
+/* pv_app_lyr_attr - Pointer to internal target layer */
+/* attributes structure */
+/* i4_update_flag - This flag indicates whether the internal*/
+/* target attrbutes should be updated or not */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_discard_nal(void *pv_nal_prms, void *pv_app_attr, void *pv_int_attr,
+ WORD32 i4_update_flag)
+{
+ WORD32 i4_discard_nal_flag;
+ nal_prms_t *ps_nal_prms;
+ target_lyr_attr_t *ps_app_attr;
+ target_lyr_attr_t *ps_int_attr;
+ WORD32 i4_status;
+
+ ps_nal_prms = (nal_prms_t *) pv_nal_prms;
+ ps_app_attr = (target_lyr_attr_t *) pv_app_attr;
+ ps_int_attr = (target_lyr_attr_t *) pv_int_attr;
+
+ /* Get the updated target layer attributes */
+ if(SVCD_TRUE == i4_update_flag)
+ {
+ i4_status = isvcd_get_int_tgt_lyr_attr(ps_app_attr, ps_int_attr, ps_nal_prms);
+ if(OK != i4_status)
+ {
+ return NOT_OK;
+ }
+ }
+
+ i4_discard_nal_flag = SVCD_FALSE;
+
+ if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
+ {
+ /*-------------------------------------------------------------------*/
+ /*!Discard VCL NAL if any of following is true */
+ /*! - Dependency id is greater than target dependency id */
+ /*! - Dependency id is equal to target dependency id but quality id */
+ /*! is greater than target quality id */
+ /*! - priority id is greater than target priority id */
+ /*! - Temporal id is greater than target temporal id */
+ /*! - If dependency id is greater than a NAL unit for which discard */
+ /*! flag of the NAL header is set */
+ /*-------------------------------------------------------------------*/
+ if(PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type)
+ {
+ if(ps_nal_prms->i4_dependency_id > ps_int_attr->i4_dependency_id)
+ {
+ i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ if(ps_nal_prms->i4_dependency_id == ps_int_attr->i4_dependency_id &&
+ ps_nal_prms->i4_quality_id > ps_int_attr->i4_quality_id)
+ {
+ i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ if(ps_nal_prms->i4_temporal_id > ps_int_attr->i4_temporal_id)
+ {
+ i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ if(ps_nal_prms->i4_priority_id > ps_int_attr->i4_priority_id)
+ {
+ i4_discard_nal_flag = SVCD_TRUE;
+ }
+ }
+ else
+ {
+ if(0 == ps_int_attr->i4_quality_id && 0 == ps_int_attr->i4_dependency_id)
+ {
+ i4_discard_nal_flag = SVCD_TRUE;
+ }
+ }
+ }
+
+ return (i4_discard_nal_flag);
+}
diff --git a/decoder/svc/isvcd_nal.h b/decoder/svc/isvcd_nal.h
new file mode 100644
index 0000000..7d9f857
--- /dev/null
+++ b/decoder/svc/isvcd_nal.h
@@ -0,0 +1,216 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal.h
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+#ifndef _SVCD_NAL_H_
+#define _SVCD_NAL_H_
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+#define START_CODE_NOT_FOUND -1
+#define END_OF_STREAM_BUFFER -2
+#define END_OF_STREAM -1
+
+#define SC_NOT_FOUND (-1)
+#define SC_FOUND 1
+
+#define NUM_OF_ZERO_BYTES_BEFORE_START_CODE (2)
+#define START_CODE_BYTE (0x01)
+
+#define EMULATION_PREVENTION_BYTE (0x03)
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Typedefs */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+typedef enum
+{
+ NON_VCL_NAL,
+ VCL_NAL
+} DERIVED_NAL_UNIT_TYPE_T;
+
+typedef enum
+{
+ NAL_START = 0,
+ FIND_NAL_END,
+ NAL_END
+} NAL_BOUND_DETECT_STATE_T;
+
+typedef enum
+{
+ STUFFED_BYTE = 0,
+ /* Should be used for reset purposes */
+ NOT_STUFFED_BYTE
+} EMULATION_STATE_T;
+
+typedef enum
+{
+ NAL_INSUFFICIENT_DATA = (WORD32) 0x80000000,
+ NAL_CORRUPT_DATA = (WORD32) 0x80000001
+} NAL_PARSE_ERR_CODES_T;
+
+/*****************************************************************************/
+/* Structure */
+/*****************************************************************************/
+typedef struct
+{
+ WORD32 i4_nal_ref_idc; /*!< NAL ref idc - decoded prm from the bitstream */
+
+ WORD32 i4_nal_unit_type; /*!< NAL unit type - decoded prm from the
+ bitstream */
+
+ WORD32 i4_priority_id; /*!< Priority id of NAL - decoded prm from the
+ bitstream. If not present then set to 0 */
+
+ WORD32 i4_dependency_id; /*!< dependency id of NAL - decoded prm from the
+ bitstream. If not present then set to 0 */
+
+ WORD32 i4_quality_id; /*!< Quality id of NAL - decoded prm from the
+ bitstream. If not present then set to 0 */
+
+ WORD32 i4_temporal_id; /*!< Temporal id of NAL - decoded prm from the
+ bitstream. If not present then set to 0 */
+
+ WORD32 i4_no_int_lyr_pred; /*!< No inter layer predictiion flag of NAL -
+ decoded prm from the bitstream. if not present then it is set to 0 */
+
+ WORD32 i4_use_ref_base_pic_flag; /*!<Use ref_base_pic flag - decoded from
+ the bitstream. If not present then it is set to 0 */
+
+ WORD32 i4_discard_flag; /*!<Discard_flag - decoded from the bitstream.
+ If not present then it is set to 0 */
+
+ WORD32 i4_derived_nal_type; /*! Derived NAL type - Place holder for enum
+ which indicates whether the current NAL is VCL NAL or NON_VCL_NAL */
+
+ WORD32 i4_idr_pic_flag; /*! Derived prm - Indicates whether current NAL
+ is idr VCL NAL or not. SVCD_TRUE means IDR PIC NAL otherwsie not */
+
+ WORD32 i4_nal_header_len; /*! lenght of NAL header in bytes */
+
+ WORD32 i4_dqid; /*! Derived parameter. It has same meaning as DQID in the
+ SVC standard */
+
+ UWORD32 u4_first_mb_addr; /*!< It shall hold the value of first MB address
+ of the VCL NAL unit (excluding the prefix NAL
+ unit) */
+
+ UWORD8 u1_sps_id; /*!< It shall have the value of SPS id for the VCL NAL
+ unit (excluding the prefix NAL unit)*/
+
+ UWORD8 u1_pps_id; /*!< It shall have the value of PPS id for the VCL NAL
+ unit (excluding the prefix NAL unit)*/
+
+ UWORD16 u2_frm_num; /*!< It shall have the value of frame number for the VCL
+ NAL unit (excluding the prefix NAL unit)*/
+
+ UWORD32 i4_idr_pic_num; /*!< It shall have the value of IDR picture number when
+ "i4_idr_pic_flag" is SVCD_TRUE for VCL NAL unit.
+ (excluding prefix NAL unit) */
+
+ WORD32 i4_poc_lsb; /*!< It shall have the value of "picture order cnt lsb"
+ when picture order count type is 0 for VCL NAL unit
+ (excluding the prefix NAL unit). When not present in the
+ bitstream, it shall be set to 0 */
+
+ WORD32 i4_delta_poc_bot; /*!< It shall have the value of "delta picture order
+ cnt bottom" when picture order count type is 0 for VCL NAL
+ unit (excluding the prefix NAL unit). When not present in
+ the bitstream, it shall be set to 0 */
+
+ WORD32 ai4_delta_poc[2]; /*!< It shall have the value of "delta picture order
+ cnt bottom" when picture order count type is 1 for VCL NAL
+ unit (excluding the prefix NAL unit). When not present in
+ the bitstream, it shall be set to 0 */
+
+} nal_prms_t;
+
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+void isvcd_nal_buf_reset(void *ps_nal_buf);
+
+UWORD32 isvcd_nal_rbsp_to_sodb(UWORD8 *pu1_buf, WORD32 i4_nal_len_in_bytes, UWORD8 u1_ecd_mode);
+
+WORD32 isvcd_get_first_start_code(UWORD8 *pu1_stream_buffer, UWORD32 *pu4_bytes_consumed,
+ UWORD32 *pu4_num_bytes);
+
+WORD32 isvcd_nal_find_start_code(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
+ WORD32 *pi4_zero_cnt, UWORD32 *pu4_bytes_consumed);
+
+WORD32 isvcd_get_annex_b_nal_unit(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
+ WORD32 *pi4_state, WORD32 *pi4_zero_byte_cnt,
+ UWORD32 *pu4_bytes_consumed, void *pv_nal_unit,
+ WORD32 *pi4_more_data_flag);
+
+void isvcd_reset_emulation_ctxt(void *pv_emulation_ctxt);
+
+UWORD32 isvcd_nal_byte_swap_emulation(UWORD32 *pu4_out_stream, UWORD32 *pu4_out_len,
+ UWORD8 *pu1_in_stream, UWORD32 u4_in_len, WORD32 i4_0s_bfr_sc,
+ void *pv_emulation_ctxt);
+
+void isvcd_dec_nal_hdr(void *pv_buf_ptr, WORD32 i4_buf_size, void *pv_nal_header_buf,
+ void *pv_nal_prms, void *pv_prefix_nal_buf, void *pv_prefix_nal_prms,
+ UWORD32 *pu4_err_code);
+
+void isvcd_set_default_nal_prms(void *pv_nal_prms);
+
+WORD32 isvcd_parse_part_slice_hdr(UWORD8 *pu1_input_buf, WORD32 i4_input_buf_size,
+ UWORD8 *pu1_temp_buf, void *ps_sps, void *ps_pps,
+ nal_prms_t *ps_nal_prms, UWORD32 *pu4_err_code,
+ WORD32 *pi4_sps_pps_status);
+
+WORD32 isvcd_discard_nal(void *pv_nal_prms, void *pv_app_attr, void *pv_int_attr,
+ WORD32 i4_update_flag);
+
+#endif /* _SVCD_NAL_H_ */
diff --git a/decoder/svc/isvcd_nal_parse.c b/decoder/svc/isvcd_nal_parse.c
new file mode 100644
index 0000000..3dbdb9c
--- /dev/null
+++ b/decoder/svc/isvcd_nal_parse.c
@@ -0,0 +1,2434 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal_parse.c
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stddef.h>
+#include <assert.h>
+
+/* standard interface include files */
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_tables.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264_debug.h"
+#include "ih264d_inter_pred.h"
+#include "isvcd_structs.h"
+#include "ih264d_nal.h"
+#include "ih264d_error_handler.h"
+
+/*****************************************************************************/
+/*Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Global Variable Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Static Global Variable Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Static function Definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_nal_buf */
+/* */
+/* Description : This routine returns the NAL buffer structure to use for */
+/* current NAL unit. This will also perform the initializa -*/
+/* tion of the structure */
+/* Inputs : 1. NAL parse structure */
+/* 2. Place holder for nal buffer structure */
+/* Globals : None */
+/* Processing : If current NAL unit prefix NAL unit then */
+/* - Resets the prefix nal buffer structure */
+/* - Assigns the buffer pointer */
+/* Otherwise */
+/* - Assigns the buffer pointer */
+/* Outputs : - Updated NAL buffer strcuture */
+/* - Updates the place holder with correct NAL buffer */
+/* structure */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_get_nal_buf(nal_parse_ctxt_t *ps_nal_parse_ctxt, nal_buf_t **pps_nal_buf)
+{
+ nal_prms_t *ps_nal_prms;
+ nal_buf_t *ps_nal_buf;
+
+ ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
+
+ /* Get the NAL buffer structure */
+ if(PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ ps_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
+
+ /* Note: This reset will cause a prefix NAL unit */
+ /* which is followed by another prefix NAL unit */
+ /* to be ignored by the module. This is indeed */
+ /* a desired behaviour */
+ isvcd_nal_buf_reset(ps_nal_buf);
+ }
+ else
+ {
+ ps_nal_buf = &ps_nal_parse_ctxt->s_nal_buf;
+ }
+
+ /* Initialize the buffer structure */
+ ps_nal_buf->i4_valid_flag = SVCD_TRUE;
+ if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
+ {
+ ps_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_vcl_nal_buf;
+ }
+ else if(NON_VCL_NAL == ps_nal_prms->i4_derived_nal_type)
+ {
+ ps_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
+ }
+ else
+ {
+ ps_nal_buf->pu1_buf = NULL;
+ return;
+ }
+
+ *pps_nal_buf = ps_nal_buf;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_dqid_ctxt_reset */
+/* */
+/* Description : This routine resets the DQID context. This routine shall */
+/* be invoked once in a picture */
+/* */
+/* Inputs : DQID context structure */
+/* Globals : None */
+/* Processing : Invalidates all the DQID nodes */
+/* */
+/* Outputs : Updated DQID context */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_dqid_ctxt_reset(dqid_ctxt_t *ps_dqid_ctxt)
+{
+ WORD32 i4_lyr_idx;
+ WORD32 i4_max_num_lyrs;
+ dqid_node_t *ps_dqid_node;
+
+ /* sanity checks */
+ if(NULL == ps_dqid_ctxt)
+ {
+ return NOT_OK;
+ }
+
+ i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
+ ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
+
+ /* Loop over all the layers */
+ for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
+ {
+ /* Reset the valid flag */
+ ps_dqid_node->u1_valid_flag = SVCD_FALSE;
+
+ /* Loop updates */
+ ps_dqid_node += 1;
+ } /* loop over all the layers */
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_dqid_node */
+/* */
+/* Description : This routine gets a DQID node corresponding to a DQID */
+/* */
+/* Inputs : 1. DQID context */
+/* 2. DQID */
+/* 3. Place holder for DQID node (output) */
+/* Globals : None */
+/* Processing : It performs the following */
+/* - Searches for all elements untill it gets element having*/
+/* DQID equal to input DQID. */
+/* - If not found it finds a free (un-occupied) node */
+/* */
+/* Outputs : 1. Updated DQID node */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_dqid_node(dqid_ctxt_t *ps_dqid_ctxt, UWORD8 u1_dqid, dqid_node_t **pps_dqid_node)
+{
+ WORD32 i4_lyr_idx;
+ WORD32 i4_max_num_lyrs;
+ dqid_node_t *ps_dqid_node;
+ dqid_node_t *ps_rqrd_dqid_node;
+
+ /* sanity checks */
+ if((NULL == ps_dqid_ctxt) || (NULL == pps_dqid_node))
+ {
+ return NOT_OK;
+ }
+
+ i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
+ ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
+
+ /*Initialization */
+ ps_rqrd_dqid_node = NULL;
+
+ /* Loop over all the buffer nodes */
+ for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
+ {
+ if((SVCD_TRUE == ps_dqid_node->u1_valid_flag) && (u1_dqid == ps_dqid_node->u1_dqid))
+ {
+ ps_rqrd_dqid_node = ps_dqid_node;
+ break;
+ }
+ /* Loop updates */
+ ps_dqid_node += 1;
+ } /* Loop over all the buffer nodes */
+
+ if(NULL == ps_rqrd_dqid_node)
+ {
+ /* If vcl node is not allocated for the requested DQID then allocate buffer */
+ ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
+ for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
+ {
+ if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
+ {
+ break;
+ }
+ /* Loop updates */
+ ps_dqid_node += 1;
+ } /* Loop over all the nodes */
+ /* Update the node structure */
+ ps_rqrd_dqid_node = ps_dqid_node;
+ }
+
+ /* sanity checks */
+ if(NULL == ps_rqrd_dqid_node)
+ {
+ return NOT_OK;
+ }
+ *pps_dqid_node = ps_rqrd_dqid_node;
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_reset_ctxt */
+/* */
+/* Description : This routine performs NAL unit level initialization */
+/* This routine shall be called before parsing a NAL unit */
+/* */
+/* Inputs : 1. NAL parse context structure */
+/* Globals : None */
+/* Processing : This does initializaiton of NAL unit level tracking */
+/* varaibles */
+/* */
+/* Outputs : Updated context structure */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_nal_reset_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ nal_unit_t *ps_nal_unit;
+
+ if(NULL == ps_nal_parse_ctxt)
+ {
+ return NOT_OK;
+ }
+
+ /* Reset the NAL boundary detetction */
+ ps_nal_parse_ctxt->i4_find_nal_state = NAL_START;
+ ps_nal_parse_ctxt->i4_zero_byte_cnt = 0;
+ ps_nal_unit = ps_nal_parse_ctxt->pv_nal_unit;
+ ps_nal_unit->i4_num_bufs = 0;
+
+ /*Reset emulation prevention */
+ isvcd_reset_emulation_ctxt(&ps_nal_parse_ctxt->s_emulation_ctxt);
+
+ /*Reset the NAL header prms */
+ isvcd_set_default_nal_prms(&ps_nal_parse_ctxt->s_nal_prms);
+
+ /* Reset other NAL level tracking variables */
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_FALSE;
+
+ /*Reset NAL buffer structure*/
+ isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_nal_buf);
+
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pic_reset_ctxt */
+/* */
+/* Description : This routine performs the picture level initialization. */
+/* This routine shall be called before parsing a access unit*/
+/* */
+/* Inputs : pv_nal_parse_ctxt - Pointer to context structure */
+/* */
+/* Globals : None */
+/* */
+/* Processing : 1. Resets the varaibles */
+/* */
+/* Outputs : Updated context structure */
+/* */
+/* Returns : none */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_pic_reset_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ WORD32 i4_status;
+
+ /*-----------------------------------------------------------------------*/
+ /*! Reset NAL boundary detetction logic */
+ /*-----------------------------------------------------------------------*/
+ i4_status = isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+
+ UNUSED(i4_status);
+
+ /*-----------------------------------------------------------------------*/
+ /*! Reset picture boundary detctetion logic */
+ /*-----------------------------------------------------------------------*/
+ ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_TRUE;
+
+ /*-----------------------------------------------------------------------*/
+ /*! Reset VCL and non VCL NAL buffer tracking variables */
+ /*-----------------------------------------------------------------------*/
+ ps_nal_parse_ctxt->pu1_non_vcl_nal_buf = ps_nal_parse_ctxt->pv_non_vcl_nal_buf;
+ ps_nal_parse_ctxt->pu1_vcl_nal_buf = ps_nal_parse_ctxt->pv_vcl_nal_buf;
+
+ /* reset the bytes left to buffer size */
+ ps_nal_parse_ctxt->u4_bytes_left_vcl = MAX_VCL_NAL_BUFF_SIZE;
+
+ ps_nal_parse_ctxt->u4_bytes_left_non_vcl = MAX_NON_VCL_NAL_BUFF_SIZE;
+
+ /* Offset the buffer to start of vcl data */
+ UPDATE_NAL_BUF_PTR(&ps_nal_parse_ctxt->pu1_non_vcl_nal_buf, NON_VCL_NAL,
+ &ps_nal_parse_ctxt->u4_bytes_left_non_vcl);
+
+ UPDATE_NAL_BUF_PTR(&ps_nal_parse_ctxt->pu1_vcl_nal_buf, VCL_NAL,
+ &ps_nal_parse_ctxt->u4_bytes_left_vcl);
+
+ /* Reset previous field */
+ ps_nal_parse_ctxt->ps_prev_non_vcl_buf = NULL;
+ ps_nal_parse_ctxt->i4_idr_pic_err_flag = 0;
+
+ /*-----------------------------------------------------------------------*/
+ /*! Reset other NAL related tracking variables */
+ /*-----------------------------------------------------------------------*/
+ ps_nal_parse_ctxt->i4_num_non_vcl_nals = 0;
+
+ /* Reset the vcl nal node buffer context */
+ i4_status = isvcd_dqid_ctxt_reset(&ps_nal_parse_ctxt->s_dqid_ctxt);
+
+ /* Reset target layer update flag */
+ ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_TRUE;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_get_nal_prms */
+/* */
+/* Description : This routine will update the nal prms */
+/* Inputs : 1. Start of bitstream buffer containing NAL header */
+/* 2. Size of the buffer */
+/* 3. NAL prms structure */
+/* 4. Place holder for error code */
+/* 5. Place holder for nal discard flag */
+/* 6. NAL parse context structure */
+/* Globals : None */
+/* Processing : 1. Parses the NAL header */
+/* 2. Sets the discard flag */
+/* 3. If NAL is not discarded and nal is VCL NAL unit then */
+/* decodes the slice prms (prefix nal units are excluded)*/
+/* Outputs : Updated NAL prms structure */
+/* Updated NAL discrd flag */
+/* Updates the error code if encountered with error */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_get_nal_prms(UWORD8 *pu1_buf, WORD32 i4_buf_size, nal_prms_t *ps_nal_prms,
+ nal_prms_t *ps_prefix_nal_prms, nal_buf_t *ps_prefix_nal_buf,
+ UWORD32 *pu4_err_code, WORD32 *pi4_sps_pps_status,
+ WORD32 *pi4_nal_discard_flag, nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ UWORD8 *pu1_input_buf;
+ WORD32 i4_status;
+ dec_seq_params_t *ps_sps;
+ dec_pic_params_t *ps_pps;
+
+ ps_sps = ps_nal_parse_ctxt->pv_seq_prms;
+ ps_pps = ps_nal_parse_ctxt->pv_pic_prms;
+
+ *pu4_err_code = 0;
+ *pi4_sps_pps_status = NAL_CORRUPT_DATA;
+
+ /* Decode the NAL header */
+ isvcd_dec_nal_hdr(pu1_buf, i4_buf_size, ps_nal_parse_ctxt->pv_nal_header_buf, ps_nal_prms,
+ ps_prefix_nal_buf, ps_prefix_nal_prms, pu4_err_code);
+
+ /* If encountered with error return fail */
+ if(0 != *pu4_err_code)
+ {
+ return (NOT_OK);
+ }
+
+ if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
+ {
+ *pi4_nal_discard_flag = 1;
+ return OK;
+ }
+
+ /* Set the discard flag */
+ *pi4_nal_discard_flag = isvcd_discard_nal(
+ (void *) ps_nal_prms, (void *) &ps_nal_parse_ctxt->s_app_attr,
+ (void *) &ps_nal_parse_ctxt->s_int_attr, ps_nal_parse_ctxt->i4_tgt_lyr_update);
+
+ /* Parse the slice header if all the following */
+ /* conditions are true */
+ /* 1. NAL is a VCL NAL unit */
+ /* 2. NAL is not a prefix NAL unit */
+ /* 3. NAL is not discarded */
+ if((NON_VCL_NAL == ps_nal_prms->i4_derived_nal_type) ||
+ (PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type) || (SVCD_TRUE == *pi4_nal_discard_flag))
+ {
+ return (OK);
+ }
+
+ pu1_input_buf = pu1_buf;
+ pu1_input_buf += ps_nal_prms->i4_nal_header_len;
+ i4_buf_size -= ps_nal_prms->i4_nal_header_len;
+
+ i4_status =
+ isvcd_parse_part_slice_hdr(pu1_input_buf, i4_buf_size, ps_nal_parse_ctxt->pv_nal_header_buf,
+ ps_sps, ps_pps, ps_nal_prms, pu4_err_code, pi4_sps_pps_status);
+
+ return (i4_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compare_nal_prms */
+/* */
+/* Description : Detects the picture boundary for annex B based input */
+/* bitstream */
+/* */
+/* Inputs : 1. Pointer to NAL prms */
+/* 2. Pass (first pass or second pass (verification) */
+/* 3. Place holder for picture boundary type */
+/* 4. Place holder for picture boundary status */
+/* 4. pointer to bitstream extract context structure */
+/* Globals : */
+/* Processing : Detects the picture bounadry as described in G.7.4.1.2.4 */
+/* */
+/* Outputs : Detects the picture boundary */
+/* Updates the first NAL in AU field */
+/* Updates the picture boundary type if picture boundary is */
+/* detetcetd otherwise it's value shall be ignored */
+/* Updates the picture boundary status with either */
+/* PIC_BOUNDARY_TRUE if picture boundary is detetcted or */
+/* PIC_BOUNDARY_FALSE otherwise */
+/* Updates the error code */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_compare_nal_prms(nal_prms_t *ps_nal_prms, WORD32 i4_pass, WORD32 i4_prev_dqid,
+ WORD32 *pi4_pic_bound_type, WORD32 *pi4_pic_bound_status,
+ nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ dqid_node_t *ps_dqid_node;
+ vcl_node_t *ps_vcl_node;
+ WORD32 i4_status;
+
+ /* If DQID is lesser than the DQID of the previous */
+ /* NAL then declare the picture boundary */
+ *pi4_pic_bound_type = PIC_BOUND_DQID;
+ if(i4_prev_dqid > ps_nal_prms->i4_dqid)
+ {
+ *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
+ return (OK);
+ }
+
+ /* Perform the picture boundary detection only for */
+ /* the layers with quality id equal to 0 */
+ if((FIRST_PASS == i4_pass) && (0 != (ps_nal_prms->i4_dqid & 0x0F)))
+ {
+ *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
+ return (OK);
+ }
+
+ /* Get the DQID node */
+ i4_status =
+ isvcd_get_dqid_node(&ps_nal_parse_ctxt->s_dqid_ctxt, (UWORD8) i4_prev_dqid, &ps_dqid_node);
+ if((OK != i4_status) || (NULL == ps_dqid_node))
+ {
+ return NOT_OK;
+ }
+ /* If the current slice is first slice in the layer */
+ /* then do not compare */
+ if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
+ {
+ *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
+ return (OK);
+ }
+
+ *pi4_pic_bound_type = PIC_BOUND_SLICE_PRMS;
+ *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
+ ps_vcl_node = ps_dqid_node->ps_vcl_node;
+
+ /* Compare NAL ref idc */
+ {
+ WORD32 i4_prev_ref_pic_flag;
+ WORD32 i4_cur_ref_pic_flag;
+
+ i4_prev_ref_pic_flag = (0 != ps_vcl_node->i4_nal_ref_idc);
+ i4_cur_ref_pic_flag = (0 != ps_nal_prms->i4_nal_ref_idc);
+
+ if(i4_prev_ref_pic_flag != i4_cur_ref_pic_flag)
+ {
+ return (OK);
+ }
+ }
+
+ /* Compare IDR picture flag */
+ if(ps_vcl_node->i4_idr_pic_flag != ps_nal_prms->i4_idr_pic_flag)
+ {
+ return (OK);
+ }
+
+ /* Compare PPS id */
+ if(ps_vcl_node->u1_pps_id != ps_nal_prms->u1_pps_id)
+ {
+ return (OK);
+ }
+
+ /* Compare idr pic num */
+ if((SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag) &&
+ (ps_vcl_node->i4_idr_pic_num != ps_nal_prms->i4_idr_pic_num))
+ {
+ return (OK);
+ }
+
+ /* Compare frame number */
+ if(ps_vcl_node->u2_frm_num != ps_nal_prms->u2_frm_num)
+ {
+ return (OK);
+ }
+
+ /* Compare poc lsb */
+ if(ps_dqid_node->i4_poc_lsb != ps_nal_prms->i4_poc_lsb)
+ {
+ return (OK);
+ }
+
+ /* Compare delta poc bottom */
+ if(ps_dqid_node->i4_delta_poc_bot != ps_nal_prms->i4_delta_poc_bot)
+ {
+ return (OK);
+ }
+
+ /* Compare delta poc [0] */
+ if(ps_dqid_node->ai4_delta_poc[0] != ps_nal_prms->ai4_delta_poc[0])
+ {
+ return (OK);
+ }
+
+ /* Compare delta poc [0] */
+ if(ps_dqid_node->ai4_delta_poc[1] != ps_nal_prms->ai4_delta_poc[1])
+ {
+ return (OK);
+ }
+
+ *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_detetct_pic_boundary_annex_b */
+/* */
+/* Description : Detects the picture boundary for annex B based input */
+/* bitstream */
+/* */
+/* */
+/* Inputs : 1. Pointer to NAL prms */
+/* 2. Input bitstream structure */
+/* 3. Current position of the bitstream pointer */
+/* 4. Place holder for picture boundary status */
+/* 5. pointer to bitstream extract context structure */
+/* Globals : */
+/* Processing : It does the following */
+/* 1. Look for next NAL. */
+/* If not found then declare picture boundary */
+/* Otherwsie goto next step */
+/* 2. Parse the NAL header */
+/* If encountered with error then declare picture */
+/* boundary */
+/* Otherwise goto next step */
+/* 3. If picture boundary type is */
+/* DQID change and DQID is not equal previous DQID then */
+/* declare picture boundary. Otherwise, the comapre the */
+/* rest of parameters. If during comparison, if there is*/
+/* 4. If picture boundary type is */
+/* SLICE PRMS CHANGE and Dependency id is not equal then*/
+/* declare picture boundary. Otherwise compre rest of */
+/* parameters and goto step 5 */
+/* 5. If during comparison, if there is */
+/* * an error - then declare picture boundary */
+/* * Otherwsie if picture boundary is not detetcted */
+/* then discard the second slice and proceed. */
+/* */
+/* Outputs : Detects the picture boundary */
+/* Updates the first NAL in AU field */
+/* Updates the picture boundary type if picture boundary is */
+/* detetcetd otherwise it's value shall be ignored */
+/* Updates the error code */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_detect_pic_boundary_annex_b(nal_prms_t *ps_nal_prms, UWORD8 *pu1_stream_buffer,
+ WORD32 i4_cur_pos, WORD32 *pi4_pic_bound_status,
+ nal_parse_ctxt_t *ps_nal_parse_ctxt,
+ UWORD32 *pu4_num_bytes)
+{
+ UWORD32 u4_err_code;
+ WORD32 i4_zero_cnt;
+ WORD32 i4_status;
+ nal_prms_t s_nal_prms = {0};
+ nal_prms_t s_prefix_nal_prms = {0};
+ nal_buf_t s_prefix_nal_buf = {0};
+ WORD32 i4_pic_bound_type;
+ WORD32 i4_pic_bound_status;
+ UWORD8 *pu1_buf;
+ WORD32 i4_buf_size;
+ WORD32 i4_more_data_flag;
+ WORD32 i4_new_lyr_flag;
+ WORD32 i4_prev_dqid;
+ WORD32 i4_nal_discard_flag;
+
+ /* Initializations */
+ i4_zero_cnt = 0;
+ s_prefix_nal_buf.i4_valid_flag = SVCD_FALSE;
+ *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
+ i4_new_lyr_flag = SVCD_TRUE;
+
+ /* Get the previous layer's DQID */
+ if(SVCD_TRUE == ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au)
+ {
+ ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
+ ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_FALSE;
+ }
+ i4_prev_dqid = ps_nal_parse_ctxt->i4_prev_dq_id;
+ ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
+
+ /* Detect the picture boundary */
+ if(ps_nal_prms->i4_dqid <= i4_prev_dqid)
+ {
+ i4_status =
+ isvcd_compare_nal_prms(ps_nal_prms, FIRST_PASS, i4_prev_dqid, &i4_pic_bound_type,
+ &i4_pic_bound_status, ps_nal_parse_ctxt);
+ if(OK != i4_status)
+ {
+ return NOT_OK;
+ }
+ i4_new_lyr_flag = SVCD_FALSE;
+
+ /* Check whether the picture boundary is detected */
+ /* or not */
+ if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
+ {
+ return (OK);
+ }
+
+ /* Otherwise look for next nal and compare again */
+ *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
+ }
+
+ do
+ {
+ WORD32 i4_sps_pps_corrupt_status;
+ WORD32 i4_tgt_lyr_bckup;
+ /* If following conditions are true then there */
+ /* is no data left to decode next NAL and hence*/
+ /* no further processing is required */
+ if((NAL_END != ps_nal_parse_ctxt->i4_find_nal_state) ||
+ ((WORD64) i4_cur_pos >= (WORD64) *pu4_num_bytes))
+ {
+ return (OK);
+ }
+
+ /* Otherwise fill the parameters */
+ pu1_buf = pu1_stream_buffer;
+ pu1_buf += i4_cur_pos;
+ i4_buf_size = *pu4_num_bytes - i4_cur_pos;
+
+ /* Get the NAL prms. This involves the following things*/
+ /* 1. Decode the NAL header */
+ /* 2. Set the discard flag */
+ /* 3. Decode the slice header if needed */
+ isvcd_set_default_nal_prms(&s_nal_prms);
+
+ /* take a back up of tgt lyr update flag */
+ i4_tgt_lyr_bckup = ps_nal_parse_ctxt->i4_tgt_lyr_update;
+
+ /* the tgt attributes should not be updaetd while pic boundary det*/
+ ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
+
+ i4_status = isvcd_get_nal_prms(pu1_buf, i4_buf_size, &s_nal_prms, &s_prefix_nal_prms,
+ &s_prefix_nal_buf, &u4_err_code, &i4_sps_pps_corrupt_status,
+ &i4_nal_discard_flag, ps_nal_parse_ctxt);
+ /* restore back the tgt lyr update flag */
+ ps_nal_parse_ctxt->i4_tgt_lyr_update = i4_tgt_lyr_bckup;
+ /* If the error code by the nal prms decoder then declare*/
+ /* picture boundary */
+ if(0 != u4_err_code)
+ {
+ return (OK);
+ }
+
+ i4_more_data_flag = SVCD_FALSE;
+
+ /* If prefix NAL unit comes then save the nal prms*/
+ if(PREFIX_UNIT_NAL == s_nal_prms.i4_nal_unit_type)
+ {
+ UWORD32 u4_bytes_consumed;
+ WORD32 i4_status;
+
+ /* If prefix NAL is not discarded then set the varaibles */
+ /* appropriatly */
+ if(SVCD_FALSE == i4_nal_discard_flag)
+ {
+ s_prefix_nal_buf.i4_valid_flag = SVCD_TRUE;
+ memcpy(&s_prefix_nal_prms, &s_nal_prms, sizeof(nal_prms_t));
+ }
+
+ /* Go to next start code */
+ i4_zero_cnt = 0;
+ u4_bytes_consumed = 0;
+ i4_status = isvcd_nal_find_start_code(pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
+ &i4_zero_cnt, &u4_bytes_consumed);
+ /* If associated NAL unit is not present then */
+ if(SC_FOUND != i4_status)
+ {
+ return (OK);
+ }
+ i4_cur_pos += u4_bytes_consumed;
+ i4_more_data_flag = SVCD_TRUE;
+ }
+ } while(SVCD_TRUE == i4_more_data_flag);
+
+ /* Do further picture boundary detection only for */
+ /* VCL NAL unit (excliding prefix NAL unit) */
+ if((NON_VCL_NAL == s_nal_prms.i4_derived_nal_type) ||
+ (PREFIX_UNIT_NAL == s_nal_prms.i4_nal_unit_type) || (SVCD_TRUE == i4_nal_discard_flag))
+ {
+ return (OK);
+ }
+
+ if(SVCD_FALSE == i4_new_lyr_flag)
+ {
+ if(PIC_BOUND_DQID == i4_pic_bound_type)
+ {
+ /* If picture boundary was detetcted based on change*/
+ /* in DQID then declare picture boundary if DQID of the third slice is different */
+ if(i4_prev_dqid != s_nal_prms.i4_dqid)
+ {
+ return (OK);
+ }
+ }
+ else
+ {
+ /* If picture boundary was detetcted based on change in DQID */
+ /* then declare picture boundary if dependency id of third slice is different */
+ if(PIC_BOUND_SLICE_PRMS != i4_pic_bound_type)
+ {
+ return NOT_OK;
+ }
+
+ if((i4_prev_dqid & 0xF) != (s_nal_prms.i4_dqid & 0xF))
+ {
+ return (OK);
+ }
+ }
+
+ isvcd_compare_nal_prms(&s_nal_prms, SECOND_PASS, i4_prev_dqid, &i4_pic_bound_type,
+ &i4_pic_bound_status, ps_nal_parse_ctxt);
+ *pi4_pic_bound_status = i4_pic_bound_status;
+
+ if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
+ {
+ ps_nal_parse_ctxt->i4_prev_dq_id = i4_prev_dqid;
+ }
+ }
+ else
+ {
+ if(SVCD_TRUE != i4_new_lyr_flag)
+ {
+ return NOT_OK;
+ }
+ /* The NAL header is not corrupted only if any of the following conditions are true */
+ /* 1. The DQID of the first slice differs with DQID of the third slice */
+ /* 2. Picture boundary is detected between first slice and third slice */
+ if(i4_prev_dqid == s_nal_prms.i4_dqid)
+ {
+ isvcd_compare_nal_prms(&s_nal_prms, SECOND_PASS, i4_prev_dqid, &i4_pic_bound_type,
+ &i4_pic_bound_status, ps_nal_parse_ctxt);
+ /* NAL header is corrupted and hence correct it */
+ if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
+ {
+ ps_nal_prms->i4_dqid = s_nal_prms.i4_dqid;
+ ps_nal_prms->i4_dependency_id = s_nal_prms.i4_dependency_id;
+ ps_nal_prms->i4_quality_id = s_nal_prms.i4_quality_id;
+ ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
+ }
+ }
+ *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
+ }
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_insert_vcl_node */
+/* */
+/* Description : This routine inserts a DQID layer into DQID list */
+/* (this will add a VCL NAL node into VCL NAL structure */
+/* */
+/* Inputs : 1. vcl nal structure */
+/* 2. VCL node to be inserted */
+/* Globals : None */
+/* Processing : */
+/* */
+/* Outputs : Updated vcl nal structure */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_insert_vcl_node(vcl_nal_t *ps_vcl_nal, vcl_node_t *ps_vcl_node)
+{
+ vcl_node_t *ps_bot_node;
+ vcl_node_t *ps_top_node;
+ vcl_node_t *ps_node;
+ WORD32 i4_rqrd_dqid;
+
+ /* sanity checks */
+ if((NULL == ps_vcl_nal) || (NULL == ps_vcl_node))
+ {
+ return NOT_OK;
+ }
+
+ i4_rqrd_dqid = (ps_vcl_node->i4_dependency_id << 4);
+ i4_rqrd_dqid += ps_vcl_node->i4_quality_id;
+ ps_node = ps_vcl_nal->ps_bot_node;
+
+ /* Search for node which has a DQID which is */
+ /* lesser than taht of the node to inserted */
+ while(NULL != ps_node)
+ {
+ WORD32 i4_dqid;
+
+ i4_dqid = (ps_node->i4_dependency_id << 4);
+ i4_dqid += ps_node->i4_quality_id;
+
+ /* If we get a DQID which is greater than*/
+ /* the DQID of the node to be inserted */
+ /* then break out of the loop and update */
+ if(i4_dqid > i4_rqrd_dqid)
+ {
+ ps_bot_node = ps_node->ps_bot_node;
+ break;
+ }
+
+ ps_node = ps_node->ps_top_node;
+ }
+
+ /* If none of the nodes in the list have DQId */
+ /* greater than the node to be inserted then */
+ /* bottom node will be top most node */
+ if(NULL == ps_node)
+ {
+ ps_bot_node = ps_vcl_nal->ps_top_node;
+ }
+
+ /* Insert the node into DQID list */
+ if(NULL != ps_bot_node)
+ {
+ ps_top_node = ps_bot_node->ps_top_node;
+ }
+ else
+ {
+ ps_top_node = ps_vcl_nal->ps_bot_node;
+ }
+
+ /* Join previous node and specified node */
+ if(NULL != ps_bot_node)
+ {
+ ps_bot_node->ps_top_node = ps_vcl_node;
+ }
+ else
+ {
+ ps_vcl_nal->ps_bot_node = ps_vcl_node;
+ }
+ ps_vcl_node->ps_bot_node = ps_bot_node;
+
+ /* Join next node and specified node */
+ if(NULL != ps_top_node)
+ {
+ ps_top_node->ps_bot_node = ps_vcl_node;
+ }
+ else
+ {
+ ps_vcl_nal->ps_top_node = ps_vcl_node;
+ }
+ ps_vcl_node->ps_top_node = ps_top_node;
+
+ return (OK);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_update_nal_ctxt */
+/* */
+/* Description : Updates the vcl nal or non vcl structures. */
+/* */
+/* Inputs : ps_nal_parse_ctxt - Bitstream extract context structure */
+/* vcl nal structure pointer */
+/* NON vcl nal structure */
+/* */
+/* Globals : None */
+/* */
+/* Processing : If VCL NAL then adds a node to DQID list */
+/* otherwise adds information to non vcl structure */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_update_nal_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt, vcl_nal_t *ps_vcl_nal,
+ non_vcl_nal_t *ps_non_vcl_nal)
+{
+ /*! If current NAL is VCL NAL then
+ - Insert a VCL node into DQID list if neccessery
+ - update the information part of NAL unit */
+ /*! Otherwise, populate the buffer parameters into non vcl output
+ structure */
+ nal_prms_t *ps_nal_prms;
+ nal_buf_t *ps_nal_buf, *ps_prefix_nal_buf;
+
+ ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
+ ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
+ ps_nal_buf = &ps_nal_parse_ctxt->s_nal_buf;
+ ps_prefix_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
+
+ /* If prefix NAL unit then */
+ /* - calculate the SODB length */
+ if(PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
+ {
+ /* Since we consume the zeroes in start code also */
+ /* size has to reduced */
+ if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
+ {
+ ps_prefix_nal_buf->i4_buf_size -= 2;
+ }
+
+ ps_prefix_nal_buf->u4_max_bits =
+ isvcd_nal_rbsp_to_sodb(ps_prefix_nal_buf->pu1_buf, ps_prefix_nal_buf->i4_buf_size, 0);
+ memcpy(&ps_nal_parse_ctxt->s_prefix_nal_prms, &ps_nal_parse_ctxt->s_nal_prms,
+ sizeof(nal_prms_t));
+ return;
+ }
+
+ if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ /* Since we consume the zeroes in start code also */
+ /* size has to reduced */
+ if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
+ {
+ ps_nal_buf->i4_buf_size -= 2;
+ }
+ }
+
+ if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
+ {
+ dqid_node_t *ps_dqid_node;
+ vcl_node_t *ps_node;
+ WORD32 i4_status;
+ dec_pic_params_t *ps_pps;
+ dec_seq_params_t *ps_sps;
+ vcl_buf_hdr_t *ps_vcl_hdr;
+ vcl_buf_hdr_t *ps_prev_vcl_hdr;
+ WORD32 i4_slice_offset;
+
+ ps_sps = ps_nal_parse_ctxt->pv_seq_prms;
+ ps_sps += ps_nal_prms->u1_sps_id;
+ ps_pps = ps_nal_parse_ctxt->pv_pic_prms;
+ ps_pps += ps_nal_prms->u1_pps_id;
+
+ /* Get the VCL NAL node */
+ i4_status = isvcd_get_dqid_node(&ps_nal_parse_ctxt->s_dqid_ctxt,
+ (UWORD8) ps_nal_parse_ctxt->i4_prev_dq_id, &ps_dqid_node);
+
+ ps_node = ps_dqid_node->ps_vcl_node;
+
+ if(NULL == ps_node)
+ {
+ /* no active node has been acquired */
+ return;
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* The DQID list updation should happen only once in a */
+ /* layer. Hence a flag used to determine whether the */
+ /* layer is already initialized or not. */
+ /*-------------------------------------------------------------------*/
+ if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
+ {
+ /* Update the DQID node */
+ ps_dqid_node->u1_valid_flag = SVCD_TRUE;
+ ps_dqid_node->u1_dqid = (ps_nal_prms->i4_dependency_id << 4);
+ ps_dqid_node->u1_dqid += ps_nal_prms->i4_quality_id;
+ ps_dqid_node->i4_poc_lsb = ps_nal_prms->i4_poc_lsb;
+ ps_dqid_node->i4_delta_poc_bot = ps_nal_prms->i4_delta_poc_bot;
+ ps_dqid_node->ai4_delta_poc[0] = ps_nal_prms->ai4_delta_poc[0];
+ ps_dqid_node->ai4_delta_poc[1] = ps_nal_prms->ai4_delta_poc[1];
+
+ /* Update the VCL node */
+ ps_node->i4_quality_id = ps_nal_prms->i4_quality_id;
+ ps_node->i4_dependency_id = ps_nal_prms->i4_dependency_id;
+ ps_node->i4_temporal_id = ps_nal_prms->i4_temporal_id;
+ ps_node->i4_priority_id = ps_nal_prms->i4_priority_id;
+ ps_node->i4_idr_pic_flag = ps_nal_prms->i4_idr_pic_flag;
+ ps_node->i4_nal_ref_idc = ps_nal_prms->i4_nal_ref_idc;
+ ps_node->i4_nal_unit_type = ps_nal_prms->i4_nal_unit_type;
+ ps_node->i4_use_ref_base = ps_nal_prms->i4_use_ref_base_pic_flag;
+ ps_node->i4_nal_ref_idc = ps_nal_prms->i4_nal_ref_idc;
+ ps_node->u1_sps_id = ps_nal_prms->u1_sps_id;
+ ps_node->u1_pps_id = ps_nal_prms->u1_pps_id;
+ ps_node->u2_frm_num = ps_nal_prms->u2_frm_num;
+ ps_node->i4_idr_pic_num = ps_nal_prms->i4_idr_pic_num;
+ ps_node->i4_num_slices = 0;
+ ps_node->u1_acc_no_int_pred = 1;
+ if(0 == ps_sps->u1_pic_order_cnt_type)
+ {
+ ps_node->i4_poc_syntax = ps_nal_prms->i4_poc_lsb;
+ }
+ else
+ {
+ ps_node->i4_poc_syntax = ps_nal_prms->ai4_delta_poc[0];
+ }
+
+ /* Insert the node into DQID list */
+ i4_status = isvcd_insert_vcl_node(ps_vcl_nal, ps_node);
+ if(OK != i4_status)
+ {
+ return;
+ }
+
+ /* Reset the previous field */
+ ps_nal_parse_ctxt->ps_prev_vcl_buf = NULL;
+ ps_node->ps_first_vcl_nal = NULL;
+ }
+
+ /* Update accumulated no inter layer prediction */
+ ps_node->u1_acc_no_int_pred &= (UWORD8) ps_nal_prms->i4_no_int_lyr_pred;
+
+ /****************** Fill VCL BUF header ************/
+
+ /* If prefix NAL unit is present then update */
+ /* the following */
+ /* - Start of buffer header will be present in*/
+ /* before the start of prefix NAL unit's SODB*/
+ /* data. */
+ /* Note: If memeory left for buffer header */
+ /* of the prefix NAL unit will have junk */
+ /* values */
+
+ if(NULL == ps_nal_buf->pu1_buf)
+ {
+ /* no nal needs to be added into the list hence return */
+ return;
+ }
+ else
+ {
+ ps_vcl_hdr = (vcl_buf_hdr_t *) (ps_nal_buf->pu1_buf - GET_NAL_BUF_INC(VCL_NAL));
+ }
+
+ i4_slice_offset = 0;
+ if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
+ {
+ ps_vcl_hdr = (vcl_buf_hdr_t *) (ps_prefix_nal_buf->pu1_buf - GET_NAL_BUF_INC(VCL_NAL));
+ i4_slice_offset = ps_nal_buf->pu1_buf - ps_prefix_nal_buf->pu1_buf;
+ }
+
+ /* Update the next field of the previous nal */
+ /* unit or if it is the first NAL then update */
+ /* VCL node information */
+ ps_prev_vcl_hdr = ps_nal_parse_ctxt->ps_prev_vcl_buf;
+ if(NULL != ps_prev_vcl_hdr)
+ {
+ ps_prev_vcl_hdr->ps_next = ps_vcl_hdr;
+ }
+ else
+ {
+ ps_node->ps_first_vcl_nal = ps_vcl_hdr;
+ }
+
+ /* Fill the VCL buffer header */
+ ps_vcl_hdr->ps_next = NULL;
+ ps_vcl_hdr->i4_no_int_lyr_pred = ps_nal_prms->i4_no_int_lyr_pred;
+ ps_vcl_hdr->i4_first_mb_addr = ps_nal_prms->u4_first_mb_addr;
+ ps_vcl_hdr->u4_prefix_nal_bits = ps_prefix_nal_buf->u4_max_bits;
+ ps_vcl_hdr->i4_slice_offset = 0;
+ ps_vcl_hdr->i4_buf_offset = GET_NAL_BUF_INC(VCL_NAL);
+ ps_vcl_hdr->i4_slice_offset = i4_slice_offset;
+
+ /* Determine max num bits */
+ ps_nal_buf->u4_max_bits = isvcd_nal_rbsp_to_sodb(
+ ps_nal_buf->pu1_buf, ps_nal_buf->i4_buf_size, ps_pps->u1_entropy_coding_mode);
+ ps_vcl_hdr->u4_max_bits = ps_nal_buf->u4_max_bits;
+
+ /* Updates */
+ ps_nal_parse_ctxt->ps_prev_vcl_buf = ps_vcl_hdr;
+ ps_node->i4_num_slices += 1;
+ }
+ /*-----------------------------------------------------------------------*/
+ /* If start of NAL and if its a NON VCL NAL then update the */
+ /* start address of the NON VCL NAL */
+ /*-----------------------------------------------------------------------*/
+ else
+ {
+ non_vcl_buf_hdr_t *ps_non_vcl_buf_hdr;
+ non_vcl_buf_hdr_t *ps_prev_non_vcl_buf_hdr;
+
+ ps_non_vcl_buf_hdr =
+ (non_vcl_buf_hdr_t *) (ps_nal_buf->pu1_buf - GET_NAL_BUF_INC(NON_VCL_NAL));
+
+ /* Update NON VCL structure */
+ ps_non_vcl_buf_hdr->i4_nal_unit_type = ps_nal_prms->i4_nal_unit_type;
+ ps_non_vcl_buf_hdr->ps_next = NULL;
+ ps_non_vcl_buf_hdr->i4_buf_offset = GET_NAL_BUF_INC(NON_VCL_NAL);
+ ps_non_vcl_buf_hdr->i4_buf_size = ps_nal_buf->i4_buf_size;
+
+ /* Update the next field and first non vcl fields of */
+ /* non vcl buffer header structure and non vcl */
+ /* structure respectively */
+ ps_prev_non_vcl_buf_hdr = ps_nal_parse_ctxt->ps_prev_non_vcl_buf;
+ if(NULL != ps_prev_non_vcl_buf_hdr)
+ {
+ ps_prev_non_vcl_buf_hdr->ps_next = ps_non_vcl_buf_hdr;
+ }
+ else
+ {
+ ps_non_vcl_nal->ps_first_non_vcl_nal = ps_non_vcl_buf_hdr;
+ }
+
+ /* Updates */
+ ps_nal_parse_ctxt->i4_num_non_vcl_nals += 1;
+ ps_non_vcl_nal->i4_num_non_vcl_nals = ps_nal_parse_ctxt->i4_num_non_vcl_nals;
+ ps_nal_parse_ctxt->ps_prev_non_vcl_buf = ps_non_vcl_buf_hdr;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_idr_err_hdlr */
+/* */
+/* Description : This routine shall be invoked to handle a case when a */
+/* slice is an IDR picture and it is referring to corrupted */
+/* SPS or PPS */
+/* */
+/* Inputs : 1. VCL NAL structure */
+/* 2. NAL paramters */
+/* 3. NAL parse context structure */
+/* Globals : None */
+/* Processing : It will set the highest available dependency id below the*/
+/* current dependency id as the target layer. Also sets the */
+/* update target layer flag to FALSE as target layer need not*/
+/* adopt to the application's target layer in the current */
+/* picture */
+/* */
+/* Outputs : Updated vcl nal structure */
+/* Updated internal target layer attributes */
+/* Updated target layer update flag */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_idr_err_hdlr(vcl_nal_t *ps_vcl_nal, nal_prms_t *ps_nal_prms,
+ nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ vcl_node_t *ps_vcl_node;
+ target_lyr_attr_t *ps_int_attr;
+
+ /* sanity checks */
+ if((NULL == ps_vcl_nal) || (NULL == ps_nal_prms) || (NULL == ps_nal_parse_ctxt))
+ {
+ return NOT_OK;
+ }
+ UNUSED(ps_nal_prms);
+
+ /* Initializations */
+ ps_vcl_node = ps_vcl_nal->ps_top_node;
+ ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
+
+ /* the highest node present in the depedency list will be */
+ /* considered as targte layer and appropriate params will be used */
+
+ /* If not found then delete all the layers in the AU */
+ if(NULL == ps_vcl_node)
+ {
+ ps_int_attr->i4_dependency_id = -1;
+ ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
+ }
+ else
+ {
+ /* Set the target layer */
+ ps_int_attr->i4_dependency_id = ps_vcl_node->i4_dependency_id;
+ ps_int_attr->i4_quality_id = ps_vcl_node->i4_quality_id;
+ }
+
+ return (OK);
+}
+/*****************************************************************************/
+/* */
+/* Function Name :svcd_refine_dqid_list */
+/* */
+/* Description : Inserts the dummy nodes for each dependency id which */
+/* have not come in the bitstream */
+/* */
+/* Inputs :VCL NAL structure */
+/* NAL parse context structure */
+/* Globals : None */
+/* Processing : For each dependency id till the target dependency id */
+/* - If layer already exists (came in the bitstream) then */
+/* do nothing */
+/* - Otherwsie insert a dummy node */
+/* */
+/* Outputs : Updated VCL NAL structure */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_refine_dqid_list(vcl_nal_t *ps_vcl_nal, nal_parse_ctxt_t *ps_nal_parse_ctxt)
+{
+ vcl_node_t *ps_node;
+ target_lyr_attr_t *ps_int_attr;
+ dqid_ctxt_t *ps_dqid_ctxt;
+ UWORD8 u1_dep_id;
+ WORD32 i4_status;
+ WORD32 i4_dep_id;
+
+ ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
+ ps_dqid_ctxt = &ps_nal_parse_ctxt->s_dqid_ctxt;
+ i4_dep_id = -1;
+
+ for(u1_dep_id = 0; u1_dep_id <= ps_int_attr->i4_dependency_id; u1_dep_id++)
+ {
+ dqid_node_t *ps_dqid_node;
+
+ /* Get a DQID node */
+ i4_status = isvcd_get_dqid_node(ps_dqid_ctxt, (UWORD8) (u1_dep_id << 4), &ps_dqid_node);
+ if(OK != i4_status)
+ {
+ return NOT_OK;
+ }
+
+ /* If node does not exist already then insert a dummy node */
+ if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
+ {
+ if(1 == ps_nal_parse_ctxt->i4_idr_pic_err_flag)
+ {
+ ps_int_attr->i4_dependency_id = i4_dep_id;
+ ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
+
+ /* remove all the nodes from dependency list */
+ /* which are at higher dependency than the */
+ /* value set in init attributes */
+ while(NULL != ps_vcl_nal->ps_top_node)
+ {
+ /* if higher dependency */
+ if(ps_vcl_nal->ps_top_node->i4_dependency_id > i4_dep_id)
+ {
+ ps_vcl_nal->ps_top_node = ps_vcl_nal->ps_top_node->ps_bot_node;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* if no node exists in the dependency list */
+ if(NULL == ps_vcl_nal->ps_top_node)
+ {
+ ps_vcl_nal->ps_bot_node = NULL;
+ }
+ else if(ps_vcl_nal->ps_top_node == ps_vcl_nal->ps_bot_node)
+ {
+ /* if a single node exists */
+ ps_vcl_nal->ps_top_node->ps_bot_node = NULL;
+ ps_vcl_nal->ps_bot_node->ps_top_node = NULL;
+ }
+
+ return (NOT_OK);
+ }
+ else
+ {
+ ps_dqid_node->u1_valid_flag = SVCD_TRUE;
+ ps_dqid_node->u1_dqid = (u1_dep_id << 4);
+
+ /* Fill VCL node information */
+ ps_node = ps_dqid_node->ps_vcl_node;
+ ps_node->i4_dependency_id = u1_dep_id;
+ ps_node->i4_quality_id = 0;
+ ps_node->ps_first_vcl_nal = NULL;
+ }
+
+ /* Insert node into DQID list */
+ i4_status = isvcd_insert_vcl_node(ps_vcl_nal, ps_node);
+ if(OK != i4_status)
+ {
+ return (NOT_OK);
+ }
+ }
+
+ i4_dep_id++;
+ } /* End of loop over all the dependency id */
+ return (OK);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_set_target_attr */
+/* */
+/* Description : Sets the target layer attributes */
+/* */
+/* Inputs : i4_target_quality_id - Target layer quality id */
+/* i4_target_dependency_id - Target layer dependency id */
+/* i4_target_temporal_id - Target layer temporal id */
+/* i4_target_priority_id - Target layer priority id */
+/* pv_nal_parse_ctxt - Pointer module handle */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_nal_parse_set_target_attr(WORD32 i4_target_quality_id, WORD32 i4_target_dependency_id,
+ WORD32 i4_target_temporal_id, WORD32 i4_target_priority_id,
+ void *pv_nal_parse_ctxt)
+{
+ nal_parse_ctxt_t *ps_nal_parse_ctxt;
+ target_lyr_attr_t *ps_app_attr;
+
+ if((i4_target_quality_id > MAX_QUALITY_ID) || (i4_target_dependency_id > MAX_DEPENDENCY_ID))
+ {
+ return IV_FAIL;
+ }
+
+ ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
+ ps_app_attr = &ps_nal_parse_ctxt->s_app_attr;
+
+ /*-----------------------------------------------------------------------*/
+ /*! Register the target information into context structure */
+ /*-----------------------------------------------------------------------*/
+ ps_app_attr->i4_quality_id = i4_target_quality_id;
+ ps_app_attr->i4_dependency_id = i4_target_dependency_id;
+ ps_app_attr->i4_temporal_id = i4_target_temporal_id;
+ ps_app_attr->i4_priority_id = i4_target_priority_id;
+ return IV_SUCCESS;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_reset_ctxt */
+/* */
+/* Description : Initializes the bitstream extraction module. Should be */
+/* called once in a sequence */
+/* */
+/* Inputs : i4_input_bitstream_mode - Input bitstream mode RFC or */
+/* Annex B */
+/* i4_input_mode - Input mode - Full input mode or partial */
+/* input mode */
+/* pv_nal_parse_ctxt - Module handle */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+void isvcd_nal_parse_reset_ctxt(WORD32 i4_input_bitstream_mode, WORD32 i4_input_mode,
+ void *pv_nal_parse_ctxt)
+{
+ nal_parse_ctxt_t *ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
+ UNUSED(i4_input_mode);
+
+ /*-----------------------------------------------------------------------*/
+ /*! Set the input bitstream mode of context structure */
+ /*-----------------------------------------------------------------------*/
+ switch(i4_input_bitstream_mode)
+ {
+ case ANNEX_B:
+ case NON_ANNEX_B:
+ break;
+ default:
+ break;
+ }
+
+ ps_nal_parse_ctxt->i4_input_bitstream_mode = i4_input_bitstream_mode;
+
+ /*-----------------------------------------------------------------------*/
+ /*! Perform the picture level initialization */
+ /*-----------------------------------------------------------------------*/
+ isvcd_pic_reset_ctxt(pv_nal_parse_ctxt);
+
+ /* Reset the prefix nal unit buffer structure */
+ isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
+
+ /*-----------------------------------------------------------------------*/
+ /*! Reset other varaibles */
+ /*-----------------------------------------------------------------------*/
+ ps_nal_parse_ctxt->i4_dec_frst_sc_flag = SVCD_TRUE;
+ ps_nal_parse_ctxt->i4_eos_flag = SVCD_FALSE;
+ ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 0;
+ ps_nal_parse_ctxt->u4_bytes_left = 0;
+
+ /* Reset target layer attributes */
+ {
+ target_lyr_attr_t *ps_app_attr;
+ target_lyr_attr_t *ps_int_attr;
+
+ ps_app_attr = &ps_nal_parse_ctxt->s_app_attr;
+ ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
+
+ ps_app_attr->i4_dependency_id = MAX_DEPENDENCY_ID;
+ ps_app_attr->i4_quality_id = MAX_QUALITY_ID;
+ ps_app_attr->i4_temporal_id = MAX_TEMPORAL_ID;
+ ps_app_attr->i4_priority_id = MAX_PRIORITY_ID;
+
+ ps_int_attr->i4_dependency_id = -1;
+ ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
+ ps_int_attr->i4_temporal_id = 0;
+ ps_int_attr->i4_priority_id = MAX_PRIORITY_ID;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_partial_signal_eos */
+/* */
+/* Description : Does processing when end of stream occurs for partial */
+/* input mode of operation. */
+/* */
+/* Inputs : pv_nal_parse_ctxt - bitstream extract context structure */
+/* pv_out_vcl_nal - vcl nal structure */
+/* pv_out_non_vcl_nal - non vcl nal structure */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : None */
+/* */
+/* Returns : Picture boundary detetcted or not */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_nal_parse_partial_signal_eos(void *pv_nal_parse_ctxt, void *pv_out_vcl_nal,
+ void *pv_out_non_vcl_nal)
+{
+ nal_parse_ctxt_t *ps_nal_parse_ctxt;
+ vcl_nal_t *ps_vcl_nal;
+
+ ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
+ ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_nal;
+
+ /* for RFC mode */
+ if(NON_ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ /* Reset the end of stream flag so that in */
+ ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
+ }
+
+ if(1 == ps_nal_parse_ctxt->u1_pic_boundary_aud_flag)
+ {
+ ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
+ }
+ /* Update VCL node if it is first call in the */
+ /* flush mode */
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_eos_flag)
+ {
+ WORD32 i4_status;
+
+ /* Update the unfinished NAL into VCL node if */
+ /* all the following conditions are true */
+ /* 1. We have not found the start code and */
+ /* NAL boundary is not detected yet */
+ /* 2. NAL is not discarded */
+ if((FIND_NAL_END == ps_nal_parse_ctxt->i4_find_nal_state) &&
+ (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag))
+ {
+ isvcd_update_nal_ctxt(ps_nal_parse_ctxt, pv_out_vcl_nal, pv_out_non_vcl_nal);
+ }
+
+ ps_nal_parse_ctxt->i4_idr_pic_err_flag = 0;
+ /* Refine based on the no inter layer pred flag*/
+ i4_status = isvcd_refine_dqid_list(ps_vcl_nal, ps_nal_parse_ctxt);
+
+ if(!(OK == i4_status))
+ {
+ return i4_status;
+ }
+ UNUSED(i4_status);
+
+ /* Reset the context structure variables */
+ isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+
+ /* Reset the end of stream flag so that in */
+ /* the next flush call the above steps need */
+ /* not be performed */
+ ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
+
+ return (PIC_BOUNDARY_TRUE);
+ }
+ else
+ {
+ return (FLUSH_DECODED_PICTURE);
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_pic_bound_proc */
+/* */
+/* Description : Function does the picture end processign and resets */
+/* */
+/* */
+/* Inputs : ps_nal_parse_ctxt, ps_vcl_nal */
+/* Globals : none */
+/* Processing : DQid list refiniment and resets */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_nal_parse_pic_bound_proc(nal_parse_ctxt_t *ps_nal_parse_ctxt, vcl_nal_t *ps_vcl_nal,
+ nal_prms_t *ps_nal_prms)
+{
+ WORD32 i4_status;
+
+ i4_status = isvcd_refine_dqid_list(ps_vcl_nal, ps_nal_parse_ctxt);
+
+ /* in case of IDR pictures if the node */
+ /* which has to be added into dependency */
+ /* list is not valied then the layer below */
+ /* that node is set as target layer */
+
+ if(NOT_OK == i4_status)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ ps_vcl_nal->i1_nal_ref_id_next = -1;
+ }
+ else
+ {
+ /* update the next access unit params */
+ /* will be used by lower level decoder*/
+ /* for concealment of frame number */
+ /* applicable for single layer cases */
+ ps_vcl_nal->i1_nal_ref_id_next = ps_nal_prms->i4_nal_ref_idc;
+
+ ps_vcl_nal->u2_frm_num_next = ps_nal_prms->u2_frm_num;
+ }
+
+ /* -------- reset few variables in context structure ----*/
+ isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_vcl_nal_partial */
+/* */
+/* Description : None */
+/* */
+/* Inputs : pv_nal_parse_ctxt - bitstream extract ctxt */
+/* structure */
+/* pv_input_bitstream_ctxt - bitstream context */
+/* pv_out_non_vcl_nal - non vcl nal structure (output) */
+/* pv_out_vcl_nal - vcl nal structure (output) */
+/* pu4_bytes_consumed - bytes consumed variable(output) */
+/* pi4_num_packets_consumed - packets consumed (output/RFC) */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : Updates bytes consumed variable, packets consumed, */
+/* output structures (vcl nal , non vcl nal) */
+/* */
+/* Returns : If picture bounadry is detetcted then PIC_BOUNDARY_TRUE */
+/* otherwise PIC_BOUNDARY_FALSE */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_nal_parse_vcl_nal_partial(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
+ void *pv_out_non_vcl_nal, void *pv_out_vcl_nal,
+ UWORD32 *pu4_bytes_consumed, UWORD32 *pu4_num_bytes)
+{
+ /*! - Search for the NAL boundary
+ - If NAL boundary is not found and bytes consumed is lesser than
+ minimum buffer size then break out of the loop
+ - if it is start of NAL then read the NAL header
+ - If it is a VCL NAL then invoke picture boundary detection logic and
+ picture boundary is detected then break out of the loop without
+ updating the bytes consumed variable
+ - NAL discard logic determines whther the current NAL has to be
+ discarded or not
+ - If NAL is not discarded then populate the vcl or non vcl output
+ structures
+ */
+ nal_parse_ctxt_t *ps_nal_parse_ctxt;
+ vcl_nal_t *ps_vcl_nal;
+ non_vcl_nal_t *ps_non_vcl_nal;
+ nal_unit_t *ps_nal_unit;
+ WORD32 i4_nal_start_flag, i4_cur_pos, i4_status;
+ WORD32 i4_nal_header_len, i4_more_data_flag;
+ UWORD32 u4_bytes_consumed_temp = 0;
+ UWORD8 **ppu1_out_buf;
+ nal_prms_t *ps_nal_prms;
+ WORD32 i4_pic_bound_status;
+
+ ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
+ ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_nal;
+ ps_non_vcl_nal = (non_vcl_nal_t *) pv_out_non_vcl_nal;
+ ps_nal_unit = (nal_unit_t *) ps_nal_parse_ctxt->pv_nal_unit;
+ ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
+
+ /* Initialization */
+ i4_cur_pos = 0;
+ *pu4_bytes_consumed = 0;
+ i4_nal_header_len = 0;
+ i4_nal_start_flag = SVCD_FALSE;
+ i4_more_data_flag = SVCD_TRUE;
+ i4_pic_bound_status = PIC_BOUNDARY_FALSE;
+
+ ps_non_vcl_nal->i4_num_non_vcl_nals = ps_nal_parse_ctxt->i4_num_non_vcl_nals;
+
+ /* Since we do not perform the picture boundary detection */
+ /* on the prefix NAL unit, the current picture's prefix */
+ /* NAL unit will be at the bottom of the buffer. Hence */
+ /* it should be copied to top of the buffer */
+ if(SVCD_TRUE == ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au)
+ {
+ nal_buf_t *ps_prefix_nal_buf;
+
+ ps_prefix_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
+ if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
+ {
+ WORD32 i4_buf_size;
+ UWORD8 *pu1_vcl_nal;
+
+ if(ps_prefix_nal_buf->i4_buf_size > 0)
+ {
+ i4_buf_size = ps_prefix_nal_buf->i4_buf_size;
+ i4_buf_size = UP_ALIGN_8(i4_buf_size + BUFFER_ALIGN_4);
+ }
+ else
+ {
+ i4_buf_size = 0;
+ }
+
+ pu1_vcl_nal = ps_nal_parse_ctxt->pu1_vcl_nal_buf + i4_buf_size;
+
+ memmove(ps_nal_parse_ctxt->pu1_vcl_nal_buf, ps_prefix_nal_buf->pu1_buf, i4_buf_size);
+ ps_prefix_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_vcl_nal_buf;
+ ps_nal_parse_ctxt->pu1_vcl_nal_buf = pu1_vcl_nal;
+
+ /* subtract the buffer size left */
+ ps_nal_parse_ctxt->u4_bytes_left_vcl -= i4_buf_size;
+ }
+ /* Reset the top and bottom node */
+ ps_vcl_nal->ps_top_node = NULL;
+ ps_vcl_nal->ps_bot_node = NULL;
+ ps_vcl_nal->i1_nal_ref_id_next = -1;
+ ps_vcl_nal->u2_frm_num_next = 0;
+ }
+
+ /* If number of bytes left in the previous process call */
+ /* is is greater or equal to number of bytes in input */
+ /* buffer of the current process call then declare that */
+ /* end of bitstream has occurred and consume the bytes */
+ /* but do not decode */
+ if(ps_nal_parse_ctxt->u4_bytes_left >= (UWORD32) *pu4_num_bytes)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ *pu4_bytes_consumed = *pu4_num_bytes;
+
+ i4_status =
+ isvcd_nal_parse_partial_signal_eos(ps_nal_parse_ctxt, ps_vcl_nal, ps_non_vcl_nal);
+ /* set the next AU params to default values */
+ ps_vcl_nal->i1_nal_ref_id_next = -1;
+ ps_vcl_nal->u2_frm_num_next = 0;
+
+ return (i4_status);
+ }
+ ps_nal_parse_ctxt->u4_bytes_left = 0;
+
+ /*************************************************************************/
+ /* LOOP OVER NALs */
+ /*************************************************************************/
+ do
+ {
+ nal_buf_t *ps_nal_buf;
+ UWORD32 *pu4_bytes_left;
+
+ /* Find NAL boundary */
+ if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ i4_nal_start_flag = isvcd_get_annex_b_nal_unit(
+ pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
+ &ps_nal_parse_ctxt->i4_find_nal_state, &ps_nal_parse_ctxt->i4_zero_byte_cnt,
+ &u4_bytes_consumed_temp, ps_nal_parse_ctxt->pv_nal_unit, &i4_more_data_flag);
+
+ i4_cur_pos += u4_bytes_consumed_temp;
+ }
+
+ /*********************************************************************/
+ /* READ NAL HEADER AND NAL DISCARD LOGIC */
+ /*********************************************************************/
+
+ /* If it is the start of NAL header perform the following */
+ /* 1. Decode NAL header */
+ /* 2. Determine whether the NAL has to be discarded or not*/
+ /* 3. Detect the picture boundary */
+ if(SVCD_TRUE == i4_nal_start_flag)
+ {
+ UWORD32 u4_err_code;
+ WORD32 i4_sps_pps_corrupt_status;
+ WORD32 i4_internal_dep_id_prev;
+
+ /* Get the NAL prms. This involves the following things*/
+ /* 1. Decode the NAL header */
+ /* 2. Set the discard flag */
+ /* 3. Decode the slice header if needed */
+
+ /* get the dependency id at which the NAl parse is currently */
+ /* present */
+ i4_internal_dep_id_prev = ps_nal_parse_ctxt->s_int_attr.i4_dependency_id;
+
+ i4_status = isvcd_get_nal_prms(
+ ps_nal_unit->pu1_bufs, ps_nal_unit->i4_buf_sizes, ps_nal_prms,
+ &ps_nal_parse_ctxt->s_prefix_nal_prms, &ps_nal_parse_ctxt->s_prefix_nal_buf,
+ &u4_err_code, &i4_sps_pps_corrupt_status, &ps_nal_parse_ctxt->i4_discard_nal_flag,
+ ps_nal_parse_ctxt);
+
+ if(NON_ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
+ }
+
+ /* If the error code returned by the "picture boundary" */
+ /* detetction is */
+ /* 1. Insufficient bitstream size: then store the bytes */
+ /* left and break out of the loop */
+ /* 2. Corrupted slice: then discard the slice */
+ if((NAL_INSUFFICIENT_DATA == (WORD32) u4_err_code) &&
+ (NAL_END != ps_nal_parse_ctxt->i4_find_nal_state))
+ {
+ ps_nal_parse_ctxt->u4_bytes_left = *pu4_num_bytes - *pu4_bytes_consumed;
+
+ /* Reset the NAL level tracking variables */
+ isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+ break;
+ }
+ else if(0 != u4_err_code)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+
+ if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
+ {
+ /* IDR Error handler is called */
+ /* only if for a given layer the NAL */
+ /* haeder and partial slice decode */
+ /* routine comes out as no SPS PPS */
+ /* error. But for Lowest layer in */
+ /* access unit it is doen always */
+ if(i4_internal_dep_id_prev != ps_nal_parse_ctxt->s_int_attr.i4_dependency_id)
+ {
+ /* if the target depedency id has been */
+ /* changed while decoding currnet NAL */
+
+ if((0 != i4_sps_pps_corrupt_status) ||
+ (-1 == ps_nal_parse_ctxt->i4_prev_dq_id))
+ {
+ i4_status =
+ isvcd_idr_err_hdlr(ps_vcl_nal, ps_nal_prms, ps_nal_parse_ctxt);
+ if(OK != i4_status)
+ {
+ return i4_status;
+ }
+ UNUSED(i4_status);
+
+ ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
+ }
+ else
+ {
+ if(0 == ps_nal_prms->i4_quality_id)
+ {
+ /* over write the frame number */
+ ps_nal_parse_ctxt->s_nal_prms.u2_frm_num = 0;
+
+ /* Get the previous layer's DQID */
+ if(ps_nal_parse_ctxt->i4_prev_dq_id < ps_nal_prms->i4_dqid)
+ {
+ ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
+ ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_FALSE;
+ }
+
+ /* update the nal context with the nal */
+ /* header params */
+ isvcd_update_nal_ctxt(ps_nal_parse_ctxt, ps_vcl_nal,
+ ps_non_vcl_nal);
+ }
+ }
+ }
+ }
+ }
+
+ /* Populate the derived nal type into bitstream extract*/
+ /* context structure */
+ i4_nal_header_len = ps_nal_prms->i4_nal_header_len;
+ ps_nal_parse_ctxt->i4_nal_type = ps_nal_prms->i4_derived_nal_type;
+
+ /* get the accumulated idr pic error flag */
+ ps_nal_parse_ctxt->i4_idr_pic_err_flag |=
+ ((SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag) &&
+ (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag) &&
+ (i4_internal_dep_id_prev != ps_nal_parse_ctxt->s_int_attr.i4_dependency_id));
+
+ if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
+ {
+ i4_pic_bound_status = PIC_BOUNDARY_TRUE;
+ ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 1;
+ /* If picture boundary is detected then come out of */
+ /* the loop */
+ if(PIC_BOUNDARY_TRUE == i4_pic_bound_status)
+ {
+ isvcd_nal_parse_pic_bound_proc(ps_nal_parse_ctxt, ps_vcl_nal, ps_nal_prms);
+ break;
+ }
+ }
+ /* Perform the picture boundary detetction if all the */
+ /* following conditions are TRUE */
+ /* 1. VCL NAL */
+ /* 2. Not a prefix NAL */
+ /* 3. Not a discardable NAL */
+ if((VCL_NAL == ps_nal_prms->i4_derived_nal_type) &&
+ (PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) &&
+ (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag))
+ {
+ if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 0;
+
+ i4_status = isvcd_detect_pic_boundary_annex_b(ps_nal_prms, pu1_stream_buffer,
+ i4_cur_pos, &i4_pic_bound_status,
+ ps_nal_parse_ctxt, pu4_num_bytes);
+ }
+
+ /* If picture boundary is detected then come out of */
+ /* the loop */
+ if(PIC_BOUNDARY_TRUE == i4_pic_bound_status)
+ {
+ isvcd_nal_parse_pic_bound_proc(ps_nal_parse_ctxt, ps_vcl_nal, ps_nal_prms);
+ break;
+ }
+ }
+
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
+ {
+ /* Set the active NAL buffer structure and initialize */
+ /* the nal buffer structure */
+ isvcd_get_nal_buf(ps_nal_parse_ctxt, &ps_nal_buf);
+ ps_nal_parse_ctxt->ps_nal_buf = ps_nal_buf;
+ }
+ else
+ {
+ ps_nal_parse_ctxt->ps_nal_buf = NULL;
+ }
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* In RFC based bitstreams, this is a dummy update (in this mode, the*/
+ /* bytes consumed updation is done by picture boundary dectection */
+ /* But for Annex B based streams this is valid update */
+ /*-------------------------------------------------------------------*/
+ *pu4_bytes_consumed += u4_bytes_consumed_temp;
+
+ /*********************************************************************/
+ /* EMULATION PREVENTION AND BYTE SWAPPING */
+ /*********************************************************************/
+
+ /* Determine output buffer */
+ ps_nal_buf = ps_nal_parse_ctxt->ps_nal_buf;
+
+ if(VCL_NAL == ps_nal_parse_ctxt->i4_nal_type)
+ {
+ ppu1_out_buf = &ps_nal_parse_ctxt->pu1_vcl_nal_buf;
+ pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_vcl;
+ if(*pu4_bytes_left < (MAX_VCL_NAL_BUFF_SIZE * 0.05))
+ {
+ return (VCL_NAL_FOUND_FALSE);
+ }
+ }
+ else
+ {
+ ppu1_out_buf = &ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
+ pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_non_vcl;
+ if(*pu4_bytes_left < (MAX_NON_VCL_NAL_BUFF_SIZE * 0.05))
+ {
+ return (VCL_NAL_FOUND_FALSE);
+ }
+ }
+
+ /* if 0 bytes left then discard the current NAL */
+ if(0 >= (WORD32) *pu4_bytes_left)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ /* Perform the emulation prevention and byte swap */
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
+ {
+ UWORD32 u4_output_bytes, u4_buf_inc;
+
+ /* Do emulation prevention and byte swapping on all the packets */
+ /* of RFC or current partial or full Annex B NAL unit */
+ {
+ UWORD32 u4_buf_size;
+
+ /* clip the size before emulation prevention */
+ u4_buf_size = (UWORD32) CLIP3(0, (WORD32) *pu4_bytes_left,
+ (ps_nal_unit->i4_buf_sizes - i4_nal_header_len));
+
+ u4_buf_inc = isvcd_nal_byte_swap_emulation(
+ (UWORD32 *) *ppu1_out_buf, &u4_output_bytes,
+ ps_nal_unit->pu1_bufs + i4_nal_header_len, u4_buf_size,
+ NUM_OF_ZERO_BYTES_BEFORE_START_CODE, &ps_nal_parse_ctxt->s_emulation_ctxt);
+
+ i4_nal_header_len = 0;
+ u4_buf_inc = UP_ALIGN_8(u4_buf_inc);
+ *ppu1_out_buf += u4_buf_inc;
+ *pu4_bytes_left -= u4_buf_inc;
+ ps_nal_buf->i4_buf_size += u4_output_bytes;
+ }
+ }
+
+ /*********************************************************************/
+ /* UPDATE VARIABLES */
+ /*********************************************************************/
+ if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
+ {
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
+ {
+ /* This fucntions updates output nal ctxt - vcl nal structure*/
+ /* and non vcl nal structure depending upon the current NAL */
+ /* type. */
+ /* This will only update parameters which are available at */
+ /* end of NAL unit like nal unit's total size */
+ isvcd_update_nal_ctxt(ps_nal_parse_ctxt, ps_vcl_nal, ps_non_vcl_nal);
+
+ UPDATE_NAL_BUF_PTR(ppu1_out_buf, ps_nal_prms->i4_derived_nal_type, pu4_bytes_left);
+ }
+
+ /* If the prefix NAL unit is not immediatly followed by */
+ /* a AVC NAL unit it shall be discarded and hence reset */
+ /* is done */
+ /* Also if prefix NAL unit is discarded then we should */
+ /* not associate the prefix NAL unit with AVC NAL unit */
+ /* and hence a reset is required */
+ if((PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) ||
+ (SVCD_TRUE == ps_nal_parse_ctxt->i4_discard_nal_flag))
+ {
+ isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
+ }
+
+ /* Reset the nal level tracking variables */
+ isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+ }
+
+ /*------------- while loop ends here --------------------------------*/
+ } while(SVCD_TRUE == i4_more_data_flag);
+
+ return (i4_pic_bound_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_nal_parse_non_vcl_nal */
+/* */
+/* Description : None */
+/* */
+/* Inputs : pv_nal_parse_ctxt - bitstream extract ctxt */
+/* structure */
+/* pv_input_bitstream_ctxt - bitstream context */
+/* pv_out_non_vcl_nal - non vcl nal structure (output) */
+/* pu4_bytes_consumed - bytes consumed variable(output) */
+/* pi4_num_packets_consumed - packets consumed (output/RFC) */
+/* */
+/* Globals : None */
+/* */
+/* Processing : None */
+/* */
+/* Outputs : Updates bytes consumed variable, packets consumed, */
+/* output structures (non vcl nal) */
+/* */
+/* Returns : If vcl nal is found then VCL_NAL_FOUND_TRUE otherwise */
+/* VCL_NAL_FOUND_FALSE */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Vijay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_nal_parse_non_vcl_nal(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
+ void *pv_out_non_vcl_nal, UWORD32 *pu4_bytes_consumed,
+ UWORD32 *pu4_num_bytes)
+{
+ /*! - Search for the NAL boundary
+ - If NAL boundary is not found and bytes consumed is lesser than
+ minimum buffer size then break out of the loop
+ - if it is start of NAL then read the NAL header
+ - If it is a VCL NAL then return from this fucntion saying that
+ VCL NAL found
+ - NAL discard logic determines whther the current NAL has to be
+ discarded or not
+ - If NAL is not discarded then populate the vcl or non vcl output
+ structures
+ */
+
+ nal_parse_ctxt_t *ps_nal_parse_ctxt;
+ non_vcl_nal_t *ps_non_vcl_nal;
+ nal_unit_t *ps_nal_unit;
+ WORD32 i4_nal_start_flag, i4_cur_pos, i4_status;
+ WORD32 i4_nal_header_len, i4_more_data_flag;
+ UWORD32 u4_bytes_consumed_temp = 0;
+ UWORD8 **ppu1_out_buf;
+ nal_prms_t *ps_nal_prms;
+
+ ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
+ ps_non_vcl_nal = (non_vcl_nal_t *) pv_out_non_vcl_nal;
+ ps_nal_unit = (nal_unit_t *) ps_nal_parse_ctxt->pv_nal_unit;
+ ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
+
+ /* Initialization */
+ i4_cur_pos = 0;
+ *pu4_bytes_consumed = 0;
+ i4_nal_header_len = 0;
+ i4_nal_start_flag = SVCD_FALSE;
+ i4_more_data_flag = SVCD_TRUE;
+ i4_status = PIC_BOUNDARY_FALSE;
+
+ /* reset the target layer update flag */
+ ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
+ /*************************************************************************/
+ /* SEARCHING FOR THE START OF BITSTREAM */
+ /*************************************************************************/
+
+ /*-----------------------------------------------------------------------*/
+ /* For Annex B based bitstreams the first start code has to decoded */
+ /* The first start code can come after multiple process call also. This */
+ /* has to be carefully handled */
+ /*-----------------------------------------------------------------------*/
+
+ if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode &&
+ SVCD_TRUE == ps_nal_parse_ctxt->i4_dec_frst_sc_flag)
+ {
+ WORD32 i4_status;
+
+ i4_status =
+ isvcd_get_first_start_code(pu1_stream_buffer, pu4_bytes_consumed, pu4_num_bytes);
+
+ /*-------------------------------------------------------------------*/
+ /* If start code found then proceed with bitstream extraction */
+ /*-------------------------------------------------------------------*/
+
+ if(i4_status == SC_NOT_FOUND)
+ {
+ return (VCL_NAL_FOUND_FALSE);
+ }
+
+ i4_cur_pos = *pu4_bytes_consumed;
+ ps_nal_parse_ctxt->i4_dec_frst_sc_flag = SVCD_FALSE;
+ }
+
+ /* If number of bytes left in the previous process call */
+ /* is is greater or equal to number of bytes in input */
+ /* buffer of the current process call then declare that */
+ /* end of bitstream has occurred and consume the bytes */
+ /* but do not decode */
+ if(ps_nal_parse_ctxt->u4_bytes_left >= (UWORD32) *pu4_num_bytes)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ *pu4_bytes_consumed = *pu4_num_bytes;
+
+ i4_status = isvcd_nal_parse_partial_signal_eos(ps_nal_parse_ctxt, NULL, ps_non_vcl_nal);
+ return (i4_status);
+ }
+
+ do
+ {
+ nal_buf_t *ps_nal_buf;
+ UWORD32 *pu4_bytes_left;
+
+ /*********************************************************************/
+ /* NAL BOUNDARY DETECTION */
+ /*********************************************************************/
+ /*-------------------------------------------------------------------*/
+ /* Detect NAL boundary */
+ /* After return, this NAL boundary detetction logic might be in */
+ /* one of following states: */
+ /* - NAL_START */
+ /* - FIND_NAL_END */
+ /* - NAL_END */
+ /*-------------------------------------------------------------------*/
+ if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
+ {
+ i4_nal_start_flag = isvcd_get_annex_b_nal_unit(
+ pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
+ &ps_nal_parse_ctxt->i4_find_nal_state, &ps_nal_parse_ctxt->i4_zero_byte_cnt,
+ &u4_bytes_consumed_temp, ps_nal_parse_ctxt->pv_nal_unit, &i4_more_data_flag);
+
+ i4_cur_pos += u4_bytes_consumed_temp;
+ }
+
+ /* If current NAL unit is start of new NAL unit then parse the NAL
+ header. If the current NAL unit type is VCL NAL then return from
+ this function. otherwise apply NAL discard logic and discard the
+ NAL if discard NAL flag is true */
+
+ if(SVCD_TRUE == i4_nal_start_flag)
+ {
+ UWORD32 u4_err_code;
+ WORD32 i4_sps_pps_corrupt_status;
+
+ /* Get the NAL prms. This involves the following things*/
+ /* 1. Decode the NAL header */
+ /* 2. Set the discard flag */
+ /* 3. Decode the slice header if needed */
+ isvcd_get_nal_prms(ps_nal_unit->pu1_bufs, ps_nal_unit->i4_buf_sizes, ps_nal_prms,
+ &ps_nal_parse_ctxt->s_prefix_nal_prms,
+ &ps_nal_parse_ctxt->s_prefix_nal_buf, &u4_err_code,
+ &i4_sps_pps_corrupt_status, &ps_nal_parse_ctxt->i4_discard_nal_flag,
+ ps_nal_parse_ctxt);
+ /* If the error code returned by the "picture boundary" */
+ /* detetction is */
+ /* 1. Insufficient bitstream size: then store the bytes */
+ /* left and break out of the loop */
+ /* 2. Corrupted slice: then discard the slice */
+ if((NAL_INSUFFICIENT_DATA == (WORD32) u4_err_code) &&
+ (NAL_END != ps_nal_parse_ctxt->i4_find_nal_state))
+ {
+ ps_nal_parse_ctxt->u4_bytes_left = *pu4_num_bytes - *pu4_bytes_consumed;
+
+ /* Reset the NAL level tracking variables */
+ isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+ break;
+ }
+ else if(0 != u4_err_code)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ /* Populate other paramters based on the nal prms */
+ ps_nal_parse_ctxt->i4_nal_type = ps_nal_prms->i4_derived_nal_type;
+ i4_nal_header_len = ps_nal_prms->i4_nal_header_len;
+
+ /* If derived NAL unit is VCL_NAL then return from this function */
+ if(VCL_NAL == ps_nal_prms->i4_derived_nal_type &&
+ PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type)
+ {
+ isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
+
+ return (VCL_NAL_FOUND_TRUE);
+ }
+
+ /* Set the active NAL buffer structure and initialize */
+ /* the nal buffer structure */
+ isvcd_get_nal_buf(ps_nal_parse_ctxt, &ps_nal_buf);
+
+ ps_nal_parse_ctxt->ps_nal_buf = ps_nal_buf;
+ }
+
+ /* Update the bytes consumed variable */
+
+ *pu4_bytes_consumed += u4_bytes_consumed_temp;
+
+ ps_nal_buf = ps_nal_parse_ctxt->ps_nal_buf;
+ if(VCL_NAL == ps_nal_parse_ctxt->i4_nal_type)
+ {
+ ppu1_out_buf = &ps_nal_parse_ctxt->pu1_vcl_nal_buf;
+ pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_vcl;
+ if(*pu4_bytes_left < (MAX_VCL_NAL_BUFF_SIZE * 0.05))
+ {
+ return (VCL_NAL_FOUND_FALSE);
+ }
+ }
+ else
+ {
+ ppu1_out_buf = &ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
+ pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_non_vcl;
+ if(*pu4_bytes_left < (MAX_NON_VCL_NAL_BUFF_SIZE * 0.05))
+ {
+ return (VCL_NAL_FOUND_FALSE);
+ }
+ }
+
+ /* if 0 bytes left then discard the current NAL */
+ if(0 >= (WORD32) *pu4_bytes_left)
+ {
+ ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
+ }
+
+ /* If NAL is not discarded then :
+ 1) Perform emulation prevention and byte swapping on the RBSP data
+ 2) Update the NAL unit ctxt:
+ a) If VCL NAL then update DQID list
+ b) If NON VCL NAL then update the non vcl output structure */
+
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
+ {
+ UWORD32 u4_output_bytes, u4_buf_inc;
+
+ {
+ UWORD32 u4_buf_size;
+
+ /* clip the size before emulation prevention */
+ u4_buf_size = (UWORD32) CLIP3(0, (WORD32) *pu4_bytes_left,
+ (ps_nal_unit->i4_buf_sizes - i4_nal_header_len));
+
+ u4_buf_inc = isvcd_nal_byte_swap_emulation(
+ (UWORD32 *) *ppu1_out_buf, &u4_output_bytes,
+ ps_nal_unit->pu1_bufs + i4_nal_header_len, u4_buf_size,
+ NUM_OF_ZERO_BYTES_BEFORE_START_CODE, &ps_nal_parse_ctxt->s_emulation_ctxt);
+ i4_nal_header_len = 0;
+
+ u4_buf_inc = UP_ALIGN_8(u4_buf_inc);
+ *ppu1_out_buf += u4_buf_inc;
+ *pu4_bytes_left -= u4_buf_inc;
+ ps_nal_buf->i4_buf_size += u4_output_bytes;
+ }
+ }
+
+ /*********************************************************************/
+ /* UPDATE VARIABLES */
+ /*********************************************************************/
+
+ if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
+ {
+ /*---------------------------------------------------------------*/
+ /* - Update the total bits in the NAL. While doing so bits */
+ /* calculated so far should be converted to SODB length */
+ /*---------------------------------------------------------------*/
+ if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
+ {
+ isvcd_update_nal_ctxt(ps_nal_parse_ctxt, NULL, ps_non_vcl_nal);
+
+ UPDATE_NAL_BUF_PTR(ppu1_out_buf, ps_nal_prms->i4_derived_nal_type, pu4_bytes_left);
+ }
+
+ /* If the prefix NAL unit is not immediatly followed by */
+ /* a AVC NAL unit it shall be discarded and hence reset */
+ /* is done */
+ /* Also if prefix NAL unit is discarded then we should */
+ /* not associate the prefix NAL unit with AVC NAL unit */
+ /* and hence a reset is required */
+ if((PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) ||
+ (SVCD_TRUE == ps_nal_parse_ctxt->i4_discard_nal_flag))
+ {
+ isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
+ }
+
+ /* Reset NAL level tracking variables */
+ isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
+ }
+
+ i4_nal_header_len = 0;
+ /*------------- while loop ends here --------------------------------*/
+ } while(SVCD_TRUE == i4_more_data_flag);
+
+ if(i4_more_data_flag == 0)
+ {
+ isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
+ return (VCL_NAL_FOUND_TRUE);
+ }
+
+ return (VCL_NAL_FOUND_FALSE);
+} \ No newline at end of file
diff --git a/decoder/svc/isvcd_nal_parse.h b/decoder/svc/isvcd_nal_parse.h
new file mode 100644
index 0000000..0303779
--- /dev/null
+++ b/decoder/svc/isvcd_nal_parse.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal_parse.h
+ *
+ * \brief
+ * Contains routines that resample for SVC resampling
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+#ifndef _SVCD_BITSTREAM_EXTRACT_H_
+#define _SVCD_BITSTREAM_EXTRACT_H_
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Typedefs */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+typedef enum
+{
+ FULL_INPUT_MODE = 0,
+ PARTIAL_INPUT_MODE
+} NAL_PARSE_INPUT_MODE_T;
+
+typedef enum
+{
+ VCL_NAL_FOUND_FALSE = 0,
+ VCL_NAL_FOUND_TRUE
+} EXTRACT_NON_VCL_NAL_RETURN_STATUS_T;
+
+typedef enum
+{
+ PIC_BOUNDARY_FALSE,
+ PIC_BOUNDARY_TRUE,
+ FLUSH_DECODED_PICTURE
+} EXTRACT_VCL_NAL_RETURN_STATUS_T;
+
+/*****************************************************************************/
+/* Structure */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+void isvcd_nal_parse_reset_ctxt(WORD32 i4_input_bitstream_mode, WORD32 i4_input_mode,
+ void *pv_nal_parse_ctxt);
+
+WORD32 isvcd_nal_parse_set_target_attr(WORD32 i4_target_quality_id, WORD32 i4_target_dependency_id,
+ WORD32 i4_target_temporal_id, WORD32 i4_target_priority_id,
+ void *pv_nal_parse_ctxt);
+
+WORD32 isvcd_nal_parse_vcl_nal_partial(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
+ void *pv_out_non_vcl_nal, void *pv_out_vcl_nal,
+ UWORD32 *pu4_bytes_consumed, UWORD32 *pu4_num_bytes);
+
+WORD32 isvcd_nal_parse_non_vcl_nal(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
+ void *pv_out_non_vcl_nal, UWORD32 *pu4_bytes_consumed,
+ UWORD32 *pu4_num_bytes);
+
+WORD32 isvcd_nal_parse_partial_signal_eos(void *pv_nal_parse_ctxt, void *pv_out_vcl_nal,
+ void *pv_out_non_vcl_nal);
+
+#endif /* _SVCD_BITSTREAM_EXTRACT_H_ */
diff --git a/decoder/svc/isvcd_nal_parse_structs.h b/decoder/svc/isvcd_nal_parse_structs.h
new file mode 100644
index 0000000..2af5376
--- /dev/null
+++ b/decoder/svc/isvcd_nal_parse_structs.h
@@ -0,0 +1,371 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal_parse_structs.h
+ *
+ * \brief
+ * Contains the definitions of structures used in the
+ * bitstream extraction module
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+#ifndef _SVCD_NAL_PARSE_STRUCTS_H_
+#define _SVCD_NAL_PARSE_STRUCTS_H_
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+#define HEADER_BUFFER_LEN_BEFORE_EP 32
+
+#define MAX_NAL_HEADER_SIZE 4
+
+#define UP_ALIGN_8(x) (((((UWORD64) x) + 7) >> 3) << 3)
+#define ALIGN_4(x) (((x) + 3) & (~3))
+
+/*--------------------------------------------------------------------------*/
+/* The start address of any VCL or NON VCL internal buffers (input to */
+/* emulation prevention should be aligned to 4 byte boundary */
+/*--------------------------------------------------------------------------*/
+
+#define BUFFER_ALIGN_4 4
+
+#define FIRST_PASS 0
+#define SECOND_PASS 1
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+static __inline UWORD32 GET_NAL_BUF_INC(WORD32 i4_derived_nal_type)
+{
+ UWORD32 u4_buf_inc;
+
+ if(VCL_NAL == i4_derived_nal_type)
+ {
+ u4_buf_inc = sizeof(vcl_buf_hdr_t);
+ }
+ else
+ {
+ u4_buf_inc = sizeof(non_vcl_buf_hdr_t);
+ }
+
+ u4_buf_inc = UP_ALIGN_8(u4_buf_inc);
+ return (u4_buf_inc);
+}
+
+static __inline void UPDATE_NAL_BUF_PTR(UWORD8 **ppu1_buf, WORD32 i4_derived_nal_type,
+ UWORD32 *pu4_bytes_left)
+{
+ UWORD8 *pu1_buf_ptr;
+ UWORD64 u4_inc;
+
+ /* Align the start of the structure */
+
+ pu1_buf_ptr = *ppu1_buf;
+
+ /* Account for the vcl or non-vcl header */
+ u4_inc = GET_NAL_BUF_INC(i4_derived_nal_type);
+ u4_inc = UP_ALIGN_8(u4_inc);
+ pu1_buf_ptr += u4_inc;
+
+ /* Update the pointers */
+ if(*pu4_bytes_left >= u4_inc)
+ {
+ *pu4_bytes_left -= u4_inc;
+ }
+ *ppu1_buf = pu1_buf_ptr;
+}
+
+/*****************************************************************************/
+/* Typedefs */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+typedef enum
+{
+ NAL_PARSE_HANDLE = 0,
+ NAL_PARSE_DQID_LIST_MEM,
+ NAL_PARSE_CMN_MEM,
+ NAL_PARSE_NAL_UNIT_MEM,
+ NAL_PARSE_NUM_MEM_TABS
+} BITSTREAM_EXTRACT_MEMTABS_T;
+
+typedef enum
+{
+ PIC_BOUND_DQID = 0, /* Second slice has lower DQID than the first slice */
+ PIC_BOUND_SLICE_PRMS = 1 /* Second slice has different slice prms as */
+ /* as compared to first slice */
+} PIC_BOUNDARY_TYPES_T;
+
+/*****************************************************************************/
+/* Structure */
+/*****************************************************************************/
+
+typedef struct
+{
+ vcl_node_t *ps_vcl_node; /*!< The pointer to VCL NAL node buffer.
+ */
+ UWORD8 u1_valid_flag; /*!< This flag shall indicate that the occupancy of
+ vcl node buffer. SVCD_TRUE shall indicate that the vcl
+ node buffer is occupied. @sa SVCD_BOOL_T
+ */
+
+ UWORD8 u1_dqid; /*!< The value of DQID assigned for this structure.
+ The range is [0,127] and is computed as
+ (Dependency id * 16 + Quality id )
+ */
+ WORD32 i4_poc_lsb; /*!< It shall have the value of "picture order cnt lsb"
+ when picture order count type is 0 for the layer. When not
+ present in the bitstream, it shall be set to 0*/
+
+ WORD32
+ i4_delta_poc_bot; /*!< It shall have the value of "delta picture order cnt
+ bottom" when picture order count type is 0 for VCL NAL unit.
+ When not present in the bitstream, it shall be set to 0*/
+
+ WORD32
+ ai4_delta_poc[2]; /*!< It shall have the value of "delta picture order cnt
+ bottom" when picture order count type is 1 for VCL NAL
+ unit.
+ When not present in the bitstream, itshall be set to 0 */
+} dqid_node_t;
+
+typedef struct
+{
+ WORD32 i4_max_num_lyrs; /*!< Maximum number of layers that will be
+ present in a access unit. This will determine the
+ length of the VCL NAL node buffer. This parameter
+ is configurable during instance creation time
+ */
+
+ dqid_node_t *ps_dqid_node; /*!< Pointer to start of VCL NAL node buffer.
+ */
+
+} dqid_ctxt_t;
+
+typedef struct
+{
+ WORD32 i4_valid_flag; /*!< It shall indicate the validity of contents of
+ this buffer structure. SVCD_TRUE shall indicate
+ that the contents of this structure is valid.
+ @sa SVCD_BOOL_T
+ */
+
+ UWORD8 *pu1_buf; /*!< It shall point to start of SODB data of the NAL.
+ It should be 8 byte aligned.
+ */
+
+ UWORD32 u4_max_bits; /*!< The length of SODB data of NAL in bits. This
+ should be set properly by taking care of whether NAL
+ is coded in CAVLC or CABAC or NAL is a NON VCL NAL
+ */
+
+ WORD32 i4_buf_size; /*!< The size of SODB data of NAL in bytes
+ */
+} nal_buf_t;
+
+typedef struct
+{
+ /*----------------------------------------------------*/
+ /*---------- Mode of operation -----------------------*/
+ /*----------------------------------------------------*/
+
+ WORD32 i4_input_bitstream_mode; /*!< RFC or Annex B */
+
+ /*----------------------------------------------------*/
+ /*---------- NAL boundary detection ------------------*/
+ /*----------------------------------------------------*/
+
+ WORD32 i4_find_nal_state; /*!< state of NAL boundary
+ detection logic */
+
+ WORD32 i4_zero_byte_cnt; /*< Number of zero bytes consumed */
+
+ WORD32 i4_dec_frst_sc_flag; /*!< A flag to decode
+ the start code only. A value of SVCD_TRUE
+ shall indicate that start code shall be
+ decoded.@sa SVCD_BOOL_T */
+
+ /*----------------------------------------------------*/
+ /*--------- Emulation prevention info ----------------*/
+ /*----------------------------------------------------*/
+
+ emulation_prevent_ctxt_t s_emulation_ctxt;
+
+ /*----------------------------------------------------*/
+ /*--------- Picture boundary detetction info ---------*/
+ /*----------------------------------------------------*/
+
+ WORD32 i4_is_frst_vcl_nal_in_au; /*!< Indicates whether
+ current NAL is first NAL in the current
+ Access unit. This is needed for detecting
+ picture boundary in partial input mode of
+ operation */
+
+ UWORD32 u4_time_stamp_lsb; /*!< Holds the LSB of time stamp of the
+ first NAL unit in the access unit.
+ Used for RFC based bitstreams */
+
+ WORD32 i4_time_stamp_msb; /*!< Holds the MSB of time stamp of the
+ first NAL unit in the access unit.
+ Used for RFC based bitstreams */
+
+ WORD32 i4_prev_dq_id; /*!< Holds the value of DQID of
+ last NAL unit parsed. this is used for
+ detetecting the picture boundary.
+ in Annex B mode of input bitstream */
+ WORD32 i4_idr_pic_err_flag; /*!< place to hold the
+ IDR status of current AU
+ */
+
+ /*----------------------------------------------------*/
+ /*-------- DQID node context -------------------------*/
+ /*----------------------------------------------------*/
+
+ dqid_ctxt_t s_dqid_ctxt;
+
+ /*----------------------------------------------------*/
+ /*-------- VCL and NON VCL buf info ------------------*/
+ /*----------------------------------------------------*/
+
+ void *pv_non_vcl_nal_buf; /*!< Start address of NON VCL
+ NAL buffer */
+
+ void *pv_vcl_nal_buf; /*!< Start address of VCL NAL
+ buffer */
+
+ UWORD32 u4_bytes_left_vcl; /*!< number of bytes left in the
+ VCL buffer
+ */
+ UWORD32 u4_bytes_left_non_vcl; /*!< number of bytes left in the
+ NON VCL buffer
+ */
+
+ UWORD8 *pu1_non_vcl_nal_buf; /*!< Current position of
+ non VCL NAL buffer pointer */
+
+ UWORD8 *pu1_vcl_nal_buf; /*!< Current position of VCL NAL
+ buffer pointer */
+
+ WORD32 i4_num_non_vcl_nals; /*!< Number of non vcl nals */
+
+ nal_buf_t s_prefix_nal_buf; /*!< NAL buffer structure
+ of prefix NAL unit */
+
+ nal_buf_t s_nal_buf; /*!< NAL buffer structure of .
+ active NAL unit ( which is not a prefix
+ NAL unit) */
+
+ nal_buf_t *ps_nal_buf; /*!< It shall point to active
+ NAL buffer structure. It shall point to
+ either "s_prefix_nal_buf" or "s_nal_buf"*/
+
+ vcl_buf_hdr_t *ps_prev_vcl_buf; /*!< It shall point
+ to vcl buffer header of the previous
+ slice of a layer */
+ non_vcl_buf_hdr_t *ps_prev_non_vcl_buf; /*!< It shall
+ point to buffer header of the previous
+ non vcl nal present in the bitstream */
+
+ /*----------------------------------------------------*/
+ /*-------- NAL structure and NAL buffer --------------*/
+ /*----------------------------------------------------*/
+
+ void *pv_nal_unit;
+ void *pv_nal_header_buf;
+ nal_prms_t s_nal_prms;
+ nal_prms_t s_prefix_nal_prms;
+
+ /*----------------------------------------------------*/
+ /*-------------- Target layer info -------------------*/
+ /*----------------------------------------------------*/
+
+ target_lyr_attr_t s_app_attr; /*!< This structure shall have
+ the target layer attributes set
+ by the application */
+
+ target_lyr_attr_t s_int_attr; /*!< This structure shall have
+ the target layer attributes set
+ by the module. At any state, the
+ module tries to attain the values
+ of application attributes at
+ the IDR pictures */
+
+ WORD32 i4_tgt_lyr_update; /*!< It is a flag which
+ indicates whether the internal target layer
+ attributes has to be updated or not. A value
+ of SVCD_TRUE shall indicate that the target
+ layer attributes shall be updated.
+ @sa SVCD_BOOL_T */
+
+ /*----------------------------------------------------*/
+ /*-------- other NAL info ----------------------------*/
+ /*----------------------------------------------------*/
+
+ WORD32 i4_discard_nal_flag;
+ WORD32 i4_nal_type;
+
+ /*----------------------------------------------------*/
+ /*---------- Seq, pic prms buffers -------------------*/
+ /*----------------------------------------------------*/
+
+ void *pv_seq_prms;
+ void *pv_pic_prms;
+
+ /*----------------------------------------------------*/
+ /*---------- Others ------------------*/
+ /*----------------------------------------------------*/
+
+ WORD32 i4_eos_flag; /*!< Flush mode related parameter.
+ This is used by the module during the
+ flush call. SVCD_TRUE shall indicate that
+ current end of bitstream has occurred.
+ @sa SVCD_BOOL_T; */
+
+ UWORD32 u4_bytes_left; /*!< This field has number of bytes not
+ consumed by the NAL parse module in the
+ previous call because of insufficient bitstream
+ to decode the slice and NAL header. */
+ UWORD8 u1_pic_boundary_aud_flag;
+} nal_parse_ctxt_t;
+
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+#endif /* _SVCD_NAL_PARSE_STRUCTS_H_ */
diff --git a/decoder/svc/isvcd_nal_structs.h b/decoder/svc/isvcd_nal_structs.h
new file mode 100644
index 0000000..0a1392e
--- /dev/null
+++ b/decoder/svc/isvcd_nal_structs.h
@@ -0,0 +1,291 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*!
+ **************************************************************************
+ * \file isvcd_nal_structs.h
+ *
+ * \brief
+ * Contains the definitions of structures used in NAL processing
+ *
+ * Detailed_description
+ *
+ * \date
+ *
+ *
+ * \author : Kishore
+ **************************************************************************
+ */
+
+#ifndef _SVCD_NAL_STRUCTS_H_
+#define _SVCD_NAL_STRUCTS_H_
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+#define MAX_NUM_SLICE_GRPS_IN_LYR 8
+
+#define MAX_NUM_PACKETS_IN_NAL \
+ 100 /*! Maximum number of packets that can be \
+ present in a NAL unit */
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+#define SLICE_PARSE_ERR_HDLR(i4_error, u4_err_code, pu4_err_code) \
+ if(0 != i4_error) \
+ { \
+ *pu4_err_code = u4_err_code; \
+ return (NOT_OK); \
+ }
+
+#define SLICE_PARSE_ERR_HDLR1(i4_error, u4_err_code, pu4_err_code, pi4_sps_pps, i4_sps_pps_err) \
+ if(0 != i4_error) \
+ { \
+ *pu4_err_code = u4_err_code; \
+ *pi4_sps_pps = i4_sps_pps_err; \
+ return (NOT_OK); \
+ }
+
+/*****************************************************************************/
+/* Typedefs */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+
+typedef enum
+{
+ NAL_DISCARD_RESET_STATE,
+ NAL_DISCARD_ACTIVE_STATE
+} NAL_DISCARD_STATE_MACHINE_T;
+
+/*****************************************************************************/
+/* Structure */
+/*****************************************************************************/
+
+typedef struct
+{
+ WORD32 i4_dependency_id; /*!< Target dependency id */
+ WORD32 i4_quality_id; /*!< Target quality id */
+ WORD32 i4_temporal_id; /*!< Target temporal id */
+ WORD32 i4_priority_id; /*!< Target priority id */
+} target_lyr_attr_t;
+
+typedef struct
+{
+ WORD32 i4_num_bufs; /*!< Number of buffers that comprises this NAL unit.
+ In case of Annex B based input, this value will always be 1. Otherwise
+ (RFC - input), this value indicates number of packets in the NAL unit
+ in the current process call */
+
+ UWORD8 *pu1_bufs; /*!< Nal unit buffer pointer */
+ WORD32 i4_buf_sizes; /*!< Nal unit buffer size */
+
+} nal_unit_t;
+
+typedef struct
+{
+ WORD32 i4_state; /*!< State of emulation prevention in the state machine */
+ WORD32 i4_zeroes_cnt; /*!< Number of consecutive zeroes counter */
+ UWORD32 u4_word; /*!< Place holder for WORD - output */
+ UWORD32 u4_bytes_in_word; /*!< Number of bytes in the WORD */
+} emulation_prevent_ctxt_t;
+
+typedef struct vcl_buf_hdr_t
+{
+ struct vcl_buf_hdr_t *ps_next; /*!< Pointer to next VCL NAL buffer header.
+ This will be poiting to next slice in the layer. This
+ field shall be set to NULL for the last slice
+ (VCL NAL) in a layer */
+
+ UWORD32 u4_max_bits; /*!< Total number of SODB bits present in the VCL
+ NAL (slice)*/
+
+ WORD32 i4_buf_offset; /*!< This is the offset from the start of the
+ VCL NAL header to start of SODB data of VCL NAL.
+ This shall be multiple of 4*/
+
+ WORD32 i4_slice_offset; /*!< It is the offset from start of VCL NAL data
+ to start of slice data. A value of 0 shall
+ indicate that prefix NAL unit is
+ not present
+ Note: If prefix NAL unit is present then it will
+ be present between the offsets "i4_buf_offset" to
+ "i4_slice_offset"*/
+
+ UWORD32 u4_prefix_nal_bits; /*!< Total number of SODB bits present in the VCL
+ NAL (slice). This shall have valid value when
+ "i4_slice_offset" has non zero value
+ */
+
+ WORD32 i4_no_int_lyr_pred; /*!< The value of no inter layer prediction
+ which is decoded from the NAL header
+ */
+
+ WORD32 i4_first_mb_addr; /*!< The 'first_mb_address' syntax
+ element value decoded form the slice
+ header present in the VCL NAL
+ */
+} vcl_buf_hdr_t;
+
+typedef struct non_vcl_buf_hdr_t
+{
+ struct non_vcl_buf_hdr_t *ps_next; /*!< This shall point to start of next NON
+ VCL buffer header that is extracted from the bitstream.
+ It shall be set to NULL for the last non VCL NAL
+ */
+
+ WORD32 i4_nal_unit_type; /*!< NAL unit type that is decoded from the NAL
+ header
+ */
+
+ WORD32 i4_buf_offset; /*!< This is the offset from the start of the
+ VCL NAL header to start of SODB data of VCL NAL.
+ This shall be multiple of 4
+ */
+
+ WORD32 i4_buf_size; /*!< Size of the NON VCL SODB data in bytes
+ */
+
+} non_vcl_buf_hdr_t;
+typedef struct vcl_node_t
+{
+ struct vcl_node_t *ps_top_node; /*!< Pointer to top node present in the DQID
+ list. This node is actually is a layer using
+ the current layer as a reference layer. Value
+ of NULL shall indicate that no more layers
+ with DQID higher than current layer is present
+ in the current access unit */
+
+ struct vcl_node_t *ps_bot_node; /*!< Pointer to bottom node present in the
+ DQID list. This node is actually the
+ reference layer of the current layer. Value
+ of NULL shall indicate that no more layers
+ with DQID lower than current layer is
+ present in the current access unit */
+
+ /*------ info part -------*/
+
+ WORD32 i4_quality_id; /*!< Quality id of the layer */
+
+ WORD32 i4_dependency_id; /*!< Dependency id of the layer */
+
+ WORD32 i4_temporal_id; /*!< Temporal id of the layer */
+
+ WORD32 i4_priority_id; /*!< Priority id of the layer */
+
+ WORD32 i4_idr_pic_flag; /*!< Flag indicating whether current layer is
+ Idr picture or not. SVCD_TRUE shall indicate
+ the idr picture
+ */
+
+ WORD32 i4_nal_unit_type; /*!< NAL unit type of all slices in the current
+ picture
+ */
+
+ WORD32
+ i4_nal_ref_idc; /*!< NAL ref idc of all slices in the current picture */
+
+ WORD32 i4_use_ref_base; /*!< Use ref base flag of NAL header. */
+
+ UWORD8 u1_sps_id; /*!< It shall have the value of SPS id used by this layer.
+ It's range is [0,63]
+ */
+
+ UWORD8 u1_pps_id; /*!< It shall have the value of PPS id used by this layer.
+ It's range is [0,255]
+ */
+ UWORD8 u1_acc_no_int_pred; /*! The value of accumulated no inter layer
+ prediction flag. This value will be "logical and
+ " of no inter layer prediction flag of all the
+ slices in the corresponding DQID
+ */
+
+ UWORD16 u2_frm_num; /*!< It is the value of frame number of the layer.
+ */
+
+ UWORD32 i4_idr_pic_num; /*!< It shall have the value of IDR picture number when
+ "i4_idr_pic_flag" is SVCD_TRUE
+ */
+
+ WORD32 i4_poc_syntax; /*!< It shall have either "picture order cnt lsb" or
+ "delta picture order cnt [0]" that is decoded from the
+ slice header. When picture order coutn type is 0 then
+ this field holds "picture order cnt lsb" and when
+ picture order cnt type is 1 then this field holds
+ "delta picture order cnt [0]". This field will not
+ have a valid value when picture order cnt type is 2
+ */
+
+ WORD32 i4_res_change_flag; /*!< 'SpatialResolutionChangeFlag' for the
+ layer as specified in section G.7.4.3.4
+ Value 'SVCD_TRUE' indicates that parameter
+ 'SpatialResolutionChangeFlag' is set to 1.
+ Otherwise it shall be set to SVCD_FALSE.
+ @sa SVCD_BOOL_T
+ */
+ WORD32 i4_ref_dq_id; /*!< reference layer DQid for current layer */
+
+ WORD32 i4_num_slices; /*!< Number of slices in the current layer */
+
+ WORD32 i4_inter_lyr_dblk_idc; /*!< Deblock filter idc for inter layer
+ deblocking. This shall be valid only
+ for layer with quality id = 0.
+ */
+ WORD32 i4_inter_lyr_alpha_c0_offset; /*!< Alpha C0 offset for inter layer
+ deblocking. This shall be valid only for
+ layers with quality id = 0.
+ */
+ WORD32 i4_inter_lyr_beta_offset; /*!< Beta offset for inter layer
+ deblocking. This shall be valid only for
+ layers with quality id = 0.
+ */
+
+ vcl_buf_hdr_t *ps_first_vcl_nal; /*!< This shall point to start of the
+ VCL NAL header of the first slice (VCL NAL)
+ in a layer.
+ */
+
+ vcl_buf_hdr_t *aps_start_addr_slices[MAX_NUM_SLICE_GRPS_IN_LYR]; /*!< array
+ to hold the start address of first slice
+ of each slice group. the address will be
+ linked to each other within a slice
+ group based on first MB address
+ each entry will be pointing to the slice
+ which will be decoded next in the slice
+ group
+ */
+
+} vcl_node_t;
+/*****************************************************************************/
+/* Extern Variable Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+#endif /* _SVCD_NAL_STRUCTS_H_ */
diff --git a/decoder/svc/isvcd_parse_cavlc.c b/decoder/svc/isvcd_parse_cavlc.c
new file mode 100644
index 0000000..8e90652
--- /dev/null
+++ b/decoder/svc/isvcd_parse_cavlc.c
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_cavlc.c
+ *
+ * @brief
+ * This file contains UVLC related functions.
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_parse_bmb_ref_index_cavlc_range1()
+ * - isvcd_parse_bmb_ref_index_cavlc()
+ * - isvcd_parse_pmb_ref_index_cavlc()
+ * - isvcd_parse_pmb_ref_index_cavlc_range1()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ih264d_bitstrm.h"
+#include "isvcd_parse_cavlc.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_cabac.h"
+#include "isvcd_structs.h"
+#include "ih264d_tables.h"
+#include "ih264d_tables.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_parse_cavlc.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_bmb_ref_index_cavlc_range1 */
+/* */
+/* Description : This function does the Cavlc TEV range > 1 parsing of */
+/* reference index for a B MB. */
+/* Range > 1 when num_ref_idx_active_minus1 > 0 */
+/* */
+/* Inputs : <What inputs does the function take?> */
+/* Globals : <Does it use any global variables?> */
+/* Processing : <Describe how the function operates - include algorithm */
+/* description> */
+/* Outputs : <What does the function produce?> */
+/* Returns : <What does the function return?> */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 19 09 2008 Jay Draft */
+/* */
+/*****************************************************************************/
+
+void isvcd_parse_bmb_ref_index_cavlc_range1(
+ UWORD32 u4_num_part, /* Number of partitions in MB */
+ dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */
+ WORD8 *pi1_ref_idx, /* pointer to reference index array */
+ UWORD32 u4_num_ref_idx_active_minus1, /* Not used for range 1 */
+ UWORD8 *pu1_motion_prediction_flag /*motion_pred_flag */
+
+)
+{
+ UWORD32 u4_i;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst;
+ UNUSED(u4_num_ref_idx_active_minus1);
+ for(u4_i = 0; u4_i < u4_num_part; u4_i++)
+ {
+ if(pi1_ref_idx[u4_i] > -1 && (((*pu1_motion_prediction_flag >> u4_i) & 0x01) == 0))
+ {
+ UWORD32 u4_ref_idx;
+ u4_ref_idx = ih264d_tev_range1(pu4_bitstream_off, pu4_bitstrm_buf);
+
+ /* Storing Reference Idx Information */
+ pi1_ref_idx[u4_i] = (WORD8) u4_ref_idx;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_bmb_ref_index_cavlc */
+/* */
+/* Description : This function does the Cavlc TEV range > 1 parsing of */
+/* reference index for a B MB. */
+/* Range > 1 when num_ref_idx_active_minus1 > 0 */
+/* */
+/* Inputs : <What inputs does the function take?> */
+/* Globals : <Does it use any global variables?> */
+/* Processing : <Describe how the function operates - include algorithm */
+/* description> */
+/* Outputs : <What does the function produce?> */
+/* Returns : <What does the function return?> */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 19 09 2008 Jay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_bmb_ref_index_cavlc(
+ UWORD32 u4_num_part, /* Number of partitions in MB */
+ dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */
+ WORD8 *pi1_ref_idx, /* pointer to reference index array */
+ UWORD32 u4_num_ref_idx_active_minus1, /* Number of active references - 1 */
+ UWORD8 *pu1_motion_prediction_flag /*motion_pred_flag */
+)
+{
+ UWORD32 u4_i;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst;
+
+ for(u4_i = 0; u4_i < u4_num_part; u4_i++)
+ {
+ if(pi1_ref_idx[u4_i] > -1 && (((*pu1_motion_prediction_flag >> u4_i) & 0x01) == 0))
+ {
+ UWORD32 u4_ref_idx;
+ // inlining ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstream_off;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstream_off = u4_bitstream_offset;
+ u4_ref_idx = ((1 << u4_ldz) + u4_word - 1);
+ // inlining ih264d_uev
+ if(u4_ref_idx > u4_num_ref_idx_active_minus1) return ERROR_REF_IDX;
+
+ /* Storing Reference Idx Information */
+ pi1_ref_idx[u4_i] = (WORD8) u4_ref_idx;
+ }
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_pmb_ref_index_cavlc */
+/* */
+/* Description : This function does the Cavlc TEV range > 1 parsing of */
+/* reference index for a P MB. */
+/* Range > 1 when num_ref_idx_active_minus1 > 0 */
+/* */
+/* Inputs : <What inputs does the function take?> */
+/* Globals : <Does it use any global variables?> */
+/* Processing : <Describe how the function operates - include algorithm */
+/* description> */
+/* Outputs : <What does the function produce?> */
+/* Returns : <What does the function return?> */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 19 09 2008 Jay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_parse_pmb_ref_index_cavlc(
+ UWORD32 u4_num_part, /* Number of partitions in MB */
+ dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */
+ WORD8 *pi1_ref_idx, /* pointer to reference index array */
+ UWORD32 u4_num_ref_idx_active_minus1, /* Number of active references - 1 */
+ UWORD8 *pu1_motion_prediction_flag /*motion_pred_flag_l0 */
+)
+{
+ UWORD32 u4_i;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst;
+
+ for(u4_i = 0; u4_i < u4_num_part; u4_i++)
+ {
+ if(((*pu1_motion_prediction_flag >> u4_i) & 0x01) == 0)
+ {
+ UWORD32 u4_ref_idx;
+ // Inlined ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstream_off;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstream_off = u4_bitstream_offset;
+ u4_ref_idx = ((1 << u4_ldz) + u4_word - 1);
+
+ // Inlined ih264d_uev
+ if(u4_ref_idx > u4_num_ref_idx_active_minus1) return ERROR_REF_IDX;
+
+ /* Storing Reference Idx Information */
+ pi1_ref_idx[u4_i] = (WORD8) u4_ref_idx;
+ }
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_pmb_ref_index_cavlc_range1 */
+/* */
+/* Description : This function does the Cavlc TEV range =1 parsing of */
+/* reference index for a P MB. Range is 1 when */
+/* num_ref_idx_active_minus1 is 0 */
+/* */
+/* Inputs : <What inputs does the function take?> */
+/* Globals : <Does it use any global variables?> */
+/* Processing : <Describe how the function operates - include algorithm */
+/* description> */
+/* Outputs : <What does the function produce?> */
+/* Returns : <What does the function return?> */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 19 09 2008 Jay Draft */
+/* */
+/*****************************************************************************/
+void isvcd_parse_pmb_ref_index_cavlc_range1(
+ UWORD32 u4_num_part, /* Number of partitions in MB */
+ dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */
+ WORD8 *pi1_ref_idx, /* pointer to reference index array */
+ UWORD32 u4_num_ref_idx_active_minus1, /* Not used for range 1 */
+ UWORD8 *pu1_motion_prediction_flag /*motion_pred_flag_l0 */
+)
+{
+ UWORD32 u4_i;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst;
+ UNUSED(u4_num_ref_idx_active_minus1);
+ for(u4_i = 0; u4_i < u4_num_part; u4_i++)
+ {
+ if(((*pu1_motion_prediction_flag >> u4_i) & 0x01) == 0)
+ {
+ UWORD32 u4_ref_idx;
+ u4_ref_idx = ih264d_tev_range1(pu4_bitstream_off, pu4_bitstrm_buf);
+
+ /* Storing Reference Idx Information */
+ pi1_ref_idx[u4_i] = (WORD8) u4_ref_idx;
+ }
+ }
+}
diff --git a/decoder/svc/isvcd_parse_cavlc.h b/decoder/svc/isvcd_parse_cavlc.h
new file mode 100644
index 0000000..a4fab57
--- /dev/null
+++ b/decoder/svc/isvcd_parse_cavlc.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_cavlc.h
+ *
+ * @brief
+ * Declaration of UVLC and CAVLC functions
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PARSE_CAVLC_H_
+#define _ISVCD_PARSE_CAVLC_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "isvcd_structs.h"
+#include "ih264d_cabac.h"
+
+void isvcd_parse_bmb_ref_index_cavlc_range1(UWORD32 u4_num_part, dec_bit_stream_t *ps_bitstrm,
+ WORD8 *pi1_ref_idx,
+ UWORD32 u4_num_ref_idx_active_minus1,
+ UWORD8 *pu1_motion_prediction_flag);
+
+WORD32 isvcd_parse_bmb_ref_index_cavlc(UWORD32 u4_num_part, dec_bit_stream_t *ps_bitstrm,
+ WORD8 *pi1_ref_idx, UWORD32 u4_num_ref_idx_active_minus1,
+ UWORD8 *pu1_motion_prediction_flag);
+
+WORD32 isvcd_parse_pmb_ref_index_cavlc(UWORD32 u4_num_part, dec_bit_stream_t *ps_bitstrm,
+ WORD8 *pi1_ref_idx, UWORD32 u4_num_ref_idx_active_minus1,
+ UWORD8 *pu1_motion_prediction_flag);
+
+void isvcd_parse_pmb_ref_index_cavlc_range1(UWORD32 u4_num_part, dec_bit_stream_t *ps_bitstrm,
+ WORD8 *pi1_ref_idx,
+ UWORD32 u4_num_ref_idx_active_minus1,
+ UWORD8 *pu1_motion_prediction_flag);
+
+#endif /*_ISVCD_PARSE_CAVLC_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_parse_ebslice.c b/decoder/svc/isvcd_parse_ebslice.c
new file mode 100644
index 0000000..3a92dfe
--- /dev/null
+++ b/decoder/svc/isvcd_parse_ebslice.c
@@ -0,0 +1,2161 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_ebslice.c
+ *
+ * @brief
+ * Contains routines that decode a I slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_parse_bmb_cabac()
+ * - isvcd_mv_pred_ref_tfr_nby2_ebmb()
+ * - isvcd_parse_bmb_cavlc()
+ * - isvcd_parse_bmb_non_direct_cabac()
+ * - isvcd_parse_bmb_non_direct_cavlc()
+ * - isvcd_parse_ebslice()
+ * - isvcd_parse_bslice()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "ih264_defs.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_cabac.h"
+#include "ih264d_parse_mb_header.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_cabac.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_headers.h"
+#include "isvcd_parse_headers.h"
+#include "isvcd_process_ebslice.h"
+#include "isvcd_parse_slice.h"
+#include "ih264_debug.h"
+#include "isvcd_parse_cavlc.h"
+#include "isvcd_mb_utils.h"
+
+void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+void isvcd_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+void ih264d_get_implicit_weights(dec_struct_t *ps_dec);
+WORD32 isvcd_interlyr_motion_mode_pred(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info,
+ parse_pmbarams_t *ps_mb_part_info,
+ parse_part_params_t *ps_part);
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_parse_bmb_cabac \endif
+ *
+ * \brief
+ * This function parses CABAC syntax of a B MB.
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_parse_bmb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ UWORD8 u1_cbp = 0;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ deblk_mb_t *ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_mb_num;
+ const UWORD8 *puc_mb_mc_mode = (const UWORD8 *) gau1_ih264d_mb_mc_mode;
+ UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env;
+ WORD32 ret;
+ UWORD8 u1_Bdirect_tranform_read = 1;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 1;
+ ps_cur_mb_info->u1_mb_mc_mode = puc_mb_mc_mode[5 + u1_mb_type];
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+ ps_cur_deblk_mb->u1_mb_type |= D_B_SLICE;
+
+ if(u1_mb_type != B_DIRECT)
+ {
+ ret = isvcd_parse_bmb_non_direct_cabac(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ u1_mb_num, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ }
+ else
+ {
+ /************ STORING PARTITION INFO ***********/
+ parse_part_params_t *ps_part_info;
+ ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ p_curr_ctxt->u1_mb_type = CAB_BD16x16;
+
+ MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
+ memset(ps_dec->pi1_left_ref_idx_ctxt_inc, 0, 4);
+ MEMSET_16BYTES(p_curr_ctxt->u1_mv, 0);
+ memset(p_curr_ctxt->i1_ref_idx, 0, 4);
+
+ /* check whether transform8x8 u4_flag to be read or not */
+ u1_Bdirect_tranform_read = ps_dec->s_high_profile.u1_direct_8x8_inference_flag;
+ }
+
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = ih264d_decode_bin(
+ 1, ps_svc_lyr_dec->ps_residual_prediction_flag, ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_svc_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag &&
+ 1 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+
+ if(ps_svc_slice_params->u1_scan_idx_end >= ps_svc_slice_params->u1_scan_idx_start)
+ {
+ /* Read the Coded block pattern */
+ u1_cbp = (WORD8) ih264d_parse_ctx_cbp_cabac(ps_dec);
+ p_curr_ctxt->u1_cbp = u1_cbp;
+ ps_cur_mb_info->u1_cbp = u1_cbp;
+
+ if(u1_cbp > 47) return ERROR_CBP;
+ COPYTHECONTEXT("coded_block_pattern", u1_cbp);
+
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ if((ps_dec->s_high_profile.u1_transform8x8_present) && (u1_cbp & (0xf)) &&
+ (ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag) && (u1_Bdirect_tranform_read))
+ {
+ ps_cur_mb_info->u1_tran_form8x8 =
+ ih264d_parse_transform8x8flag_cabac(ps_dec, ps_cur_mb_info);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8;
+ }
+ else
+ {
+ p_curr_ctxt->u1_transform8x8_ctxt = 0;
+ }
+ }
+
+ p_curr_ctxt->u1_intra_chroma_pred_mode = 0;
+ p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE;
+ ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6;
+
+ /* Read mb_qp_delta */
+ if(u1_cbp)
+ {
+ WORD8 c_temp;
+ ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &c_temp);
+ if(ret != OK) return ret;
+ COPYTHECONTEXT("mb_qp_delta", c_temp);
+ if(c_temp)
+ {
+ ret = ih264d_update_qp(ps_dec, c_temp);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ ps_dec->i1_prev_mb_qp_delta = 0;
+
+ /*RESIDUAL FOR Start to end idx*/
+ ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, 0);
+ if(EXCEED_OFFSET(ps_dec->ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_mv_pred_ref_tfr_nby2_ebmb \endif
+ *
+ * \brief
+ * This function computes the mv pred for b frame
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_mv_pred_ref_tfr_nby2_ebmb(dec_struct_t *ps_dec, UWORD8 u1_mb_idx, UWORD8 u1_num_mbs)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) ps_dec;
+ parse_pmbarams_t *ps_mb_part_info;
+ parse_part_params_t *ps_part;
+ mv_pred_t *ps_mv_nmb, *ps_mv_nmb_start, *ps_mv_ntop, *ps_mv_ntop_start;
+ pic_buffer_t *ps_ref_frame;
+ UWORD8 u1_direct_mode_width;
+ UWORD8 i, j;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 u1_field;
+ WORD32 ret = 0;
+ WORD16 i2_mv_x, i2_mv_y;
+
+ ps_dec->i4_submb_ofst -= (u1_num_mbs - u1_mb_idx) << 4;
+ ps_mb_part_info = ps_dec->ps_parse_mb_data;
+ ps_part = ps_dec->ps_parse_part_params;
+
+ /* N/2 Mb MvPred and Transfer Setup Loop */
+ for(i = u1_mb_idx; i < u1_num_mbs; i++, ps_mb_part_info++)
+ {
+ UWORD8 u1_colz = 0;
+ ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
+ /* Restore the slice scratch MbX and MbY context */
+ ps_cur_mb_info = ps_dec->ps_nmb_info + i;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + i;
+ u1_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+ ps_mv_nmb_start = ps_dec->ps_mv_cur + (i << 4);
+ ps_dec->u2_mbx = ps_cur_mb_info->u2_mbx;
+ ps_dec->u2_mby = ps_cur_mb_info->u2_mby;
+ ps_dec->u1_currB_type = 0;
+ ps_dec->u2_mv_2mb[i & 0x1] = 0;
+
+ /* Look for MV Prediction and Reference Transfer in Non-I Mbs */
+ if(!ps_mb_part_info->u1_isI_mb)
+ {
+ UWORD8 u1_blk_no;
+ WORD16 i1_ref_idx, i1_ref_idx1;
+ UWORD8 u1_pred_mode;
+ UWORD8 u1_sub_mb_x, u1_sub_mb_y, u1_sub_mb_num;
+ UWORD8 u1_lx, u1_lx_start, u1_lxend, u1_tmp_lx;
+ UWORD8 u1_num_part, u1_num_ref, u1_wd, u1_ht;
+ UWORD32 *pu4_wt_offst;
+ UWORD8 u1_scale_ref, u4_bot_mb;
+ deblk_mb_t *ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + i;
+ WORD8(*pi1_ref_idx)[MAX_REFIDX_INFO_PER_MB] = ps_mb_part_info->i1_ref_idx;
+ WORD8 *pi1_ref_idx0 = pi1_ref_idx[0], *pi1_ref_idx1 = pi1_ref_idx[1];
+ UWORD32 **ppu4_wt_ofst = ps_mb_part_info->pu4_wt_offst;
+ WORD32 i4_mb_mode_svc;
+ UWORD8 u1_motion_pred_flag_l0 = ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+ UWORD8 u1_motion_pred_flag_l1 = ps_svc_cur_mb_info->au1_motion_pred_flag[1];
+
+ /* MB Level initialisations */
+ ps_dec->u4_num_pmbair = i >> u1_mbaff;
+ ps_dec->u1_mb_idx_mv = i;
+
+ i4_mb_mode_svc = isvcd_interlyr_motion_mode_pred(
+ ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info, ps_mb_part_info, ps_part);
+
+ if((-1 == i4_mb_mode_svc) || (SVC_INTER_MB == i4_mb_mode_svc))
+ {
+ ps_mv_ntop_start =
+ ps_mv_nmb_start - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12;
+
+ u1_num_part = ps_mb_part_info->u1_num_part;
+ ps_cur_deblk_mb->u1_mb_type |= (u1_num_part > 1) << 1;
+ u1_direct_mode_width = (1 == ps_mb_part_info->u1_num_part) ? 16 : 8;
+
+ ps_cur_mb_info->u4_pred_info_pkd_idx = ps_dec->u4_pred_info_pkd_idx;
+ ps_cur_mb_info->u1_num_pred_parts = 0;
+
+ /****************************************************/
+ /* weighted u4_ofst pointer calculations, this loop */
+ /* runs maximum 4 times, even in direct cases */
+ /****************************************************/
+ u1_scale_ref = u1_mbaff & ps_cur_mb_info->u1_mb_field_decodingflag;
+ u4_bot_mb = 1 - ps_cur_mb_info->u1_topmb;
+ if(ps_dec->ps_cur_pps->u1_wted_bipred_idc)
+ {
+ u1_num_ref = MIN(u1_num_part, 4);
+ if(PART_DIRECT_16x16 != ps_part->u1_is_direct)
+ {
+ for(u1_blk_no = 0; u1_blk_no < u1_num_ref; u1_blk_no++)
+ {
+ i1_ref_idx = MAX(pi1_ref_idx0[u1_blk_no], 0);
+ if(u1_scale_ref) i1_ref_idx >>= 1;
+ i1_ref_idx *= ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1];
+ if(u1_scale_ref)
+ i1_ref_idx += (MAX(pi1_ref_idx1[u1_blk_no], 0) >> 1);
+ else
+ i1_ref_idx += MAX(pi1_ref_idx1[u1_blk_no], 0);
+ pu4_wt_offst = (UWORD32 *) &ps_dec->pu4_wt_ofsts[2 * X3(i1_ref_idx)];
+
+ if(pi1_ref_idx0[u1_blk_no] < 0) pu4_wt_offst += 1;
+
+ ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst;
+ if(u1_scale_ref && (ps_dec->ps_cur_pps->u1_wted_bipred_idc == 2))
+ {
+ i1_ref_idx = MAX(pi1_ref_idx0[u1_blk_no], 0);
+ i1_ref_idx *=
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] << 1);
+ i1_ref_idx += MAX(pi1_ref_idx1[u1_blk_no], 0);
+ if(u4_bot_mb)
+ {
+ i1_ref_idx +=
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] << 1) *
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] << 1);
+ }
+ pu4_wt_offst =
+ (UWORD32 *) &ps_dec->pu4_mbaff_wt_mat[2 * X3(i1_ref_idx)];
+ ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst;
+ }
+ }
+ }
+ }
+
+ /**************************************************/
+ /* Loop on Partitions */
+ /* direct mode is reflected as a single partition */
+ /**************************************************/
+ for(j = 0; j < u1_num_part; j++, ps_part++)
+ {
+ u1_sub_mb_num = ps_part->u1_sub_mb_num;
+ ps_dec->u1_sub_mb_num = u1_sub_mb_num;
+
+ if(PART_NOT_DIRECT != ps_part->u1_is_direct)
+ {
+ /**************************************************/
+ /* Direct Mode, Call DecodeSpatial/TemporalDirect */
+ /* only (those will in turn call FormMbPartInfo) */
+ /**************************************************/
+ ret = isvcd_decode_spatial_direct(ps_dec, u1_direct_mode_width,
+ ps_cur_mb_info, i);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_type |= (ps_dec->u1_currB_type << 1);
+ }
+ else
+ {
+ mv_pred_t s_mvPred = {0};
+ /**************************************************/
+ /* Non Direct Mode, Call Motion Vector Predictor */
+ /* and FormMbpartInfo */
+ /**************************************************/
+ u1_sub_mb_x = u1_sub_mb_num & 0x03;
+ u1_sub_mb_y = u1_sub_mb_num >> 2;
+ u1_blk_no = (u1_num_part < 4)
+ ? j
+ : (((u1_sub_mb_y >> 1) << 1) + (u1_sub_mb_x >> 1));
+
+ ps_mv_ntop = ps_mv_ntop_start + u1_sub_mb_x;
+ ps_mv_nmb = ps_mv_nmb_start + u1_sub_mb_num;
+
+ /* Populate the colpic info and reference frames */
+ s_mvPred.i1_ref_frame[0] = pi1_ref_idx0[u1_blk_no];
+ s_mvPred.i1_ref_frame[1] = pi1_ref_idx1[u1_blk_no];
+ u1_pred_mode = ps_part->u1_pred_mode;
+ u1_wd = ps_part->u1_partwidth;
+ u1_ht = ps_part->u1_partheight;
+
+ if(1 != ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ u1_lx_start = 0;
+ u1_lxend = 2;
+ if(PRED_L0 == u1_pred_mode)
+ {
+ s_mvPred.i2_mv[2] = 0;
+ s_mvPred.i2_mv[3] = 0;
+ if(0 == (u1_motion_pred_flag_l0 & (1 << u1_blk_no)))
+ {
+ u1_lxend = 1;
+ }
+ else
+ {
+ u1_lxend = 0;
+ }
+ }
+ else if(PRED_L1 == u1_pred_mode)
+ {
+ s_mvPred.i2_mv[0] = 0;
+ s_mvPred.i2_mv[1] = 0;
+ if(0 == (u1_motion_pred_flag_l1 & (1 << u1_blk_no)))
+ {
+ u1_lx_start = 1;
+ }
+ else
+ {
+ u1_lx_start = 2;
+ }
+ }
+ else // Bi Pred
+ {
+ if(0 == (u1_motion_pred_flag_l0 & (1 << u1_blk_no)))
+ {
+ u1_lxend = 1;
+ }
+ if(0 == (u1_motion_pred_flag_l1 & (1 << u1_blk_no)))
+ {
+ u1_lx_start = 1;
+ }
+ if((0 != (u1_motion_pred_flag_l0 & (1 << u1_blk_no))) &&
+ (0 != (u1_motion_pred_flag_l1 & (1 << u1_blk_no))))
+ {
+ u1_lx_start = 0;
+ u1_lxend = 0;
+ }
+ if((0 == (u1_motion_pred_flag_l0 & (1 << u1_blk_no))) &&
+ (0 == (u1_motion_pred_flag_l1 & (1 << u1_blk_no))))
+ {
+ u1_lx_start = 0;
+ u1_lxend = 2;
+ }
+ }
+ ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb, ps_mv_ntop,
+ &s_mvPred, u1_sub_mb_num, u1_wd, u1_lx_start,
+ u1_lxend, ps_cur_mb_info->u1_mb_mc_mode);
+ }
+
+ /* for generic case based on pred mode derived / signalled */
+ u1_lx_start = 0;
+ u1_lxend = 2;
+ if(PRED_L0 == u1_pred_mode)
+ {
+ s_mvPred.i2_mv[2] = 0;
+ s_mvPred.i2_mv[3] = 0;
+ u1_lxend = 1;
+ }
+ if(PRED_L1 == u1_pred_mode)
+ {
+ s_mvPred.i2_mv[0] = 0;
+ s_mvPred.i2_mv[1] = 0;
+ u1_lx_start = 1;
+ }
+
+ /**********************************************************/
+ /* Loop on number of predictors, 1 Each for Forw Backw */
+ /* Loop 2 times for BiDirect mode */
+ /**********************************************************/
+ for(u1_lx = u1_lx_start; u1_lx < u1_lxend; u1_lx++)
+ {
+ UWORD8 u1_motion_pred_flag =
+ u1_lx ? u1_motion_pred_flag_l1 : u1_motion_pred_flag_l0;
+
+ if((0 != (u1_motion_pred_flag & (1 << u1_blk_no))) ||
+ (ps_svc_cur_mb_info->u1_base_mode_flag))
+ {
+ isvcd_retrive_infer_mode_mv(ps_svc_lyr_dec, &s_mvPred, u1_lx,
+ u1_sub_mb_num);
+ }
+ /********************************************************/
+ /* Predict Mv */
+ /* Add Mv Residuals and store back */
+ /********************************************************/
+ u1_tmp_lx = (u1_lx << 1);
+ i1_ref_idx = s_mvPred.i1_ref_frame[u1_lx];
+ if(0 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ i2_mv_x = ps_mv_nmb->i2_mv[u1_tmp_lx];
+ i2_mv_y = ps_mv_nmb->i2_mv[u1_tmp_lx + 1];
+
+ i2_mv_x += s_mvPred.i2_mv[u1_tmp_lx];
+ i2_mv_y += s_mvPred.i2_mv[u1_tmp_lx + 1];
+
+ s_mvPred.i2_mv[u1_tmp_lx] = i2_mv_x;
+ s_mvPred.i2_mv[u1_tmp_lx + 1] = i2_mv_y;
+ }
+ else
+ {
+ i2_mv_x = s_mvPred.i2_mv[u1_tmp_lx];
+ i2_mv_y = s_mvPred.i2_mv[u1_tmp_lx + 1];
+ }
+
+ /********************************************************/
+ /* Transfer setup call */
+ /* convert RefIdx if it is MbAff */
+ /* Pass Weight Offset and refFrame */
+ /********************************************************/
+ i1_ref_idx1 = i1_ref_idx >> u1_scale_ref;
+
+ if(-1 == i1_ref_idx1) return NOT_OK;
+ if(u1_scale_ref && ((i1_ref_idx & 0x01) != u4_bot_mb))
+ i1_ref_idx1 += MAX_REF_BUFS;
+ ps_ref_frame = ps_dec->ps_ref_pic_buf_lx[u1_lx][i1_ref_idx1];
+
+ /* Storing Colocated-Zero u4_flag */
+ if(u1_lx == u1_lx_start)
+ {
+ /* Fill colocated info in MvPred structure */
+ s_mvPred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id;
+ s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type;
+
+ /* Calculating colocated zero information */
+ u1_colz =
+ (u1_field << 1) | ((i1_ref_idx == 0) && (ABS(i2_mv_x) <= 1) &&
+ (ABS(i2_mv_y) <= 1));
+ u1_colz |= ps_mb_part_info->u1_col_info[u1_blk_no];
+ }
+
+ pu4_wt_offst = ppu4_wt_ofst[u1_blk_no];
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD16 i2_mv[2];
+
+ i2_mv[0] = i2_mv_x;
+ i2_mv[1] = i2_mv_y;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(i2_mv, u1_wd, u1_ht, u1_sub_mb_num,
+ u1_pred_mode, ps_pred_pkd,
+ ps_ref_frame->u1_pic_buf_id, i1_ref_idx,
+ pu4_wt_offst, ps_ref_frame->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+ if(ps_mv_nmb)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb, u1_sub_mb_num, u1_colz,
+ u1_ht, u1_wd);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ /* to take care of 16 parttitions increment for base mode flag case*/
+ if(1 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_part += (MAX_NUM_MB_PART - u1_num_part);
+ }
+ }
+ else
+ {
+ /* Set zero values in case of Intra Mbs */
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ /* to take care of 16 parttitions increment for base mode flag case*/
+ if(1 != ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ return NOT_OK;
+ }
+
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_IBL;
+ if((ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER) &&
+ (DBLK_ENABLED == ps_dec->ps_cur_slice->u1_disable_dblk_filter_idc))
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_ENABLE_FILTERING;
+ }
+
+ ps_part += (MAX_NUM_MB_PART);
+ /* Storing colocated zero information */
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (u1_field << 1), 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ else
+ {
+ /* Set zero values in case of Intra Mbs */
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ /* Storing colocated zero information */
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, (UWORD8) (u1_field << 1),
+ 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_bmb_cavlc \endif
+*
+* \brief
+* This function parses CAVLC syntax of a B MB.
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_bmb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ UWORD32 u4_cbp = 0;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ deblk_mb_t *ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_mb_num;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ const UWORD8 *puc_mb_mc_mode = (const UWORD8 *) gau1_ih264d_mb_mc_mode;
+ UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ WORD32 ret;
+ UWORD8 u1_Bdirect_tranform_read = 1;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 1;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+ ps_cur_mb_info->u1_mb_mc_mode = puc_mb_mc_mode[5 + u1_mb_type];
+ ps_cur_deblk_mb->u1_mb_type |= D_B_SLICE;
+ if(u1_mb_type != B_DIRECT)
+ {
+ ret = isvcd_parse_bmb_non_direct_cavlc(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ u1_mb_num, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ }
+ else
+ {
+ /************ STORING PARTITION INFO ***********/
+ parse_part_params_t *ps_part_info;
+ ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ /* check whether transform8x8 u4_flag to be read or not */
+ u1_Bdirect_tranform_read = ps_dec->s_high_profile.u1_direct_8x8_inference_flag;
+ }
+
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_svc_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag &&
+ 1 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+
+ if(ps_svc_slice_params->u1_scan_idx_end >= ps_svc_slice_params->u1_scan_idx_start)
+ {
+ /* Read the Coded block pattern */
+ const UWORD8 *puc_CbpInter = gau1_ih264d_cbp_inter;
+ // Inlined ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_cbp = ((1 << u4_ldz) + u4_word - 1);
+ // Inlined ih264d_uev
+ if(u4_cbp > 47) return ERROR_CBP;
+ u4_cbp = puc_CbpInter[u4_cbp];
+
+ if((ps_dec->s_high_profile.u1_transform8x8_present) && (u4_cbp & (0xf)) &&
+ (ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag) && (u1_Bdirect_tranform_read))
+ {
+ ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+
+ COPYTHECONTEXT("coded_block_pattern", u4_cbp);
+ ps_cur_mb_info->u1_cbp = u4_cbp;
+ }
+
+ /* Read mb_qp_delta */
+ if(u4_cbp)
+ {
+ WORD32 i_temp;
+ // inlining ih264d_sev
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i_temp = (-(WORD32) u4_abs_val);
+ else
+ i_temp = (u4_abs_val);
+
+ if(i_temp < -26 || i_temp > 25) return ERROR_INV_RANGE_QP_T;
+ // inlinined ih264d_sev
+ COPYTHECONTEXT("mb_qp_delta", i_temp);
+ if(i_temp)
+ {
+ ret = ih264d_update_qp(ps_dec, (WORD8) i_temp);
+ if(ret != OK) return ret;
+ }
+
+ /*SVC residual from start to end idx*/
+ ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, 0);
+ if(ret != OK) return ret;
+ if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ }
+ else
+ {
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+ }
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : ParseMb_SubMb_PredBCab_svc\endif
+*
+* \brief
+* Implements sub_mb_pred() of 7.3.5.2. & mb_pred() of 7.3.5.1
+*
+* \return
+* None.
+*
+**************************************************************************
+*/
+
+WORD32 isvcd_parse_bmb_non_direct_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ /* Loads from ps_dec */
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data + u1_num_mbsNby2;
+
+ /* table pointer loads */
+ const UWORD8 *pu1_sub_mb_pred_modes = (UWORD8 *) (gau1_ih264d_submb_pred_modes) + 4;
+ const UWORD8(*pu1_mb_pred_modes)[32] = (const UWORD8(*)[32]) gau1_ih264d_mb_pred_modes;
+ const UWORD8 *pu1_num_mb_part = (const UWORD8 *) gau1_ih264d_num_mb_part;
+ const UWORD8 *pu1_sub_mb_mc_mode = (UWORD8 *) (gau1_ih264d_submb_mc_mode) + 4;
+
+ const UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ UWORD8 *pu1_col_info = ps_parse_mb_data->u1_col_info;
+ WORD8 *pi1_ref_idx_l0 = &ps_parse_mb_data->i1_ref_idx[0][0];
+ WORD8 *pi1_ref_idx_l1 = &ps_parse_mb_data->i1_ref_idx[1][0];
+ UWORD8 u1_dec_ref_l0, u1_dec_ref_l1;
+
+ UWORD8 u1_num_mb_part, u1_mb_mc_mode, u1_sub_mb, u1_mbpred_mode = 5 + u1_mb_type;
+ UWORD32 u4_mb_mc_mode = 0, u4_mb_pred_mode = 0;
+ WORD32 ret;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ p_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
+ u1_sub_mb = !(u1_mb_type ^ B_8x8);
+
+ {
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 *pu1_num_ref_idx_lx_active = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active;
+ UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+ UWORD8 u1_mbaff_field = (u1_mbaff & uc_field);
+ u1_dec_ref_l0 = (pu1_num_ref_idx_lx_active[0] << u1_mbaff_field) - 1;
+ u1_dec_ref_l1 = (pu1_num_ref_idx_lx_active[1] << u1_mbaff_field) - 1;
+ }
+
+ if(u1_sub_mb)
+ {
+ const UWORD8 u1_colz = ((PRED_8x8) << 6);
+ UWORD8 uc_i;
+ u1_mb_mc_mode = 0;
+ u1_num_mb_part = 4;
+ /* Reading the subMB type */
+ for(uc_i = 0; uc_i < 4; uc_i++)
+ {
+ UWORD8 u1_sub_mb_mode, u1_subMbPredModes;
+ u1_sub_mb_mode =
+ ih264d_parse_submb_type_cabac(1, ps_cab_env, ps_bitstrm, ps_dec->p_sub_mb_type_t);
+
+ if(u1_sub_mb_mode > 12) return ERROR_SUB_MB_TYPE;
+
+ u1_subMbPredModes = pu1_sub_mb_pred_modes[u1_sub_mb_mode];
+ u4_mb_mc_mode = (u4_mb_mc_mode << 8) | pu1_sub_mb_mc_mode[u1_sub_mb_mode];
+ u4_mb_pred_mode = (u4_mb_pred_mode << 8) | u1_subMbPredModes;
+ *pi1_ref_idx_l0++ = (u1_subMbPredModes & PRED_L0) ? u1_dec_ref_l0 : -1;
+ *pi1_ref_idx_l1++ = (u1_subMbPredModes & PRED_L1) ? u1_dec_ref_l1 : -1;
+ COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode);
+ /* Storing collocated Mb and SubMb mode information */
+ *pu1_col_info++ = (u1_colz | (pu1_sub_mb_mc_mode[u1_sub_mb_mode] << 4));
+ if(u1_sub_mb_mode != B_DIRECT_8x8)
+ {
+ if(u1_sub_mb_mode > B_BI_8x8)
+ {
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ else if(!ps_dec->s_high_profile.u1_direct_8x8_inference_flag)
+ {
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ pi1_ref_idx_l0 -= 4;
+ pi1_ref_idx_l1 -= 4;
+ }
+ else
+ {
+ UWORD8 u1_mb_pred_mode_part0 = pu1_mb_pred_modes[0][u1_mbpred_mode];
+ UWORD8 u1_mb_pred_mode_part1 = pu1_mb_pred_modes[1][u1_mbpred_mode];
+ u1_mb_mc_mode = ps_cur_mb_info->u1_mb_mc_mode;
+ u1_num_mb_part = pu1_num_mb_part[u1_mb_mc_mode];
+ /* Storing collocated Mb and SubMb mode information */
+ *pu1_col_info++ = (u1_mb_mc_mode << 6);
+ if(u1_mb_mc_mode) *pu1_col_info++ = (u1_mb_mc_mode << 6);
+ u4_mb_mc_mode = u1_mb_mc_mode | (u1_mb_mc_mode << 8);
+ u4_mb_mc_mode <<= 16;
+ u4_mb_pred_mode = ((u1_mb_pred_mode_part0 << 8) | u1_mb_pred_mode_part1) << 16;
+
+ *pi1_ref_idx_l0++ = (u1_mb_pred_mode_part0 & PRED_L0) ? u1_dec_ref_l0 : -1;
+ *pi1_ref_idx_l0-- = (u1_mb_pred_mode_part1 & PRED_L0) ? u1_dec_ref_l0 : -1;
+ *pi1_ref_idx_l1++ = (u1_mb_pred_mode_part0 & PRED_L1) ? u1_dec_ref_l1 : -1;
+ *pi1_ref_idx_l1-- = (u1_mb_pred_mode_part1 & PRED_L1) ? u1_dec_ref_l1 : -1;
+ }
+
+ /*Adding SVC extension code to get Motion Prediction Flags*/
+ {
+ UWORD8 uc_i, u1_mvp_l1, u1_mvp_l0;
+ UWORD8 *pu1_motion_pred_flag_l0;
+ UWORD8 *pu1_motion_pred_flag_l1;
+ WORD8 *pi1_ref_idx;
+ WORD8 *pi1_lft_cxt = ps_dec->pi1_left_ref_idx_ctxt_inc;
+ WORD8 *pi1_top_cxt = p_curr_ctxt->i1_ref_idx;
+
+ pu1_motion_pred_flag_l0 = &ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+ *pu1_motion_pred_flag_l0 = 0;
+ pu1_motion_pred_flag_l1 = &ps_svc_cur_mb_info->au1_motion_pred_flag[1];
+ *pu1_motion_pred_flag_l1 = 0;
+
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag)
+ {
+ pi1_ref_idx = pi1_ref_idx_l0;
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++, pi1_ref_idx++)
+ {
+ if(*pi1_ref_idx > 0)
+ {
+ u1_mvp_l0 = ih264d_decode_bin(0, ps_svc_lyr_dec->ps_motion_prediction_flag_l0,
+ ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_motion_prediction_flag_l0", u1_mvp_l0);
+
+ *pu1_motion_pred_flag_l0 |= (u1_mvp_l0 << uc_i);
+ if((u1_mvp_l0 & 0x01))
+ {
+ *pi1_ref_idx = -1;
+ }
+ }
+ }
+ pi1_ref_idx = pi1_ref_idx_l1;
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++, pi1_ref_idx++)
+ {
+ if(*pi1_ref_idx > 0)
+ {
+ u1_mvp_l1 = ih264d_decode_bin(0, ps_svc_lyr_dec->ps_motion_prediction_flag_l1,
+ ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_motion_prediction_flag_l1", u1_mvp_l1);
+
+ *pu1_motion_pred_flag_l1 |= (u1_mvp_l1 << uc_i);
+
+ if((u1_mvp_l1 & 0x01))
+ {
+ *pi1_ref_idx = -1;
+ }
+ }
+ }
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ *pu1_motion_pred_flag_l0 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ *pu1_motion_pred_flag_l1 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ if(ps_svc_slice_params->u1_default_motion_prediction_flag)
+ {
+ pi1_ref_idx_l0[0] = -1;
+ pi1_ref_idx_l0[1] = -1;
+ pi1_ref_idx_l0[2] = -1;
+ pi1_ref_idx_l0[3] = -1;
+
+ pi1_ref_idx_l1[0] = -1;
+ pi1_ref_idx_l1[1] = -1;
+ pi1_ref_idx_l1[2] = -1;
+ pi1_ref_idx_l1[3] = -1;
+ }
+ }
+
+ ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 0, u1_dec_ref_l0, u1_mb_mc_mode,
+ pi1_ref_idx_l0, pi1_lft_cxt, pi1_top_cxt, ps_cab_env,
+ ps_bitstrm, ps_dec->p_ref_idx_t);
+
+ if(ret != OK)
+ {
+ return ret;
+ }
+ ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 2, u1_dec_ref_l1, u1_mb_mc_mode,
+ pi1_ref_idx_l1, pi1_lft_cxt, pi1_top_cxt, ps_cab_env,
+ ps_bitstrm, ps_dec->p_ref_idx_t);
+
+ if(ret != OK)
+ {
+ return ret;
+ }
+ }
+ /* Read MotionVectors */
+ {
+ const UWORD8 *pu1_top_left_sub_mb_indx;
+ UWORD8 uc_j, uc_lx;
+ UWORD8 u1_mb_part_wd, u1_mb_part_ht;
+
+ const UWORD8 *pu1_sub_mb_indx_mod =
+ (const UWORD8 *) gau1_ih264d_submb_indx_mod + (u1_sub_mb * 6);
+ const UWORD8 *pu1_sub_mb_partw = (const UWORD8 *) gau1_ih264d_submb_partw;
+ const UWORD8 *pu1_sub_mb_parth = (const UWORD8 *) gau1_ih264d_submb_parth;
+ const UWORD8 *pu1_num_sub_mb_part = (const UWORD8 *) gau1_ih264d_num_submb_part;
+ const UWORD8 *pu1_mb_partw = (const UWORD8 *) gau1_ih264d_mb_partw;
+ const UWORD8 *pu1_mb_parth = (const UWORD8 *) gau1_ih264d_mb_parth;
+
+ UWORD8 u1_p_idx = 0;
+ UWORD8 u1_num_submb_part;
+ parse_part_params_t *ps_part;
+ mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4);
+ ps_part = ps_dec->ps_part;
+
+ /* Default initialization for non subMb case */
+ u1_mb_part_wd = pu1_mb_partw[u1_mb_mc_mode];
+ u1_mb_part_ht = pu1_mb_parth[u1_mb_mc_mode];
+ u1_num_submb_part = 1;
+
+ /* Decoding the MV for the subMB */
+ for(uc_lx = 0; uc_lx < 2; uc_lx++)
+ {
+ UWORD8 u1_sub_mb_num = 0;
+ UWORD32 u4_mb_pred_mode_tmp = u4_mb_pred_mode;
+ UWORD32 u4_mb_mc_mode_tmp = u4_mb_mc_mode;
+ UWORD8 u1_mb_mc_mode_1, u1_pred_mode, uc_i;
+ UWORD16 u2_sub_mb_num = 0x028A;
+ UWORD8 u1_b2 = uc_lx << 1;
+ u1_pred_mode = (uc_lx) ? PRED_L1 : PRED_L0;
+ /* Default for Cabac */
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode << 1);
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ WORD8 i1_pred = (UWORD8) (u4_mb_pred_mode_tmp >> 24);
+ u1_mb_mc_mode_1 = (UWORD8) (u4_mb_mc_mode_tmp >> 24);
+ u4_mb_pred_mode_tmp <<= 8;
+ u4_mb_mc_mode_tmp <<= 8;
+
+ /* subMb prediction mode */
+ if(u1_sub_mb)
+ {
+ u1_mb_part_wd = pu1_sub_mb_partw[u1_mb_mc_mode_1];
+ u1_mb_part_ht = pu1_sub_mb_parth[u1_mb_mc_mode_1];
+ u1_sub_mb_num = u2_sub_mb_num >> 12;
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode_1 << 1);
+ u1_num_submb_part = pu1_num_sub_mb_part[u1_mb_mc_mode_1];
+ u2_sub_mb_num = u2_sub_mb_num << 4;
+ }
+
+ for(uc_j = 0; uc_j < u1_num_submb_part; uc_j++, pu1_top_left_sub_mb_indx++)
+ {
+ mv_pred_t *ps_mv;
+ u1_sub_mb_num = u1_sub_mb_num + *pu1_top_left_sub_mb_indx;
+ ps_mv = ps_mv_start + u1_sub_mb_num;
+
+ /* Storing Info for partitions, writing only once */
+ if(uc_lx)
+ {
+ ps_part->u1_is_direct = (!i1_pred);
+ ps_part->u1_pred_mode = i1_pred;
+ ps_part->u1_sub_mb_num = u1_sub_mb_num;
+ ps_part->u1_partheight = u1_mb_part_ht;
+ ps_part->u1_partwidth = u1_mb_part_wd;
+
+ /* Increment partition Index */
+ u1_p_idx++;
+ ps_part++;
+ }
+
+ ih264d_get_mvd_cabac(u1_sub_mb_num, u1_b2, u1_mb_part_wd, u1_mb_part_ht,
+ (UWORD8) (i1_pred & u1_pred_mode), ps_dec, ps_mv);
+ }
+ }
+ }
+ /* write back to the scratch partition info */
+ ps_dec->ps_part = ps_part;
+ ps_parse_mb_data->u1_num_part = u1_sub_mb ? u1_p_idx : u1_num_mb_part;
+ }
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_bmb_non_direct_cavlc\endif
+*
+* \brief
+* Implements sub_mb_pred() of 7.3.5.2. & mb_pred() of 7.3.5.1
+*
+* \return
+* None.
+*
+**************************************************************************
+*/
+WORD32 isvcd_parse_bmb_non_direct_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD8 *pu1_sub_mb_pred_modes = (UWORD8 *) (gau1_ih264d_submb_pred_modes) + 4;
+ const UWORD8(*pu1_mb_pred_modes)[32] = (const UWORD8(*)[32]) gau1_ih264d_mb_pred_modes;
+ const UWORD8 *pu1_num_mb_part = (const UWORD8 *) gau1_ih264d_num_mb_part;
+ const UWORD8 *pu1_sub_mb_mc_mode = (const UWORD8 *) (gau1_ih264d_submb_mc_mode) + 4;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data + u1_num_mbsNby2;
+ UWORD8 *pu1_col_info = ps_parse_mb_data->u1_col_info;
+ WORD8(*pi1_ref_idx)[MAX_REFIDX_INFO_PER_MB] = ps_parse_mb_data->i1_ref_idx;
+ UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ UWORD8 u1_mb_mc_mode, u1_num_mb_part, u1_sub_mb = !(u1_mb_type ^ B_8x8);
+ UWORD32 u4_mb_mc_mode = 0, u4_mb_pred_mode = 0;
+ WORD32 ret = OK;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ if(u1_sub_mb)
+ {
+ UWORD8 uc_i;
+ u1_mb_mc_mode = 0;
+ u1_num_mb_part = 4;
+ /* Reading the subMB type */
+ for(uc_i = 0; uc_i < 4; uc_i++)
+ {
+ UWORD32 ui_sub_mb_mode;
+ // Inlined ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ ui_sub_mb_mode = ((1 << u4_ldz) + u4_word - 1);
+ // Inlined ih264d_uev
+ if(ui_sub_mb_mode > 12)
+ return ERROR_SUB_MB_TYPE;
+ else
+ {
+ UWORD8 u1_subMbPredMode = pu1_sub_mb_pred_modes[ui_sub_mb_mode];
+ u4_mb_mc_mode = (u4_mb_mc_mode << 8) | pu1_sub_mb_mc_mode[ui_sub_mb_mode];
+ u4_mb_pred_mode = (u4_mb_pred_mode << 8) | u1_subMbPredMode;
+ pi1_ref_idx[0][uc_i] = ((u1_subMbPredMode & PRED_L0) - 1) >> 1;
+ pi1_ref_idx[1][uc_i] = ((u1_subMbPredMode & PRED_L1) - 1) >> 1;
+ COPYTHECONTEXT("sub_mb_type", u1_subMbPredMode);
+ }
+ /* Storing collocated Mb and SubMb mode information */
+ *pu1_col_info++ = ((PRED_8x8) << 6) | ((pu1_sub_mb_mc_mode[ui_sub_mb_mode] << 4));
+ if(ui_sub_mb_mode != B_DIRECT_8x8)
+ {
+ if(ui_sub_mb_mode > B_BI_8x8)
+ {
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ else if(!ps_dec->s_high_profile.u1_direct_8x8_inference_flag)
+ {
+ ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ }
+ else
+ {
+ UWORD8 u1_mb_pred_mode_idx = 5 + u1_mb_type;
+ UWORD8 u1_mb_pred_mode_part0 = pu1_mb_pred_modes[0][u1_mb_pred_mode_idx];
+ UWORD8 u1_mb_pred_mode_part1 = pu1_mb_pred_modes[1][u1_mb_pred_mode_idx];
+ u1_mb_mc_mode = ps_cur_mb_info->u1_mb_mc_mode;
+ u1_num_mb_part = pu1_num_mb_part[u1_mb_mc_mode];
+
+ pi1_ref_idx[0][0] = ((u1_mb_pred_mode_part0 & PRED_L0) - 1) >> 1;
+ pi1_ref_idx[1][0] = ((u1_mb_pred_mode_part0 & PRED_L1) - 1) >> 1;
+ pi1_ref_idx[0][1] = ((u1_mb_pred_mode_part1 & PRED_L0) - 1) >> 1;
+ pi1_ref_idx[1][1] = ((u1_mb_pred_mode_part1 & PRED_L1) - 1) >> 1;
+
+ u4_mb_pred_mode = (u1_mb_pred_mode_part0 << 8) | u1_mb_pred_mode_part1;
+ u4_mb_mc_mode = u1_mb_mc_mode | (u1_mb_mc_mode << 8);
+ u4_mb_mc_mode <<= 16;
+ u4_mb_pred_mode <<= 16;
+
+ /* Storing collocated Mb and SubMb mode information */
+ *pu1_col_info++ = (u1_mb_mc_mode << 6);
+ if(u1_mb_mc_mode) *pu1_col_info++ = (u1_mb_mc_mode << 6);
+ }
+
+ {
+ UWORD8 uc_i;
+ UWORD8 *pu1_motion_pred_flag_l0;
+ UWORD8 *pu1_motion_pred_flag_l1;
+ UWORD8 u1_mvp_l1;
+ UWORD8 u1_mvp_l0;
+
+ pu1_motion_pred_flag_l0 = &ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+ *pu1_motion_pred_flag_l0 = 0;
+ pu1_motion_pred_flag_l1 = &ps_svc_cur_mb_info->au1_motion_pred_flag[1];
+ *pu1_motion_pred_flag_l1 = 0;
+
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag)
+ {
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ if(pi1_ref_idx[0][uc_i] > -1)
+ {
+ u1_mvp_l0 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: ps_motion_prediction_flag_l0", u1_mvp_l0);
+ *pu1_motion_pred_flag_l0 |= (u1_mvp_l0 << uc_i);
+ }
+ }
+
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ if(pi1_ref_idx[1][uc_i] > -1)
+ {
+ u1_mvp_l1 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: ps_motion_prediction_flag_l1", u1_mvp_l1);
+ *pu1_motion_pred_flag_l1 |= (u1_mvp_l1 << uc_i);
+ }
+ }
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ *pu1_motion_pred_flag_l0 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ *pu1_motion_pred_flag_l1 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ }
+
+ {
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+ UWORD8 *pu1_num_ref_idx_lx_active = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active;
+ const UWORD8 u1_mbaff_field = (u1_mbaff & uc_field);
+ UWORD8 u4_num_ref_idx_lx_active;
+
+ u4_num_ref_idx_lx_active = (pu1_num_ref_idx_lx_active[0] << u1_mbaff_field) - 1;
+
+ if(u4_num_ref_idx_lx_active)
+ {
+ if(1 == u4_num_ref_idx_lx_active)
+ isvcd_parse_bmb_ref_index_cavlc_range1(u1_num_mb_part, ps_bitstrm,
+ pi1_ref_idx[0], u4_num_ref_idx_lx_active,
+ pu1_motion_pred_flag_l0);
+ else
+ {
+ isvcd_parse_bmb_ref_index_cavlc(u1_num_mb_part, ps_bitstrm, pi1_ref_idx[0],
+ u4_num_ref_idx_lx_active,
+ pu1_motion_pred_flag_l0);
+ if(ret != OK) return ret;
+ }
+ }
+
+ u4_num_ref_idx_lx_active = (pu1_num_ref_idx_lx_active[1] << u1_mbaff_field) - 1;
+
+ if(u4_num_ref_idx_lx_active)
+ {
+ if(1 == u4_num_ref_idx_lx_active)
+ isvcd_parse_bmb_ref_index_cavlc_range1(u1_num_mb_part, ps_bitstrm,
+ pi1_ref_idx[1], u4_num_ref_idx_lx_active,
+ pu1_motion_pred_flag_l1);
+ else
+ {
+ ret = isvcd_parse_bmb_ref_index_cavlc(u1_num_mb_part, ps_bitstrm,
+ pi1_ref_idx[1], u4_num_ref_idx_lx_active,
+ pu1_motion_pred_flag_l1);
+ if(ret != OK) return ret;
+ }
+ }
+ }
+ }
+ /* Read MotionVectors */
+ {
+ const UWORD8 *pu1_top_left_sub_mb_indx;
+ const UWORD8 *pu1_sub_mb_indx_mod =
+ (const UWORD8 *) (gau1_ih264d_submb_indx_mod) + (u1_sub_mb * 6);
+ const UWORD8 *pu1_sub_mb_partw = (const UWORD8 *) gau1_ih264d_submb_partw;
+ const UWORD8 *pu1_sub_mb_parth = (const UWORD8 *) gau1_ih264d_submb_parth;
+ const UWORD8 *pu1_num_sub_mb_part = (const UWORD8 *) gau1_ih264d_num_submb_part;
+ const UWORD8 *pu1_mb_partw = (const UWORD8 *) gau1_ih264d_mb_partw;
+ const UWORD8 *pu1_mb_parth = (const UWORD8 *) gau1_ih264d_mb_parth;
+ UWORD8 u1_p_idx = 0, u1_num_submb_part, uc_lx;
+ parse_part_params_t *ps_part;
+ mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4);
+ UWORD8 u1_mb_part_wd, u1_mb_part_ht;
+
+ ps_part = ps_dec->ps_part;
+ /* Default Initialization for Non subMb Case Mode */
+ u1_mb_part_wd = pu1_mb_partw[u1_mb_mc_mode];
+ u1_mb_part_ht = pu1_mb_parth[u1_mb_mc_mode];
+ u1_num_submb_part = 1;
+
+ /* Decoding the MV for the subMB */
+ for(uc_lx = 0; uc_lx < 2; uc_lx++)
+ {
+ UWORD8 u1_sub_mb_num = 0, u1_pred_mode, uc_i;
+ UWORD32 u4_mb_mc_mode_tmp = u4_mb_mc_mode;
+ UWORD32 u4_mb_pred_mode_tmp = u4_mb_pred_mode;
+ UWORD16 u2_sub_mb_num = 0x028A; // for sub mb case
+ UWORD8 u1_b2 = uc_lx << 1;
+ u1_pred_mode = (uc_lx) ? PRED_L1 : PRED_L0;
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode << 1);
+
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ UWORD8 u1_mb_mc_mode, uc_j;
+ UWORD8 i1_pred = u4_mb_pred_mode_tmp >> 24;
+ u1_mb_mc_mode = u4_mb_mc_mode_tmp >> 24;
+ u4_mb_pred_mode_tmp <<= 8;
+ u4_mb_mc_mode_tmp <<= 8;
+ /* subMb prediction mode */
+ if(u1_sub_mb)
+ {
+ u1_mb_part_wd = pu1_sub_mb_partw[u1_mb_mc_mode];
+ u1_mb_part_ht = pu1_sub_mb_parth[u1_mb_mc_mode];
+ u1_sub_mb_num = u2_sub_mb_num >> 12;
+ u1_num_submb_part = pu1_num_sub_mb_part[u1_mb_mc_mode];
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode << 1);
+ u2_sub_mb_num <<= 4;
+ }
+ for(uc_j = 0; uc_j < u1_num_submb_part; uc_j++, pu1_top_left_sub_mb_indx++)
+ {
+ mv_pred_t *ps_mv;
+ u1_sub_mb_num = u1_sub_mb_num + *pu1_top_left_sub_mb_indx;
+ ps_mv = ps_mv_start + u1_sub_mb_num;
+
+ /* Storing Info for partitions, writing only once */
+ if(uc_lx)
+ {
+ ps_part->u1_is_direct = (!i1_pred);
+ ps_part->u1_pred_mode = i1_pred;
+ ps_part->u1_sub_mb_num = u1_sub_mb_num;
+ ps_part->u1_partheight = u1_mb_part_ht;
+ ps_part->u1_partwidth = u1_mb_part_wd;
+ /* Increment partition Index */
+ u1_p_idx++;
+ ps_part++;
+ }
+
+ if(i1_pred & u1_pred_mode)
+ {
+ WORD16 i2_mvx, i2_mvy;
+ // inlining ih264d_sev
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i2_mvx = (-(WORD32) u4_abs_val);
+ else
+ i2_mvx = (u4_abs_val);
+ }
+ // inlinined ih264d_sev
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i2_mvy = (-(WORD32) u4_abs_val);
+ else
+ i2_mvy = (u4_abs_val);
+ }
+ // inlinined ih264d_sev
+ /* Storing Mv residuals */
+ ps_mv->i2_mv[u1_b2] = i2_mvx;
+ ps_mv->i2_mv[u1_b2 + 1] = i2_mvy;
+ }
+ }
+ }
+ }
+ /* write back to the scratch partition info */
+ ps_dec->ps_part = ps_part;
+ ps_parse_mb_data->u1_num_part = u1_sub_mb ? u1_p_idx : u1_num_mb_part;
+ }
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : ih264d_decode_ebslice \endif
+*
+* \brief
+* Decodes an EB Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_ebslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i_status = OK;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ dec_subset_seq_params_t *ps_sps_svc_ext = NULL;
+ dec_nal_unit_svc_ext_params_t *ps_nal_svc_ext = NULL;
+ UWORD8 u1_ref_idx_re_flag_lx;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD64 u8_ref_idx_l0, u8_ref_idx_l1;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+
+ ps_nal_svc_ext = ps_svc_lyr_dec->ps_nal_svc_ext;
+ ps_subset_seq = ps_svc_lyr_dec->ps_cur_subset_sps;
+ ps_sps_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD8 *pi1_buf;
+ WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv;
+ WORD32 *pi4_mv = (WORD32 *) pi2_mv;
+ WORD16 *pi16_refFrame;
+ pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame;
+ pi16_refFrame = (WORD16 *) pi1_buf;
+ *pi4_mv = 0;
+ *(pi4_mv + 1) = 0;
+ *pi16_refFrame = OUT_OF_RANGE_REF;
+ ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8) -1;
+ ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8) -1;
+ }
+
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ ps_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: num_ref_idx_override_flag",
+ ps_slice->u1_num_ref_idx_active_override_flag);
+
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ u8_ref_idx_l1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1];
+ if(ps_slice->u1_num_ref_idx_active_override_flag)
+ {
+ u8_ref_idx_l0 = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: num_ref_idx_l0_active_minus1", u8_ref_idx_l0 - 1);
+
+ u8_ref_idx_l1 = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: num_ref_idx_l1_active_minus1", u8_ref_idx_l1 - 1);
+ }
+
+ {
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS;
+ if(ps_slice->u1_field_pic_flag)
+ {
+ u1_max_ref_idx = H264_MAX_REF_PICS << 1;
+ }
+ if((u8_ref_idx_l0 >= u1_max_ref_idx) || (u8_ref_idx_l1 >= u1_max_ref_idx))
+ {
+ return ERROR_NUM_REF;
+ }
+ ps_slice->u1_num_ref_idx_lx_active[0] = (UWORD8) u8_ref_idx_l0;
+ ps_slice->u1_num_ref_idx_lx_active[1] = (UWORD8) u8_ref_idx_l1;
+ }
+
+ ih264d_init_ref_idx_lx_b(ps_dec);
+ /* Store the value for future slices in the same picture */
+ ps_dec->u1_num_ref_idx_lx_active_prev = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0];
+
+ u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: ref_pic_list_reordering_flag_l0",
+ u1_ref_idx_re_flag_lx);
+
+ /* Modified temporarily */
+ if(u1_ref_idx_re_flag_lx)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ ret = ih264d_ref_idx_reordering(ps_dec, 0);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0];
+
+ u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: ref_pic_list_reordering_flag_l1",
+ u1_ref_idx_re_flag_lx);
+
+ /* Modified temporarily */
+ if(u1_ref_idx_re_flag_lx)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_mod_dpb[1];
+ ret = ih264d_ref_idx_reordering(ps_dec, 1);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_init_dpb[1];
+
+ /* Create refIdx to POC mapping */
+ {
+ void **ppv_map_ref_idx_to_poc_lx;
+ WORD8 idx;
+ struct pic_buffer_t *ps_pic;
+
+ ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0;
+ ppv_map_ref_idx_to_poc_lx[0] = 0;
+ ppv_map_ref_idx_to_poc_lx++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1);
+ }
+
+ ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1;
+
+ ppv_map_ref_idx_to_poc_lx[0] = 0;
+ ppv_map_ref_idx_to_poc_lx++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx];
+ ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1);
+ }
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b;
+
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L0;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L0;
+
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1);
+
+ ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1;
+
+ ppv_map_ref_idx_to_poc_lx_t += 2;
+ ppv_map_ref_idx_to_poc_lx_b += 2;
+ }
+
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L1;
+
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; idx++)
+ {
+ UWORD8 u1_tmp_idx = idx << 1;
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx];
+ ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx + 1] = (ps_pic->pu1_buf1);
+
+ ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx + 1] = (ps_pic->pu1_buf1) + 1;
+ }
+ }
+
+ /* BS is moved post recon gen in SVC ext*/
+ if(ps_dec->u4_num_cores >= 2)
+ {
+ WORD32 num_entries;
+ WORD32 size;
+ num_entries = MAX_FRAMES;
+ if((1 >= ps_dec->ps_cur_sps->u1_num_ref_frames) && (0 == ps_dec->i4_display_delay))
+ {
+ num_entries = 1;
+ }
+
+ num_entries = ((2 * num_entries) + 1);
+ num_entries *= 2;
+
+ size = num_entries * sizeof(void *);
+ size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ memcpy((void *) ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc,
+ ps_dec->ppv_map_ref_idx_to_poc, size);
+ }
+ }
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag &&
+ (ps_dec->ps_cur_slice->u1_field_pic_flag == 0))
+ {
+ ih264d_convert_frm_mbaff_list(ps_dec);
+ }
+
+ if(ps_pps->u1_wted_bipred_idc == 1)
+ {
+ if(!ps_nal_svc_ext->u1_no_inter_layer_pred_flag)
+ {
+ ps_svc_slice_params->u1_base_pred_weight_table_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_base_pred_weight_table_flag",
+ ps_svc_slice_params->u1_base_pred_weight_table_flag);
+ }
+
+ if(ps_nal_svc_ext->u1_no_inter_layer_pred_flag ||
+ !ps_svc_slice_params->u1_base_pred_weight_table_flag)
+ {
+ ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm);
+
+ ih264d_form_pred_weight_matrix(ps_dec);
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+ }
+ else if(ps_pps->u1_wted_bipred_idc == 2)
+ {
+ /* Implicit Weighted prediction */
+ ps_slice->u2_log2Y_crwd = 0x0505;
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ ih264d_get_implicit_weights(ps_dec);
+ }
+ else
+ ps_dec->ps_cur_slice->u2_log2Y_crwd = 0;
+
+ ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
+
+ /* G050 */
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+
+ if(!ps_sps_svc_ext->u1_slice_header_restriction_flag)
+ {
+ ps_svc_slice_params->u1_store_ref_base_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_SVC_EXT: u1_store_ref_base_pic_flag",
+ ps_svc_slice_params->u1_store_ref_base_pic_flag);
+
+ if(0 != ps_svc_slice_params->u1_store_ref_base_pic_flag)
+ {
+ return NOT_OK;
+ }
+ if(((1 == ps_nal_svc_ext->u1_use_ref_base_pic_flag) ||
+ (1 == ps_svc_slice_params->u1_store_ref_base_pic_flag)) &&
+ (!ps_nal_svc_ext->u1_idr_flag))
+ {
+ i_status = isvcd_dec_ref_base_pic_marking(
+ &ps_svc_slice_params->s_ref_base_pic_marking_svc_ext, ps_bitstrm);
+ if(i_status != OK)
+ {
+ return i_status;
+ }
+ }
+ }
+ }
+ }
+ /* G050 */
+ /*Code is present in standard but omitted in the reference code*/
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->u1_cabac_init_idc = u4_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: cabac_init_idc", ps_slice->u1_cabac_init_idc);
+ }
+
+ {
+ /* Read slice_qp_delta */
+ WORD64 i8_temp =
+ (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_qp_delta",
+ (WORD8) (ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
+ }
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ COPYTHECONTEXT("Slice Header SVC ext: disable_deblocking_filter_idc", u4_temp);
+ ps_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_alpha_c0_offset_div2",
+ ps_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_beta_offset_div2",
+ ps_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_slice->u1_disable_dblk_filter_idc = 0;
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+
+ /* add the remaining part of the code for svc extension from reference */
+ ret = isvcd_set_default_slice_header_ext(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ret = isvcd_parse_slice_header(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ if(ret != OK)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ ps_dec->u1_slice_header_done = 2;
+ if(!ps_svc_slice_params->u1_slice_skip_flag)
+ {
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext =
+ isvcd_parse_inter_slice_data_cabac_enh_lyr;
+ ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext = isvcd_parse_bmb_cabac;
+ isvcd_init_cabac_contexts(B_SLICE, ps_dec);
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+ }
+ else
+ {
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext =
+ isvcd_parse_inter_slice_data_cavlc_enh_lyr;
+ ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext = isvcd_parse_bmb_cavlc;
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ }
+ }
+ else
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ret = ih264d_cal_col_pic(ps_dec);
+ if(ret != OK) return ret;
+ ps_dec->u1_B = 1;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = isvcd_mv_pred_ref_tfr_nby2_ebmb;
+ ret = ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext(ps_svc_lyr_dec, ps_slice,
+ u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_bslice \endif
+*
+* \brief
+* Decodes a B Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_bslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD8 u1_ref_idx_re_flag_lx;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD64 u8_ref_idx_l0, u8_ref_idx_l1;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD8 *pi1_buf;
+ WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv;
+ WORD32 *pi4_mv = (WORD32 *) pi2_mv;
+ WORD16 *pi16_refFrame;
+ pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame;
+ pi16_refFrame = (WORD16 *) pi1_buf;
+ *pi4_mv = 0;
+ *(pi4_mv + 1) = 0;
+ *pi16_refFrame = OUT_OF_RANGE_REF;
+ ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8) -1;
+ ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8) -1;
+ }
+
+ ps_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_slice->u1_num_ref_idx_active_override_flag);
+
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ u8_ref_idx_l1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1];
+ if(ps_slice->u1_num_ref_idx_active_override_flag)
+ {
+ u8_ref_idx_l0 = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", u8_ref_idx_l0 - 1);
+
+ u8_ref_idx_l1 = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: num_ref_idx_l1_active_minus1", u8_ref_idx_l1 - 1);
+ }
+
+ {
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS;
+ if(ps_slice->u1_field_pic_flag)
+ {
+ u1_max_ref_idx = H264_MAX_REF_PICS << 1;
+ }
+ if((u8_ref_idx_l0 >= u1_max_ref_idx) || (u8_ref_idx_l1 >= u1_max_ref_idx))
+ {
+ return ERROR_NUM_REF;
+ }
+ ps_slice->u1_num_ref_idx_lx_active[0] = (UWORD8) u8_ref_idx_l0;
+ ps_slice->u1_num_ref_idx_lx_active[1] = (UWORD8) u8_ref_idx_l1;
+ }
+
+ ih264d_init_ref_idx_lx_b(ps_dec);
+ /* Store the value for future slices in the same picture */
+ ps_dec->u1_num_ref_idx_lx_active_prev = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0];
+
+ u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l0", u1_ref_idx_re_flag_lx);
+
+ /* Modified temporarily */
+ if(u1_ref_idx_re_flag_lx)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ ret = ih264d_ref_idx_reordering(ps_dec, 0);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0];
+
+ u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l1", u1_ref_idx_re_flag_lx);
+
+ /* Modified temporarily */
+ if(u1_ref_idx_re_flag_lx)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_mod_dpb[1];
+ ret = ih264d_ref_idx_reordering(ps_dec, 1);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_init_dpb[1];
+
+ /* Create refIdx to POC mapping */
+ {
+ void **ppv_map_ref_idx_to_poc_lx;
+ WORD8 idx;
+ struct pic_buffer_t *ps_pic;
+
+ ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0;
+ ppv_map_ref_idx_to_poc_lx[0] = 0;
+ ppv_map_ref_idx_to_poc_lx++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1);
+ }
+
+ ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1;
+
+ ppv_map_ref_idx_to_poc_lx[0] = 0;
+ ppv_map_ref_idx_to_poc_lx++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx];
+ ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1);
+ }
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b;
+
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L0;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L0;
+
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1);
+
+ ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1;
+
+ ppv_map_ref_idx_to_poc_lx_t += 2;
+ ppv_map_ref_idx_to_poc_lx_b += 2;
+ }
+
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L1;
+
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+ for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; idx++)
+ {
+ UWORD8 u1_tmp_idx = idx << 1;
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx];
+ ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx + 1] = (ps_pic->pu1_buf1);
+
+ ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx + 1] = (ps_pic->pu1_buf1) + 1;
+ }
+ }
+ }
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag && (ps_dec->ps_cur_slice->u1_field_pic_flag == 0))
+ {
+ ih264d_convert_frm_mbaff_list(ps_dec);
+ }
+
+ if(ps_pps->u1_wted_bipred_idc == 1)
+ {
+ ret = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm);
+ if(ret != OK) return ret;
+ ih264d_form_pred_weight_matrix(ps_dec);
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+ else if(ps_pps->u1_wted_bipred_idc == 2)
+ {
+ /* Implicit Weighted prediction */
+ ps_slice->u2_log2Y_crwd = 0x0505;
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ ih264d_get_implicit_weights(ps_dec);
+ }
+ else
+ ps_dec->ps_cur_slice->u2_log2Y_crwd = 0;
+
+ ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
+
+ /* G050 */
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+ }
+ /* G050 */
+
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->u1_cabac_init_idc = u4_temp;
+ COPYTHECONTEXT("SH: cabac_init_idc", ps_slice->u1_cabac_init_idc);
+ }
+ {
+ /* Read slice_qp_delta */
+ WORD64 i8_temp =
+ (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("SH: slice_qp_delta",
+ (WORD8) (ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
+ }
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp);
+ ps_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2",
+ ps_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_beta_offset_div2", ps_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_slice->u1_disable_dblk_filter_idc = 0;
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ if(ret != OK)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ ps_dec->u1_slice_header_done = 2;
+
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_svc_inter_slice = isvcd_parse_inter_slice_data_cabac;
+ ps_dec->pf_parse_inter_mb = ih264d_parse_bmb_cabac;
+ ih264d_init_cabac_contexts(B_SLICE, ps_dec);
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+ }
+ else
+ {
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_svc_inter_slice = isvcd_parse_inter_slice_data_cavlc;
+ ps_dec->pf_parse_inter_mb = ih264d_parse_bmb_cavlc;
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ }
+
+ ret = ih264d_cal_col_pic(ps_dec);
+ if(ret != OK) return ret;
+ ps_dec->u1_B = 1;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_bmb;
+ ret = ps_svc_lyr_dec->pf_parse_svc_inter_slice(ps_svc_lyr_dec, ps_slice, u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_parse_eislice.c b/decoder/svc/isvcd_parse_eislice.c
new file mode 100644
index 0000000..4b3728c
--- /dev/null
+++ b/decoder/svc/isvcd_parse_eislice.c
@@ -0,0 +1,2103 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_eislice.c
+ *
+ * @brief
+ * Contains routines that decode a EI slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_parse_islice_data_cabac()
+ * - isvcd_parse_islice_data_cavlc()
+ * - isvcd_parse_imb_cavlc()
+ * - isvcd_parse_eislice()
+ * - isvcd_parse_eislice_data_cabac()
+ * - isvcd_parse_eislice_data_cavlc()
+ * - isvcd_parse_imb_cabac()
+ * - isvcd_parse_islice()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264_defs.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_debug.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_tables.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_cabac.h"
+#include "ih264d_parse_cabac.h"
+#include "ih264d_parse_mb_header.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ithread.h"
+#include "ih264d_parse_mb_header.h"
+#include "assert.h"
+#include "ih264d_utils.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_parse_headers.h"
+#include "isvcd_parse_headers.h"
+#include "isvcd_parse_slice.h"
+#include "isvcd_mb_utils.h"
+
+void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+void isvcd_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_islice_data_cabac */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 06 2005 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_islice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice)
+{
+ UWORD8 uc_more_data_flag;
+ UWORD8 u1_num_mbs, u1_mb_idx;
+ dec_mb_info_t *ps_cur_mb_info;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ WORD16 i2_cur_mb_addr;
+ UWORD8 u1_mbaff;
+ UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb;
+ WORD32 ret = OK;
+
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+
+ if(ps_bitstrm->u4_ofst & 0x07)
+ {
+ ps_bitstrm->u4_ofst += 8;
+ ps_bitstrm->u4_ofst &= 0xFFFFFFF8;
+ }
+ ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm);
+ if(ret != OK) return ret;
+ ih264d_init_cabac_contexts(I_SLICE, ps_dec);
+
+ ps_dec->i1_prev_mb_qp_delta = 0;
+
+ /* initializations */
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ uc_more_data_flag = 1;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ do
+ {
+ UWORD16 u2_mbx;
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ {
+ UWORD8 u1_mb_type;
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0);
+ u2_mbx = ps_dec->u2_mbx;
+
+ /*********************************************************************/
+ /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */
+ /*********************************************************************/
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_MB;
+
+ /* Macroblock Layer Begins */
+ /* Decode the u1_mb_type */
+ u1_mb_type = ih264d_parse_mb_type_intra_cabac(0, ps_dec);
+ if(u1_mb_type > 25) return ERROR_MB_TYPE;
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+
+ /* Parse Macroblock Data */
+ if(25 == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ }
+ else
+ {
+ ret = ih264d_parse_imb_cabac(ps_dec, ps_cur_mb_info, u1_mb_type);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ }
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ }
+
+ if(ps_cur_mb_info->u1_topmb && u1_mbaff)
+ uc_more_data_flag = 1;
+ else
+ {
+ uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, ps_bitstrm);
+ uc_more_data_flag = !uc_more_data_flag;
+ COPYTHECONTEXT("Decode Sliceterm", !uc_more_data_flag);
+ }
+
+ if(u1_mbaff)
+ {
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /* Next macroblock information */
+ i2_cur_mb_addr++;
+ /* Store the colocated information */
+ {
+ mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4);
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (ps_dec->u1_cur_mb_fld_dec_flag << 1), 4, 4);
+ }
+ /*if num _cores is set to 3,compute bs will be done in another thread*/
+ if(ps_dec->u4_num_cores < 3)
+ {
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ps_svc_lyr_dec->pf_svc_compute_bs(ps_svc_lyr_dec, ps_cur_mb_info,
+ (UWORD16) (u1_num_mbs >> u1_mbaff));
+ }
+ u1_num_mbs++;
+ }
+
+ /****************************************************************/
+ /* Check for End Of Row */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_tfr_n_mb =
+ (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || (!uc_more_data_flag);
+ ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag);
+
+ if(u1_tfr_n_mb || (!uc_more_data_flag))
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ else
+ {
+ isvcd_decode_recon_tfr_nmb_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ }
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ } while(uc_more_data_flag);
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_islice_data_cavlc */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 06 2005 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_parse_islice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice)
+{
+ UWORD8 uc_more_data_flag;
+ UWORD8 u1_num_mbs, u1_mb_idx;
+ dec_mb_info_t *ps_cur_mb_info;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ WORD16 i2_cur_mb_addr;
+ UWORD8 u1_mbaff;
+ UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb;
+ WORD32 ret = OK;
+
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+
+ /* initializations */
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+
+ uc_more_data_flag = 1;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ do
+ {
+ UWORD8 u1_mb_type;
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0);
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_MB;
+
+ /**************************************************************/
+ /* Macroblock Layer Begins, Decode the u1_mb_type */
+ /**************************************************************/
+ /* Inlined ih264d_uev */
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_temp;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+ if(u4_temp > 25) return ERROR_MB_TYPE;
+ u1_mb_type = u4_temp;
+ }
+ /* Inlined ih264d_uev */
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+
+ /**************************************************************/
+ /* Parse Macroblock data */
+ /**************************************************************/
+ if(25 == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ }
+ else
+ {
+ ret = ih264d_parse_imb_cavlc(ps_dec, ps_cur_mb_info, u1_num_mbs, u1_mb_type);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ }
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /**************************************************************/
+ /* Get next Macroblock address */
+ /**************************************************************/
+ i2_cur_mb_addr++;
+ /* Store the colocated information */
+ {
+ mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4);
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (ps_dec->u1_cur_mb_fld_dec_flag << 1), 4, 4);
+ }
+
+ /*if num _cores is set to 3,compute bs will be done in another thread*/
+ if(ps_dec->u4_num_cores < 3)
+ {
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ps_svc_lyr_dec->pf_svc_compute_bs(ps_svc_lyr_dec, ps_cur_mb_info,
+ (UWORD16) (u1_num_mbs >> u1_mbaff));
+ }
+ u1_num_mbs++;
+
+ /****************************************************************/
+ /* Check for End Of Row */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_tfr_n_mb =
+ (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || (!uc_more_data_flag);
+ ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag);
+
+ if(u1_tfr_n_mb || (!uc_more_data_flag))
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ else
+ {
+ isvcd_decode_recon_tfr_nmb_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ }
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ } while(uc_more_data_flag);
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+/*!
+**************************************************************************
+* \if Function name : ParseIMb \endif
+*
+* \brief
+* This function parses CAVLC syntax of a I MB. If 16x16 Luma DC transform
+* is also done here. Transformed Luma DC values are copied in their
+* 0th pixel location of corrosponding CoeffBlock.
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_imb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_mb_type)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i4_delta_qp;
+ UWORD32 u4_temp;
+ UWORD32 ui_is_top_mb_available;
+ UWORD32 ui_is_left_mb_available;
+ UWORD32 u4_cbp;
+ UWORD32 u4_offset;
+ UWORD32 *pu4_bitstrm_buf;
+ WORD32 ret;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UNUSED(u1_mb_num);
+
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+ u4_temp = ps_dec->u1_mb_ngbr_availablity;
+ ui_is_top_mb_available = BOOLEAN(u4_temp & TOP_MB_AVAILABLE_MASK);
+ ui_is_left_mb_available = BOOLEAN(u4_temp & LEFT_MB_AVAILABLE_MASK);
+ pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+
+ ps_cur_mb_info->ps_curmb->u1_mb_type = P_MB;
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ if(u1_mb_type == I_4x4_MB)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB;
+ u4_offset = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Read transform_size_8x8_flag if present */
+ /*--------------------------------------------------------------------*/
+ if(ps_dec->ps_cur_pps->i4_transform_8x8_mode_flag)
+ {
+ ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Read the IntraPrediction modes for LUMA */
+ /*--------------------------------------------------------------------*/
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ UWORD8 *pu1_temp;
+ ih264d_read_intra_pred_modes(ps_dec, ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data),
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data + 16),
+ ps_cur_mb_info->u1_tran_form8x8);
+ pu1_temp = (UWORD8 *) ps_dec->pv_parse_tu_coeff_data;
+ pu1_temp += 32;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pu1_temp;
+ }
+ else
+ {
+ UWORD8 *pu1_temp;
+ ih264d_read_intra_pred_modes(ps_dec, ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data),
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data + 4),
+ ps_cur_mb_info->u1_tran_form8x8);
+ pu1_temp = (UWORD8 *) ps_dec->pv_parse_tu_coeff_data;
+ pu1_temp += 8;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pu1_temp;
+ }
+ /*--------------------------------------------------------------------*/
+ /* Read the IntraPrediction mode for CHROMA */
+ /*--------------------------------------------------------------------*/
+ /* Inlined ih264d_uev */
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_temp;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+ if(u4_temp > 3)
+ {
+ return ERROR_CHROMA_PRED_MODE;
+ }
+ ps_cur_mb_info->u1_chroma_pred_mode = u4_temp;
+ COPYTHECONTEXT("intra_chroma_pred_mode", ps_cur_mb_info->u1_chroma_pred_mode);
+ }
+ /*--------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*--------------------------------------------------------------------*/
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_cbp = ((1 << u4_ldz) + u4_word - 1);
+ }
+ if(u4_cbp > 47)
+ {
+ return ERROR_CBP;
+ }
+
+ u4_cbp = gau1_ih264d_cbp_table[u4_cbp][0];
+ COPYTHECONTEXT("coded_block_pattern", u4_cbp);
+ ps_cur_mb_info->u1_cbp = u4_cbp;
+
+ /*--------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*--------------------------------------------------------------------*/
+ if(ps_cur_mb_info->u1_cbp)
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ {
+ i4_delta_qp = (-(WORD32) u4_abs_val);
+ }
+ else
+ {
+ i4_delta_qp = (u4_abs_val);
+ }
+
+ if((i4_delta_qp < -26) || (i4_delta_qp > 25))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+
+ COPYTHECONTEXT("mb_qp_delta", i1_delta_qp);
+ if(i4_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, (WORD8) i4_delta_qp);
+ if(ret != OK) return ret;
+ }
+ }
+ }
+ else
+ {
+ u4_offset = 1;
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB;
+ /*-------------------------------------------------------------------*/
+ /* Read the IntraPrediction mode for CHROMA */
+ /*-------------------------------------------------------------------*/
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+
+ /* Inlined ih264d_uev */
+ if(u4_temp > 3)
+ {
+ return ERROR_CHROMA_PRED_MODE;
+ }
+ ps_cur_mb_info->u1_chroma_pred_mode = u4_temp;
+ COPYTHECONTEXT("intra_chroma_pred_mode", ps_cur_mb_info->u1_chroma_pred_mode);
+ }
+ /*-------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*-------------------------------------------------------------------*/
+ u4_cbp = gau1_ih264d_cbp_tab[(u1_mb_type - 1) >> 2];
+ ps_cur_mb_info->u1_cbp = u4_cbp;
+
+ /*-------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*-------------------------------------------------------------------*/
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i4_delta_qp = (-(WORD32) u4_abs_val);
+ else
+ i4_delta_qp = (u4_abs_val);
+
+ if((i4_delta_qp < -26) || (i4_delta_qp > 25)) return ERROR_INV_RANGE_QP_T;
+ }
+ /* inlinined ih264d_sev */
+ COPYTHECONTEXT("Delta quant", i1_delta_qp);
+
+ if(i4_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, (WORD8) i4_delta_qp);
+ if(ret != OK) return ret;
+ }
+
+ {
+ WORD16 i_scaleFactor;
+ UWORD32 ui_N = 0;
+ WORD16 *pi2_scale_matrix_ptr;
+ /*******************************************************************/
+ /* for luma DC coefficients the scaling is done during the parsing */
+ /* to preserve the precision */
+ /*******************************************************************/
+ if(ps_dec->s_high_profile.u1_scaling_present)
+ {
+ pi2_scale_matrix_ptr = ps_dec->s_high_profile.i2_scalinglist4x4[0];
+ }
+ else
+ {
+ i_scaleFactor = 16;
+ pi2_scale_matrix_ptr = &i_scaleFactor;
+ }
+
+ /*---------------------------------------------------------------*/
+ /* Decode DC coefficients */
+ /*---------------------------------------------------------------*/
+ /*---------------------------------------------------------------*/
+ /* Calculation of N */
+ /*---------------------------------------------------------------*/
+ if(ui_is_left_mb_available)
+ {
+ if(ui_is_top_mb_available)
+ {
+ ui_N = ((ps_cur_mb_info->ps_top_mb->pu1_nnz_y[0] +
+ ps_dec->pu1_left_nnz_y[0] + 1) >>
+ 1);
+ }
+ else
+ {
+ ui_N = ps_dec->pu1_left_nnz_y[0];
+ }
+ }
+ else if(ui_is_top_mb_available)
+ {
+ ui_N = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[0];
+ }
+
+ {
+ WORD16 pi2_dc_coef[16] = {0};
+ WORD32 pi4_tmp[16] = {0};
+ tu_sblk4x4_coeff_data_t *ps_tu_4x4 =
+ (tu_sblk4x4_coeff_data_t *) ps_dec->pv_parse_tu_coeff_data;
+ WORD16 *pi2_coeff_block = (WORD16 *) ps_dec->pv_parse_tu_coeff_data;
+ UWORD32 u4_num_coeff;
+ ps_tu_4x4->u2_sig_coeff_map = 0;
+ ret = ps_dec->pf_cavlc_parse4x4coeff[(ui_N > 7)](pi2_dc_coef, 0, ui_N, ps_dec,
+ &u4_num_coeff);
+ if(ret != OK) return ret;
+
+ if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ if(ps_tu_4x4->u2_sig_coeff_map)
+ {
+ memset(pi2_dc_coef, 0, sizeof(pi2_dc_coef));
+ ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, pi2_dc_coef,
+ ps_dec->pu1_inv_scan);
+
+ PROFILE_DISABLE_IQ_IT_RECON()
+ ps_dec->pf_ihadamard_scaling_4x4(
+ pi2_dc_coef, pi2_coeff_block, ps_dec->pu2_quant_scale_y,
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_dec->u1_qp_y_div6, pi4_tmp);
+ pi2_coeff_block += 16;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pi2_coeff_block;
+ SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 0);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ u4_offset = 0;
+ /*--------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*--------------------------------------------------------------------*/
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_cbp = ((1 << u4_ldz) + u4_word - 1);
+ }
+ if(u4_cbp > 47)
+ {
+ return ERROR_CBP;
+ }
+
+ /* inter cbp table to be used for base mode flag*/
+ u4_cbp = gau1_ih264d_cbp_table[u4_cbp][1];
+ COPYTHECONTEXT("coded_block_pattern", u4_cbp);
+ ps_cur_mb_info->u1_cbp = u4_cbp;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Read transform_size_8x8_flag if present */
+ /*--------------------------------------------------------------------*/
+ if((ps_dec->ps_cur_pps->i4_transform_8x8_mode_flag) && (ps_cur_mb_info->u1_cbp & 0xf))
+ {
+ ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+ /*--------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*--------------------------------------------------------------------*/
+ if(ps_cur_mb_info->u1_cbp)
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ {
+ i4_delta_qp = (-(WORD32) u4_abs_val);
+ }
+ else
+ {
+ i4_delta_qp = (u4_abs_val);
+ }
+
+ if((i4_delta_qp < -26) || (i4_delta_qp > 25))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+
+ COPYTHECONTEXT("mb_qp_delta", i4_delta_qp);
+ if(i4_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, (WORD8) i4_delta_qp);
+ if(ret != OK) return ret;
+ }
+ }
+ }
+ if(u4_cbp)
+ {
+ ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, (UWORD8) u4_offset);
+ if(ret != OK) return ret;
+ if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+
+ /* Store Left Mb NNZ and TOP chroma NNZ */
+ }
+ else
+ {
+ ps_cur_mb_info->u1_qp_div6 = ps_dec->u1_qp_y_div6;
+ ps_cur_mb_info->u1_qpc_div6 = ps_dec->u1_qp_u_div6;
+ ps_cur_mb_info->u1_qpcr_div6 = ps_dec->u1_qp_v_div6;
+ ps_cur_mb_info->u1_qp_rem6 = ps_dec->u1_qp_y_rem6;
+ ps_cur_mb_info->u1_qpc_rem6 = ps_dec->u1_qp_u_rem6;
+ ps_cur_mb_info->u1_qpcr_rem6 = ps_dec->u1_qp_v_rem6;
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+ }
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : ih264d_decode_eislice \endif
+*
+* \brief
+* Decodes an EI Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_eislice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i_status = OK;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ dec_subset_seq_params_t *ps_sps_svc_ext = NULL;
+ dec_nal_unit_svc_ext_params_t *ps_nal_svc_ext = NULL;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+ UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
+
+ ps_nal_svc_ext = ps_svc_lyr_dec->ps_nal_svc_ext;
+ ps_seq = ps_dec->ps_cur_sps;
+ ps_subset_seq =
+ &ps_svc_lyr_dec->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_seq->u1_seq_parameter_set_id];
+ ps_sps_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ /* dec_ref_pic_marking function */
+ /* G050 */
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_dec->ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+
+ if(!ps_sps_svc_ext->u1_slice_header_restriction_flag)
+ {
+ ps_svc_slice_params->u1_store_ref_base_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_SVC_EXT: u1_store_ref_base_pic_flag",
+ ps_svc_slice_params->u1_store_ref_base_pic_flag);
+
+ if(0 != ps_svc_slice_params->u1_store_ref_base_pic_flag)
+ {
+ return NOT_OK;
+ }
+ if(((1 == ps_nal_svc_ext->u1_use_ref_base_pic_flag) ||
+ (1 == ps_svc_slice_params->u1_store_ref_base_pic_flag)) &&
+ (!ps_nal_svc_ext->u1_idr_flag))
+ {
+ i_status = isvcd_dec_ref_base_pic_marking(
+ &ps_svc_slice_params->s_ref_base_pic_marking_svc_ext, ps_bitstrm);
+ if(i_status != OK)
+ {
+ return i_status;
+ }
+ }
+ }
+ }
+ }
+
+ {
+ /* G050 */
+ /* Read slice_qp_delta */
+ WORD64 i8_temp =
+ (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T;
+ ps_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_qp_delta",
+ ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp);
+ }
+
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: disable_deblocking_filter_idc", u4_temp);
+
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_alpha_c0_offset_div2",
+ ps_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_beta_offset_div2",
+ ps_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_slice->u1_disable_dblk_filter_idc = 0;
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+
+ /* add the remaining part of the code for svc extension from reference */
+ ret = isvcd_set_default_slice_header_ext(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ret = isvcd_parse_slice_header(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ /* Initialization to check if number of motion vector per 2 Mbs */
+ /* are exceeding the range or not */
+ ps_dec->u2_mv_2mb[0] = 0;
+ ps_dec->u2_mv_2mb[1] = 0;
+
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ if(ret != OK)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ /*set slice header cone to 2 ,to indicate correct header*/
+ ps_dec->u1_slice_header_done = 2;
+
+ if(!ps_svc_slice_params->u1_slice_skip_flag)
+ {
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+
+ ret = isvcd_parse_eislice_data_cabac(ps_svc_lyr_dec, ps_slice, u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ }
+ else
+ {
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ ret = isvcd_parse_eislice_data_cavlc(ps_svc_lyr_dec, ps_slice, u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_eislice_data_cabac */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 06 2005 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_eislice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 uc_more_data_flag;
+ UWORD8 u1_num_mbs, u1_mb_idx;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ WORD16 i2_cur_mb_addr;
+ UWORD8 u1_mbaff;
+ UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb;
+ WORD32 ret = OK;
+ decoding_envirnoment_t *ps_cab_env;
+ UWORD8 *pu1_cur_svc_base_mode_flag;
+ UWORD8 u1_left_svc_base_mode_flag;
+ UWORD8 u1_top_svc_base_mode_flag;
+ UWORD32 u4_a, u4_b, u4_ctxt_inc;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+
+ if(ps_bitstrm->u4_ofst & 0x07)
+ {
+ ps_bitstrm->u4_ofst += 8;
+ ps_bitstrm->u4_ofst &= 0xFFFFFFF8;
+ }
+ ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm);
+ if(ret != OK) return ret;
+ isvcd_init_cabac_contexts(I_SLICE, ps_dec);
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_cab_env = &ps_dec->s_cab_dec_env;
+ /* initializations */
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ uc_more_data_flag = 1;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ do
+ {
+ UWORD16 u2_mbx;
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ {
+ UWORD8 u1_mb_type;
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_mb_info->u1_end_of_slice = 0;
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0);
+ u2_mbx = ps_dec->u2_mbx;
+ ps_svc_cur_mb_info->u1_crop_window_flag =
+ *(ps_svc_lyr_dec->pu1_crop_wnd_flag + ps_cur_mb_info->u2_mbx +
+ (ps_cur_mb_info->u2_mby * ps_dec->u2_frm_wd_in_mbs));
+ /*********************************************************************/
+ /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */
+ /*********************************************************************/
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ /* Macroblock Layer Begins */
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_base_mode_flag)
+ {
+ pu1_cur_svc_base_mode_flag =
+ ps_svc_lyr_dec->pu1_svc_base_mode_flag + ps_cur_mb_info->u2_mbx;
+ pu1_cur_svc_base_mode_flag +=
+ ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride;
+
+ u1_left_svc_base_mode_flag = 0;
+ if(ps_dec->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK)
+ u1_left_svc_base_mode_flag = *(pu1_cur_svc_base_mode_flag - 1);
+
+ u1_top_svc_base_mode_flag = 0;
+ if(ps_dec->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK)
+ u1_top_svc_base_mode_flag =
+ *(pu1_cur_svc_base_mode_flag -
+ ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride);
+
+ u4_a = 1;
+ u4_b = 1;
+
+ if(u1_top_svc_base_mode_flag)
+ {
+ u4_a = 0;
+ }
+
+ if(u1_left_svc_base_mode_flag)
+ {
+ u4_b = 0;
+ }
+
+ u4_ctxt_inc = u4_a + u4_b;
+ ps_svc_cur_mb_info->u1_base_mode_flag = ih264d_decode_bin(
+ u4_ctxt_inc, ps_svc_lyr_dec->ps_base_mode_flag, ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_base_mode_flag", ps_cur_mb_info->u1_base_mode_flag);
+ *pu1_cur_svc_base_mode_flag = ps_svc_cur_mb_info->u1_base_mode_flag;
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag =
+ ps_svc_slice_params->u1_default_base_mode_flag;
+ }
+
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ /* Decode the u1_mb_type */
+ u1_mb_type = ih264d_parse_mb_type_intra_cabac(0, ps_dec);
+ if(u1_mb_type > 25) return ERROR_MB_TYPE;
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_MB;
+ }
+ else
+ {
+ ps_cur_mb_info->u1_mb_type = MB_INFER;
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_IBL;
+ }
+ /* Parse Macroblock Data */
+ u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ if(25 == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ }
+ else
+ {
+ ret = isvcd_parse_imb_cabac(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ u1_mb_type);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ }
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ }
+
+ if(ps_cur_mb_info->u1_topmb && u1_mbaff)
+ uc_more_data_flag = 1;
+ else
+ {
+ uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, ps_bitstrm);
+ uc_more_data_flag = !uc_more_data_flag;
+ COPYTHECONTEXT("Decode Sliceterm", !uc_more_data_flag);
+ }
+
+ if(u1_mbaff)
+ {
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /* Next macroblock information */
+ i2_cur_mb_addr++;
+ /* Store the colocated information */
+ {
+ mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4);
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (ps_dec->u1_cur_mb_fld_dec_flag << 1), 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+
+ u1_num_mbs++;
+ }
+
+ /****************************************************************/
+ /* Check for End Of Row */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_tfr_n_mb =
+ (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || (!uc_more_data_flag);
+ ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag);
+
+ if(u1_tfr_n_mb || (!uc_more_data_flag))
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ ret = isvcd_decode_recon_tfr_nmb_non_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ if(ret != OK) return ret;
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ } while(uc_more_data_flag);
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_eislice_data_cavlc */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 06 2005 Kishore Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_eislice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 uc_more_data_flag;
+ UWORD8 u1_num_mbs, u1_mb_idx;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ WORD16 i2_cur_mb_addr;
+ UWORD8 u1_mbaff;
+ UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb;
+ WORD32 ret = OK;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ uc_more_data_flag = 1;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+
+ do
+ {
+ UWORD8 u1_mb_type;
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_mb_info->u1_end_of_slice = 0;
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0);
+ ps_svc_cur_mb_info->u1_crop_window_flag =
+ *(ps_svc_lyr_dec->pu1_crop_wnd_flag + ps_cur_mb_info->u2_mbx +
+ (ps_cur_mb_info->u2_mby * ps_dec->u2_frm_wd_in_mbs));
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_base_mode_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: u1_base_mode_flag", ps_cur_mb_info->u1_base_mode_flag);
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag = ps_svc_slice_params->u1_default_base_mode_flag;
+ }
+
+ /**************************************************************/
+ /* Macroblock Layer Begins, Decode the u1_mb_type */
+ /**************************************************************/
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag) /* Inlined ih264d_uev */
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_temp;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+ if(u4_temp > 25) return ERROR_MB_TYPE;
+ u1_mb_type = u4_temp;
+
+ /* Inlined ih264d_uev */
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_MB;
+ }
+ else
+ {
+ ps_cur_mb_info->u1_mb_type = MB_INFER;
+ ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_IBL;
+ }
+
+ /**************************************************************/
+ /* Parse Macroblock data */
+ /**************************************************************/
+ u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ if(25 == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ }
+ else
+ {
+ ret = isvcd_parse_imb_cavlc(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ u1_num_mbs, u1_mb_type);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ }
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /**************************************************************/
+ /* Get next Macroblock address */
+ /**************************************************************/
+ i2_cur_mb_addr++;
+ /* Store the colocated information */
+ {
+ mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4);
+ mv_pred_t s_mvPred = {{0, 0, 0, 0}, {-1, -1}, 0, 0};
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (ps_dec->u1_cur_mb_fld_dec_flag << 1), 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ u1_num_mbs++;
+
+ /****************************************************************/
+ /* Check for End Of Row */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_tfr_n_mb =
+ (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || (!uc_more_data_flag);
+ ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag);
+
+ if(u1_tfr_n_mb || (!uc_more_data_flag))
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ ret = isvcd_decode_recon_tfr_nmb_non_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ if(ret != OK) return ret;
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ } while(uc_more_data_flag);
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*!
+**************************************************************************
+* \if Function name : ParseIMbCab \endif
+*
+* \brief
+* This function parses CABAC syntax of a I MB. If 16x16 Luma DC transform
+* is also done here. Transformed Luma DC values are copied in their
+* 0th pixel location of corrosponding CoeffBlock.
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_imb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_type)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD8 i1_delta_qp;
+ UWORD8 u1_cbp;
+ UWORD8 u1_offset;
+ /* Variables for handling Cabac contexts */
+ ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info;
+ ctxt_inc_mb_info_t *ps_left_ctxt = ps_dec->p_left_ctxt_mb_info;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ bin_ctxt_model_t *p_bin_ctxt;
+ UWORD8 u1_intra_chrom_pred_mode;
+ UWORD8 u1_dc_block_flag = 0;
+ WORD32 ret;
+
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+
+ if(ps_left_ctxt == ps_dec->ps_def_ctxt_mb_info)
+ {
+ ps_dec->pu1_left_yuv_dc_csbp[0] = 0xf;
+ }
+
+ if(ps_dec->ps_cur_slice->u1_slice_type != I_SLICE)
+ {
+ MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
+ *((UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc) = 0;
+ MEMSET_16BYTES(p_curr_ctxt->u1_mv, 0);
+ memset(p_curr_ctxt->i1_ref_idx, 0, 4);
+ }
+
+ /* default */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = P_MB;
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ if(u1_mb_type == I_4x4_MB)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB;
+ p_curr_ctxt->u1_mb_type = CAB_I4x4;
+ u1_offset = 0;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ /*--------------------------------------------------------------------*/
+ /* Read transform_size_8x8_flag if present */
+ /*--------------------------------------------------------------------*/
+ if(ps_dec->ps_cur_pps->i4_transform_8x8_mode_flag)
+ {
+ ps_cur_mb_info->u1_tran_form8x8 =
+ ih264d_parse_transform8x8flag_cabac(ps_dec, ps_cur_mb_info);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+ else
+ {
+ p_curr_ctxt->u1_transform8x8_ctxt = 0;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Read the IntraPrediction modes for LUMA */
+ /*--------------------------------------------------------------------*/
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ UWORD8 *pu1_temp;
+ ih264d_read_intra_pred_modes_cabac(ps_dec,
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data),
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data + 16),
+ ps_cur_mb_info->u1_tran_form8x8);
+ pu1_temp = (UWORD8 *) ps_dec->pv_parse_tu_coeff_data;
+ pu1_temp += 32;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pu1_temp;
+ }
+ else
+ {
+ UWORD8 *pu1_temp;
+ ih264d_read_intra_pred_modes_cabac(ps_dec,
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data),
+ ((UWORD8 *) ps_dec->pv_parse_tu_coeff_data + 4),
+ ps_cur_mb_info->u1_tran_form8x8);
+ pu1_temp = (UWORD8 *) ps_dec->pv_parse_tu_coeff_data;
+ pu1_temp += 8;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pu1_temp;
+ }
+ /*--------------------------------------------------------------------*/
+ /* Read the IntraPrediction mode for CHROMA */
+ /*--------------------------------------------------------------------*/
+ u1_intra_chrom_pred_mode = ih264d_parse_chroma_pred_mode_cabac(ps_dec);
+ COPYTHECONTEXT("intra_chroma_pred_mode", u1_intra_chrom_pred_mode);
+ p_curr_ctxt->u1_intra_chroma_pred_mode = ps_cur_mb_info->u1_chroma_pred_mode =
+ u1_intra_chrom_pred_mode;
+
+ /*--------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*--------------------------------------------------------------------*/
+ u1_cbp = ih264d_parse_ctx_cbp_cabac(ps_dec);
+ COPYTHECONTEXT("coded_block_pattern", u1_cbp);
+ ps_cur_mb_info->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_cbp = u1_cbp;
+
+ /*--------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*--------------------------------------------------------------------*/
+ if(ps_cur_mb_info->u1_cbp)
+ {
+ ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &i1_delta_qp);
+ if(ret != OK) return ret;
+ COPYTHECONTEXT("mb_qp_delta", i1_delta_qp);
+ if(i1_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, i1_delta_qp);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE;
+ }
+ else
+ {
+ u1_offset = 1;
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB;
+ p_curr_ctxt->u1_mb_type = CAB_I16x16;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ p_curr_ctxt->u1_transform8x8_ctxt = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ /*--------------------------------------------------------------------*/
+ /* Read the IntraPrediction mode for CHROMA */
+ /*--------------------------------------------------------------------*/
+ u1_intra_chrom_pred_mode = ih264d_parse_chroma_pred_mode_cabac(ps_dec);
+ if(u1_intra_chrom_pred_mode > 3) return ERROR_CHROMA_PRED_MODE;
+
+ COPYTHECONTEXT("Chroma intra_chroma_pred_mode pred mode", u1_intra_chrom_pred_mode);
+ p_curr_ctxt->u1_intra_chroma_pred_mode = ps_cur_mb_info->u1_chroma_pred_mode =
+ u1_intra_chrom_pred_mode;
+
+ /*--------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*--------------------------------------------------------------------*/
+ u1_cbp = gau1_ih264d_cbp_tab[(u1_mb_type - 1) >> 2];
+ ps_cur_mb_info->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_cbp = u1_cbp;
+
+ /*--------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*--------------------------------------------------------------------*/
+ ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &i1_delta_qp);
+ if(ret != OK) return ret;
+ COPYTHECONTEXT("mb_qp_delta", i1_delta_qp);
+ if(i1_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, i1_delta_qp);
+ if(ret != OK) return ret;
+ }
+
+ {
+ WORD16 i_scaleFactor;
+ WORD16 *pi2_scale_matrix_ptr;
+ /*******************************************************************/
+ /* for luma DC coefficients the scaling is done during the parsing */
+ /* to preserve the precision */
+ /*******************************************************************/
+ if(ps_dec->s_high_profile.u1_scaling_present)
+ {
+ pi2_scale_matrix_ptr = ps_dec->s_high_profile.i2_scalinglist4x4[0];
+ }
+ else
+ {
+ i_scaleFactor = 16;
+ pi2_scale_matrix_ptr = &i_scaleFactor;
+ }
+ {
+ ctxt_inc_mb_info_t *ps_top_ctxt = ps_dec->p_top_ctxt_mb_info;
+ UWORD8 uc_a, uc_b;
+ UWORD32 u4_ctx_inc;
+ INC_SYM_COUNT(&(ps_dec->s_cab_dec_env));
+
+ /* if MbAddrN not available then CondTermN = 1 */
+ uc_b = ((ps_top_ctxt->u1_yuv_dc_csbp) & 0x01);
+
+ /* if MbAddrN not available then CondTermN = 1 */
+ uc_a = ((ps_dec->pu1_left_yuv_dc_csbp[0]) & 0x01);
+
+ u4_ctx_inc = (uc_a + (uc_b << 1));
+ {
+ WORD16 pi2_dc_coef[16] = {0};
+ tu_sblk4x4_coeff_data_t *ps_tu_4x4 =
+ (tu_sblk4x4_coeff_data_t *) ps_dec->pv_parse_tu_coeff_data;
+ WORD16 *pi2_coeff_block = (WORD16 *) ps_dec->pv_parse_tu_coeff_data;
+
+ p_bin_ctxt = (ps_dec->p_cbf_t[LUMA_DC_CTXCAT]) + u4_ctx_inc;
+
+ u1_dc_block_flag = ih264d_read_coeff4x4_cabac(
+ ps_bitstrm, LUMA_DC_CTXCAT,
+ ps_dec->p_significant_coeff_flag_t[LUMA_DC_CTXCAT], ps_dec, p_bin_ctxt);
+
+ /* Store coded_block_flag */
+ p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE;
+ p_curr_ctxt->u1_yuv_dc_csbp |= u1_dc_block_flag;
+ if(u1_dc_block_flag)
+ {
+ WORD32 pi4_tmp[16] = {0};
+ memset(pi2_dc_coef, 0, sizeof(pi2_dc_coef));
+ ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, pi2_dc_coef,
+ ps_dec->pu1_inv_scan);
+
+ PROFILE_DISABLE_IQ_IT_RECON()
+ ps_dec->pf_ihadamard_scaling_4x4(
+ pi2_dc_coef, pi2_coeff_block, ps_dec->pu2_quant_scale_y,
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_dec->u1_qp_y_div6, pi4_tmp);
+ pi2_coeff_block += 16;
+ ps_dec->pv_parse_tu_coeff_data = (void *) pi2_coeff_block;
+ SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 0);
+ }
+ }
+ }
+ }
+ }
+ ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_dec->pu1_left_yuv_dc_csbp[0] |= u1_dc_block_flag;
+ }
+ else
+ {
+ u1_offset = 0;
+ /*--------------------------------------------------------------------*/
+ /* Read the Coded block pattern */
+ /*--------------------------------------------------------------------*/
+ u1_cbp = ih264d_parse_ctx_cbp_cabac(ps_dec);
+ COPYTHECONTEXT("coded_block_pattern", u1_cbp);
+
+ ps_cur_mb_info->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE;
+ ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ p_curr_ctxt->u1_mb_type = CAB_INFERRED;
+ p_curr_ctxt->u1_intra_chroma_pred_mode = 0;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Read transform_size_8x8_flag if present */
+ /*--------------------------------------------------------------------*/
+ if((ps_dec->ps_cur_pps->i4_transform_8x8_mode_flag) && (u1_cbp & 0xf))
+ {
+ ps_cur_mb_info->u1_tran_form8x8 =
+ ih264d_parse_transform8x8flag_cabac(ps_dec, ps_cur_mb_info);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+ else
+ {
+ p_curr_ctxt->u1_transform8x8_ctxt = 0;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Read mb_qp_delta */
+ /*--------------------------------------------------------------------*/
+ if(ps_cur_mb_info->u1_cbp)
+ {
+ ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &i1_delta_qp);
+ if(ret != OK) return ret;
+ COPYTHECONTEXT("mb_qp_delta", i1_delta_qp);
+ if(i1_delta_qp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, i1_delta_qp);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ }
+
+ ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, u1_offset);
+ if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_decode_islice \endif
+*
+* \brief
+* Decodes an I Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_islice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ /* dec_ref_pic_marking function */
+ /* G050 */
+ if(ps_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_dec->ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+ }
+
+ {
+ /* G050 */
+ /* Read slice_qp_delta */
+ WORD64 i8_temp =
+ (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T;
+ ps_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("SH: slice_qp_delta", ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp);
+ }
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp);
+
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2",
+ ps_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_beta_offset_div2", ps_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_slice->u1_disable_dblk_filter_idc = 0;
+ ps_slice->i1_slice_alpha_c0_offset = 0;
+ ps_slice->i1_slice_beta_offset = 0;
+ }
+
+ /* Initialization to check if number of motion vector per 2 Mbs */
+ /* are exceeding the range or not */
+ ps_dec->u2_mv_2mb[0] = 0;
+ ps_dec->u2_mv_2mb[1] = 0;
+
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ if(ret != OK)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ /*set slice header cone to 2 ,to indicate correct header*/
+ ps_dec->u1_slice_header_done = 2;
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+
+ ret = isvcd_parse_islice_data_cabac(ps_svc_lyr_dec, ps_slice, u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ }
+ else
+ {
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ ret = isvcd_parse_islice_data_cavlc(ps_svc_lyr_dec, ps_slice, u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+ }
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_parse_epslice.c b/decoder/svc/isvcd_parse_epslice.c
new file mode 100644
index 0000000..bfd32bb
--- /dev/null
+++ b/decoder/svc/isvcd_parse_epslice.c
@@ -0,0 +1,3501 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_epslice.c
+ *
+ * @brief
+ * Contains routines that decode a EP slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_parse_epslice()
+ * - isvcd_parse_inter_slice_data_cabac()
+ * - isvcd_parse_inter_slice_data_cabac_enh_lyr()
+ * - isvcd_parse_inter_slice_data_cavlc_enh_lyr()
+ * - isvcd_parse_pmb_cabac()
+ * - isvcd_parse_pmb_cavlc()
+ * - isvcd_mark_err_slice_skip()
+ * - isvcd_parse_interlayer_resamp_func_init()
+ * - isvcd_parse_pslice()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264_defs.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_cabac.h"
+#include "ih264d_parse_mb_header.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_quant_scaling.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ih264d_thread_compute_bs.h"
+#include "ih264d_process_bslice.h"
+#include "ithread.h"
+#include "ih264d_utils.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_parse_headers.h"
+#include "isvcd_parse_headers.h"
+#include "isvcd_process_epslice.h"
+#include "isvcd_mode_mv_resamp.h"
+#include "isvcd_parse_slice.h"
+#include "isvcd_parse_cavlc.h"
+#include "isvcd_mb_utils.h"
+
+void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+void isvcd_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t *ps_dec);
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_epslice \endif
+*
+* \brief
+* Decodes a EP Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_epslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i_status = OK;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ dec_subset_seq_params_t *ps_sps_svc_ext = NULL;
+ dec_nal_unit_svc_ext_params_t *ps_nal_svc_ext = NULL;
+
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
+
+ UWORD64 u8_ref_idx_l0;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+ WORD64 i8_temp;
+
+ ps_nal_svc_ext = ps_svc_lyr_dec->ps_nal_svc_ext;
+ ps_seq = ps_pps->ps_sps;
+ ps_seq += MAX_NUM_SEQ_PARAMS;
+ ps_subset_seq =
+ &ps_svc_lyr_dec->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_seq->u1_seq_parameter_set_id];
+ ps_sps_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD8 *pi1_buf;
+ WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv;
+ WORD32 *pi4_mv = (WORD32 *) pi2_mv;
+ WORD16 *pi16_refFrame;
+
+ pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame;
+ pi16_refFrame = (WORD16 *) pi1_buf;
+ *pi4_mv = 0;
+ *(pi4_mv + 1) = 0;
+ *pi16_refFrame = OUT_OF_RANGE_REF;
+ ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8) -1;
+ ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8) -1;
+ }
+
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ ps_cur_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ COPYTHECONTEXT("Slice Header SVC ext: num_ref_idx_override_flag",
+ ps_cur_slice->u1_num_ref_idx_active_override_flag);
+
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ if(ps_cur_slice->u1_num_ref_idx_active_override_flag)
+ {
+ u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64) 1;
+ }
+
+ {
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS << u1_field_pic_flag;
+ if(u8_ref_idx_l0 > u1_max_ref_idx)
+ {
+ return ERROR_NUM_REF;
+ }
+ ps_cur_slice->u1_num_ref_idx_lx_active[0] = (UWORD8) u8_ref_idx_l0;
+ COPYTHECONTEXT("Slice Header SVC ext: num_ref_idx_l0_active_minus1",
+ ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1);
+ }
+
+ {
+ UWORD8 uc_refIdxReFlagL0 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: ref_pic_list_reordering_flag_l0",
+ uc_refIdxReFlagL0);
+
+ ih264d_init_ref_idx_lx_p(ps_dec);
+ /* Store the value for future slices in the same picture */
+ ps_dec->u1_num_ref_idx_lx_active_prev = ps_cur_slice->u1_num_ref_idx_lx_active[0];
+
+ /* Modified temporarily */
+ if(uc_refIdxReFlagL0)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ ret = ih264d_ref_idx_reordering(ps_dec, 0);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0];
+ }
+ /* Create refIdx to POC mapping */
+ {
+ void **pui_map_ref_idx_to_poc_lx0, **pui_map_ref_idx_to_poc_lx1;
+ WORD8 idx;
+ struct pic_buffer_t *ps_pic;
+
+ pui_map_ref_idx_to_poc_lx0 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0;
+ pui_map_ref_idx_to_poc_lx0[0] = 0;
+ pui_map_ref_idx_to_poc_lx0++;
+ for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ pui_map_ref_idx_to_poc_lx0[idx] = (ps_pic->pu1_buf1);
+ }
+
+ /* Bug Fix Deblocking */
+ pui_map_ref_idx_to_poc_lx1 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1;
+ pui_map_ref_idx_to_poc_lx1[0] = 0;
+
+ if(u1_mbaff)
+ {
+ void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b;
+ void **ppv_map_ref_idx_to_poc_lx_t1, **ppv_map_ref_idx_to_poc_lx_b1;
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L0;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L0;
+
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+
+ idx = 0;
+ for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1);
+
+ ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1;
+
+ ppv_map_ref_idx_to_poc_lx_t += 2;
+ ppv_map_ref_idx_to_poc_lx_b += 2;
+ }
+ ppv_map_ref_idx_to_poc_lx_t1 = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_t1[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b1 = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_b1[0] = 0;
+ }
+ /* BS is moved post recon gen in libsvc*/
+ if(ps_dec->u4_num_cores >= 2)
+ {
+ WORD32 num_entries;
+ WORD32 size;
+
+ num_entries = MAX_FRAMES;
+ if((1 >= ps_dec->ps_cur_sps->u1_num_ref_frames) && (0 == ps_dec->i4_display_delay))
+ {
+ num_entries = 1;
+ }
+ num_entries = ((2 * num_entries) + 1);
+ num_entries *= 2;
+
+ size = num_entries * sizeof(void *);
+ size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ memcpy((void *) ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc,
+ ps_dec->ppv_map_ref_idx_to_poc, size);
+ }
+ }
+ if(ps_pps->u1_wted_pred_flag)
+ {
+ if(!ps_nal_svc_ext->u1_no_inter_layer_pred_flag)
+ {
+ ps_svc_slice_params->u1_base_pred_weight_table_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_base_pred_weight_table_flag",
+ ps_svc_slice_params->u1_base_pred_weight_table_flag);
+ }
+
+ if(ps_nal_svc_ext->u1_no_inter_layer_pred_flag ||
+ !ps_svc_slice_params->u1_base_pred_weight_table_flag)
+ {
+ ret = ih264d_parse_pred_weight_table(ps_cur_slice, ps_bitstrm);
+ if(ret != OK) return ret;
+
+ ih264d_form_pred_weight_matrix(ps_dec);
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+ }
+ else
+ {
+ ps_dec->ps_cur_slice->u2_log2Y_crwd = 0;
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+
+ ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
+
+ if(u1_mbaff && (u1_field_pic_flag == 0))
+ {
+ ih264d_convert_frm_mbaff_list(ps_dec);
+ }
+
+ /* G050 */
+ if(ps_cur_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+
+ if(!ps_sps_svc_ext->u1_slice_header_restriction_flag)
+ {
+ ps_svc_slice_params->u1_store_ref_base_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_SVC_EXT: u1_store_ref_base_pic_flag",
+ ps_svc_slice_params->u1_store_ref_base_pic_flag);
+
+ if(0 != ps_svc_slice_params->u1_store_ref_base_pic_flag)
+ {
+ return NOT_OK;
+ }
+ if(((1 == ps_nal_svc_ext->u1_use_ref_base_pic_flag) ||
+ (1 == ps_svc_slice_params->u1_store_ref_base_pic_flag)) &&
+ (!ps_nal_svc_ext->u1_idr_flag))
+ {
+ i_status = isvcd_dec_ref_base_pic_marking(
+ &ps_svc_slice_params->s_ref_base_pic_marking_svc_ext, ps_bitstrm);
+ if(i_status != OK)
+ {
+ return i_status;
+ }
+ }
+ }
+ }
+ }
+ /* G050 */
+
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_temp > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->u1_cabac_init_idc = u4_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: cabac_init_idc", ps_cur_slice->u1_cabac_init_idc);
+ }
+
+ /* Read slice_qp_delta */
+ i8_temp = (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_cur_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_qp_delta",
+ (WORD8) (ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
+
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("Slice Header SVC ext: disable_deblocking_filter_idc", u4_temp);
+ ps_cur_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_alpha_c0_offset_div2",
+ ps_cur_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_beta_offset_div2",
+ ps_cur_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_cur_slice->u1_disable_dblk_filter_idc = 0;
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+
+ /* add the remaining part of the code for svc extension from reference */
+ ret = isvcd_set_default_slice_header_ext(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ret = isvcd_parse_slice_header(ps_svc_lyr_dec);
+ if(ret != OK)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ if(ret != OK)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ ps_dec->u1_slice_header_done = 2;
+
+ if(!ps_svc_slice_params->u1_slice_skip_flag)
+ {
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext =
+ isvcd_parse_inter_slice_data_cabac_enh_lyr;
+ ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext = isvcd_parse_pmb_cabac;
+
+ isvcd_init_cabac_contexts(P_SLICE, ps_dec);
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+ }
+ else
+ {
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext =
+ isvcd_parse_inter_slice_data_cavlc_enh_lyr;
+ ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext = isvcd_parse_pmb_cavlc;
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ }
+ }
+ else
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ ps_dec->u1_B = 0;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = isvcd_mv_pred_ref_tfr_nby2_epmb;
+ ret = ps_svc_lyr_dec->pf_parse_inter_slice_svc_ext(ps_svc_lyr_dec, ps_cur_slice,
+ u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_inter_slice_data_cabac */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* 2. MV prediction and DMA happens on a N/2 MB basis. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 13 07 2002 Jay Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_parse_inter_slice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ UWORD32 uc_more_data_flag;
+ WORD32 i2_cur_mb_addr;
+ UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx;
+ UWORD32 u1_mbaff;
+ UWORD32 u1_num_mbs_next, u1_end_of_row;
+ const UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_slice_end = 0;
+ UWORD32 u1_tfr_n_mb = 0;
+ UWORD32 u1_decode_nmb = 0;
+
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_mb_info_t *ps_cur_mb_info;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ UWORD32 u1_inter_mb_skip_type;
+ UWORD32 u1_inter_mb_type;
+ UWORD32 u1_deblk_mb_type;
+ UWORD32 u1_mb_threshold;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ WORD32 ret = OK;
+
+ /******************************************************/
+ /* Initialisations specific to B or P slice */
+ /******************************************************/
+ if(ps_slice->u1_slice_type == P_SLICE)
+ {
+ u1_inter_mb_skip_type = CAB_P_SKIP;
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+ u1_mb_threshold = 5;
+ }
+ else // B_SLICE
+ {
+ u1_inter_mb_skip_type = CAB_B_SKIP;
+ u1_inter_mb_type = B_MB;
+ u1_deblk_mb_type = D_B_SLICE;
+ u1_mb_threshold = 23;
+ }
+
+ /******************************************************/
+ /* Slice Level Initialisations */
+ /******************************************************/
+ i2_cur_mb_addr = u2_first_mb_in_slice;
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ u1_num_mbsNby2 = 0;
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ uc_more_data_flag = 1;
+
+ /* Initialisations specific to cabac */
+ if(ps_bitstrm->u4_ofst & 0x07)
+ {
+ ps_bitstrm->u4_ofst += 8;
+ ps_bitstrm->u4_ofst &= 0xFFFFFFF8;
+ }
+
+ ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm);
+ if(ret != OK) return ret;
+
+ ps_dec->i1_prev_mb_qp_delta = 0;
+
+ while(!u1_slice_end)
+ {
+ UWORD8 u1_mb_type;
+ UWORD32 u4_mb_skip;
+
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /* Storing Default partition info */
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ u4_mb_skip = ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 1);
+
+ /*********************************************************************/
+ /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */
+ /*********************************************************************/
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ if(u4_mb_skip)
+ {
+ /* Set appropriate flags in ps_cur_mb_info and ps_dec */
+ memset(ps_dec->ps_curr_ctxt_mb_info, 0, sizeof(ctxt_inc_mb_info_t));
+ ps_dec->ps_curr_ctxt_mb_info->u1_mb_type = u1_inter_mb_skip_type;
+
+ MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
+
+ *((UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc) = 0;
+ *(ps_dec->pu1_left_yuv_dc_csbp) = 0;
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_cbp = 0;
+
+ {
+ /* Storing Skip partition info */
+ parse_part_params_t *ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ }
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CABAC);
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Macroblock Layer Begins */
+ /* Decode the u1_mb_type */
+ u1_mb_type = ih264d_parse_mb_type_cabac(ps_dec);
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ if(u1_mb_type > (25 + u1_mb_threshold)) return ERROR_MB_TYPE;
+
+ /* Parse Macroblock Data */
+ if(u1_mb_type < u1_mb_threshold)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ *(ps_dec->pu1_left_yuv_dc_csbp) &= 0x6;
+
+ ret = ps_dec->pf_parse_inter_mb(ps_dec, ps_cur_mb_info, u1_num_mbs, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Storing Intra partition info */
+ ps_parse_mb_data->u1_num_part = 0;
+ ps_parse_mb_data->u1_isI_mb = 1;
+
+ if((25 + u1_mb_threshold) == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ }
+ else
+ {
+ if(u1_mb_type == u1_mb_threshold)
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB;
+ else
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB;
+
+ ret = ih264d_parse_imb_cabac(ps_dec, ps_cur_mb_info,
+ (UWORD8) (u1_mb_type - u1_mb_threshold));
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ }
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ }
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ }
+
+ if(ps_cur_mb_info->u1_topmb && u1_mbaff)
+ uc_more_data_flag = 1;
+ else
+ {
+ uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, ps_bitstrm);
+ uc_more_data_flag = !uc_more_data_flag;
+ COPYTHECONTEXT("Decode Sliceterm", !uc_more_data_flag);
+ }
+
+ if(u1_mbaff)
+ {
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /* Next macroblock information */
+ i2_cur_mb_addr++;
+ u1_num_mbs++;
+ u1_num_mbsNby2++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_slice_end = !uc_more_data_flag;
+ u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || u1_slice_end;
+ u1_decode_nmb = u1_tfr_n_mb || u1_slice_end;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(u1_decode_nmb)
+ {
+ ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ u1_num_mbsNby2 = 0;
+ {
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ }
+ if(ret != OK) return ret;
+ }
+
+ if(u1_decode_nmb)
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ else
+ {
+ isvcd_decode_recon_tfr_nmb_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ }
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ }
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_inter_slice_data_cavlc */
+/* */
+/* Description : This function parses cavlc syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* 2. MV prediction and DMA happens on a N/2 MB basis. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 13 07 2002 Jay Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_parse_inter_slice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 uc_more_data_flag;
+ WORD32 i2_cur_mb_addr;
+ UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx;
+ UWORD32 i2_mb_skip_run;
+ UWORD32 u1_read_mb_type;
+
+ UWORD32 u1_mbaff;
+ UWORD32 u1_num_mbs_next, u1_end_of_row;
+ const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_slice_end = 0;
+ UWORD32 u1_tfr_n_mb = 0;
+ UWORD32 u1_decode_nmb = 0;
+
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_mb_info_t *ps_cur_mb_info;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ UWORD32 u1_inter_mb_type;
+ UWORD32 u1_deblk_mb_type;
+ UWORD32 u1_mb_threshold;
+ WORD32 ret = OK;
+
+ /******************************************************/
+ /* Initialisations specific to B or P slice */
+ /******************************************************/
+ if(ps_slice->u1_slice_type == P_SLICE)
+ {
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+ u1_mb_threshold = 5;
+ }
+ else // B_SLICE
+ {
+ u1_inter_mb_type = B_MB;
+ u1_deblk_mb_type = D_B_SLICE;
+ u1_mb_threshold = 23;
+ }
+
+ /******************************************************/
+ /* Slice Level Initialisations */
+ /******************************************************/
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+
+ u1_num_mbsNby2 = 0;
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ i2_mb_skip_run = 0;
+ uc_more_data_flag = 1;
+ u1_read_mb_type = 0;
+
+ while(!u1_slice_end)
+ {
+ UWORD8 u1_mb_type;
+
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /* Storing Default partition info */
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ if((!i2_mb_skip_run) && (!u1_read_mb_type))
+ {
+ // Inlined ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ i2_mb_skip_run = ((1 << u4_ldz) + u4_word - 1);
+ // Inlined ih264d_uev
+ COPYTHECONTEXT("mb_skip_run", i2_mb_skip_run);
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+ u1_read_mb_type = uc_more_data_flag;
+ }
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, i2_mb_skip_run);
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ if(i2_mb_skip_run)
+ {
+ /* Set appropriate flags in ps_cur_mb_info and ps_dec */
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_dec->u1_sub_mb_num = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_mb_mc_mode = PRED_16x16;
+ ps_cur_mb_info->u1_cbp = 0;
+
+ {
+ /* Storing Skip partition info */
+ parse_part_params_t *ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ }
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+
+ i2_mb_skip_run--;
+ }
+ else
+ {
+ u1_read_mb_type = 0;
+ /**************************************************************/
+ /* Macroblock Layer Begins, Decode the u1_mb_type */
+ /**************************************************************/
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_temp;
+
+ // Inlined ih264d_uev
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+ // Inlined ih264d_uev
+ if(u4_temp > (UWORD32) (25 + u1_mb_threshold)) return ERROR_MB_TYPE;
+ u1_mb_type = u4_temp;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+ }
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+
+ /**************************************************************/
+ /* Parse Macroblock data */
+ /**************************************************************/
+ if(u1_mb_type < u1_mb_threshold)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+
+ ret = ps_dec->pf_parse_inter_mb(ps_dec, ps_cur_mb_info, u1_num_mbs, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Storing Intra partition info */
+ ps_parse_mb_data->u1_num_part = 0;
+ ps_parse_mb_data->u1_isI_mb = 1;
+
+ if((25 + u1_mb_threshold) == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_dec->u1_qp = 0;
+ }
+ else
+ {
+ ret = ih264d_parse_imb_cavlc(ps_dec, ps_cur_mb_info, u1_num_mbs,
+ (UWORD8) (u1_mb_type - u1_mb_threshold));
+ if(ret != OK) return ret;
+ }
+
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+ }
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ if(!uc_more_data_flag && !i2_mb_skip_run && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+
+ /**************************************************************/
+ /* Get next Macroblock address */
+ /**************************************************************/
+ i2_cur_mb_addr++;
+
+ u1_num_mbs++;
+ u1_num_mbsNby2++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_slice_end = (!(uc_more_data_flag || i2_mb_skip_run));
+ u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || u1_slice_end;
+ u1_decode_nmb = u1_tfr_n_mb || u1_slice_end;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(u1_decode_nmb)
+ {
+ ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ u1_num_mbsNby2 = 0;
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ if(ret != OK) return ret;
+ }
+
+ if(u1_decode_nmb)
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ else
+ {
+ isvcd_decode_recon_tfr_nmb_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ }
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ }
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_inter_slice_data_cabac_enh_lyr */
+/* */
+/* Description : This function parses cabac syntax of a inter slice on */
+/* N MB basis for svc ext */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* 2. MV prediction and DMA happens on a N/2 MB basis. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 09 06 2021 Jay Draft */
+/* */
+/*****************************************************************************/
+WORD32
+isvcd_parse_inter_slice_data_cabac_enh_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 uc_more_data_flag;
+ WORD32 i2_cur_mb_addr;
+ UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx;
+ UWORD32 u1_mbaff;
+ UWORD32 u1_num_mbs_next, u1_end_of_row;
+ const UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_slice_end = 0;
+ UWORD32 u1_tfr_n_mb = 0;
+ UWORD32 u1_decode_nmb = 0;
+
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ UWORD32 u1_inter_mb_skip_type;
+ UWORD32 u1_inter_mb_type;
+ UWORD32 u1_deblk_mb_type;
+ UWORD32 u1_mb_threshold;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ decoding_envirnoment_t *ps_cab_env = NULL;
+ WORD32 ret = OK;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ /******************************************************/
+ /* Initialisations specific to B or P slice */
+ /******************************************************/
+ if(ps_slice->u1_slice_type == P_SLICE)
+ {
+ u1_inter_mb_skip_type = CAB_P_SKIP;
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+ u1_mb_threshold = 5;
+ }
+ else // EB_SLICE
+ {
+ u1_inter_mb_skip_type = CAB_B_SKIP;
+ u1_inter_mb_type = B_MB;
+ u1_deblk_mb_type = D_B_SLICE;
+ u1_mb_threshold = 23;
+ }
+
+ /******************************************************/
+ /* Slice Level Initialisations */
+ /******************************************************/
+ i2_cur_mb_addr = u2_first_mb_in_slice;
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ u1_num_mbsNby2 = 0;
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ uc_more_data_flag = 1;
+
+ /* Initialisations specific to cabac */
+ if(ps_bitstrm->u4_ofst & 0x07)
+ {
+ ps_bitstrm->u4_ofst += 8;
+ ps_bitstrm->u4_ofst &= 0xFFFFFFF8;
+ }
+
+ ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm);
+ if(ret != OK) return ret;
+
+ ps_cab_env = &ps_dec->s_cab_dec_env;
+ ps_dec->i1_prev_mb_qp_delta = 0;
+
+ while(!u1_slice_end)
+ {
+ UWORD8 u1_mb_type;
+ UWORD32 u4_mb_skip;
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /* Storing Default partition info */
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ u4_mb_skip = ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 1);
+ ps_svc_cur_mb_info->u1_crop_window_flag =
+ *(ps_svc_lyr_dec->pu1_crop_wnd_flag + ps_cur_mb_info->u2_mbx +
+ (ps_cur_mb_info->u2_mby * ps_dec->u2_frm_wd_in_mbs));
+ /*********************************************************************/
+ /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */
+ /*********************************************************************/
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ if(u4_mb_skip)
+ {
+ /* Set appropriate flags in ps_cur_mb_info and ps_dec */
+ memset(ps_dec->ps_curr_ctxt_mb_info, 0, sizeof(ctxt_inc_mb_info_t));
+ ps_dec->ps_curr_ctxt_mb_info->u1_mb_type = u1_inter_mb_skip_type;
+
+ MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
+
+ *((UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc) = 0;
+ *(ps_dec->pu1_left_yuv_dc_csbp) = 0;
+
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_cbp = 0;
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[0] = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[1] = 0;
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+
+ {
+ /* Storing Skip partition info */
+ parse_part_params_t *ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ }
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CABAC);
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Variables for handling Cabac contexts */
+ UWORD8 *pu1_cur_svc_base_mode_flag;
+ UWORD8 u1_left_svc_base_mode_flag;
+ UWORD8 u1_top_svc_base_mode_flag;
+
+ UWORD32 u4_a, u4_b, u4_ctxt_inc;
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ /* Macroblock Layer Begins */
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_base_mode_flag)
+ {
+ pu1_cur_svc_base_mode_flag =
+ ps_svc_lyr_dec->pu1_svc_base_mode_flag + ps_cur_mb_info->u2_mbx;
+ pu1_cur_svc_base_mode_flag +=
+ ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride;
+
+ u1_left_svc_base_mode_flag = 0;
+ if(ps_dec->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK)
+ u1_left_svc_base_mode_flag = *(pu1_cur_svc_base_mode_flag - 1);
+
+ u1_top_svc_base_mode_flag = 0;
+ if(ps_dec->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK)
+ u1_top_svc_base_mode_flag =
+ *(pu1_cur_svc_base_mode_flag -
+ ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride);
+
+ u4_a = 1;
+ u4_b = 1;
+
+ if(u1_top_svc_base_mode_flag)
+ {
+ u4_a = 0;
+ }
+
+ if(u1_left_svc_base_mode_flag)
+ {
+ u4_b = 0;
+ }
+
+ u4_ctxt_inc = u4_a + u4_b;
+ ps_svc_cur_mb_info->u1_base_mode_flag = ih264d_decode_bin(
+ u4_ctxt_inc, ps_svc_lyr_dec->ps_base_mode_flag, ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_base_mode_flag", ps_svc_cur_mb_info->u1_base_mode_flag);
+ *pu1_cur_svc_base_mode_flag = ps_svc_cur_mb_info->u1_base_mode_flag;
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag =
+ ps_svc_slice_params->u1_default_base_mode_flag;
+ }
+
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ /* Decode the u1_mb_type */
+ u1_mb_type = ih264d_parse_mb_type_cabac(ps_dec);
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ if(u1_mb_type > (25 + u1_mb_threshold)) return ERROR_MB_TYPE;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+ }
+ else
+ {
+ // default intialization for Base mode flag : reserved
+ ps_dec->ps_part += MAX_NUM_MB_PART;
+
+ ps_svc_cur_mb_info->au1_motion_pred_flag[0] = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[1] = 0;
+ ps_cur_mb_info->u1_mb_type = MB_INFER;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+
+ /*SVC EXT needs to update incropwindow*/
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = ih264d_decode_bin(
+ 0, ps_svc_lyr_dec->ps_residual_prediction_flag, ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_svc_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+ }
+
+ /* Parse Macroblock Data */
+ u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ if(u1_mb_type < u1_mb_threshold)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ *(ps_dec->pu1_left_yuv_dc_csbp) &= 0x6;
+
+ ret = ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext(
+ ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info, u1_num_mbs, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Storing Intra partition info */
+ ps_parse_mb_data->u1_num_part = 0;
+ ps_parse_mb_data->u1_isI_mb = 1;
+
+ if((25 + u1_mb_threshold) == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = 0;
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ else
+ {
+ if(u1_mb_type == u1_mb_threshold)
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB;
+ else
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB;
+
+ ret = isvcd_parse_imb_cabac(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ (UWORD8) (u1_mb_type - u1_mb_threshold));
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+ if(0 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ }
+ ps_parse_mb_data->u1_isI_mb = !ps_svc_cur_mb_info->u1_base_mode_flag;
+ }
+ }
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ }
+
+ if(ps_cur_mb_info->u1_topmb && u1_mbaff)
+ uc_more_data_flag = 1;
+ else
+ {
+ uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, ps_bitstrm);
+ uc_more_data_flag = !uc_more_data_flag;
+ COPYTHECONTEXT("Decode Sliceterm", !uc_more_data_flag);
+ }
+
+ if(u1_mbaff)
+ {
+ if(!uc_more_data_flag && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /* Next macroblock information */
+ i2_cur_mb_addr++;
+ u1_num_mbs++;
+ u1_num_mbsNby2++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_slice_end = !uc_more_data_flag;
+ u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || u1_slice_end;
+ u1_decode_nmb = u1_tfr_n_mb || u1_slice_end;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(u1_decode_nmb)
+ {
+ ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ u1_num_mbsNby2 = 0;
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ if(ret != OK) return ret;
+ }
+
+ if(u1_decode_nmb)
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ ret = isvcd_decode_recon_tfr_nmb_non_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ if(ret != OK) return ret;
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ }
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_inter_slice_data_cavlc_enh_lyr */
+/* */
+/* Description : This function parses cavlc syntax of a inter slice on */
+/* N MB basis. */
+/* */
+/* Inputs : ps_dec */
+/* sliceparams */
+/* firstMbInSlice */
+/* */
+/* Processing : 1. After parsing syntax for N MBs those N MBs are */
+/* decoded till the end of slice. */
+/* 2. MV prediction and DMA happens on a N/2 MB basis. */
+/* */
+/* Returns : 0 */
+/* */
+/* Issues : <List any issues or problems with this function> */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 09 06 2021 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_parse_inter_slice_data_cavlc_enh_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 uc_more_data_flag;
+ WORD32 i2_cur_mb_addr;
+ UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx;
+ UWORD32 i2_mb_skip_run;
+ UWORD32 u1_read_mb_type;
+
+ UWORD32 u1_mbaff;
+ UWORD32 u1_num_mbs_next, u1_end_of_row;
+ const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_slice_end = 0;
+ UWORD32 u1_tfr_n_mb = 0;
+ UWORD32 u1_decode_nmb = 0;
+
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ UWORD32 u1_inter_mb_type;
+ UWORD32 u1_deblk_mb_type;
+ UWORD32 u1_mb_threshold;
+ WORD32 ret = OK;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ /******************************************************/
+ /* Initialisations specific to EB or EP slice */
+ /******************************************************/
+
+ if(ps_slice->u1_slice_type == P_SLICE)
+ {
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+ u1_mb_threshold = 5;
+ }
+ else
+ {
+ u1_inter_mb_type = B_MB;
+ u1_deblk_mb_type = D_B_SLICE;
+ u1_mb_threshold = 23;
+ }
+
+ /******************************************************/
+ /* Slice Level Initialisations */
+ /******************************************************/
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ u1_num_mbs = u1_mb_idx;
+ u1_num_mbsNby2 = 0;
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+ i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff;
+ i2_mb_skip_run = 0;
+ uc_more_data_flag = 1;
+ u1_read_mb_type = 0;
+
+ while(!u1_slice_end)
+ {
+ UWORD8 u1_mb_type;
+
+ ps_dec->pv_prev_mb_parse_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ break;
+ }
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /* Storing Default partition info */
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ if((!i2_mb_skip_run) && (!u1_read_mb_type))
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz)
+ {
+ GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ }
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ i2_mb_skip_run = ((1 << u4_ldz) + u4_word - 1);
+
+ COPYTHECONTEXT("mb_skip_run", i2_mb_skip_run);
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+ u1_read_mb_type = uc_more_data_flag;
+ }
+
+ /***************************************************************/
+ /* Get the required information for decoding of MB */
+ /* mb_x, mb_y , neighbour availablity, */
+ /***************************************************************/
+ ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, i2_mb_skip_run);
+ ps_svc_cur_mb_info->u1_crop_window_flag =
+ *(ps_svc_lyr_dec->pu1_crop_wnd_flag + ps_cur_mb_info->u2_mbx +
+ (ps_cur_mb_info->u2_mby * ps_dec->u2_frm_wd_in_mbs));
+ /***************************************************************/
+ /* Set the deblocking parameters for this MB */
+ /***************************************************************/
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+
+ if(i2_mb_skip_run)
+ {
+ /* Set appropriate flags in ps_cur_mb_info and ps_dec */
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_dec->u1_sub_mb_num = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_mb_mc_mode = PRED_16x16;
+ ps_cur_mb_info->u1_cbp = 0;
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[0] = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[1] = 0;
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+
+ {
+ /* Storing Skip partition info */
+ parse_part_params_t *ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+ }
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ i2_mb_skip_run--;
+ }
+ else
+ {
+ UWORD32 u4_word, u4_ldz, u4_temp;
+
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_base_mode_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC :u1_base_mode_flag", ps_cur_mb_info->u1_base_mode_flag);
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_base_mode_flag =
+ ps_svc_slice_params->u1_default_base_mode_flag;
+ }
+
+ if(!ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+
+ u1_read_mb_type = 0;
+ /**************************************************************/
+ /* Macroblock Layer Begins, Decode the u1_mb_type */
+ /**************************************************************/
+ {
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_temp = ((1 << u4_ldz) + u4_word - 1);
+
+ if(u4_temp > (UWORD32) (25 + u1_mb_threshold)) return ERROR_MB_TYPE;
+ u1_mb_type = u4_temp;
+ COPYTHECONTEXT("u1_mb_type", u1_mb_type);
+ }
+ ps_cur_mb_info->u1_mb_type = u1_mb_type;
+ }
+ else
+ {
+ /* default intialization for Base mode flag : reserved */
+ ps_dec->ps_part += MAX_NUM_MB_PART;
+ u1_read_mb_type = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[0] = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[1] = 0;
+ ps_cur_mb_info->u1_mb_type = MB_INFER;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+
+ /*SVC EXT needs to update incropwindow*/
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+ }
+
+ /**************************************************************/
+ /* Parse Macroblock data */
+ /**************************************************************/
+ u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ if(u1_mb_type < u1_mb_threshold)
+ {
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+
+ ret = ps_svc_lyr_dec->pf_parse_inter_mb_svc_ext(
+ ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info, u1_num_mbs, u1_num_mbsNby2);
+ if(ret != OK) return ret;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+ }
+ else
+ {
+ /* Storing Intra partition info */
+ ps_parse_mb_data->u1_num_part = 0;
+
+ if((25 + u1_mb_threshold) == u1_mb_type)
+ {
+ /* I_PCM_MB */
+ ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB;
+ ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs);
+ if(ret != OK) return ret;
+ ps_dec->u1_qp = 0;
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ else
+ {
+ ret =
+ isvcd_parse_imb_cavlc(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info,
+ u1_num_mbs, (UWORD8) (u1_mb_type - u1_mb_threshold));
+ if(ret != OK) return ret;
+
+ if(0 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB;
+ }
+ }
+ ps_parse_mb_data->u1_isI_mb = !ps_svc_cur_mb_info->u1_base_mode_flag;
+ }
+ uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+ }
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1,
+ ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp);
+ }
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ if(!uc_more_data_flag && !i2_mb_skip_run && (0 == (i2_cur_mb_addr & 1)))
+ {
+ return ERROR_EOB_FLUSHBITS_T;
+ }
+ }
+ /**************************************************************/
+ /* Get next Macroblock address */
+ /**************************************************************/
+ i2_cur_mb_addr++;
+ u1_num_mbs++;
+ u1_num_mbsNby2++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_slice_end = (!(uc_more_data_flag || i2_mb_skip_run));
+ u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || u1_slice_end;
+ u1_decode_nmb = u1_tfr_n_mb || u1_slice_end;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(u1_decode_nmb)
+ {
+ ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ u1_num_mbsNby2 = 0;
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ if(ret != OK) return ret;
+ }
+
+ if(u1_decode_nmb)
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ ret = isvcd_decode_recon_tfr_nmb_non_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ if(ret != OK) return ret;
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ }
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr - (u2_first_mb_in_slice << u1_mbaff);
+
+ return ret;
+}
+
+/*!
+**************************************************************************
+* \if Function name : ih264d_parse_pmb_cabac_svc \endif
+*
+* \brief
+* This function parses CABAC syntax of a P MB.
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_pmb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ UWORD32 u1_num_mb_part;
+ UWORD32 uc_sub_mb;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data + u1_num_mbsNby2;
+ WORD8 *pi1_ref_idx = ps_parse_mb_data->i1_ref_idx[0];
+ const UWORD8 *pu1_num_mb_part = (const UWORD8 *) gau1_ih264d_num_mb_part;
+ const UWORD32 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ UWORD8 *pu1_col_info = ps_parse_mb_data->u1_col_info;
+ UWORD32 u1_mb_mc_mode = u1_mb_type;
+ ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info;
+ decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 u4_sub_mb_pack = 0;
+ WORD32 ret;
+
+ UWORD8 u1_no_submb_part_size_lt8x8_flag = 1;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+ p_curr_ctxt->u1_mb_type = CAB_P;
+ ps_cur_mb_info->u1_mb_mc_mode = u1_mb_type;
+ uc_sub_mb = ((u1_mb_type == PRED_8x8) | (u1_mb_type == PRED_8x8R0));
+
+ /* Reading the subMB type */
+ if(uc_sub_mb)
+ {
+ UWORD8 u1_colz = (PRED_8x8 << 6);
+ u1_mb_mc_mode = 0;
+ {
+ UWORD8 u1_sub_mb_mode;
+ u1_sub_mb_mode =
+ ih264d_parse_submb_type_cabac(0, ps_cab_env, ps_bitstrm, ps_dec->p_sub_mb_type_t);
+ if(u1_sub_mb_mode > 3) return ERROR_SUB_MB_TYPE;
+
+ u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode;
+ /* Storing collocated information */
+ *pu1_col_info++ = u1_colz | ((UWORD8) (u1_sub_mb_mode << 4));
+ COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode);
+ /* check if Motion compensation is done below 8x8 */
+ if(u1_sub_mb_mode != P_L0_8x8)
+ {
+ u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ {
+ UWORD8 u1_sub_mb_mode;
+ u1_sub_mb_mode =
+ ih264d_parse_submb_type_cabac(0, ps_cab_env, ps_bitstrm, ps_dec->p_sub_mb_type_t);
+ if(u1_sub_mb_mode > 3) return ERROR_SUB_MB_TYPE;
+
+ u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode;
+ /* Storing collocated information */
+ *pu1_col_info++ = u1_colz | ((UWORD8) (u1_sub_mb_mode << 4));
+ COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode);
+ /* check if Motion compensation is done below 8x8 */
+ if(u1_sub_mb_mode != P_L0_8x8)
+ {
+ u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ {
+ UWORD8 u1_sub_mb_mode;
+ u1_sub_mb_mode =
+ ih264d_parse_submb_type_cabac(0, ps_cab_env, ps_bitstrm, ps_dec->p_sub_mb_type_t);
+ if(u1_sub_mb_mode > 3) return ERROR_SUB_MB_TYPE;
+
+ u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode;
+ /* Storing collocated information */
+ *pu1_col_info++ = u1_colz | ((UWORD8) (u1_sub_mb_mode << 4));
+ COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode);
+ /* check if Motion compensation is done below 8x8 */
+ if(u1_sub_mb_mode != P_L0_8x8)
+ {
+ u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ {
+ UWORD8 u1_sub_mb_mode;
+ u1_sub_mb_mode =
+ ih264d_parse_submb_type_cabac(0, ps_cab_env, ps_bitstrm, ps_dec->p_sub_mb_type_t);
+ if(u1_sub_mb_mode > 3) return ERROR_SUB_MB_TYPE;
+
+ u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode;
+ /* Storing collocated information */
+ *pu1_col_info++ = u1_colz | ((UWORD8) (u1_sub_mb_mode << 4));
+ COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode);
+ /* check if Motion compensation is done below 8x8 */
+ if(u1_sub_mb_mode != P_L0_8x8)
+ {
+ u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ u1_num_mb_part = 4;
+ }
+ else
+ {
+ u1_num_mb_part = pu1_num_mb_part[u1_mb_type];
+ /* Storing collocated Mb and SubMb mode information */
+ *pu1_col_info++ = (u1_mb_type << 6);
+ if(u1_mb_type) *pu1_col_info++ = (u1_mb_type << 6);
+ }
+
+ /*Adding code to get Motion Prediction Flags*/
+ {
+ UWORD8 uc_i;
+ UWORD8 *pu1_motion_pred_flag_l0;
+ UWORD8 u1_mvp_flag;
+ WORD8 *pi1_top_ref_idx_ctx_inc_arr = p_curr_ctxt->i1_ref_idx;
+ WORD8 *pi1_left_ref_idx_ctxt_inc = ps_dec->pi1_left_ref_idx_ctxt_inc;
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+ UWORD8 uc_num_ref_idx_l0_active_minus1 =
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] << (u1_mbaff & uc_field)) - 1;
+ pu1_motion_pred_flag_l0 = &ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+ *pu1_motion_pred_flag_l0 = 0;
+
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag)
+ {
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ /*usage of bins and ctxt check*/
+ u1_mvp_flag = ih264d_decode_bin(0, ps_svc_lyr_dec->ps_motion_prediction_flag_l0,
+ ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: ps_motion_prediction_flag_l0", u1_mvp_flag);
+
+ *pu1_motion_pred_flag_l0 |= (u1_mvp_flag << uc_i);
+ if(u1_mvp_flag)
+ {
+ pi1_ref_idx[uc_i] = -1;
+ }
+ }
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ *pu1_motion_pred_flag_l0 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ if(ps_svc_slice_params->u1_default_motion_prediction_flag)
+ {
+ pi1_ref_idx[0] = -1;
+ pi1_ref_idx[1] = -1;
+ pi1_ref_idx[2] = -1;
+ pi1_ref_idx[3] = -1;
+ }
+ }
+
+ /* Decoding reference index 0: For simple profile the following */
+ /* conditions are always true (mb_field_decoding_flag == 0); */
+ /* (MbPartPredMode != PredL1) */
+ if((uc_num_ref_idx_l0_active_minus1 > 0) & (u1_mb_type != PRED_8x8R0))
+ {
+ /* force the routine to decode ref idx for each partition */
+ /*SVC added motion_prediction_flag to force it to take it only for
+ * !motion_pred_flag_l0*/
+
+ ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 0, uc_num_ref_idx_l0_active_minus1,
+ u1_mb_mc_mode, pi1_ref_idx, pi1_left_ref_idx_ctxt_inc,
+ pi1_top_ref_idx_ctx_inc_arr, ps_cab_env, ps_bitstrm,
+ ps_dec->p_ref_idx_t);
+ if(ret != OK)
+ {
+ return ret;
+ }
+ }
+ else
+ {
+ /* When there exists only a single frame to predict from */
+ pi1_left_ref_idx_ctxt_inc[0] = 0;
+ pi1_left_ref_idx_ctxt_inc[1] = 0;
+ pi1_top_ref_idx_ctx_inc_arr[0] = 0;
+ pi1_top_ref_idx_ctx_inc_arr[1] = 0;
+ *((UWORD32 *) pi1_ref_idx) = 0;
+ }
+ }
+
+ {
+ UWORD8 u1_p_idx, uc_i;
+ parse_part_params_t *ps_part = ps_dec->ps_part;
+ UWORD8 u1_sub_mb_mode, u1_num_subpart, u1_mb_part_width, u1_mb_part_height;
+ UWORD8 u1_sub_mb_num;
+ const UWORD8 *pu1_top_left_sub_mb_indx;
+ mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4);
+ UWORD16 u2_sub_mb_num_pack = 0x028A;
+
+ /* Loading the table pointers */
+ const UWORD8 *pu1_mb_partw = (const UWORD8 *) gau1_ih264d_mb_partw;
+ const UWORD8 *pu1_mb_parth = (const UWORD8 *) gau1_ih264d_mb_parth;
+ const UWORD8 *pu1_sub_mb_indx_mod =
+ (const UWORD8 *) (gau1_ih264d_submb_indx_mod) + (uc_sub_mb * 6);
+ const UWORD8 *pu1_sub_mb_partw = (const UWORD8 *) gau1_ih264d_submb_partw;
+ const UWORD8 *pu1_sub_mb_parth = (const UWORD8 *) gau1_ih264d_submb_parth;
+ const UWORD8 *pu1_num_sub_mb_part = (const UWORD8 *) gau1_ih264d_num_submb_part;
+
+ /*********************************************************/
+ /* default initialisations for condition (uc_sub_mb == 0) */
+ /* i.e. all are subpartitions of 8x8 */
+ /*********************************************************/
+ u1_sub_mb_mode = 0;
+ u1_num_subpart = 1;
+ u1_mb_part_width = pu1_mb_partw[u1_mb_type];
+ u1_mb_part_height = pu1_mb_parth[u1_mb_type];
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_type << 1);
+ u1_sub_mb_num = 0;
+
+ /* Loop on number of partitions */
+ for(uc_i = 0, u1_p_idx = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ UWORD8 uc_j;
+ if(uc_sub_mb)
+ {
+ u1_sub_mb_mode = u4_sub_mb_pack >> 24;
+ u1_num_subpart = pu1_num_sub_mb_part[u1_sub_mb_mode];
+ u1_mb_part_width = pu1_sub_mb_partw[u1_sub_mb_mode];
+ u1_mb_part_height = pu1_sub_mb_parth[u1_sub_mb_mode];
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_sub_mb_mode << 1);
+ u1_sub_mb_num = u2_sub_mb_num_pack >> 12;
+ u4_sub_mb_pack <<= 8;
+ u2_sub_mb_num_pack <<= 4;
+ }
+ /* Loop on Number of sub-partitions */
+ for(uc_j = 0; uc_j < u1_num_subpart; uc_j++, pu1_top_left_sub_mb_indx++)
+ {
+ mv_pred_t *ps_mv;
+ u1_sub_mb_num += *pu1_top_left_sub_mb_indx;
+ ps_mv = ps_mv_start + u1_sub_mb_num;
+
+ /* Storing Info for partitions */
+ ps_part->u1_is_direct = PART_NOT_DIRECT;
+ ps_part->u1_sub_mb_num = u1_sub_mb_num;
+ ps_part->u1_partheight = u1_mb_part_height;
+ ps_part->u1_partwidth = u1_mb_part_width;
+
+ /* Increment partition Index */
+ u1_p_idx++;
+ ps_part++;
+
+ ih264d_get_mvd_cabac(u1_sub_mb_num, 0, u1_mb_part_width, u1_mb_part_height, 1,
+ ps_dec, ps_mv);
+ }
+ }
+ ps_parse_mb_data->u1_num_part = u1_p_idx;
+ ps_dec->ps_part = ps_part;
+ }
+
+ /* update incropwindow*/
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = ih264d_decode_bin(
+ 1, ps_svc_lyr_dec->ps_residual_prediction_flag, ps_bitstrm, ps_cab_env);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+
+ if(ps_svc_slice_params->u1_scan_idx_end >= ps_svc_slice_params->u1_scan_idx_start)
+ {
+ UWORD8 u1_cbp;
+ /* Read the Coded block pattern */
+ u1_cbp = (WORD8) ih264d_parse_ctx_cbp_cabac(ps_dec);
+ COPYTHECONTEXT("coded_block_pattern", u1_cbp);
+ ps_cur_mb_info->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_cbp = u1_cbp;
+ p_curr_ctxt->u1_intra_chroma_pred_mode = 0;
+ p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE;
+ ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6;
+
+ if(u1_cbp > 47) return ERROR_CBP;
+
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+
+ /* Read the transform8x8 u4_flag if present */
+ if((ps_dec->s_high_profile.u1_transform8x8_present) && (u1_cbp & 0xf) &&
+ u1_no_submb_part_size_lt8x8_flag)
+ {
+ ps_cur_mb_info->u1_tran_form8x8 =
+ ih264d_parse_transform8x8flag_cabac(ps_dec, ps_cur_mb_info);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+ else
+ {
+ p_curr_ctxt->u1_transform8x8_ctxt = 0;
+ }
+
+ /* Read mb_qp_delta */
+ if(u1_cbp)
+ {
+ WORD8 c_temp;
+ ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &c_temp);
+ if(ret != OK) return ret;
+ COPYTHECONTEXT("mb_qp_delta", c_temp);
+ if(c_temp != 0)
+ {
+ ret = ih264d_update_qp(ps_dec, c_temp);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ ps_dec->i1_prev_mb_qp_delta = 0;
+
+ /*residual from start to end idx */
+ ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, 0);
+ if(EXCEED_OFFSET(ps_dec->ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ }
+ return OK;
+}
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_parse_pmb_cavlc \endif
+ *
+ * \brief
+ * This function parses CAVLC syntax of a P MB.
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_parse_pmb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ UWORD32 u1_num_mb_part;
+ UWORD32 uc_sub_mb;
+ dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *const pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data + u1_num_mbsNby2;
+ WORD8 *pi1_ref_idx = ps_parse_mb_data->i1_ref_idx[0];
+ const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ const UWORD8 *pu1_num_mb_part = (const UWORD8 *) gau1_ih264d_num_mb_part;
+ UWORD8 *pu1_col_info = ps_parse_mb_data->u1_col_info;
+ UWORD32 u1_mb_type = ps_cur_mb_info->u1_mb_type;
+ UWORD32 u4_sum_mb_mode_pack = 0;
+ WORD32 ret;
+ UWORD8 u1_no_submb_part_size_lt8x8_flag = 1;
+
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+ ps_cur_mb_info->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0;
+ ps_cur_mb_info->u1_yuv_dc_block_flag = 0;
+ ps_cur_mb_info->u1_mb_mc_mode = u1_mb_type;
+ uc_sub_mb = ((u1_mb_type == PRED_8x8) | (u1_mb_type == PRED_8x8R0));
+
+ /* Reading the subMB type */
+ if(uc_sub_mb)
+ {
+ WORD32 i;
+ UWORD8 u1_colz = (PRED_8x8 << 6);
+
+ for(i = 0; i < 4; i++)
+ {
+ UWORD32 ui_sub_mb_mode;
+
+ // Inlined ih264d_uev
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ ui_sub_mb_mode = ((1 << u4_ldz) + u4_word - 1);
+ // Inlined ih264d_uev
+
+ if(ui_sub_mb_mode > 3)
+ {
+ return ERROR_SUB_MB_TYPE;
+ }
+ else
+ {
+ u4_sum_mb_mode_pack = (u4_sum_mb_mode_pack << 8) | ui_sub_mb_mode;
+ /* Storing collocated information */
+ *pu1_col_info++ = u1_colz | (UWORD8) (ui_sub_mb_mode << 4);
+
+ COPYTHECONTEXT("sub_mb_type", ui_sub_mb_mode);
+ }
+
+ /* check if Motion compensation is done below 8x8 */
+ if(ui_sub_mb_mode != P_L0_8x8)
+ {
+ u1_no_submb_part_size_lt8x8_flag = 0;
+ }
+ }
+ u1_num_mb_part = 4;
+ }
+ else
+ {
+ *pu1_col_info++ = (u1_mb_type << 6);
+ if(u1_mb_type) *pu1_col_info++ = (u1_mb_type << 6);
+ u1_num_mb_part = pu1_num_mb_part[u1_mb_type];
+ }
+
+ /*Adding code to get Motion Prediction Flags*/
+ {
+ /*free the scratch buffer once used*/
+ UWORD8 uc_i;
+ UWORD8 *pu1_motion_pred_flag_l0;
+ UWORD8 u1_mvp_flag;
+ UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+ UWORD8 uc_num_ref_idx_l0_active_minus1 =
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] << (u1_mbaff & uc_field)) - 1;
+
+ pu1_motion_pred_flag_l0 = &ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+ *pu1_motion_pred_flag_l0 = 0;
+ if(ps_svc_cur_mb_info->u1_crop_window_flag &&
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag)
+ {
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ /*usage of bins and ctxt check*/
+ u1_mvp_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: ps_motion_prediction_flag_l0", u1_mvp_flag);
+
+ *pu1_motion_pred_flag_l0 |= (u1_mvp_flag << uc_i);
+ }
+ }
+ else if(ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ *pu1_motion_pred_flag_l0 = ps_svc_slice_params->u1_default_motion_prediction_flag
+ ? ((1 << u1_num_mb_part) - 1)
+ : 0;
+ }
+
+ /* Decoding reference index 0: For simple profile the following */
+ /* conditions are always true (mb_field_decoding_flag == 0); */
+ /* (MbPartPredMode != PredL1) */
+ if((uc_num_ref_idx_l0_active_minus1 > 0) & (u1_mb_type != PRED_8x8R0))
+ {
+ if(1 == uc_num_ref_idx_l0_active_minus1)
+ isvcd_parse_pmb_ref_index_cavlc_range1(u1_num_mb_part, ps_bitstrm, pi1_ref_idx,
+ uc_num_ref_idx_l0_active_minus1,
+ pu1_motion_pred_flag_l0);
+ else
+ {
+ ret = isvcd_parse_pmb_ref_index_cavlc(u1_num_mb_part, ps_bitstrm, pi1_ref_idx,
+ uc_num_ref_idx_l0_active_minus1,
+ pu1_motion_pred_flag_l0);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ {
+ /* When there exists only a single frame to predict from */
+ UWORD8 uc_i;
+ for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++) /* Storing Reference Idx Information */
+ pi1_ref_idx[uc_i] = 0;
+ }
+ }
+
+ {
+ UWORD8 u1_p_idx, uc_i;
+ parse_part_params_t *ps_part = ps_dec->ps_part;
+ UWORD8 u1_sub_mb_mode, u1_num_subpart, u1_mb_part_width, u1_mb_part_height;
+ UWORD8 u1_sub_mb_num;
+ const UWORD8 *pu1_top_left_sub_mb_indx;
+ mv_pred_t *ps_mv, *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4);
+ /* Loading the table pointers */
+ const UWORD8 *pu1_mb_partw = (const UWORD8 *) gau1_ih264d_mb_partw;
+ const UWORD8 *pu1_mb_parth = (const UWORD8 *) gau1_ih264d_mb_parth;
+ const UWORD8 *pu1_sub_mb_indx_mod =
+ (const UWORD8 *) (gau1_ih264d_submb_indx_mod) + (uc_sub_mb * 6);
+ const UWORD8 *pu1_sub_mb_partw = (const UWORD8 *) gau1_ih264d_submb_partw;
+ const UWORD8 *pu1_sub_mb_parth = (const UWORD8 *) gau1_ih264d_submb_parth;
+ const UWORD8 *pu1_num_sub_mb_part = (const UWORD8 *) gau1_ih264d_num_submb_part;
+ UWORD16 u2_sub_mb_num = 0x028A;
+
+ /*********************************************************/
+ /* default initialisations for condition (uc_sub_mb == 0) */
+ /* i.e. all are subpartitions of 8x8 */
+ /*********************************************************/
+ u1_sub_mb_mode = 0;
+ u1_num_subpart = 1;
+ u1_mb_part_width = pu1_mb_partw[u1_mb_type];
+ u1_mb_part_height = pu1_mb_parth[u1_mb_type];
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_type << 1);
+ u1_sub_mb_num = 0;
+
+ /* Loop on number of partitions */
+ for(uc_i = 0, u1_p_idx = 0; uc_i < u1_num_mb_part; uc_i++)
+ {
+ UWORD8 uc_j;
+ if(uc_sub_mb)
+ {
+ u1_sub_mb_mode = u4_sum_mb_mode_pack >> 24;
+ u1_num_subpart = pu1_num_sub_mb_part[u1_sub_mb_mode];
+ u1_mb_part_width = pu1_sub_mb_partw[u1_sub_mb_mode];
+ u1_mb_part_height = pu1_sub_mb_parth[u1_sub_mb_mode];
+ pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_sub_mb_mode << 1);
+ u1_sub_mb_num = u2_sub_mb_num >> 12;
+ u4_sum_mb_mode_pack <<= 8;
+ u2_sub_mb_num <<= 4;
+ }
+ /* Loop on Number of sub-partitions */
+ for(uc_j = 0; uc_j < u1_num_subpart; uc_j++, pu1_top_left_sub_mb_indx++)
+ {
+ WORD16 i2_mvx, i2_mvy;
+ u1_sub_mb_num += *pu1_top_left_sub_mb_indx;
+ ps_mv = ps_mv_start + u1_sub_mb_num;
+
+ /* Reading the differential Mv from the bitstream */
+ // inlining ih264d_sev
+ {
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i2_mvx = (-(WORD32) u4_abs_val);
+ else
+ i2_mvx = (u4_abs_val);
+ }
+ // inlinined ih264d_sev
+ COPYTHECONTEXT("MVD", i2_mvx);
+ i2_mvy = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("MVD", i2_mvy);
+
+ /* Storing Info for partitions */
+ ps_part->u1_is_direct = PART_NOT_DIRECT;
+ ps_part->u1_sub_mb_num = u1_sub_mb_num;
+ ps_part->u1_partheight = u1_mb_part_height;
+ ps_part->u1_partwidth = u1_mb_part_width;
+
+ /* Storing Mv residuals */
+ ps_mv->i2_mv[0] = i2_mvx;
+ ps_mv->i2_mv[1] = i2_mvy;
+
+ /* Increment partition Index */
+ u1_p_idx++;
+ ps_part++;
+ }
+ }
+ ps_parse_mb_data->u1_num_part = u1_p_idx;
+ ps_dec->ps_part = ps_part;
+ }
+
+ if(ps_svc_slice_params->u1_adaptive_residual_prediction_flag &&
+ ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SVC ext: u1_residual_prediction_flag",
+ ps_svc_cur_mb_info->u1_residual_prediction_flag);
+ }
+ else
+ {
+ /*residual flag inference code */
+ if(1 == ps_svc_cur_mb_info->u1_crop_window_flag)
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag =
+ ps_svc_slice_params->u1_default_residual_prediction_flag;
+ }
+ else
+ {
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ }
+ }
+
+ if(ps_svc_slice_params->u1_scan_idx_end >= ps_svc_slice_params->u1_scan_idx_start)
+ {
+ UWORD32 u4_cbp;
+ /* Read the Coded block pattern */
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_cbp = ((1 << u4_ldz) + u4_word - 1);
+
+ if(u4_cbp > 47) return ERROR_CBP;
+
+ u4_cbp = *((UWORD8 *) gau1_ih264d_cbp_inter + u4_cbp);
+ COPYTHECONTEXT("coded_block_pattern", u4_cbp);
+ ps_cur_mb_info->u1_cbp = u4_cbp;
+
+ /* Read the transform8x8 u4_flag if present */
+ if((ps_dec->s_high_profile.u1_transform8x8_present) && (u4_cbp & 0xf) &&
+ u1_no_submb_part_size_lt8x8_flag)
+ {
+ ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8);
+ ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8;
+ }
+
+ /* Read mb_qp_delta */
+ if(u4_cbp)
+ {
+ WORD32 i_temp;
+ UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst;
+ UWORD32 u4_word, u4_ldz, u4_abs_val;
+
+ /***************************************************************/
+ /* Find leading zeros in next 32 bits */
+ /***************************************************************/
+ NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf);
+ u4_ldz = CLZ(u4_word);
+
+ /* Flush the ps_bitstrm */
+ u4_bitstream_offset += (u4_ldz + 1);
+
+ /* Read the suffix from the ps_bitstrm */
+ u4_word = 0;
+ if(u4_ldz) GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz);
+
+ *pu4_bitstrm_ofst = u4_bitstream_offset;
+ u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1;
+
+ if(u4_word & 0x1)
+ i_temp = (-(WORD32) u4_abs_val);
+ else
+ i_temp = (u4_abs_val);
+
+ if((i_temp < -26) || (i_temp > 25)) return ERROR_INV_RANGE_QP_T;
+ // inlinined ih264d_sev
+
+ COPYTHECONTEXT("mb_qp_delta", i_temp);
+ if(i_temp)
+ {
+ ret = ih264d_update_qp(ps_dec, (WORD8) i_temp);
+ if(ret != OK) return ret;
+ }
+
+ /*change to support start to end idx*/
+ ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, 0);
+ if(ret != OK) return ret;
+ if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_TERMINATE_T;
+ }
+ else
+ {
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+ }
+ }
+
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_mark_err_slice_skip \endif
+ *
+ * \brief
+ *
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_mark_err_slice_skip(svc_dec_lyr_struct_t *ps_svc_lyr_dec, WORD32 num_mb_skip,
+ UWORD8 u1_is_idr_slice, UWORD16 u2_frame_num,
+ pocstruct_t *ps_cur_poc, WORD32 prev_slice_err)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i2_cur_mb_addr;
+ UWORD32 u1_num_mbs;
+ UWORD32 u1_mb_idx = ps_dec->u1_mb_idx;
+ UWORD32 i2_mb_skip_run;
+ UWORD32 u1_num_mbs_next, u1_end_of_row;
+ const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD32 u1_slice_end;
+ UWORD32 u1_tfr_n_mb;
+ UWORD32 u1_decode_nmb;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ deblk_mb_t *ps_cur_deblk_mb;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ parse_pmbarams_t *ps_parse_mb_data;
+ UWORD32 u1_inter_mb_type;
+ UWORD32 u1_deblk_mb_type;
+ UWORD32 u1_mbaff;
+ parse_part_params_t *ps_part_info;
+ WORD32 ret;
+ UNUSED(u1_is_idr_slice);
+
+ ps_svc_lyr_dec->u1_error_in_cur_frame = 1;
+ if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+ {
+ ih264d_err_pic_dispbuf_mgr(ps_dec);
+ return 0;
+ }
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag && (num_mb_skip & 1))
+ {
+ num_mb_skip++;
+ }
+ ps_dec->ps_dpb_cmds->u1_long_term_reference_flag = 0;
+ if(prev_slice_err == 1)
+ {
+ /* first slice - missing/header corruption */
+ ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num;
+ {
+ WORD32 i, j, poc = 0;
+ ps_dec->ps_cur_slice->u2_first_mb_in_slice = 0;
+ ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
+ ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
+ ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
+
+ if(ps_dec->ps_cur_pic != NULL)
+ {
+ poc = ps_dec->ps_cur_pic->i4_poc;
+ if(poc <= INT32_MAX - 2) poc += 2;
+ }
+
+ j = -1;
+ for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
+ {
+ if(ps_dec->ps_pps[i].u1_is_valid == TRUE)
+ {
+ if(ps_dec->ps_pps[i].ps_sps->u1_is_valid == TRUE)
+ {
+ j = i;
+ break;
+ }
+ }
+ }
+
+ // if valid SPS PPS is not found return error
+ if(j == -1)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ /* call ih264d_start_of_pic only if it was not called earlier*/
+ if(ps_dec->u4_pic_buf_got == 0)
+ {
+ // initialize slice params required by isvcd_start_of_pic to valid values
+ ps_dec->ps_cur_slice->u1_slice_type = P_SLICE;
+ ps_dec->ps_cur_slice->u1_nal_ref_idc = 1;
+ ps_dec->ps_cur_slice->u1_nal_unit_type = 1;
+ ret = isvcd_start_of_pic(ps_svc_lyr_dec, poc, ps_cur_poc,
+ ps_dec->ps_cur_slice->u2_frame_num, &ps_dec->ps_pps[j]);
+
+ if(ret != OK)
+ {
+ return ret;
+ }
+ /*inter layer buffer intialization */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start;
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_cur_mb =
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base;
+ }
+
+ ps_dec->ps_ref_pic_buf_lx[0][0]->u1_pic_buf_id = 0;
+ ps_dec->u4_output_present = 0;
+
+ {
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
+ /* If error code is non-zero then there is no buffer available for
+ display, hence avoid format conversion */
+
+ if(0 != ps_dec->s_disp_op.u4_error_code)
+ {
+ ps_dec->u4_output_present = 0;
+ ps_dec->u4_fmt_conv_cur_row = ps_dec->s_disp_frame_info.u4_y_ht;
+ }
+ else
+ ps_dec->u4_output_present = 1;
+ }
+
+ if(ps_dec->u1_separate_parse == 1)
+ {
+#ifdef KEEP_THREADS_ACTIVE
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[0] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+#endif
+#ifdef KEEP_THREADS_ACTIVE
+ if(ps_dec->u4_bs_deblk_thread_created)
+ {
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[1] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+#endif
+ }
+ }
+ }
+ else
+ {
+ // Middle / last slice
+ dec_slice_struct_t *ps_parse_cur_slice;
+ ps_parse_cur_slice = ps_dec->ps_dec_slice_buf + ps_dec->u2_cur_slice_num;
+
+ if(ps_dec->u1_slice_header_done && ps_parse_cur_slice == ps_dec->ps_parse_cur_slice)
+ {
+ // Slice data corrupted
+ // in the case of mbaff, conceal from the even mb.
+ if((ps_dec->ps_cur_slice->u1_mbaff_frame_flag) && (ps_dec->u4_num_mbs_cur_nmb & 1))
+ {
+ ps_dec->u4_num_mbs_cur_nmb = ps_dec->u4_num_mbs_cur_nmb - 1;
+ ps_dec->u2_cur_mb_addr--;
+ }
+
+ u1_num_mbs = ps_dec->u4_num_mbs_cur_nmb;
+ if(u1_num_mbs)
+ {
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs - 1;
+ }
+ else
+ {
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_cur_mb_info = ps_dec->ps_nmb_info;
+ }
+ else
+ {
+ ps_cur_mb_info = ps_dec->ps_nmb_info + ps_dec->u4_num_mbs_prev_nmb - 1;
+ }
+ }
+
+ ps_dec->u2_mby = ps_cur_mb_info->u2_mby;
+ ps_dec->u2_mbx = ps_cur_mb_info->u2_mbx;
+ ps_dec->u1_mb_ngbr_availablity = ps_cur_mb_info->u1_mb_ngbr_availablity;
+
+ if(u1_num_mbs)
+ {
+ // Going back 1 mb
+ ps_dec->pv_parse_tu_coeff_data = ps_dec->pv_prev_mb_parse_tu_coeff_data;
+ ps_dec->u2_cur_mb_addr--;
+ ps_dec->i4_submb_ofst -= SUB_BLK_SIZE;
+
+ // Parse/decode N-MB left unparsed
+ if(ps_dec->u1_pr_sl_type == P_SLICE || ps_dec->u1_pr_sl_type == B_SLICE)
+ {
+ if((ps_dec->i4_submb_ofst - ((WORD32) ((u1_num_mbs - u1_mb_idx) << 4))) < 0)
+ {
+ ps_dec->i4_submb_ofst = ((u1_num_mbs - u1_mb_idx) << 4);
+ }
+
+ ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ if(ret != OK) return ret;
+ }
+
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row =
+ (!u1_num_mbs_next) &&
+ (!(ps_dec->ps_cur_slice->u1_mbaff_frame_flag && (u1_num_mbs & 0x01)));
+ u1_slice_end = 1;
+ u1_tfr_n_mb = 1;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ ps_dec->u1_mb_idx = 0;
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ }
+
+ if(ps_dec->u2_total_mbs_coded >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+ {
+ ps_dec->u1_pic_decode_done = 1;
+ return 0;
+ }
+
+ /* Inserting new slice only if the current slice has atleast 1 MB*/
+ if(ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice <
+ (UWORD32) (ps_dec->u2_total_mbs_coded >> ps_slice->u1_mbaff_frame_flag))
+ {
+ ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
+ ps_dec->u2_cur_slice_num++;
+ ps_dec->ps_parse_cur_slice++;
+ }
+ }
+ else
+ {
+ // Slice missing / header corrupted
+ ps_dec->ps_parse_cur_slice = ps_dec->ps_dec_slice_buf + ps_dec->u2_cur_slice_num;
+ }
+ }
+
+ /******************************************************/
+ /* Initializations to new slice */
+ /******************************************************/
+ {
+ WORD32 num_entries;
+ WORD32 size;
+ UWORD8 *pu1_buf;
+
+ num_entries = MAX_FRAMES;
+ if((1 >= ps_dec->ps_cur_sps->u1_num_ref_frames) && (0 == ps_dec->i4_display_delay))
+ {
+ num_entries = 1;
+ }
+ num_entries = ((2 * num_entries) + 1);
+ num_entries *= 2;
+
+ size = num_entries * sizeof(void *);
+ size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ pu1_buf = (UWORD8 *) ps_dec->pv_map_ref_idx_to_poc_buf;
+ pu1_buf += size * ps_dec->u2_cur_slice_num;
+ ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = (volatile void **) pu1_buf;
+ }
+ u1_mbaff = ps_slice->u1_mbaff_frame_flag;
+ ps_dec->ps_cur_slice->u2_first_mb_in_slice = ps_dec->u2_total_mbs_coded >> u1_mbaff;
+ ps_dec->ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_dec->ps_cur_slice->i1_slice_beta_offset = 0;
+
+ if(ps_dec->ps_cur_slice->u1_field_pic_flag)
+ ps_dec->u2_prv_frame_num = ps_dec->ps_cur_slice->u2_frame_num;
+
+ ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice = ps_dec->u2_total_mbs_coded >> u1_mbaff;
+ ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_dec->ps_parse_cur_slice->pv_tu_coeff_data_start = ps_dec->pv_parse_tu_coeff_data;
+ }
+ else
+ {
+ ps_dec->pv_proc_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ }
+
+ /******************************************************/
+ /* Initializations specific to P slice */
+ /******************************************************/
+ u1_inter_mb_type = P_MB;
+ u1_deblk_mb_type = D_INTER_MB;
+
+ ps_dec->ps_cur_slice->u1_slice_type = P_SLICE;
+ ps_dec->ps_parse_cur_slice->slice_type = P_SLICE;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ ps_dec->u2_mbx =
+ (MOD(ps_dec->ps_cur_slice->u2_first_mb_in_slice - 1, ps_dec->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby =
+ (DIV(ps_dec->ps_cur_slice->u2_first_mb_in_slice - 1, ps_dec->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby <<= u1_mbaff;
+
+ /******************************************************/
+ /* Parsing / decoding the slice */
+ /******************************************************/
+ ret = isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec,
+ ps_dec->ps_cur_slice->u2_first_mb_in_slice);
+ ps_dec->u1_slice_header_done = 2;
+
+ ps_dec->u1_qp = ps_slice->u1_slice_qp;
+ ih264d_update_qp(ps_dec, 0);
+ u1_mb_idx = ps_dec->u1_mb_idx;
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ u1_num_mbs = u1_mb_idx;
+ u1_slice_end = 0;
+ u1_tfr_n_mb = 0;
+ u1_decode_nmb = 0;
+ i2_cur_mb_addr = ps_dec->u2_total_mbs_coded;
+ i2_mb_skip_run = num_mb_skip;
+ if(0 == ps_dec->u2_total_mbs_coded)
+ {
+ ps_dec->ps_cur_mb_row = ps_dec->ps_nbr_mb_row; //[0];
+ // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be valid
+ ps_dec->ps_cur_mb_row += 2;
+ ps_dec->ps_top_mb_row = ps_dec->ps_nbr_mb_row;
+ ps_dec->ps_top_mb_row +=
+ ((ps_dec->u2_frm_wd_in_mbs + 2) << (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag));
+ // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be valid
+ ps_dec->ps_top_mb_row += 2;
+
+ /* CHANGED CODE */
+ ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->ps_mv_left = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->ps_mv_top = ps_dec->ps_mv_top_p[0];
+ ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic;
+ ps_dec->ps_mv = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->ps_mv_bank_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->pu1_col_zero_flag = ps_dec->s_cur_pic.pu1_col_zero_flag;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = isvcd_mv_pred_ref_tfr_nby2_epmb;
+ }
+ while(!u1_slice_end)
+ {
+ if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr) break;
+
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + u1_num_mbs;
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs;
+ ps_dec->u4_num_mbs_cur_nmb = u1_num_mbs;
+ ps_cur_mb_info->u1_Mux = 0;
+ ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff);
+ ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs;
+ ps_cur_mb_info->u1_end_of_slice = 0;
+
+ /* Storing Default partition info */
+ ps_parse_mb_data->u1_num_part = 1;
+ ps_parse_mb_data->u1_isI_mb = 0;
+
+ /**************************************************************/
+ /* Get the required information for decoding of MB */
+ /**************************************************************/
+ /* mb_x, mb_y, neighbor availablity, */
+ if(u1_mbaff)
+ ih264d_get_mb_info_cavlc_mbaff(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, i2_mb_skip_run);
+ else
+ isvcd_get_mb_info_cavlc_nonmbaff(ps_dec, i2_cur_mb_addr, ps_cur_mb_info,
+ i2_mb_skip_run);
+
+ {
+ UWORD16 *pu2_res_luma_csbp;
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_res_luma_csbp +=
+ ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+ *pu2_res_luma_csbp = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
+ ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+ }
+
+ /* Set the deblocking parameters for this MB */
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ {
+ ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice,
+ ps_dec->u1_mb_ngbr_availablity,
+ ps_dec->u1_cur_mb_fld_dec_flag);
+ }
+
+ /* Set appropriate flags in ps_cur_mb_info and ps_dec */
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_dec->u1_sub_mb_num = 0;
+ ps_cur_mb_info->u1_mb_type = MB_SKIP;
+ ps_cur_mb_info->u1_mb_mc_mode = PRED_16x16;
+ ps_cur_mb_info->u1_cbp = 0;
+
+ /* set appropriat flags in svc cur MB info */
+ ps_svc_cur_mb_info->u1_base_mode_flag = 0;
+ ps_svc_cur_mb_info->u1_residual_prediction_flag = 0;
+ ps_svc_cur_mb_info->u1_crop_window_flag = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[0] = 0;
+ ps_svc_cur_mb_info->au1_motion_pred_flag[1] = 0;
+
+ /* Storing Skip partition info */
+ ps_part_info = ps_dec->ps_part;
+ ps_part_info->u1_is_direct = PART_DIRECT_16x16;
+ ps_part_info->u1_sub_mb_num = 0;
+ ps_dec->ps_part++;
+
+ /* Update Nnzs */
+ ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC);
+
+ ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type;
+ ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type;
+
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING;
+ }
+
+ i2_mb_skip_run--;
+ ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp;
+
+ if(u1_mbaff)
+ {
+ ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info);
+ }
+
+ /**************************************************************/
+ /* Get next Macroblock address */
+ /**************************************************************/
+ i2_cur_mb_addr++;
+ u1_num_mbs++;
+ ps_parse_mb_data++;
+
+ /****************************************************************/
+ /* Check for End Of Row and other flags that determine when to */
+ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */
+ /* N-Mb */
+ /****************************************************************/
+ u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1;
+ u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01)));
+ u1_slice_end = !i2_mb_skip_run;
+ u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row || u1_slice_end;
+ u1_decode_nmb = u1_tfr_n_mb || u1_slice_end;
+ ps_cur_mb_info->u1_end_of_slice = u1_slice_end;
+
+ if(u1_decode_nmb)
+ {
+ if((ps_dec->i4_submb_ofst - ((WORD32) ((u1_num_mbs - u1_mb_idx) << 4))) < 0)
+ {
+ ps_dec->i4_submb_ofst = ((u1_num_mbs - u1_mb_idx) << 4);
+ }
+
+ ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs);
+ ps_parse_mb_data = ps_dec->ps_parse_mb_data;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ ps_dec->ps_nmb_info += u1_num_mbs;
+ ps_svc_lyr_dec->ps_svc_nmb_info += u1_num_mbs;
+ }
+ else
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, u1_num_mbs_next,
+ u1_tfr_n_mb, u1_end_of_row);
+ }
+ else
+ {
+ isvcd_decode_recon_tfr_nmb_base_lyr(ps_svc_lyr_dec, u1_mb_idx, u1_num_mbs,
+ u1_num_mbs_next, u1_tfr_n_mb,
+ u1_end_of_row);
+ }
+ }
+ ps_dec->u2_total_mbs_coded += u1_num_mbs;
+ if(u1_tfr_n_mb) u1_num_mbs = 0;
+ u1_mb_idx = u1_num_mbs;
+ ps_dec->u1_mb_idx = u1_num_mbs;
+ }
+ }
+
+ ps_dec->u4_num_mbs_cur_nmb = 0;
+ ps_dec->ps_cur_slice->u4_mbs_in_slice =
+ i2_cur_mb_addr - ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice;
+
+ H264_DEC_DEBUG_PRINT("Mbs in slice: %d\n", ps_dec->ps_cur_slice->u4_mbs_in_slice);
+
+ /* incremented here only if first slice is inserted */
+ if(ps_dec->u4_first_slice_in_pic != 0)
+ {
+ ps_dec->ps_parse_cur_slice++;
+ ps_dec->u2_cur_slice_num++;
+ }
+
+ ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
+
+ if(ps_dec->u2_total_mbs_coded >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+ {
+ ps_dec->u1_pic_decode_done = 1;
+ }
+
+ return 0;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_interlayer_resamp_func_init \endif
+
+* \brief
+* This function initilizes default values for svcd inter layer func.
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_interlayer_resamp_func_init(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ WORD32 ret = OK;
+
+ if(TARGET_LAYER != ps_svc_lyr_dec->u1_layer_identifier)
+ {
+ ps_slice->u1_disable_dblk_filter_idc = ps_svc_lyr_dec->u1_inter_lyr_disable_dblk_filter_idc;
+ ps_slice->i1_slice_alpha_c0_offset = ps_svc_lyr_dec->i1_inter_lyr_slice_alpha_c0_offset;
+ ps_slice->i1_slice_beta_offset = ps_svc_lyr_dec->i1_inter_lyr_slice_beta_offset;
+ }
+
+ if(0 == u2_first_mb_in_slice)
+ {
+ ret = isvcd_populate_res_prms(ps_svc_lyr_dec);
+ if(ret != OK) return NOT_OK;
+ isvcd_crop_wnd_flag_res_int(ps_svc_lyr_dec);
+ ret = isvcd_comp_mode_mv_res_init(ps_svc_lyr_dec);
+ if(ret != OK) return NOT_OK;
+ ret = isvcd_ii_pred_res_init(ps_svc_lyr_dec);
+ if(ret != OK) return NOT_OK;
+ ret = isvcd_intra_resamp_res_init(ps_svc_lyr_dec);
+ if(ret != OK) return NOT_OK;
+ ret = isvcd_residual_samp_res_init(ps_svc_lyr_dec);
+ if(ret != OK) return NOT_OK;
+ }
+
+ return ret;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_decode_pslice \endif
+*
+* \brief
+* Decodes a P Slice
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_pslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
+ UWORD64 u8_ref_idx_l0;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ WORD32 ret;
+ WORD64 i8_temp;
+
+ /*--------------------------------------------------------------------*/
+ /* Read remaining contents of the slice header */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD8 *pi1_buf;
+ WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv;
+ WORD32 *pi4_mv = (WORD32 *) pi2_mv;
+ WORD16 *pi16_refFrame;
+
+ pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame;
+ pi16_refFrame = (WORD16 *) pi1_buf;
+ *pi4_mv = 0;
+ *(pi4_mv + 1) = 0;
+ *pi16_refFrame = OUT_OF_RANGE_REF;
+ ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8) -1;
+ ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8) -1;
+ }
+
+ ps_cur_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: num_ref_idx_override_flag",
+ ps_cur_slice->u1_num_ref_idx_active_override_flag);
+
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ if(ps_cur_slice->u1_num_ref_idx_active_override_flag)
+ {
+ u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64) 1;
+ }
+
+ {
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS << u1_field_pic_flag;
+ if(u8_ref_idx_l0 >= u1_max_ref_idx)
+ {
+ return ERROR_NUM_REF;
+ }
+ ps_cur_slice->u1_num_ref_idx_lx_active[0] = (UWORD8) u8_ref_idx_l0;
+ COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1",
+ ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1);
+ }
+
+ {
+ UWORD8 uc_refIdxReFlagL0 = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l0", uc_refIdxReFlagL0);
+
+ ih264d_init_ref_idx_lx_p(ps_dec);
+ /* Store the value for future slices in the same picture */
+ ps_dec->u1_num_ref_idx_lx_active_prev = ps_cur_slice->u1_num_ref_idx_lx_active[0];
+
+ /* Modified temporarily */
+ if(uc_refIdxReFlagL0)
+ {
+ WORD8 ret;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ ret = ih264d_ref_idx_reordering(ps_dec, 0);
+ if(ret == -1) return ERROR_REFIDX_ORDER_T;
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0];
+ }
+ else
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0];
+ }
+ /* Create refIdx to POC mapping */
+ {
+ void **pui_map_ref_idx_to_poc_lx0, **pui_map_ref_idx_to_poc_lx1;
+ WORD8 idx;
+ struct pic_buffer_t *ps_pic;
+
+ pui_map_ref_idx_to_poc_lx0 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0;
+ pui_map_ref_idx_to_poc_lx0[0] = 0;
+ pui_map_ref_idx_to_poc_lx0++;
+ for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ pui_map_ref_idx_to_poc_lx0[idx] = (ps_pic->pu1_buf1);
+ }
+
+ /* Bug Fix Deblocking */
+ pui_map_ref_idx_to_poc_lx1 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1;
+ pui_map_ref_idx_to_poc_lx1[0] = 0;
+
+ if(u1_mbaff)
+ {
+ void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b;
+ void **ppv_map_ref_idx_to_poc_lx_t1, **ppv_map_ref_idx_to_poc_lx_b1;
+ ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L0;
+ ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L0;
+ ppv_map_ref_idx_to_poc_lx_t[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_t++;
+ ppv_map_ref_idx_to_poc_lx_b[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b++;
+ idx = 0;
+ for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++)
+ {
+ ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx];
+ ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1);
+ ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1;
+ ppv_map_ref_idx_to_poc_lx_t += 2;
+ ppv_map_ref_idx_to_poc_lx_b += 2;
+ }
+ ppv_map_ref_idx_to_poc_lx_t1 = ps_dec->ppv_map_ref_idx_to_poc + TOP_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_t1[0] = 0;
+ ppv_map_ref_idx_to_poc_lx_b1 = ps_dec->ppv_map_ref_idx_to_poc + BOT_LIST_FLD_L1;
+ ppv_map_ref_idx_to_poc_lx_b1[0] = 0;
+ }
+ }
+ if(ps_pps->u1_wted_pred_flag)
+ {
+ ret = ih264d_parse_pred_weight_table(ps_cur_slice, ps_bitstrm);
+ if(ret != OK) return ret;
+
+ ih264d_form_pred_weight_matrix(ps_dec);
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+ else
+ {
+ ps_dec->ps_cur_slice->u2_log2Y_crwd = 0;
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+ }
+
+ ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
+
+ if(u1_mbaff && (u1_field_pic_flag == 0))
+ {
+ ih264d_convert_frm_mbaff_list(ps_dec);
+ }
+
+ /* G050 */
+ if(ps_cur_slice->u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
+ UWORD8 u1_nal_unit_type_tmp = ps_dec->u1_nal_unit_type;
+
+ ps_pps->ps_sps = ps_dec->ps_cur_sps;
+ if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
+ ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
+
+ i_temp = ih264d_read_mmco_commands(ps_dec);
+
+ ps_pps->ps_sps = ps_sps_tmp;
+ ps_dec->u1_nal_unit_type = u1_nal_unit_type_tmp;
+
+ if(i_temp < 0)
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+ ps_dec->u4_bitoffset = i_temp;
+ }
+ else
+ ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset;
+ }
+ /* G050 */
+
+ if(ps_pps->u1_entropy_coding_mode == CABAC)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_temp > MAX_CABAC_INIT_IDC)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->u1_cabac_init_idc = u4_temp;
+ COPYTHECONTEXT("SH: cabac_init_idc", ps_cur_slice->u1_cabac_init_idc);
+ }
+
+ /* Read slice_qp_delta */
+ i8_temp = (WORD64) ps_pps->u1_pic_init_qp + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
+ {
+ return ERROR_INV_RANGE_QP_T;
+ }
+ ps_cur_slice->u1_slice_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("SH: slice_qp_delta",
+ (WORD8) (ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
+
+ if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp);
+ ps_cur_slice->u1_disable_dblk_filter_idc = u4_temp;
+ if(u4_temp != 1)
+ {
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->i1_slice_alpha_c0_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2",
+ ps_cur_slice->i1_slice_alpha_c0_offset >> 1);
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) << 1;
+ if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF))
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_cur_slice->i1_slice_beta_offset = i_temp;
+ COPYTHECONTEXT("SH: slice_beta_offset_div2", ps_cur_slice->i1_slice_beta_offset >> 1);
+ }
+ else
+ {
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+ }
+ else
+ {
+ ps_cur_slice->u1_disable_dblk_filter_idc = 0;
+ ps_cur_slice->i1_slice_alpha_c0_offset = 0;
+ ps_cur_slice->i1_slice_beta_offset = 0;
+ }
+
+ isvcd_parse_interlayer_resamp_func_init(ps_svc_lyr_dec, u2_first_mb_in_slice);
+
+ ps_dec->u1_slice_header_done = 2;
+ if(ps_pps->u1_entropy_coding_mode)
+ {
+ SWITCHOFFTRACE;
+ SWITCHONTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_svc_inter_slice = isvcd_parse_inter_slice_data_cabac;
+ ps_dec->pf_parse_inter_mb = ih264d_parse_pmb_cabac;
+ ih264d_init_cabac_contexts(P_SLICE, ps_dec);
+
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff;
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cabac_nonmbaff;
+ }
+ else
+ {
+ SWITCHONTRACE;
+ SWITCHOFFTRACECABAC;
+ ps_svc_lyr_dec->pf_parse_svc_inter_slice = isvcd_parse_inter_slice_data_cavlc;
+ ps_dec->pf_parse_inter_mb = ih264d_parse_pmb_cavlc;
+ if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff;
+ }
+ else
+ ps_dec->pf_get_mb_info = isvcd_get_mb_info_cavlc_nonmbaff;
+ }
+
+ ps_dec->u1_B = 0;
+ ps_dec->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb;
+ ret = ps_svc_lyr_dec->pf_parse_svc_inter_slice(ps_svc_lyr_dec, ps_cur_slice,
+ u2_first_mb_in_slice);
+ if(ret != OK) return ret;
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_parse_headers.c b/decoder/svc/isvcd_parse_headers.c
new file mode 100644
index 0000000..abf4a1b
--- /dev/null
+++ b/decoder/svc/isvcd_parse_headers.c
@@ -0,0 +1,1874 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_headers.c
+ *
+ * @brief
+ * Contains High level syntax[above slice] parsing routines
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_set_default_seq_svc_ext()
+ * - isvcd_parse_subset_sps()
+ * - isvcd_dec_ref_base_pic_marking()
+ * - isvcd_parse_nal_unit()
+ * - isvcd_parse_sps()
+ * - isvcd_parse_pps()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_defs.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_tables.h"
+#include "ih264d_utils.h"
+#include "ih264d_nal.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_mem_request.h"
+#include "ih264d_debug.h"
+#include "ih264_debug.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_sei.h"
+#include "ih264d_vui.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ih264d_thread_compute_bs.h"
+#include "ih264d_quant_scaling.h"
+#include "ih264d_defs.h"
+#include "ivd.h"
+#include "ih264d_parse_islice.h"
+#include "isvcd_parse_slice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_vui.h"
+
+WORD32 ih264d_access_unit_delimiter_rbsp(dec_struct_t *ps_dec);
+void ih264d_get_pre_sei_params(dec_struct_t *ps_dec, UWORD8 u1_nal_unit_type);
+UWORD32 ih264d_correct_level_idc(UWORD32 u4_level_idc, UWORD32 u4_total_mbs);
+WORD32 ih264d_parse_filler_data(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm);
+void ih264d_parse_end_of_stream(dec_struct_t *ps_dec);
+WORD32 ih264d_parse_slice_partition(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm);
+/*!
+**************************************************************************
+* \if Function name : isvcd_set_default_seq_svc_ext \en
+dif
+*
+* \brief
+* Sets the default values for the svc params in the SVC bitstream
+*
+* \return
+**************************************************************************
+*/
+void isvcd_set_default_seq_svc_ext(dec_subset_seq_params_t *ps_seq_svc_ext)
+{
+ ps_seq_svc_ext->u1_inter_layer_deblocking_filter_control_present_flag = 0;
+ ps_seq_svc_ext->u1_extended_spatial_scalability_idc = 0;
+ ps_seq_svc_ext->u1_chroma_phase_x_plus1_flag = 1;
+ ps_seq_svc_ext->u1_chroma_phase_y_plus1 = 1;
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_x_plus1_flag =
+ ps_seq_svc_ext->u1_chroma_phase_x_plus1_flag;
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1 = ps_seq_svc_ext->u1_chroma_phase_y_plus1;
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset = 0;
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset = 0;
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_right_offset = 0;
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_bottom_offset = 0;
+ ps_seq_svc_ext->u1_seq_tcoeff_level_prediction_flag =
+ ps_seq_svc_ext->u1_adaptive_tcoeff_level_prediction_flag = 0;
+ ps_seq_svc_ext->u1_slice_header_restriction_flag = 0;
+ ps_seq_svc_ext->u1_svc_vui_parameters_present_flag = 0;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_subset_sps \en
+dif
+*
+* \brief
+* Decodes Sequence parameter set from the SVC bitstream
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_subset_sps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 i;
+ dec_seq_params_t *ps_seq = NULL;
+ dec_svc_seq_params_t *ps_subset_seq = NULL;
+ dec_subset_seq_params_t *ps_seq_svc_ext;
+ UWORD8 u1_profile_idc, u1_level_idc, u1_seq_parameter_set_id, u1_mb_aff_flag = 0;
+ UWORD16 i2_max_frm_num;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_flag, uc_constraint_set2_flag;
+ WORD32 i4_cropped_ht, i4_cropped_wd;
+ UWORD32 u4_temp;
+ UWORD64 u8_temp;
+ UWORD32 u4_pic_height_in_map_units, u4_pic_width_in_mbs;
+ UWORD32 u2_pic_wd = 0;
+ UWORD32 u2_pic_ht = 0;
+ UWORD32 u2_frm_wd_y = 0;
+ UWORD32 u2_frm_ht_y = 0;
+ UWORD32 u2_frm_wd_uv = 0;
+ UWORD32 u2_frm_ht_uv = 0;
+ UWORD32 u2_crop_offset_y = 0;
+ UWORD32 u2_crop_offset_uv = 0;
+ WORD32 ret;
+ /* High profile related syntax element */
+ WORD32 i4_i;
+ /* G050 */
+ UWORD8 u1_frame_cropping_flag,
+ u1_frame_cropping_rect_left_ofst = 0, u1_frame_cropping_rect_right_ofst = 0,
+ u1_frame_cropping_rect_top_ofst = 0, u1_frame_cropping_rect_bottom_ofst = 0;
+ /* G050 */
+ /*--------------------------------------------------------------------*/
+ /* Decode seq_parameter_set_id and profile and level values */
+ /*--------------------------------------------------------------------*/
+ SWITCHONTRACE;
+ u1_profile_idc = ih264d_get_bits_h264(ps_bitstrm, 8);
+ COPYTHECONTEXT("SPS: profile_idc", u1_profile_idc);
+
+ /* G050 */
+ uc_constraint_set0_flag = ih264d_get_bit_h264(ps_bitstrm);
+ uc_constraint_set1_flag = ih264d_get_bit_h264(ps_bitstrm);
+ uc_constraint_set2_flag = ih264d_get_bit_h264(ps_bitstrm);
+ UNUSED(uc_constraint_set1_flag);
+ UNUSED(uc_constraint_set2_flag);
+
+ /*****************************************************/
+ /* Read 5 bits for uc_constraint_set3_flag (1 bit) */
+ /* and reserved_zero_4bits (4 bits) - Sushant */
+ /*****************************************************/
+ ih264d_get_bits_h264(ps_bitstrm, 5);
+ /* G050 */
+ u1_level_idc = (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 8);
+ COPYTHECONTEXT("SPS: u4_level_idc", u1_level_idc);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_SEQ_SET_ID) return ERROR_INV_SPS_PPS_T;
+ u1_seq_parameter_set_id = u4_temp;
+ COPYTHECONTEXT("SPS: seq_parameter_set_id", u1_seq_parameter_set_id);
+
+ if(u1_seq_parameter_set_id >= MAX_NUM_SEQ_PARAMS) return ERROR_INV_SPS_PPS_T;
+
+ /*--------------------------------------------------------------------*/
+ /* Find an seq param entry in seqparam array of decStruct */
+ /*--------------------------------------------------------------------*/
+ ps_subset_seq = ps_svc_lyr_dec->pv_scratch_subset_sps;
+ memset(ps_subset_seq, 0, sizeof(dec_svc_seq_params_t));
+ ps_seq = ps_dec->pv_scratch_sps_pps;
+ memset(ps_seq, 0, sizeof(dec_seq_params_t));
+
+ if(ps_dec->i4_header_decoded & 1)
+ {
+ if(NULL != ps_dec->ps_cur_sps)
+ *ps_seq = *ps_dec->ps_cur_sps;
+ else
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ ps_seq->u1_profile_idc = u1_profile_idc;
+ ps_seq->u1_level_idc = u1_level_idc;
+ ps_seq->u1_seq_parameter_set_id = u1_seq_parameter_set_id;
+
+ /* subset_seq_sps_will be stored from location 32 : MAX_NUM_SEQ_PARAMS*/
+ u1_seq_parameter_set_id += MAX_NUM_SEQ_PARAMS;
+ ps_subset_seq->ps_seq = &ps_dec->ps_sps[u1_seq_parameter_set_id];
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_profile_idc != u1_profile_idc))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_level_idc != u1_level_idc))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ /*******************************************************************/
+ /* Initializations for high profile - Sushant */
+ /*******************************************************************/
+ ps_seq->i4_chroma_format_idc = 1;
+ ps_seq->i4_bit_depth_luma_minus8 = 0;
+ ps_seq->i4_bit_depth_chroma_minus8 = 0;
+ ps_seq->i4_qpprime_y_zero_transform_bypass_flag = 0;
+ ps_seq->i4_seq_scaling_matrix_present_flag = 0;
+ if(u1_profile_idc == HIGH_PROFILE_IDC || u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC ||
+ u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC)
+ {
+ /* reading chroma_format_idc */
+ ps_seq->i4_chroma_format_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ /* Monochrome is not supported */
+ if(ps_seq->i4_chroma_format_idc != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading bit_depth_luma_minus8 */
+ ps_seq->i4_bit_depth_luma_minus8 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_seq->i4_bit_depth_luma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading bit_depth_chroma_minus8 */
+ ps_seq->i4_bit_depth_chroma_minus8 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_seq->i4_bit_depth_chroma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading qpprime_y_zero_transform_bypass_flag */
+ ps_seq->i4_qpprime_y_zero_transform_bypass_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_seq->i4_qpprime_y_zero_transform_bypass_flag != 0)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ /* reading seq_scaling_matrix_present_flag */
+ ps_seq->i4_seq_scaling_matrix_present_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_seq->i4_seq_scaling_matrix_present_flag)
+ {
+ for(i4_i = 0; i4_i < 8; i4_i++)
+ {
+ ps_seq->u1_seq_scaling_list_present_flag[i4_i] = ih264d_get_bit_h264(ps_bitstrm);
+
+ /* initialize u1_use_default_scaling_matrix_flag[i4_i] to zero */
+ /* before calling scaling list */
+ ps_seq->u1_use_default_scaling_matrix_flag[i4_i] = 0;
+
+ if(ps_seq->u1_seq_scaling_list_present_flag[i4_i])
+ {
+ if(i4_i < 6)
+ {
+ ret = ih264d_scaling_list(ps_seq->i2_scalinglist4x4[i4_i], 16,
+ &ps_seq->u1_use_default_scaling_matrix_flag[i4_i],
+ ps_bitstrm);
+ }
+ else
+ {
+ ret = ih264d_scaling_list(ps_seq->i2_scalinglist8x8[i4_i - 6], 64,
+ &ps_seq->u1_use_default_scaling_matrix_flag[i4_i],
+ ps_bitstrm);
+ }
+ if(ret != OK)
+ {
+ return ret;
+ }
+ }
+ }
+ }
+ }
+ /*--------------------------------------------------------------------*/
+ /* Decode MaxFrameNum */
+ /*--------------------------------------------------------------------*/
+ u8_temp = (UWORD64) 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_FRAME_NUM)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ ps_seq->u1_bits_in_frm_num = (UWORD8) u8_temp;
+ COPYTHECONTEXT("SPS: log2_max_frame_num_minus4", (ps_seq->u1_bits_in_frm_num - 4));
+
+ i2_max_frm_num = (1 << (ps_seq->u1_bits_in_frm_num));
+ ps_seq->u2_u4_max_pic_num_minus1 = i2_max_frm_num - 1;
+ /*--------------------------------------------------------------------*/
+ /* Decode picture order count and related values */
+ /*--------------------------------------------------------------------*/
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_temp > MAX_PIC_ORDER_CNT_TYPE)
+ {
+ return ERROR_INV_POC_TYPE_T;
+ }
+ ps_seq->u1_pic_order_cnt_type = u4_temp;
+ COPYTHECONTEXT("SPS: pic_order_cnt_type", ps_seq->u1_pic_order_cnt_type);
+
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1;
+ if(ps_seq->u1_pic_order_cnt_type == 0)
+ {
+ u8_temp = (UWORD64) 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_POC_LSB)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = (UWORD8) u8_temp;
+ ps_seq->i4_max_pic_order_cntLsb = (1 << u8_temp);
+ COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4", (u8_temp - 4));
+ }
+ else if(ps_seq->u1_pic_order_cnt_type == 1)
+ {
+ ps_seq->u1_delta_pic_order_always_zero_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: delta_pic_order_always_zero_flag",
+ ps_seq->u1_delta_pic_order_always_zero_flag);
+
+ ps_seq->i4_ofst_for_non_ref_pic = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_non_ref_pic", ps_seq->i4_ofst_for_non_ref_pic);
+
+ ps_seq->i4_ofst_for_top_to_bottom_field = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_top_to_bottom_field",
+ ps_seq->i4_ofst_for_top_to_bottom_field);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > 255) return ERROR_INV_SPS_PPS_T;
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = u4_temp;
+ COPYTHECONTEXT("SPS: num_ref_frames_in_pic_order_cnt_cycle",
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
+
+ for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ ps_seq->i4_ofst_for_ref_frame[i] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_ref_frame", ps_seq->i4_ofst_for_ref_frame[i]);
+ }
+ }
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((u4_temp > H264_MAX_REF_PICS))
+ {
+ return ERROR_NUM_REF;
+ }
+
+ /* Compare with older num_ref_frames is header is already once */
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_num_ref_frames != u4_temp))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ ps_seq->u1_num_ref_frames = u4_temp;
+ COPYTHECONTEXT("SPS: num_ref_frames", ps_seq->u1_num_ref_frames);
+
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: gaps_in_frame_num_value_allowed_flag",
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag);
+ /* SVC_DEC_REVIEW */
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Decode FrameWidth and FrameHeight and related values */
+ /*--------------------------------------------------------------------*/
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ /* Check for unsupported resolutions*/
+ if(u8_temp > (H264_MAX_FRAME_WIDTH >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ u4_pic_width_in_mbs = (UWORD32) u8_temp;
+ COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1", u4_pic_width_in_mbs - 1);
+
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > (H264_MAX_FRAME_HEIGHT >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ u4_pic_height_in_map_units = (UWORD32) u8_temp;
+
+ ps_seq->u2_frm_wd_in_mbs = u4_pic_width_in_mbs;
+ ps_seq->u2_frm_ht_in_mbs = u4_pic_height_in_map_units;
+
+ u2_pic_wd = (u4_pic_width_in_mbs << 4);
+ u2_pic_ht = (u4_pic_height_in_map_units << 4);
+ /*--------------------------------------------------------------------*/
+ /* Get the value of MaxMbAddress and Number of bits needed for it */
+ /*--------------------------------------------------------------------*/
+ ps_seq->u2_max_mb_addr = (ps_seq->u2_frm_wd_in_mbs * ps_seq->u2_frm_ht_in_mbs) - 1;
+
+ ps_seq->u2_total_num_of_mbs = ps_seq->u2_max_mb_addr + 1;
+
+ ps_seq->u1_level_idc = ih264d_correct_level_idc(u1_level_idc, ps_seq->u2_total_num_of_mbs);
+
+ u1_frm = ih264d_get_bit_h264(ps_bitstrm);
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_frame_mbs_only_flag != u1_frm))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ ps_seq->u1_frame_mbs_only_flag = u1_frm;
+
+ COPYTHECONTEXT("SPS: frame_mbs_only_flag", u1_frm);
+
+ if(!u1_frm) u1_mb_aff_flag = ih264d_get_bit_h264(ps_bitstrm);
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_mb_aff_flag != u1_mb_aff_flag))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ if(!u1_frm)
+ {
+ u2_pic_ht <<= 1;
+ ps_seq->u1_mb_aff_flag = u1_mb_aff_flag;
+ COPYTHECONTEXT("SPS: mb_adaptive_frame_field_flag", ps_seq->u1_mb_aff_flag);
+ }
+ else
+ ps_seq->u1_mb_aff_flag = 0;
+
+ ps_seq->u1_direct_8x8_inference_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ COPYTHECONTEXT("SPS: direct_8x8_inference_flag", ps_seq->u1_direct_8x8_inference_flag);
+
+ /* G050 */
+ u1_frame_cropping_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: frame_cropping_flag", u1_frame_cropping_flag);
+
+ if(u1_frame_cropping_flag)
+ {
+ u1_frame_cropping_rect_left_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_left_offset", u1_frame_cropping_rect_left_ofst);
+ u1_frame_cropping_rect_right_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_right_offset", u1_frame_cropping_rect_right_ofst);
+ u1_frame_cropping_rect_top_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_top_offset", u1_frame_cropping_rect_top_ofst);
+ u1_frame_cropping_rect_bottom_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_bottom_offset",
+ u1_frame_cropping_rect_bottom_ofst);
+ }
+ /* G050 */
+ ps_seq->u1_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: vui_parameters_present_flag", ps_seq->u1_vui_parameters_present_flag);
+
+ u2_frm_wd_y = u2_pic_wd + (UWORD8) (PAD_LEN_Y_H << 1);
+ if(1 == ps_dec->u4_share_disp_buf)
+ {
+ if(ps_dec->u4_app_disp_width > u2_frm_wd_y) u2_frm_wd_y = ps_dec->u4_app_disp_width;
+ }
+
+ u2_frm_ht_y = u2_pic_ht + (UWORD8) (PAD_LEN_Y_V << 2);
+ u2_frm_wd_uv = u2_pic_wd + (UWORD8) (PAD_LEN_UV_H << 2);
+ u2_frm_wd_uv = MAX(u2_frm_wd_uv, u2_frm_wd_y);
+
+ u2_frm_ht_uv = (u2_pic_ht >> 1) + (UWORD8) (PAD_LEN_UV_V << 2);
+ u2_frm_ht_uv = MAX(u2_frm_ht_uv, (u2_frm_ht_y >> 1));
+
+ /* Calculate display picture width, height and start u4_ofst from YUV420 */
+ /* pictute buffers as per cropping information parsed above */
+ {
+ UWORD16 u2_rgt_ofst = 0;
+ UWORD16 u2_lft_ofst = 0;
+ UWORD16 u2_top_ofst = 0;
+ UWORD16 u2_btm_ofst = 0;
+ UWORD8 u1_frm_mbs_flag;
+ UWORD8 u1_vert_mult_factor;
+
+ if(u1_frame_cropping_flag)
+ {
+ /* Calculate right and left u4_ofst for cropped picture */
+ u2_rgt_ofst = u1_frame_cropping_rect_right_ofst << 1;
+ u2_lft_ofst = u1_frame_cropping_rect_left_ofst << 1;
+
+ /* Know frame MBs only u4_flag */
+ u1_frm_mbs_flag = (1 == ps_seq->u1_frame_mbs_only_flag);
+
+ /* Simplify the vertical u4_ofst calculation from field/frame */
+ u1_vert_mult_factor = (2 - u1_frm_mbs_flag);
+
+ /* Calculate bottom and top u4_ofst for cropped picture */
+ u2_btm_ofst = (u1_frame_cropping_rect_bottom_ofst << u1_vert_mult_factor);
+ u2_top_ofst = (u1_frame_cropping_rect_top_ofst << u1_vert_mult_factor);
+ }
+
+ /* Calculate u4_ofst from start of YUV 420 picture buffer to start of*/
+ /* cropped picture buffer */
+ u2_crop_offset_y = (u2_frm_wd_y * u2_top_ofst) + (u2_lft_ofst);
+ u2_crop_offset_uv =
+ (u2_frm_wd_uv * (u2_top_ofst >> 1)) + (u2_lft_ofst >> 1) * YUV420SP_FACTOR;
+ /* Calculate the display picture width and height based on crop */
+ /* information */
+ i4_cropped_ht = (WORD32) u2_pic_ht - (WORD32) (u2_btm_ofst + u2_top_ofst);
+ i4_cropped_wd = (WORD32) u2_pic_wd - (WORD32) (u2_rgt_ofst + u2_lft_ofst);
+
+ if((i4_cropped_ht < MB_SIZE) || (i4_cropped_wd < MB_SIZE))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_pic_wd != u2_pic_wd))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_disp_width != i4_cropped_wd))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_pic_ht != u2_pic_ht))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_disp_height != i4_cropped_ht))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ /* Check again for unsupported resolutions with updated values*/
+ if((u2_pic_wd > SVCD_MAX_FRAME_WIDTH) || (u2_pic_ht > SVCD_MAX_FRAME_HEIGHT) ||
+ (u2_pic_wd < SVCD_MIN_FRAME_WIDTH) || (u2_pic_ht < SVCD_MIN_FRAME_HEIGHT) ||
+ (u2_pic_wd * (UWORD32) u2_pic_ht > SVCD_MAX_FRAME_SIZE))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+
+ /* If MBAff is enabled, decoder support is limited to streams with
+ * width less than half of H264_MAX_FRAME_WIDTH.
+ * In case of MBAff decoder processes two rows at a time
+ */
+ if((u2_pic_wd << ps_seq->u1_mb_aff_flag) > H264_MAX_FRAME_WIDTH)
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ }
+
+ if(1 == ps_seq->u1_vui_parameters_present_flag)
+ {
+ ret = ih264d_parse_vui_parametres(&ps_seq->s_vui, ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ ps_seq_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+
+ isvcd_set_default_seq_svc_ext(ps_seq_svc_ext);
+
+ if(SCALABLE_BASELINE_PROFILE_IDC == ps_seq->u1_profile_idc ||
+ SCALABLE_HIGH_PROFILE_IDC == ps_seq->u1_profile_idc)
+ {
+ SWITCHONTRACE;
+ ps_seq_svc_ext->u1_inter_layer_deblocking_filter_control_present_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_inter_layer_deblocking_filter_control_present_flag",
+ ps_seq_svc_ext->u1_inter_layer_deblocking_filter_control_present_flag);
+
+ ps_seq_svc_ext->u1_extended_spatial_scalability_idc = ih264d_get_bits_h264(ps_bitstrm, 2);
+ COPYTHECONTEXT("SPS_EXt: u1_extended_spatial_scalability_idc",
+ ps_seq_svc_ext->u1_extended_spatial_scalability_idc);
+
+ /* u1_extended_spatial_scalability_idc value 0, 1 and 2 are supported */
+ if(ps_seq_svc_ext->u1_extended_spatial_scalability_idc > 2)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ /* ChromaArrayType = i4_chroma_format_idc if separate_colour_plane_flag =
+ * 0 for all chroma format except 4:4:4 */
+ if(1 == ps_seq->i4_chroma_format_idc || 2 == ps_seq->i4_chroma_format_idc)
+ {
+ ps_seq_svc_ext->u1_chroma_phase_x_plus1_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_chroma_phase_x_plus1_flag",
+ ps_seq_svc_ext->u1_chroma_phase_x_plus1_flag);
+ }
+
+ if(1 == ps_seq->i4_chroma_format_idc)
+ {
+ ps_seq_svc_ext->u1_chroma_phase_y_plus1 = ih264d_get_bits_h264(ps_bitstrm, 2);
+ COPYTHECONTEXT("SPS_EXt: u1_chroma_phase_y_plus1",
+ ps_seq_svc_ext->u1_chroma_phase_y_plus1);
+
+ if(ps_seq_svc_ext->u1_chroma_phase_y_plus1 >= 3)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+ }
+
+ /* inferred values not covered in isvcd_set_default_seq_svc_ext*/
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_x_plus1_flag =
+ ps_seq_svc_ext->u1_chroma_phase_x_plus1_flag;
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1 =
+ ps_seq_svc_ext->u1_chroma_phase_y_plus1;
+
+ if(1 == ps_seq_svc_ext->u1_extended_spatial_scalability_idc)
+ {
+ if(ps_seq->i4_chroma_format_idc > 0)
+ {
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_x_plus1_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_seq_ref_layer_chroma_phase_x_plus1_flag",
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_x_plus1_flag);
+
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1 =
+ ih264d_get_bits_h264(ps_bitstrm, 2);
+ COPYTHECONTEXT("SPS_EXt: u1_seq_ref_layer_chroma_phase_y_plus1",
+ ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1);
+
+ if(ps_seq_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1 >= 3)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+ }
+
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS_EXt: i4_seq_scaled_ref_layer_left_offset",
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset);
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset != 0)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS_EXt: i4_seq_scaled_ref_layer_top_offset",
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset);
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset != 0)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_right_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS_EXt: i4_seq_scaled_ref_layer_right_offset",
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_right_offset);
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_right_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_right_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_SVC_INV_SUBSET_SPS;
+ }
+
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_bottom_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS_EXt: i4_seq_scaled_ref_layer_bottom_offset",
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_bottom_offset);
+
+ if(ps_seq_svc_ext->i4_seq_scaled_ref_layer_bottom_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_seq_svc_ext->i4_seq_scaled_ref_layer_bottom_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+
+ ps_seq_svc_ext->u1_seq_tcoeff_level_prediction_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_seq_tcoeff_level_prediction_flag",
+ ps_seq_svc_ext->u1_seq_tcoeff_level_prediction_flag);
+
+ if(1 == ps_seq_svc_ext->u1_seq_tcoeff_level_prediction_flag)
+ {
+ ps_seq_svc_ext->u1_adaptive_tcoeff_level_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_adaptive_tcoeff_level_prediction_flag",
+ ps_seq_svc_ext->u1_adaptive_tcoeff_level_prediction_flag);
+ }
+
+ ps_seq_svc_ext->u1_slice_header_restriction_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_slice_header_restriction_flag",
+ ps_seq_svc_ext->u1_slice_header_restriction_flag);
+
+ ps_seq_svc_ext->u1_svc_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS_EXt: u1_svc_vui_parameters_present_flag",
+ ps_seq_svc_ext->u1_svc_vui_parameters_present_flag);
+
+ if(1 == ps_seq_svc_ext->u1_svc_vui_parameters_present_flag)
+ {
+ if(NULL ==
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].s_sps_svc_ext.ps_svc_vui_ext)
+ {
+ void *pv_buf;
+ UWORD32 size;
+ /* Memory allocation only if VUI is enabled in a particular subset SPS*/
+ size = sizeof(svc_vui_ext_t);
+ pv_buf = ps_dec->pf_aligned_alloc(ps_dec->pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_seq_svc_ext->ps_svc_vui_ext = pv_buf;
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id]
+ .s_sps_svc_ext.ps_svc_vui_ext = pv_buf;
+ }
+ else
+ {
+ ps_seq_svc_ext->ps_svc_vui_ext =
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id]
+ .s_sps_svc_ext.ps_svc_vui_ext;
+ }
+ ret = isvcd_parse_vui_ext_parametres(ps_seq_svc_ext->ps_svc_vui_ext, ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ }
+ /* Add conditions for SCALABLE BASELINE PROFILE */
+ if(SCALABLE_BASELINE_PROFILE_IDC == ps_seq->u1_profile_idc ||
+ ((SCALABLE_HIGH_PROFILE_IDC == ps_seq->u1_profile_idc) && (1 == uc_constraint_set0_flag)))
+ {
+ if(ps_seq->i4_chroma_format_idc != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ if(ps_seq->i4_bit_depth_luma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ if(ps_seq->i4_bit_depth_chroma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ if(ps_seq->i4_qpprime_y_zero_transform_bypass_flag != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ if(ps_seq->u1_frame_mbs_only_flag != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ if((0 != ps_seq_svc_ext->i4_seq_scaled_ref_layer_left_offset % 16) &&
+ (0 != ps_seq_svc_ext->i4_seq_scaled_ref_layer_top_offset % 16))
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+ }
+ /* Compare older num_reorder_frames with the new one if header is already
+ * decoded */
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_vui_parameters_present_flag) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].s_vui.u1_bitstream_restriction_flag))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ /* In case bitstream read has exceeded the filled size, then return an error */
+ if(EXCEED_OFFSET(ps_bitstrm))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* All initializations to ps_dec are beyond this point */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD32 reorder_depth = ih264d_get_dpb_size(ps_seq);
+ if((1 == ps_seq->u1_vui_parameters_present_flag) &&
+ (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+ {
+ reorder_depth = ps_seq->s_vui.u4_num_reorder_frames + 1;
+ }
+
+ if(reorder_depth > H264_MAX_REF_PICS)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if(ps_seq->u1_frame_mbs_only_flag != 1) reorder_depth *= 2;
+ ps_subset_seq->i4_reorder_depth = reorder_depth + DISPLAY_LATENCY;
+ }
+ ps_subset_seq->u2_disp_height = i4_cropped_ht;
+ ps_subset_seq->u2_disp_width = i4_cropped_wd;
+ ps_subset_seq->u2_pic_wd = u2_pic_wd;
+ ps_subset_seq->u2_pic_ht = u2_pic_ht;
+
+ /* Assuming 8k is the maximum resolution svc dec supports*/
+ if(u2_frm_wd_y > H264_MAX_FRAME_WIDTH) return (NOT_OK);
+ if(u2_frm_ht_y > H264_MAX_FRAME_HEIGHT) return (NOT_OK);
+ if(u2_frm_wd_uv > H264_MAX_FRAME_WIDTH) return (NOT_OK);
+ if(u2_frm_ht_uv > H264_MAX_FRAME_HEIGHT) return (NOT_OK);
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_subset_seq->u2_frm_wd_y = u2_frm_wd_y;
+ ps_subset_seq->u2_frm_ht_y = u2_frm_ht_y;
+ ps_subset_seq->u2_frm_wd_uv = u2_frm_wd_uv;
+ ps_subset_seq->u2_frm_ht_uv = u2_frm_ht_uv;
+
+ ps_subset_seq->u1_pad_len_y_v = (UWORD8) (PAD_LEN_Y_V << (1 - u1_frm));
+ ps_subset_seq->u1_pad_len_cr_v = (UWORD8) (PAD_LEN_UV_V << (1 - u1_frm));
+
+ ps_subset_seq->u2_crop_offset_y = u2_crop_offset_y;
+ ps_subset_seq->u2_crop_offset_uv = u2_crop_offset_uv;
+
+ if(((ps_dec->u2_pic_wd * ps_dec->u2_pic_ht) <
+ (ps_subset_seq->u2_pic_wd * ps_subset_seq->u2_pic_ht)) ||
+ (ps_dec->i4_reorder_depth < ps_subset_seq->i4_reorder_depth))
+ {
+ ps_dec->i4_reorder_depth = ps_subset_seq->i4_reorder_depth;
+
+ ps_dec->u2_disp_height = ps_subset_seq->u2_disp_height;
+ ps_dec->u2_disp_width = ps_subset_seq->u2_disp_width;
+
+ ps_dec->u2_pic_wd = ps_subset_seq->u2_pic_wd;
+ ps_dec->u2_pic_ht = ps_subset_seq->u2_pic_ht;
+ ps_dec->u4_total_mbs = ps_seq->u2_total_num_of_mbs << (1 - ps_seq->u1_frame_mbs_only_flag);
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_dec->u2_frm_wd_y = ps_subset_seq->u2_frm_wd_y;
+ ps_dec->u2_frm_ht_y = ps_subset_seq->u2_frm_ht_y;
+ ps_dec->u2_frm_wd_uv = ps_subset_seq->u2_frm_wd_uv;
+ ps_dec->u2_frm_ht_uv = ps_subset_seq->u2_frm_ht_uv;
+
+ ps_dec->s_pad_mgr.u1_pad_len_y_v = ps_subset_seq->u1_pad_len_y_v;
+ ps_dec->s_pad_mgr.u1_pad_len_cr_v = ps_subset_seq->u1_pad_len_cr_v;
+
+ ps_dec->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ ps_dec->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
+
+ ps_dec->u2_crop_offset_y = ps_subset_seq->u2_crop_offset_y;
+ ps_dec->u2_crop_offset_uv = ps_subset_seq->u2_crop_offset_uv;
+ }
+
+ ps_seq->u1_is_valid = TRUE;
+ ps_dec->ps_sps[u1_seq_parameter_set_id] = *ps_seq;
+ if(NULL != ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].s_sps_svc_ext.ps_svc_vui_ext)
+ {
+ ps_seq_svc_ext->ps_svc_vui_ext =
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].s_sps_svc_ext.ps_svc_vui_ext;
+ }
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id] = *ps_subset_seq;
+ ps_dec->ps_cur_sps = &ps_dec->ps_sps[u1_seq_parameter_set_id];
+ ps_svc_lyr_dec->ps_cur_subset_sps = &ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id];
+
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_dec_ref_base_pic_marking \endif
+ *
+ * \brief
+ * Decodes reference base pic marking params
+ *
+ * \return
+ * 0 on Success and error code otherwise
+ **************************************************************************
+ */
+
+WORD32 isvcd_dec_ref_base_pic_marking(
+ dec_ref_base_pic_marking_params_t *ps_ref_base_pic_marking_svc_ext,
+ dec_bit_stream_t *ps_bitstrm)
+{
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+
+ SWITCHONTRACE;
+
+ ps_ref_base_pic_marking_svc_ext->u1_adaptive_ref_base_pic_marking_mode_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT(
+ "Dec ref base pic marking params : "
+ "u1_adaptive_ref_base_pic_marking_mode_flag",
+ ps_ref_base_pic_marking_svc_ext->u1_adaptive_ref_base_pic_marking_mode_flag);
+
+ if(1 == ps_ref_base_pic_marking_svc_ext->u1_adaptive_ref_base_pic_marking_mode_flag)
+ {
+ do
+ {
+ ps_ref_base_pic_marking_svc_ext->u4_memory_management_base_control_operation =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT(
+ "Dec ref base pic marking params : "
+ "u4_memory_management_base_control_operation",
+ ps_ref_base_pic_marking_svc_ext->u4_memory_management_base_control_operation);
+
+ if(1 == ps_ref_base_pic_marking_svc_ext->u4_memory_management_base_control_operation)
+ {
+ ps_ref_base_pic_marking_svc_ext->u4_difference_of_base_pic_nums_minus1 =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT(
+ "Dec ref base pic marking params : "
+ "u4_difference_of_base_pic_nums_minus1",
+ ps_ref_base_pic_marking_svc_ext->u4_difference_of_base_pic_nums_minus1);
+ }
+
+ if(2 == ps_ref_base_pic_marking_svc_ext->u4_memory_management_base_control_operation)
+ {
+ ps_ref_base_pic_marking_svc_ext->u4_long_term_base_pic_num =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Dec ref base pic marking params : u4_long_term_base_pic_num",
+ ps_ref_base_pic_marking_svc_ext->u4_long_term_base_pic_num);
+ }
+
+ } while(0 != ps_ref_base_pic_marking_svc_ext->u4_memory_management_base_control_operation);
+ }
+ SWITCHOFFTRACE;
+
+ return OK;
+}
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_parse_nal_unit \endif
+ *
+ * \brief
+ * Decodes NAL unit
+ *
+ * \return
+ * 0 on Success and error code otherwise
+ **************************************************************************
+ */
+
+WORD32 isvcd_parse_nal_unit(svc_dec_lyr_struct_t *dec_svc_hdl, UWORD8 u1_nal_ref_idc)
+{
+ dec_bit_stream_t *ps_bitstrm;
+
+ dec_struct_t *ps_dec;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec;
+ UWORD8 u1_nal_unit_type;
+ WORD32 i_status = OK;
+
+ ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) dec_svc_hdl;
+ ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ {
+ SWITCHOFFTRACE;
+ u1_nal_unit_type = ps_dec->u1_nal_unit_type;
+
+ ps_bitstrm = ps_dec->ps_bitstrm;
+
+ // Skip all NALUs if SPS and PPS are not decoded
+ switch(u1_nal_unit_type)
+ {
+ case SLICE_DATA_PARTITION_A_NAL:
+ case SLICE_DATA_PARTITION_B_NAL:
+ case SLICE_DATA_PARTITION_C_NAL:
+ if(!ps_dec->i4_decode_header) ih264d_parse_slice_partition(ps_dec, ps_bitstrm);
+ break;
+
+ case IDR_SLICE_NAL:
+ case SLICE_NAL:
+
+ if(ps_svc_lyr_dec->u1_base_res_flag != 1)
+ {
+ return NOT_OK;
+ }
+ if(!ps_dec->i4_decode_header)
+ {
+ if(ps_dec->i4_header_decoded == 3)
+ {
+ /* ! */
+ DEBUG_THREADS_PRINTF("Decoding a slice NAL\n");
+ {
+ ih264d_get_pre_sei_params(ps_dec, u1_nal_unit_type);
+ /* ! */
+ ps_dec->u4_slice_start_code_found = 1;
+
+ i_status = isvcd_parse_decode_slice(
+ (UWORD8) (u1_nal_unit_type == IDR_SLICE_NAL), u1_nal_ref_idc,
+ ps_svc_lyr_dec);
+
+ if(i_status != OK)
+ {
+ return i_status;
+ }
+ }
+ }
+ }
+ break;
+
+ case SEI_NAL:
+ case PREFIX_UNIT_NAL:
+ case SEQ_PARAM_NAL:
+ case PIC_PARAM_NAL:
+ case SUBSET_SPS_NAL:
+ H264_DEC_DEBUG_PRINT("\nUnknown NAL type %d\n", u1_nal_unit_type);
+ break;
+
+ case ACCESS_UNIT_DELIMITER_RBSP:
+ if(!ps_dec->i4_decode_header)
+ {
+ ih264d_access_unit_delimiter_rbsp(ps_dec);
+ }
+ break;
+ // ignore the END_OF_SEQ_RBSP NAL and decode even after this NAL
+ case END_OF_STREAM_RBSP:
+ if(!ps_dec->i4_decode_header)
+ {
+ ih264d_parse_end_of_stream(ps_dec);
+ }
+ break;
+ case FILLER_DATA_NAL:
+ if(!ps_dec->i4_decode_header)
+ {
+ ih264d_parse_filler_data(ps_dec, ps_bitstrm);
+ }
+ break;
+ case CODED_SLICE_EXTENSION_NAL:
+
+ if(ps_svc_lyr_dec->u1_base_res_flag == 1)
+ {
+ return NOT_OK;
+ }
+ if(!ps_dec->i4_decode_header)
+ {
+ if(ps_dec->i4_header_decoded == 3)
+ {
+ /* ! */
+ DEBUG_THREADS_PRINTF("Decoding an SVC slice NAL\n");
+ {
+ {
+ ih264d_get_pre_sei_params(ps_dec, u1_nal_unit_type);
+ /* ! */
+ ps_dec->u4_slice_start_code_found = 1;
+
+ i_status = isvcd_parse_decode_slice_ext_nal(
+ (UWORD8) (ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag),
+ u1_nal_ref_idc, ps_svc_lyr_dec);
+
+ if(i_status != OK)
+ {
+ return i_status;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ H264_DEC_DEBUG_PRINT("\nUnknown NAL type %d\n", u1_nal_unit_type);
+ break;
+ }
+ }
+ return i_status;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_sps \endif
+*
+* \brief
+* Decodes Picture Parameter set
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_sps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 i;
+ dec_seq_params_t *ps_seq = NULL;
+ dec_svc_seq_params_t *ps_subset_seq = NULL;
+ UWORD8 u1_profile_idc, u1_level_idc, u1_seq_parameter_set_id, u1_mb_aff_flag = 0;
+ UWORD16 i2_max_frm_num;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_flag, uc_constraint_set2_flag;
+ WORD32 i4_cropped_ht, i4_cropped_wd;
+ UWORD32 u4_temp;
+ UWORD64 u8_temp;
+ UWORD32 u4_pic_height_in_map_units, u4_pic_width_in_mbs;
+ UWORD32 u2_pic_wd = 0;
+ UWORD32 u2_pic_ht = 0;
+ UWORD32 u2_frm_wd_y = 0;
+ UWORD32 u2_frm_ht_y = 0;
+ UWORD32 u2_frm_wd_uv = 0;
+ UWORD32 u2_frm_ht_uv = 0;
+ UWORD32 u2_crop_offset_y = 0;
+ UWORD32 u2_crop_offset_uv = 0;
+ WORD32 ret;
+ WORD32 num_reorder_frames;
+ /* High profile related syntax element */
+ WORD32 i4_i;
+ /* G050 */
+ UWORD8 u1_frame_cropping_flag,
+ u1_frame_cropping_rect_left_ofst = 0, u1_frame_cropping_rect_right_ofst = 0,
+ u1_frame_cropping_rect_top_ofst = 0, u1_frame_cropping_rect_bottom_ofst = 0;
+ /* G050 */
+ /*--------------------------------------------------------------------*/
+ /* Decode seq_parameter_set_id and profile and level values */
+ /*--------------------------------------------------------------------*/
+ SWITCHONTRACE;
+ u1_profile_idc = ih264d_get_bits_h264(ps_bitstrm, 8);
+ COPYTHECONTEXT("SPS: profile_idc", u1_profile_idc);
+
+ /* G050 */
+ uc_constraint_set0_flag = ih264d_get_bit_h264(ps_bitstrm);
+ uc_constraint_set1_flag = ih264d_get_bit_h264(ps_bitstrm);
+ uc_constraint_set2_flag = ih264d_get_bit_h264(ps_bitstrm);
+ UNUSED(uc_constraint_set2_flag);
+ /*****************************************************/
+ /* Read 5 bits for uc_constraint_set3_flag (1 bit) */
+ /* and reserved_zero_4bits (4 bits) - Sushant */
+ /*****************************************************/
+ ih264d_get_bits_h264(ps_bitstrm, 5);
+ /* G050 */
+ /* Check whether particular profile is suported or not */
+ /* Check whether particular profile is suported or not */
+ if((u1_profile_idc != MAIN_PROFILE_IDC) && (u1_profile_idc != BASE_PROFILE_IDC) &&
+ (u1_profile_idc != HIGH_PROFILE_IDC))
+ {
+ /* Apart from Baseline, main and high profile,
+ * only extended profile is supported provided
+ * uc_constraint_set0_flag or uc_constraint_set1_flag are set to 1
+ */
+ if((u1_profile_idc != EXTENDED_PROFILE_IDC) ||
+ ((uc_constraint_set1_flag != 1) && (uc_constraint_set0_flag != 1)))
+ {
+ return (ERROR_FEATURE_UNAVAIL);
+ }
+ }
+
+ u1_level_idc = ih264d_get_bits_h264(ps_bitstrm, 8);
+ COPYTHECONTEXT("SPS: u4_level_idc", u1_level_idc);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_SEQ_SET_ID) return ERROR_INV_SPS_PPS_T;
+ u1_seq_parameter_set_id = u4_temp;
+ COPYTHECONTEXT("SPS: seq_parameter_set_id", u1_seq_parameter_set_id);
+
+ /*--------------------------------------------------------------------*/
+ /* Find an seq param entry in seqparam array of decStruct */
+ /*--------------------------------------------------------------------*/
+ ps_subset_seq = ps_svc_lyr_dec->pv_scratch_subset_sps;
+ memset(ps_subset_seq, 0, sizeof(dec_svc_seq_params_t));
+ ps_seq = ps_dec->pv_scratch_sps_pps;
+ memset(ps_seq, 0, sizeof(dec_seq_params_t));
+
+ if(ps_dec->i4_header_decoded & 1)
+ {
+ if(ps_dec->ps_cur_sps != NULL)
+ *ps_seq = *ps_dec->ps_cur_sps;
+ else
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_profile_idc != u1_profile_idc))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_level_idc != u1_level_idc))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ ps_seq->u1_profile_idc = u1_profile_idc;
+ ps_seq->u1_level_idc = u1_level_idc;
+ ps_seq->u1_seq_parameter_set_id = u1_seq_parameter_set_id;
+ ps_subset_seq->ps_seq = &ps_dec->ps_sps[u1_seq_parameter_set_id];
+
+ /*******************************************************************/
+ /* Initializations for high profile - Sushant */
+ /*******************************************************************/
+ ps_seq->i4_chroma_format_idc = 1;
+ ps_seq->i4_bit_depth_luma_minus8 = 0;
+ ps_seq->i4_bit_depth_chroma_minus8 = 0;
+ ps_seq->i4_qpprime_y_zero_transform_bypass_flag = 0;
+ ps_seq->i4_seq_scaling_matrix_present_flag = 0;
+ if(u1_profile_idc == HIGH_PROFILE_IDC || u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC ||
+ u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC)
+ {
+ /* reading chroma_format_idc */
+ ps_seq->i4_chroma_format_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ /* Monochrome is not supported */
+ if(ps_seq->i4_chroma_format_idc != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading bit_depth_luma_minus8 */
+ ps_seq->i4_bit_depth_luma_minus8 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_seq->i4_bit_depth_luma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading bit_depth_chroma_minus8 */
+ ps_seq->i4_bit_depth_chroma_minus8 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(ps_seq->i4_bit_depth_chroma_minus8 != 0)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+
+ /* reading qpprime_y_zero_transform_bypass_flag */
+ ps_seq->i4_qpprime_y_zero_transform_bypass_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_seq->i4_qpprime_y_zero_transform_bypass_flag != 0)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ /* reading seq_scaling_matrix_present_flag */
+ ps_seq->i4_seq_scaling_matrix_present_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_seq->i4_seq_scaling_matrix_present_flag)
+ {
+ for(i4_i = 0; i4_i < 8; i4_i++)
+ {
+ ps_seq->u1_seq_scaling_list_present_flag[i4_i] = ih264d_get_bit_h264(ps_bitstrm);
+
+ /* initialize u1_use_default_scaling_matrix_flag[i4_i] to zero */
+ /* before calling scaling list */
+ ps_seq->u1_use_default_scaling_matrix_flag[i4_i] = 0;
+
+ if(ps_seq->u1_seq_scaling_list_present_flag[i4_i])
+ {
+ if(i4_i < 6)
+ {
+ ret = ih264d_scaling_list(ps_seq->i2_scalinglist4x4[i4_i], 16,
+ &ps_seq->u1_use_default_scaling_matrix_flag[i4_i],
+ ps_bitstrm);
+ }
+ else
+ {
+ ret = ih264d_scaling_list(ps_seq->i2_scalinglist8x8[i4_i - 6], 64,
+ &ps_seq->u1_use_default_scaling_matrix_flag[i4_i],
+ ps_bitstrm);
+ }
+ if(ret != OK)
+ {
+ return ret;
+ }
+ }
+ }
+ }
+ }
+ /*--------------------------------------------------------------------*/
+ /* Decode MaxFrameNum */
+ /*--------------------------------------------------------------------*/
+ u8_temp = (UWORD64) 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_FRAME_NUM)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ ps_seq->u1_bits_in_frm_num = (UWORD8) u8_temp;
+ COPYTHECONTEXT("SPS: log2_max_frame_num_minus4", (ps_seq->u1_bits_in_frm_num - 4));
+
+ i2_max_frm_num = (1 << (ps_seq->u1_bits_in_frm_num));
+ ps_seq->u2_u4_max_pic_num_minus1 = i2_max_frm_num - 1;
+ /*--------------------------------------------------------------------*/
+ /* Decode picture order count and related values */
+ /*--------------------------------------------------------------------*/
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_PIC_ORDER_CNT_TYPE)
+ {
+ return ERROR_INV_POC_TYPE_T;
+ }
+ ps_seq->u1_pic_order_cnt_type = u4_temp;
+ COPYTHECONTEXT("SPS: pic_order_cnt_type", ps_seq->u1_pic_order_cnt_type);
+
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1;
+ if(ps_seq->u1_pic_order_cnt_type == 0)
+ {
+ u8_temp = (UWORD64) 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_POC_LSB)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = (UWORD8) u8_temp;
+ ps_seq->i4_max_pic_order_cntLsb = (1 << u8_temp);
+ COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4", (u8_temp - 4));
+ }
+ else if(ps_seq->u1_pic_order_cnt_type == 1)
+ {
+ ps_seq->u1_delta_pic_order_always_zero_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: delta_pic_order_always_zero_flag",
+ ps_seq->u1_delta_pic_order_always_zero_flag);
+
+ ps_seq->i4_ofst_for_non_ref_pic = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_non_ref_pic", ps_seq->i4_ofst_for_non_ref_pic);
+
+ ps_seq->i4_ofst_for_top_to_bottom_field = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_top_to_bottom_field",
+ ps_seq->i4_ofst_for_top_to_bottom_field);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > 255) return ERROR_INV_SPS_PPS_T;
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = u4_temp;
+ COPYTHECONTEXT("SPS: num_ref_frames_in_pic_order_cnt_cycle",
+ ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
+
+ for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ ps_seq->i4_ofst_for_ref_frame[i] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: offset_for_ref_frame", ps_seq->i4_ofst_for_ref_frame[i]);
+ }
+ }
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((u4_temp > H264_MAX_REF_PICS))
+ {
+ return ERROR_NUM_REF;
+ }
+
+ /* Compare with older num_ref_frames is header is already once */
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_num_ref_frames != u4_temp))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ ps_seq->u1_num_ref_frames = u4_temp;
+ COPYTHECONTEXT("SPS: num_ref_frames", ps_seq->u1_num_ref_frames);
+
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: gaps_in_frame_num_value_allowed_flag",
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag);
+
+ ps_seq->u1_gaps_in_frame_num_value_allowed_flag = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Decode FrameWidth and FrameHeight and related values */
+ /*--------------------------------------------------------------------*/
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ /* Check for unsupported resolutions*/
+ if(u8_temp > (H264_MAX_FRAME_WIDTH >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ u4_pic_width_in_mbs = (UWORD32) u8_temp;
+ COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1", u4_pic_width_in_mbs - 1);
+
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > (H264_MAX_FRAME_HEIGHT >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ u4_pic_height_in_map_units = (UWORD32) u8_temp;
+
+ ps_seq->u2_frm_wd_in_mbs = u4_pic_width_in_mbs;
+ ps_seq->u2_frm_ht_in_mbs = u4_pic_height_in_map_units;
+ u2_pic_wd = (u4_pic_width_in_mbs << 4);
+ u2_pic_ht = (u4_pic_height_in_map_units << 4);
+ /*--------------------------------------------------------------------*/
+ /* Get the value of MaxMbAddress and Number of bits needed for it */
+ /*--------------------------------------------------------------------*/
+ ps_seq->u2_max_mb_addr = (ps_seq->u2_frm_wd_in_mbs * ps_seq->u2_frm_ht_in_mbs) - 1;
+ ps_seq->u2_total_num_of_mbs = ps_seq->u2_max_mb_addr + 1;
+ ps_seq->u1_level_idc = ih264d_correct_level_idc(u1_level_idc, ps_seq->u2_total_num_of_mbs);
+
+ u1_frm = ih264d_get_bit_h264(ps_bitstrm);
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_frame_mbs_only_flag != u1_frm))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ ps_seq->u1_frame_mbs_only_flag = u1_frm;
+ COPYTHECONTEXT("SPS: frame_mbs_only_flag", u1_frm);
+
+ if(!u1_frm) u1_mb_aff_flag = ih264d_get_bit_h264(ps_bitstrm);
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_dec->ps_sps[u1_seq_parameter_set_id].u1_mb_aff_flag != u1_mb_aff_flag))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if(!u1_frm)
+ {
+ u2_pic_ht <<= 1;
+ ps_seq->u1_mb_aff_flag = u1_mb_aff_flag;
+ COPYTHECONTEXT("SPS: mb_adaptive_frame_field_flag", ps_seq->u1_mb_aff_flag);
+ }
+ else
+ ps_seq->u1_mb_aff_flag = 0;
+
+ ps_seq->u1_direct_8x8_inference_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: direct_8x8_inference_flag", ps_seq->u1_direct_8x8_inference_flag);
+
+ /* G050 */
+ u1_frame_cropping_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: frame_cropping_flag", u1_frame_cropping_flag);
+
+ if(u1_frame_cropping_flag)
+ {
+ u1_frame_cropping_rect_left_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_left_offset", u1_frame_cropping_rect_left_ofst);
+ u1_frame_cropping_rect_right_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_right_offset", u1_frame_cropping_rect_right_ofst);
+ u1_frame_cropping_rect_top_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_top_offset", u1_frame_cropping_rect_top_ofst);
+ u1_frame_cropping_rect_bottom_ofst = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SPS: frame_cropping_rect_bottom_offset",
+ u1_frame_cropping_rect_bottom_ofst);
+ }
+ /* G050 */
+ ps_seq->u1_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SPS: vui_parameters_present_flag", ps_seq->u1_vui_parameters_present_flag);
+
+ u2_frm_wd_y = u2_pic_wd + (UWORD8) (PAD_LEN_Y_H << 1);
+
+ if(1 == ps_dec->u4_share_disp_buf)
+ {
+ if(ps_dec->u4_app_disp_width > u2_frm_wd_y) u2_frm_wd_y = ps_dec->u4_app_disp_width;
+ }
+
+ u2_frm_ht_y = u2_pic_ht + (UWORD8) (PAD_LEN_Y_V << 2);
+ u2_frm_wd_uv = u2_pic_wd + (UWORD8) (PAD_LEN_UV_H << 2);
+ u2_frm_wd_uv = MAX(u2_frm_wd_uv, u2_frm_wd_y);
+ u2_frm_ht_uv = (u2_pic_ht >> 1) + (UWORD8) (PAD_LEN_UV_V << 2);
+ u2_frm_ht_uv = MAX(u2_frm_ht_uv, (u2_frm_ht_y >> 1));
+
+ /* Calculate display picture width, height and start u4_ofst from YUV420 */
+ /* pictute buffers as per cropping information parsed above */
+ {
+ UWORD16 u2_rgt_ofst = 0;
+ UWORD16 u2_lft_ofst = 0;
+ UWORD16 u2_top_ofst = 0;
+ UWORD16 u2_btm_ofst = 0;
+ UWORD8 u1_frm_mbs_flag;
+ UWORD8 u1_vert_mult_factor;
+
+ if(u1_frame_cropping_flag)
+ {
+ /* Calculate right and left u4_ofst for cropped picture */
+ u2_rgt_ofst = u1_frame_cropping_rect_right_ofst << 1;
+ u2_lft_ofst = u1_frame_cropping_rect_left_ofst << 1;
+
+ /* Know frame MBs only u4_flag */
+ u1_frm_mbs_flag = (1 == ps_seq->u1_frame_mbs_only_flag);
+
+ /* Simplify the vertical u4_ofst calculation from field/frame */
+ u1_vert_mult_factor = (2 - u1_frm_mbs_flag);
+
+ /* Calculate bottom and top u4_ofst for cropped picture */
+ u2_btm_ofst = (u1_frame_cropping_rect_bottom_ofst << u1_vert_mult_factor);
+ u2_top_ofst = (u1_frame_cropping_rect_top_ofst << u1_vert_mult_factor);
+ }
+
+ /* Calculate u4_ofst from start of YUV 420 picture buffer to start of*/
+ /* cropped picture buffer */
+ u2_crop_offset_y = (u2_frm_wd_y * u2_top_ofst) + (u2_lft_ofst);
+ u2_crop_offset_uv =
+ (u2_frm_wd_uv * (u2_top_ofst >> 1)) + (u2_lft_ofst >> 1) * YUV420SP_FACTOR;
+ /* Calculate the display picture width and height based on crop */
+ /* information */
+ i4_cropped_ht = (WORD32) u2_pic_ht - (WORD32) (u2_btm_ofst + u2_top_ofst);
+ i4_cropped_wd = (WORD32) u2_pic_wd - (WORD32) (u2_rgt_ofst + u2_lft_ofst);
+
+ if((i4_cropped_ht < MB_SIZE) || (i4_cropped_wd < MB_SIZE))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_pic_wd != u2_pic_wd))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_disp_width != i4_cropped_wd))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_pic_ht != u2_pic_ht))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) &&
+ (ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id].u2_disp_height != i4_cropped_ht))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+ /* Check again for unsupported resolutions with updated values*/
+ if((u2_pic_wd > SVCD_MAX_FRAME_WIDTH) || (u2_pic_ht > SVCD_MAX_FRAME_HEIGHT) ||
+ (u2_pic_wd < SVCD_MIN_FRAME_WIDTH) || (u2_pic_ht < SVCD_MIN_FRAME_HEIGHT) ||
+ (u2_pic_wd * (UWORD32) u2_pic_ht > SVCD_MAX_FRAME_SIZE))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+
+ /* If MBAff is enabled, decoder support is limited to streams with
+ * width less than half of H264_MAX_FRAME_WIDTH.
+ * In case of MBAff decoder processes two rows at a time
+ */
+ if((u2_pic_wd << ps_seq->u1_mb_aff_flag) > H264_MAX_FRAME_WIDTH)
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ }
+
+ /* Backup num_reorder_frames if header is already decoded */
+ if((ps_dec->i4_header_decoded & 1) && (1 == ps_seq->u1_vui_parameters_present_flag) &&
+ (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+ {
+ num_reorder_frames = (WORD32) ps_seq->s_vui.u4_num_reorder_frames;
+ }
+ else
+ {
+ num_reorder_frames = -1;
+ }
+ if(1 == ps_seq->u1_vui_parameters_present_flag)
+ {
+ ret = ih264d_parse_vui_parametres(&ps_seq->s_vui, ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+
+ /* Compare older num_reorder_frames with the new one if header is already
+ * decoded */
+ if((ps_dec->i4_header_decoded & 1) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_is_valid) && (-1 != num_reorder_frames) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].u1_vui_parameters_present_flag) &&
+ (1 == ps_dec->ps_sps[u1_seq_parameter_set_id].s_vui.u1_bitstream_restriction_flag) &&
+ ((WORD32) ps_dec->ps_sps[u1_seq_parameter_set_id].s_vui.u4_num_reorder_frames !=
+ num_reorder_frames))
+ {
+ ps_dec->u1_res_changed = 1;
+ return IVD_RES_CHANGED;
+ }
+
+ /* In case bitstream read has exceeded the filled size, then return an error */
+ if(EXCEED_OFFSET(ps_bitstrm))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* All initializations to ps_dec are beyond this point */
+ /*--------------------------------------------------------------------*/
+ {
+ WORD32 reorder_depth = ih264d_get_dpb_size(ps_seq);
+ if((1 == ps_seq->u1_vui_parameters_present_flag) &&
+ (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+ {
+ reorder_depth = ps_seq->s_vui.u4_num_reorder_frames + 1;
+ }
+
+ if(reorder_depth > H264_MAX_REF_PICS)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if(ps_seq->u1_frame_mbs_only_flag != 1) reorder_depth *= 2;
+ ps_subset_seq->i4_reorder_depth = reorder_depth + DISPLAY_LATENCY;
+ }
+ ps_subset_seq->u2_disp_height = i4_cropped_ht;
+ ps_subset_seq->u2_disp_width = i4_cropped_wd;
+ ps_subset_seq->u2_pic_wd = u2_pic_wd;
+ ps_subset_seq->u2_pic_ht = u2_pic_ht;
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_subset_seq->u2_frm_wd_y = u2_frm_wd_y;
+ ps_subset_seq->u2_frm_ht_y = u2_frm_ht_y;
+ ps_subset_seq->u2_frm_wd_uv = u2_frm_wd_uv;
+ ps_subset_seq->u2_frm_ht_uv = u2_frm_ht_uv;
+
+ ps_subset_seq->u1_pad_len_y_v = (UWORD8) (PAD_LEN_Y_V << (1 - u1_frm));
+ ps_subset_seq->u1_pad_len_cr_v = (UWORD8) (PAD_LEN_UV_V << (1 - u1_frm));
+
+ ps_subset_seq->u2_crop_offset_y = u2_crop_offset_y;
+ ps_subset_seq->u2_crop_offset_uv = u2_crop_offset_uv;
+
+ if(((ps_dec->u2_pic_wd * ps_dec->u2_pic_ht) <
+ (ps_subset_seq->u2_pic_wd * ps_subset_seq->u2_pic_ht)) ||
+ (ps_dec->i4_reorder_depth < ps_subset_seq->i4_reorder_depth))
+ {
+ ps_dec->i4_reorder_depth = ps_subset_seq->i4_reorder_depth;
+
+ ps_dec->u2_disp_height = ps_subset_seq->u2_disp_height;
+ ps_dec->u2_disp_width = ps_subset_seq->u2_disp_width;
+ ps_dec->u2_pic_wd = ps_subset_seq->u2_pic_wd;
+ ps_dec->u2_pic_ht = ps_subset_seq->u2_pic_ht;
+ ps_dec->u4_total_mbs = ps_seq->u2_total_num_of_mbs << (1 - ps_seq->u1_frame_mbs_only_flag);
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_dec->u2_frm_wd_y = ps_subset_seq->u2_frm_wd_y;
+ ps_dec->u2_frm_ht_y = ps_subset_seq->u2_frm_ht_y;
+ ps_dec->u2_frm_wd_uv = ps_subset_seq->u2_frm_wd_uv;
+ ps_dec->u2_frm_ht_uv = ps_subset_seq->u2_frm_ht_uv;
+
+ ps_dec->s_pad_mgr.u1_pad_len_y_v = ps_subset_seq->u1_pad_len_y_v;
+ ps_dec->s_pad_mgr.u1_pad_len_cr_v = ps_subset_seq->u1_pad_len_cr_v;
+
+ ps_dec->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ ps_dec->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
+ ps_dec->u2_crop_offset_y = ps_subset_seq->u2_crop_offset_y;
+ ps_dec->u2_crop_offset_uv = ps_subset_seq->u2_crop_offset_uv;
+ }
+
+ ps_seq->u1_is_valid = TRUE;
+ ps_dec->ps_sps[u1_seq_parameter_set_id] = *ps_seq;
+ ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id] = *ps_subset_seq;
+ ps_dec->ps_cur_sps = &ps_dec->ps_sps[u1_seq_parameter_set_id];
+ ps_svc_lyr_dec->ps_cur_subset_sps = &ps_svc_lyr_dec->ps_subset_sps[u1_seq_parameter_set_id];
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_pps \endif
+*
+* \brief
+* Decodes Picture Parameter set
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_pps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 uc_temp;
+ dec_seq_params_t *ps_sps = NULL;
+ dec_pic_params_t *ps_pps = NULL;
+ UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
+
+ /* Variables used for error resilience checks */
+ UWORD64 u8_temp;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+
+ /* For High profile related syntax elements */
+ UWORD8 u1_more_data_flag;
+ WORD32 i4_i;
+
+ /*--------------------------------------------------------------------*/
+ /* Decode pic_parameter_set_id and find corresponding pic params */
+ /*--------------------------------------------------------------------*/
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_PIC_SET_ID) return ERROR_INV_SPS_PPS_T;
+ ps_pps = ps_dec->pv_scratch_sps_pps;
+ *ps_pps = ps_dec->ps_pps[u4_temp];
+ ps_pps->u1_pic_parameter_set_id = (UWORD8) u4_temp;
+ COPYTHECONTEXT("PPS: pic_parameter_set_id", ps_pps->u1_pic_parameter_set_id);
+
+ /************************************************/
+ /* initilization of High profile syntax element */
+ /************************************************/
+ ps_pps->i4_transform_8x8_mode_flag = 0;
+ ps_pps->i4_pic_scaling_matrix_present_flag = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Decode seq_parameter_set_id and map it to a seq_parameter_set */
+ /*--------------------------------------------------------------------*/
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_SEQ_SET_ID) return ERROR_INV_SPS_PPS_T;
+ COPYTHECONTEXT("PPS: seq_parameter_set_id", u4_temp);
+ ps_sps = &ps_dec->ps_sps[u4_temp];
+ ps_pps->ps_sps = ps_sps;
+
+ /*--------------------------------------------------------------------*/
+ /* Decode entropy_coding_mode */
+ /*--------------------------------------------------------------------*/
+ ps_pps->u1_entropy_coding_mode = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: entropy_coding_mode_flag", ps_pps->u1_entropy_coding_mode);
+
+ ps_pps->u1_pic_order_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: pic_order_present_flag", ps_pps->u1_pic_order_present_flag);
+
+ /*--------------------------------------------------------------------*/
+ /* Decode num_slice_groups_minus1 */
+ /*--------------------------------------------------------------------*/
+ u8_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64) 1;
+ if(u8_temp != 1)
+ {
+ return ERROR_FEATURE_UNAVAIL;
+ }
+ ps_pps->u1_num_slice_groups = (UWORD8) u8_temp;
+ COPYTHECONTEXT("PPS: num_slice_groups_minus1", ps_pps->u1_num_slice_groups - 1);
+
+ /*--------------------------------------------------------------------*/
+ /* Other parameter set values */
+ /*--------------------------------------------------------------------*/
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp >= H264_MAX_REF_IDX) return ERROR_REF_IDX;
+ ps_pps->u1_num_ref_idx_lx_active[0] = (UWORD8) u8_temp;
+ COPYTHECONTEXT("PPS: num_ref_idx_l0_active_minus1", ps_pps->u1_num_ref_idx_lx_active[0] - 1);
+
+ u8_temp = (UWORD64) 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp >= H264_MAX_REF_IDX) return ERROR_REF_IDX;
+ ps_pps->u1_num_ref_idx_lx_active[1] = (UWORD8) u8_temp;
+ COPYTHECONTEXT("PPS: num_ref_idx_l1_active_minus1", ps_pps->u1_num_ref_idx_lx_active[1] - 1);
+
+ ps_pps->u1_wted_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: weighted prediction u4_flag", ps_pps->u1_wted_pred_flag);
+ uc_temp = (UWORD8) ih264d_get_bits_h264(ps_bitstrm, 2);
+ COPYTHECONTEXT("PPS: weighted_bipred_idc", uc_temp);
+ ps_pps->u1_wted_bipred_idc = uc_temp;
+
+ if(ps_pps->u1_wted_bipred_idc > MAX_WEIGHT_BIPRED_IDC) return ERROR_INV_SPS_PPS_T;
+
+ {
+ WORD64 i8_temp = (WORD64) 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T;
+
+ ps_pps->u1_pic_init_qp = (UWORD8) i8_temp;
+ COPYTHECONTEXT("PPS: pic_init_qp_minus26", ps_pps->u1_pic_init_qp - 26);
+
+ i8_temp = (WORD64) 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T;
+
+ ps_pps->u1_pic_init_qs = (UWORD8) i8_temp;
+ COPYTHECONTEXT("PPS: pic_init_qs_minus26", ps_pps->u1_pic_init_qs - 26);
+ }
+
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i_temp < -12) || (i_temp > 12)) return ERROR_INV_RANGE_QP_T;
+ ps_pps->i1_chroma_qp_index_offset = i_temp;
+ COPYTHECONTEXT("PPS: chroma_qp_index_offset", ps_pps->i1_chroma_qp_index_offset);
+
+ /***************************************************************************/
+ /* initialize second_chroma_qp_index_offset to i1_chroma_qp_index_offset if */
+ /* second_chroma_qp_index_offset is not present in bit-ps_bitstrm */
+ /***************************************************************************/
+ ps_pps->i1_second_chroma_qp_index_offset = ps_pps->i1_chroma_qp_index_offset;
+
+ ps_pps->u1_deblocking_filter_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: deblocking_filter_control_present_flag",
+ ps_pps->u1_deblocking_filter_parameters_present_flag);
+ ps_pps->u1_constrained_intra_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: constrained_intra_pred_flag", ps_pps->u1_constrained_intra_pred_flag);
+ ps_pps->u1_redundant_pic_cnt_present_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("PPS: redundant_pic_cnt_present_flag",
+ ps_pps->u1_redundant_pic_cnt_present_flag);
+
+ /* High profile related syntax elements */
+ u1_more_data_flag = MORE_RBSP_DATA(ps_bitstrm);
+
+ if(u1_more_data_flag)
+ {
+ /* read transform_8x8_mode_flag */
+ ps_pps->i4_transform_8x8_mode_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ /* read pic_scaling_matrix_present_flag */
+ ps_pps->i4_pic_scaling_matrix_present_flag = (WORD32) ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_pps->i4_pic_scaling_matrix_present_flag)
+ {
+ /* read the scaling matrices */
+ for(i4_i = 0; i4_i < (6 + (ps_pps->i4_transform_8x8_mode_flag << 1)); i4_i++)
+ {
+ ps_pps->u1_pic_scaling_list_present_flag[i4_i] = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(ps_pps->u1_pic_scaling_list_present_flag[i4_i])
+ {
+ WORD32 ret;
+ if(i4_i < 6)
+ {
+ ret = ih264d_scaling_list(
+ ps_pps->i2_pic_scalinglist4x4[i4_i], 16,
+ &ps_pps->u1_pic_use_default_scaling_matrix_flag[i4_i], ps_bitstrm);
+ }
+ else
+ {
+ ret = ih264d_scaling_list(
+ ps_pps->i2_pic_scalinglist8x8[i4_i - 6], 64,
+ &ps_pps->u1_pic_use_default_scaling_matrix_flag[i4_i], ps_bitstrm);
+ }
+
+ if(ret != OK)
+ {
+ return ret;
+ }
+ }
+ }
+ }
+
+ /* read second_chroma_qp_index_offset syntax element */
+ i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i_temp < -12) || (i_temp > 12)) return ERROR_INV_RANGE_QP_T;
+
+ ps_pps->i1_second_chroma_qp_index_offset = i_temp;
+ }
+
+ if(SCALABLE_BASELINE_PROFILE_IDC == ps_sps->u1_profile_idc)
+
+ {
+ if(ps_pps->u1_num_slice_groups > 7)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ }
+
+ /* In case bitstream read has exceeded the filled size, then return an error */
+ if(EXCEED_OFFSET(ps_bitstrm))
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ ps_pps->u1_is_valid = TRUE;
+ ps_dec->ps_pps[ps_pps->u1_pic_parameter_set_id] = *ps_pps;
+ return OK;
+}
diff --git a/decoder/svc/isvcd_parse_headers.h b/decoder/svc/isvcd_parse_headers.h
new file mode 100644
index 0000000..ceadc08
--- /dev/null
+++ b/decoder/svc/isvcd_parse_headers.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_headers.h
+ *
+ * @brief
+ * Contains declarations high level syntax[above slice] parsing routines
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PARSE_HEADERS_H_
+#define _ISVCD_PARSE_HEADERS_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "isvcd_structs.h"
+
+WORD32 isvcd_parse_subset_sps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm);
+
+WORD32 isvcd_parse_nal_unit(svc_dec_lyr_struct_t *dec_hdl, UWORD8 u1_nal_ref_idc);
+
+WORD32 isvcd_dec_ref_base_pic_marking(
+ dec_ref_base_pic_marking_params_t *ps_ref_base_pic_marking_svc_ext,
+ dec_bit_stream_t *ps_bitstrm);
+
+WORD32 isvcd_parse_pps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm);
+
+WORD32 isvcd_parse_sps(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_bit_stream_t *ps_bitstrm);
+
+#endif /*_ISVCD_PARSE_HEADERS_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_parse_slice.c b/decoder/svc/isvcd_parse_slice.c
new file mode 100644
index 0000000..f8270b6
--- /dev/null
+++ b/decoder/svc/isvcd_parse_slice.c
@@ -0,0 +1,2768 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_slice.c
+ *
+ * @brief
+ * Contains routines that decodes a slice NAL unit
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include <assert.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ithread.h"
+#include "isvcd_structs.h"
+#include "ih264d_debug.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_parse_mb_header.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_utils.h"
+#include "isvcd_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_defs.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_tables.h"
+#include "ih264d_defs.h"
+#include "ih264d_mem_request.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_defs.h"
+#include "ih264d_quant_scaling.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_sei.h"
+#include "ih264_error.h"
+#include "ih264_disp_mgr.h"
+#include "ih264_buf_mgr.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ih264d_thread_compute_bs.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_parse_islice.h"
+#include "isvcd_parse_slice.h"
+#include "isvcd_process_epslice.h"
+#include "isvcd_process_ebslice.h"
+#include "isvcd_thread_compute_bs.h"
+#include "isvcd_thread_parse_decode.h"
+#include "isvcd_deblocking.h"
+
+#define RET_LAST_SKIP 0x80000000
+
+WORD32 check_app_out_buf_size(dec_struct_t *ps_dec);
+/*!
+**************************************************************************
+* \if Function name : isvcd_verify_level \endif
+*
+* \brief
+* Initialize the Parameter required for all the slices for a picture
+*
+* \return : Nothing
+*
+**************************************************************************
+*/
+WORD32 isvcd_verify_level(UWORD8 u1_level_idc)
+{
+ switch(u1_level_idc)
+ {
+ case H264_LEVEL_1_0:
+ case H264_LEVEL_1_1:
+ case H264_LEVEL_1_2:
+ case H264_LEVEL_1_3:
+ case H264_LEVEL_2_0:
+ case H264_LEVEL_2_1:
+ case H264_LEVEL_2_2:
+ case H264_LEVEL_3_0:
+ case H264_LEVEL_3_1:
+ case H264_LEVEL_3_2:
+ case H264_LEVEL_4_0:
+ case H264_LEVEL_4_1:
+ case H264_LEVEL_4_2:
+ case H264_LEVEL_5_0:
+ case H264_LEVEL_5_1:
+ return OK;
+ default:
+ return NOT_OK;
+ }
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_start_of_pic \endif
+*
+* \brief
+* Initialize the Parameter required for all the slices for a picture
+*
+* \return : Nothing
+*
+**************************************************************************
+*/
+
+WORD32 isvcd_start_of_pic(svc_dec_lyr_struct_t *ps_svc_lyr_dec, WORD32 i4_poc,
+ pocstruct_t *ps_temp_poc, UWORD16 u2_frame_num, dec_pic_params_t *ps_pps)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ pocstruct_t *ps_prev_poc = &ps_dec->s_cur_pic_poc;
+ pocstruct_t *ps_cur_poc = ps_temp_poc;
+
+ dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
+ dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps;
+ UWORD8 u1_bottom_field_flag = ps_cur_slice->u1_bottom_field_flag;
+ UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
+ /* high profile related declarations */
+ WORD32 ret;
+
+ H264_MUTEX_LOCK(&ps_dec->process_disp_mutex);
+
+ if(u1_field_pic_flag == 1)
+ {
+ ps_dec->i4_error_code = ERROR_SVC_FIELD_PIC_UNSUPPORTED;
+ return ERROR_SVC_FIELD_PIC_UNSUPPORTED;
+ }
+
+ /* check output buffer size given by the application */
+ if(check_app_out_buf_size(ps_dec) != IV_SUCCESS) return IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0];
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1];
+ ps_prev_poc->u1_bot_field = ps_dec->ps_cur_slice->u1_bottom_field_flag;
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst;
+ ps_prev_poc->u2_frame_num = u2_frame_num;
+ ps_dec->i1_prev_mb_qp_delta = 0;
+ ps_dec->i1_next_ctxt_idx = 0;
+
+ ps_dec->u4_nmb_deblk = 0;
+ if(ps_dec->u4_num_cores == 1) ps_dec->u4_nmb_deblk = 1;
+
+ if(ps_seq->u1_mb_aff_flag == 1)
+ {
+ ps_dec->u4_nmb_deblk = 0;
+ if(ps_dec->u4_num_cores > 2) ps_dec->u4_num_cores = 2;
+ }
+
+ ps_dec->u4_use_intrapred_line_copy = 0;
+
+ if(ps_seq->u1_mb_aff_flag == 0)
+ {
+ ps_dec->u4_use_intrapred_line_copy = 1;
+ }
+
+ ps_dec->u4_app_disable_deblk_frm = 0;
+ /* If degrade is enabled, set the degrade flags appropriately */
+ if(ps_dec->i4_degrade_type && ps_dec->i4_degrade_pics)
+ {
+ WORD32 degrade_pic;
+ ps_dec->i4_degrade_pic_cnt++;
+ degrade_pic = 0;
+
+ /* If degrade is to be done in all frames, then do not check further */
+ switch(ps_dec->i4_degrade_pics)
+ {
+ case 4:
+ {
+ degrade_pic = 1;
+ break;
+ }
+ case 3:
+ {
+ if(ps_cur_slice->u1_slice_type != I_SLICE) degrade_pic = 1;
+
+ break;
+ }
+ case 2:
+ {
+ /* If pic count hits non-degrade interval or it is an islice, then do not
+ * degrade */
+ if((ps_cur_slice->u1_slice_type != I_SLICE) &&
+ (ps_dec->i4_degrade_pic_cnt != ps_dec->i4_nondegrade_interval))
+ degrade_pic = 1;
+
+ break;
+ }
+ case 1:
+ {
+ /* Check if the current picture is non-ref */
+ if(0 == ps_cur_slice->u1_nal_ref_idc)
+ {
+ degrade_pic = 1;
+ }
+ break;
+ }
+ }
+ if(degrade_pic)
+ {
+ if(ps_dec->i4_degrade_type & 0x2) ps_dec->u4_app_disable_deblk_frm = 1;
+
+ /* MC degrading is done only for non-ref pictures */
+ if(0 == ps_cur_slice->u1_nal_ref_idc)
+ {
+ if(ps_dec->i4_degrade_type & 0x4) ps_dec->i4_mv_frac_mask = 0;
+
+ if(ps_dec->i4_degrade_type & 0x8) ps_dec->i4_mv_frac_mask = 0;
+ }
+ }
+ else
+ ps_dec->i4_degrade_pic_cnt = 0;
+ }
+
+ {
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ if((ps_cur_slice->u1_slice_type == I_SLICE) || (ps_cur_slice->u1_slice_type == SI_SLICE))
+ ps_err->u1_cur_pic_type = PIC_TYPE_I;
+ else
+ ps_err->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
+
+ if(ps_err->u1_pic_aud_i == PIC_TYPE_I)
+ {
+ ps_err->u1_cur_pic_type = PIC_TYPE_I;
+ ps_err->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
+ }
+
+ if(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
+ {
+ if(ps_err->u1_err_flag) ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr);
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ }
+ }
+
+ if(ps_dec->u1_init_dec_flag && ps_dec->s_prev_seq_params.u1_eoseq_pending)
+ {
+ /* Reset the decoder picture buffers */
+ WORD32 j;
+ for(j = 0; j < MAX_DISP_BUFS_NEW; j++)
+ {
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, j, BUF_MGR_REF);
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_mv_buf_mgr,
+ ps_dec->as_buf_id_info_map[j].mv_buf_id, BUF_MGR_REF);
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, j, BUF_MGR_IO);
+ }
+
+ /* reset the decoder structure parameters related to buffer handling */
+ ps_dec->u1_second_field = 0;
+ ps_dec->i4_cur_display_seq = 0;
+
+ /********************************************************************/
+ /* indicate in the decoder output i4_status that some frames are being */
+ /* dropped, so that it resets timestamp and wait for a new sequence */
+ /********************************************************************/
+ ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
+ }
+ ret = isvcd_init_pic(ps_svc_lyr_dec, u2_frame_num, i4_poc, ps_pps);
+ if(ret != OK) return ret;
+
+ ps_dec->pv_parse_tu_coeff_data = ps_dec->pv_pic_tu_coeff_data;
+ ps_dec->pv_proc_tu_coeff_data = ps_dec->pv_pic_tu_coeff_data;
+ ps_dec->ps_nmb_info = ps_dec->ps_frm_mb_info;
+ ps_svc_lyr_dec->ps_svc_nmb_info = ps_svc_lyr_dec->ps_svc_frm_mb_info;
+ if(ps_dec->u1_separate_parse)
+ {
+ UWORD32 num_mbs;
+ num_mbs = ps_dec->ps_cur_sps->u2_total_num_of_mbs
+ << (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag);
+
+ if(ps_dec->pu1_dec_mb_map)
+ {
+ memset((void *) ps_dec->pu1_dec_mb_map, 0, num_mbs);
+ }
+
+ if(ps_dec->pu1_recon_mb_map)
+ {
+ memset((void *) ps_dec->pu1_recon_mb_map, 0, num_mbs);
+ }
+
+ if(ps_dec->pu2_slice_num_map)
+ {
+ memset((void *) ps_dec->pu2_slice_num_map, 0, (num_mbs * sizeof(UWORD16)));
+ }
+ }
+
+ ps_dec->ps_parse_cur_slice = &(ps_dec->ps_dec_slice_buf[0]);
+ ps_dec->ps_decode_cur_slice = &(ps_dec->ps_dec_slice_buf[0]);
+ ps_dec->ps_computebs_cur_slice = &(ps_dec->ps_dec_slice_buf[0]);
+ ps_dec->u2_cur_slice_num = 0;
+
+ /* Initialize all the HP toolsets to zero */
+ ps_dec->s_high_profile.u1_scaling_present = 0;
+ ps_dec->s_high_profile.u1_transform8x8_present = 0;
+
+ /* Get Next Free Picture */
+ if(1 == ps_dec->u4_share_disp_buf)
+ {
+ UWORD32 i;
+ /* Free any buffer that is in the queue to be freed */
+ for(i = 0; i < MAX_DISP_BUFS_NEW; i++)
+ {
+ if(0 == ps_dec->u4_disp_buf_to_be_freed[i]) continue;
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, i, BUF_MGR_IO);
+ ps_dec->u4_disp_buf_to_be_freed[i] = 0;
+ ps_dec->u4_disp_buf_mapping[i] = 0;
+ }
+ }
+ if(!(u1_field_pic_flag && 0 != ps_dec->u1_top_bottom_decoded))
+ {
+ pic_buffer_t *ps_cur_pic;
+ WORD32 cur_pic_buf_id, cur_mv_buf_id;
+ col_mv_buf_t *ps_col_mv;
+ while(1)
+ {
+ ps_cur_pic = (pic_buffer_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_dec->pv_pic_buf_mgr, &cur_pic_buf_id);
+
+ /* In case of IDR slices, if there is no free picture buffer, then release
+ * all buffers from display and reference
+ */
+ if((ps_cur_pic == NULL) && (ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL))
+ {
+ WORD32 j;
+
+ for(j = 0; j < MAX_DISP_BUFS_NEW; j++)
+ {
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, j, BUF_MGR_REF);
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_mv_buf_mgr,
+ ps_dec->as_buf_id_info_map[j].mv_buf_id, BUF_MGR_REF);
+
+ ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, j, BUF_MGR_IO);
+ }
+ ps_cur_pic = (pic_buffer_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_dec->pv_pic_buf_mgr, &cur_pic_buf_id);
+ }
+ if(ps_cur_pic == NULL)
+ {
+ ps_dec->i4_error_code = ERROR_UNAVAIL_PICBUF_T;
+ ps_dec->ps_dec_err_status->u1_err_flag |= REJECT_CUR_PIC;
+ return ERROR_UNAVAIL_PICBUF_T;
+ }
+ if(0 == ps_dec->u4_disp_buf_mapping[cur_pic_buf_id])
+ {
+ break;
+ }
+ }
+ ps_col_mv = (col_mv_buf_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_dec->pv_mv_buf_mgr, &cur_mv_buf_id);
+ if(ps_col_mv == NULL)
+ {
+ ps_dec->i4_error_code = ERROR_UNAVAIL_MVBUF_T;
+ ps_dec->ps_dec_err_status->u1_err_flag |= REJECT_CUR_PIC;
+ return ERROR_UNAVAIL_MVBUF_T;
+ }
+
+ ps_dec->ps_cur_pic = ps_cur_pic;
+ ps_dec->u1_pic_buf_id = cur_pic_buf_id;
+ ps_cur_pic->u4_ts = ps_dec->u4_ts;
+ memcpy(&ps_cur_pic->s_sei_pic, ps_dec->ps_sei, sizeof(sei));
+
+ ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id;
+ ps_dec->as_buf_id_info_map[cur_pic_buf_id].mv_buf_id = cur_mv_buf_id;
+
+ if(ps_dec->u1_enable_mb_info)
+ {
+ UWORD32 mb_info_map_size = ps_dec->u4_total_mbs << 2;
+ ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map =
+ ps_dec->pu1_qp_map_base + cur_pic_buf_id * mb_info_map_size;
+ ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_mb_type_map =
+ ps_dec->pu1_mb_type_map_base + cur_pic_buf_id * mb_info_map_size;
+ memset(ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map, 0, mb_info_map_size);
+ memset(ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_mb_type_map, 0, mb_info_map_size);
+ }
+ ps_cur_pic->pu1_col_zero_flag = (UWORD8 *) ps_col_mv->pv_col_zero_flag;
+ ps_cur_pic->ps_mv = (mv_pred_t *) ps_col_mv->pv_mv;
+ ps_dec->au1_pic_buf_ref_flag[cur_pic_buf_id] = 0;
+
+ {
+ /*make first entry of list0 and list1 point to cur pic,
+ *so that if first slice is in error, ref pic struct will have valid
+ *entries*/
+ ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0];
+ ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_init_dpb[1];
+ *(ps_dec->ps_dpb_mgr->ps_init_dpb[0][0]) = *ps_cur_pic;
+ /* Initialize for field reference as well */
+ *(ps_dec->ps_dpb_mgr->ps_init_dpb[0][MAX_REF_BUFS]) = *ps_cur_pic;
+
+ *(ps_dec->ps_dpb_mgr->ps_mod_dpb[0][0]) = *ps_cur_pic;
+ /* Initialize for field reference as well */
+ *(ps_dec->ps_dpb_mgr->ps_mod_dpb[0][MAX_REF_BUFS]) = *ps_cur_pic;
+ *(ps_dec->ps_dpb_mgr->ps_init_dpb[1][0]) = *ps_cur_pic;
+ /* Initialize for field reference as well */
+ *(ps_dec->ps_dpb_mgr->ps_init_dpb[1][MAX_REF_BUFS]) = *ps_cur_pic;
+ *(ps_dec->ps_dpb_mgr->ps_mod_dpb[1][0]) = *ps_cur_pic;
+ /* Initialize for field reference as well */
+ *(ps_dec->ps_dpb_mgr->ps_mod_dpb[1][MAX_REF_BUFS]) = *ps_cur_pic;
+ }
+
+ ps_dec->ps_cur_pic->u1_picturetype = u1_field_pic_flag;
+ ps_dec->ps_cur_pic->u4_pack_slc_typ = SKIP_NONE;
+ H264_DEC_DEBUG_PRINT("got a buffer\n");
+ }
+ else
+ {
+ H264_DEC_DEBUG_PRINT("did not get a buffer\n");
+ }
+
+ ps_dec->u4_pic_buf_got = 1;
+
+ ps_dec->ps_cur_pic->i4_poc = i4_poc;
+ ps_dec->ps_cur_pic->i4_frame_num = u2_frame_num;
+ ps_dec->ps_cur_pic->i4_pic_num = u2_frame_num;
+ ps_dec->ps_cur_pic->i4_top_field_order_cnt = ps_pps->i4_top_field_order_cnt;
+ ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = ps_pps->i4_bottom_field_order_cnt;
+ ps_dec->ps_cur_pic->i4_avg_poc = ps_pps->i4_avg_poc;
+ ps_dec->ps_cur_pic->u4_time_stamp = ps_dec->u4_pts;
+
+ ps_dec->s_cur_pic = *(ps_dec->ps_cur_pic);
+ if(u1_field_pic_flag && u1_bottom_field_flag)
+ {
+ WORD32 i4_temp_poc;
+ WORD32 i4_top_field_order_poc, i4_bot_field_order_poc;
+ /* Point to odd lines, since it's bottom field */
+ ps_dec->s_cur_pic.pu1_buf1 += ps_dec->s_cur_pic.u2_frm_wd_y;
+ ps_dec->s_cur_pic.pu1_buf2 += ps_dec->s_cur_pic.u2_frm_wd_uv;
+ ps_dec->s_cur_pic.pu1_buf3 += ps_dec->s_cur_pic.u2_frm_wd_uv;
+ ps_dec->s_cur_pic.ps_mv += ((ps_dec->u2_pic_ht * ps_dec->u2_pic_wd) >> 5);
+ ps_dec->s_cur_pic.pu1_col_zero_flag += ((ps_dec->u2_pic_ht * ps_dec->u2_pic_wd) >> 5);
+ ps_dec->ps_cur_pic->u1_picturetype |= BOT_FLD;
+ i4_top_field_order_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ i4_bot_field_order_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ i4_temp_poc = MIN(i4_top_field_order_poc, i4_bot_field_order_poc);
+ ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
+ }
+
+ ps_cur_slice->u1_mbaff_frame_flag = ps_seq->u1_mb_aff_flag && (!u1_field_pic_flag);
+ ps_dec->ps_cur_pic->u1_picturetype |= (ps_cur_slice->u1_mbaff_frame_flag << 2);
+
+ ps_dec->ps_cur_mb_row = ps_dec->ps_nbr_mb_row;
+ ps_dec->ps_cur_mb_row += 2;
+ ps_dec->ps_top_mb_row = ps_dec->ps_nbr_mb_row;
+ ps_dec->ps_top_mb_row +=
+ ((ps_dec->u2_frm_wd_in_mbs + 2) << (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag));
+ // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be valid
+ ps_dec->ps_top_mb_row += 2;
+ ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->ps_mv_top = ps_dec->ps_mv_top_p[0];
+ ps_dec->u1_mv_top_p = 0;
+ ps_dec->u1_mb_idx = 0;
+ ps_dec->ps_mv_left = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->u2_total_mbs_coded = 0;
+ ps_dec->i4_submb_ofst = -(SUB_BLK_SIZE);
+ ps_dec->u4_pred_info_idx = 0;
+ ps_dec->u4_pred_info_pkd_idx = 0;
+ ps_dec->u4_dma_buf_idx = 0;
+ ps_dec->ps_mv = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->ps_mv_bank_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_dec->pu1_col_zero_flag = ps_dec->s_cur_pic.pu1_col_zero_flag;
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+ ps_dec->i2_prev_slice_mbx = -1;
+ ps_dec->i2_prev_slice_mby = 0;
+ ps_dec->u2_mv_2mb[0] = 0;
+ ps_dec->u2_mv_2mb[1] = 0;
+ ps_dec->u1_last_pic_not_decoded = 0;
+
+ ps_dec->u2_cur_slice_num_dec_thread = 0;
+ ps_dec->u2_cur_slice_num_bs = 0;
+ ps_dec->u4_intra_pred_line_ofst = 0;
+ ps_dec->pu1_cur_y_intra_pred_line = ps_dec->pu1_y_intra_pred_line;
+ ps_dec->pu1_cur_u_intra_pred_line = ps_dec->pu1_u_intra_pred_line;
+ ps_dec->pu1_cur_v_intra_pred_line = ps_dec->pu1_v_intra_pred_line;
+
+ ps_dec->pu1_cur_y_intra_pred_line_base = ps_dec->pu1_y_intra_pred_line;
+ ps_dec->pu1_cur_u_intra_pred_line_base = ps_dec->pu1_u_intra_pred_line;
+ ps_dec->pu1_cur_v_intra_pred_line_base = ps_dec->pu1_v_intra_pred_line;
+
+ ps_dec->pu1_prev_y_intra_pred_line =
+ ps_dec->pu1_y_intra_pred_line + (ps_dec->u2_frm_wd_in_mbs * MB_SIZE);
+
+ ps_dec->pu1_prev_u_intra_pred_line =
+ ps_dec->pu1_u_intra_pred_line + ps_dec->u2_frm_wd_in_mbs * BLK8x8SIZE * YUV420SP_FACTOR;
+ ps_dec->pu1_prev_v_intra_pred_line =
+ ps_dec->pu1_v_intra_pred_line + ps_dec->u2_frm_wd_in_mbs * BLK8x8SIZE;
+
+ ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic;
+ /* Initialize The Function Pointer Depending Upon the Entropy and MbAff Flag
+ */
+ {
+ if(ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ ps_dec->pf_compute_bs = ih264d_compute_bs_mbaff;
+ ps_dec->pf_mvpred = ih264d_mvpred_mbaff;
+ ps_svc_lyr_dec->pf_svc_compute_bs = isvcd_compute_bs_non_mbaff;
+ }
+ else
+ {
+ ps_dec->pf_compute_bs = ih264d_compute_bs_non_mbaff;
+ ps_svc_lyr_dec->pf_svc_compute_bs = isvcd_compute_bs_non_mbaff;
+ ps_dec->u1_cur_mb_fld_dec_flag = ps_cur_slice->u1_field_pic_flag;
+
+ if((ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
+ (0 == ps_svc_lyr_dec->u1_base_res_flag))
+ {
+ ps_svc_lyr_dec->pf_svc_compute_bs = isvcd_compute_bs_non_mbaff_target_lyr;
+ }
+
+ if((ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
+ (1 == ps_svc_lyr_dec->u1_base_res_flag))
+ {
+ ps_svc_lyr_dec->pf_svc_compute_bs =
+ isvcd_compute_bs_non_mbaff_target_lyr_no_inter_layer;
+ }
+
+ if((ps_svc_lyr_dec->u1_layer_identifier == MEDIAL_ENHANCEMENT_LAYER) &&
+ (0 == ps_svc_lyr_dec->u1_base_res_flag))
+ {
+ ps_svc_lyr_dec->pf_svc_compute_bs = isvcd_compute_bs_non_mbaff_medial_lyr;
+ }
+ }
+ }
+ /* Set up the Parameter for DMA transfer */
+ {
+ UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
+ UWORD8 u1_mbaff = ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD8 uc_lastmbs = (((ps_dec->u2_pic_wd) >> 4) % (ps_dec->u1_recon_mb_grp >> u1_mbaff));
+ UWORD16 ui16_lastmbs_widthY =
+ (uc_lastmbs ? (uc_lastmbs << 4) : ((ps_dec->u1_recon_mb_grp >> u1_mbaff) << 4));
+ UWORD16 ui16_lastmbs_widthUV =
+ uc_lastmbs ? (uc_lastmbs << 3) : ((ps_dec->u1_recon_mb_grp >> u1_mbaff) << 3);
+
+ ps_dec->s_tran_addrecon.pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1;
+ ps_dec->s_tran_addrecon.pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2;
+ ps_dec->s_tran_addrecon.pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3;
+
+ ps_dec->s_tran_addrecon.u2_frm_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
+ ps_dec->s_tran_addrecon.u2_frm_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
+
+ if(u1_field_pic_flag)
+ {
+ ui16_lastmbs_widthY += ps_dec->u2_frm_wd_y;
+ ui16_lastmbs_widthUV += ps_dec->u2_frm_wd_uv;
+ }
+
+ /* Normal Increment of Pointer */
+ ps_dec->s_tran_addrecon.u4_inc_y[0] = ((ps_dec->u1_recon_mb_grp << 4) >> u1_mbaff);
+ ps_dec->s_tran_addrecon.u4_inc_uv[0] = ((ps_dec->u1_recon_mb_grp << 4) >> u1_mbaff);
+
+ /* End of Row Increment */
+ ps_dec->s_tran_addrecon.u4_inc_y[1] =
+ (ui16_lastmbs_widthY + (PAD_LEN_Y_H << 1) +
+ ps_dec->s_tran_addrecon.u2_frm_wd_y * ((15 << u1_mbaff) + u1_mbaff));
+ ps_dec->s_tran_addrecon.u4_inc_uv[1] =
+ (ui16_lastmbs_widthUV + (PAD_LEN_UV_H << 2) +
+ ps_dec->s_tran_addrecon.u2_frm_wd_uv * ((15 << u1_mbaff) + u1_mbaff));
+
+ /* Assign picture numbers to each frame/field */
+ /* only once per picture. */
+ ih264d_assign_pic_num(ps_dec);
+ ps_dec->s_tran_addrecon.u2_mv_top_left_inc =
+ (ps_dec->u1_recon_mb_grp << 2) - 1 - (u1_mbaff << 2);
+ ps_dec->s_tran_addrecon.u2_mv_left_inc = ((ps_dec->u1_recon_mb_grp >> u1_mbaff) - 1)
+ << (4 + u1_mbaff);
+ }
+ /**********************************************************************/
+ /* High profile related initialization at pictrue level */
+ /**********************************************************************/
+ if((ps_seq->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_seq->u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC) ||
+ (ps_seq->u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC))
+ {
+ if((ps_seq->i4_seq_scaling_matrix_present_flag) ||
+ (ps_pps->i4_pic_scaling_matrix_present_flag))
+ {
+ ret = ih264d_form_scaling_matrix_picture(ps_seq, ps_pps, ps_dec);
+ ps_dec->s_high_profile.u1_scaling_present = 1;
+ }
+ else
+ {
+ ret = ih264d_form_default_scaling_matrix(ps_dec);
+ }
+
+ if(ps_pps->i4_transform_8x8_mode_flag)
+ {
+ ps_dec->s_high_profile.u1_transform8x8_present = 1;
+ }
+ }
+ else
+ {
+ ret = ih264d_form_default_scaling_matrix(ps_dec);
+ }
+
+ if(ret != OK) return ret;
+
+ /* required while reading the transform_size_8x8 u4_flag */
+ ps_dec->s_high_profile.u1_direct_8x8_inference_flag = ps_seq->u1_direct_8x8_inference_flag;
+ ps_dec->s_high_profile.s_cavlc_ctxt = ps_dec->s_cavlc_ctxt;
+
+ ps_dec->i1_recon_in_thread3_flag = 1;
+ ps_dec->ps_frame_buf_ip_recon = &ps_dec->s_tran_addrecon;
+ if(ps_dec->u1_separate_parse)
+ {
+ memcpy(&ps_dec->s_tran_addrecon_parse, &ps_dec->s_tran_addrecon, sizeof(tfr_ctxt_t));
+ }
+
+ ih264d_init_deblk_tfr_ctxt(ps_dec, &(ps_dec->s_pad_mgr), &(ps_dec->s_tran_addrecon),
+ ps_dec->u2_frm_wd_in_mbs, 0);
+
+ ps_dec->ps_cur_deblk_mb = ps_dec->ps_deblk_pic;
+ ps_dec->u4_cur_deblk_mb_num = 0;
+ ps_dec->u4_deblk_mb_x = 0;
+ ps_dec->u4_deblk_mb_y = 0;
+ ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat;
+
+ ps_dec->u4_first_slice_in_pic = 0;
+ H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex);
+ return OK;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_decode_slice_ext_nal \endif
+*
+* \brief
+* Parses a slice extension NAL
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_decode_slice_ext_nal(UWORD8 u1_is_idr_slice, UWORD8 u1_nal_ref_idc,
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_pic_params_t *ps_pps;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_params_t *ps_cur_slice = NULL;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ pocstruct_t s_tmp_poc = {0};
+ WORD32 i_delta_poc[2] = {0};
+ WORD32 i4_poc = 0;
+ UWORD16 u2_first_mb_in_slice, u2_frame_num;
+ UWORD8 u1_field_pic_flag, u1_redundant_pic_cnt = 0, u1_slice_type;
+ UWORD32 u4_idr_pic_id = 0;
+ UWORD8 u1_bottom_field_flag, u1_pic_order_cnt_type;
+
+ UWORD8 u1_nal_unit_type;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ WORD8 i1_is_end_of_poc;
+ WORD32 ret;
+ WORD32 prev_slice_err, num_mb_skipped;
+ UWORD8 u1_mbaff;
+ pocstruct_t *ps_cur_poc;
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ svc_dec_ctxt_t *psvcd_dec_ctxt;
+ dec_struct_t *ps_dec_cur_lyr_minus_1;
+ svc_dec_lyr_struct_t *ps_svc_cur_lyr_dec_minus_1;
+
+ ps_cur_slice = ps_dec->ps_cur_slice;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ /* read FirstMbInSlice and slice type*/
+ ps_dec->ps_dpb_cmds->u1_dpb_commands_read_slc = 0;
+ u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u2_first_mb_in_slice > (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ /*we currently don not support ASO*/
+ if(((u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) <= ps_dec->u2_cur_mb_addr) &&
+ (ps_dec->u4_first_slice_in_pic == 0))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ COPYTHECONTEXT("Slice Header SVC ext: first_mb_in_slice", u2_first_mb_in_slice);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+
+ if(u4_temp > 9) return ERROR_INV_SLC_TYPE_T;
+
+ u1_slice_type = u4_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: slice_type", (u1_slice_type));
+ /* Find Out the Slice Type is 5 to 9 or not then Set the Flag */
+ /* u1_sl_typ_5_9 = 1 .Which tells that all the slices in the Pic*/
+ /* will be of same type of current */
+ if(u1_slice_type > 4)
+ {
+ u1_slice_type -= 5;
+ }
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_PIC_SET_ID) return ERROR_INV_SLICE_HDR_T;
+ /* discard slice if pic param is invalid */
+ COPYTHECONTEXT("Slice Header SVC ext: pic_parameter_set_id", u4_temp);
+ ps_pps = &ps_dec->ps_pps[u4_temp];
+ if(FALSE == ps_pps->u1_is_valid)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ /* slices in a layer should have same PPS id*/
+ if(UINT32_MAX == ps_svc_lyr_dec->u4_pps_id_for_layer)
+ {
+ ps_svc_lyr_dec->u4_pps_id_for_layer = u4_temp;
+ }
+ else if(u4_temp != ps_svc_lyr_dec->u4_pps_id_for_layer)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_seq = ps_pps->ps_sps;
+ ps_seq += MAX_NUM_SEQ_PARAMS;
+ ps_subset_seq =
+ &ps_svc_lyr_dec->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_seq->u1_seq_parameter_set_id];
+
+ ps_dec->ps_cur_sps = ps_seq;
+ ps_svc_lyr_dec->ps_cur_subset_sps = ps_subset_seq;
+
+ if(!ps_seq) return ERROR_INV_SLICE_HDR_T;
+ if(FALSE == ps_seq->u1_is_valid) return ERROR_INV_SLICE_HDR_T;
+ if(ps_seq->u1_mb_aff_flag) return ERROR_INV_SLICE_HDR_T;
+ if(ps_seq->u1_level_idc > H264_LEVEL_4_2) return ERROR_INV_SLICE_HDR_T;
+ if(!ps_seq->u1_frame_mbs_only_flag) return ERROR_INV_SLICE_HDR_T;
+ if(OK != isvcd_verify_level(ps_seq->u1_level_idc)) return ERROR_INV_SLICE_HDR_T;
+
+ if(ps_dec->u1_init_dec_flag == 1)
+ {
+ if(ps_dec->u2_frm_wd_in_mbs != ps_seq->u2_frm_wd_in_mbs) return ERROR_INV_SLICE_HDR_T;
+ if(ps_dec->u2_frm_ht_in_mbs != ps_seq->u2_frm_ht_in_mbs) return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_dec->i4_reorder_depth = ps_subset_seq->i4_reorder_depth;
+
+ ps_dec->u2_disp_height = ps_subset_seq->u2_disp_height;
+ ps_dec->u2_disp_width = ps_subset_seq->u2_disp_width;
+
+ if(ps_svc_lyr_dec->u1_layer_id > 0)
+ {
+ psvcd_dec_ctxt = ps_svc_lyr_dec->ps_svcd_ctxt;
+ ps_svc_cur_lyr_dec_minus_1 =
+ &psvcd_dec_ctxt->ps_svc_dec_lyr[ps_svc_lyr_dec->u1_layer_id - 1];
+
+ ps_dec_cur_lyr_minus_1 = &ps_svc_cur_lyr_dec_minus_1->s_dec;
+
+ if((ps_dec_cur_lyr_minus_1->u2_pic_wd > ps_subset_seq->u2_pic_wd) ||
+ (ps_dec_cur_lyr_minus_1->u2_pic_ht > ps_subset_seq->u2_pic_ht))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ }
+
+ ps_dec->u2_pic_wd = ps_subset_seq->u2_pic_wd;
+ ps_dec->u2_pic_ht = ps_subset_seq->u2_pic_ht;
+ ps_dec->u4_total_mbs = ps_seq->u2_total_num_of_mbs << (1 - ps_seq->u1_frame_mbs_only_flag);
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_dec->u2_frm_wd_y = ps_subset_seq->u2_frm_wd_y;
+ ps_dec->u2_frm_ht_y = ps_subset_seq->u2_frm_ht_y;
+
+ ps_dec->u2_frm_wd_uv = ps_subset_seq->u2_frm_wd_uv;
+ ps_dec->u2_frm_ht_uv = ps_subset_seq->u2_frm_ht_uv;
+
+ ps_dec->s_pad_mgr.u1_pad_len_y_v = ps_subset_seq->u1_pad_len_y_v;
+ ps_dec->s_pad_mgr.u1_pad_len_cr_v = ps_subset_seq->u1_pad_len_cr_v;
+
+ ps_dec->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ ps_dec->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
+
+ ps_dec->u2_crop_offset_y = ps_subset_seq->u2_crop_offset_y;
+ ps_dec->u2_crop_offset_uv = ps_subset_seq->u2_crop_offset_uv;
+
+ /* Get the frame num */
+ u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, ps_seq->u1_bits_in_frm_num);
+
+ COPYTHECONTEXT("Slice Header SVC ext: frame_num", u2_frame_num);
+ if(!ps_dec->u1_first_slice_in_stream && ps_dec->u4_first_slice_in_pic)
+ {
+ pocstruct_t *ps_prev_poc = &ps_dec->s_prev_pic_poc;
+ pocstruct_t *ps_cur_poc = &ps_dec->s_cur_pic_poc;
+
+ ps_dec->u2_mbx = 0xffff;
+ ps_dec->u2_mby = 0;
+
+ if((0 == u1_is_idr_slice) && ps_cur_slice->u1_nal_ref_idc)
+ ps_dec->u2_prev_ref_frame_num = ps_cur_slice->u2_frame_num;
+
+ if(u1_is_idr_slice || ps_cur_slice->u1_mmco_equalto5) ps_dec->u2_prev_ref_frame_num = 0;
+
+ if(ps_dec->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag)
+ {
+ isvcd_decode_gaps_in_frame_num(ps_dec, u2_frame_num);
+ }
+
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst;
+ ps_prev_poc->u2_frame_num = ps_cur_poc->u2_frame_num;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_slice->u1_mmco_equalto5;
+ if(ps_cur_slice->u1_nal_ref_idc)
+ {
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0];
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1];
+ ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field;
+ }
+
+ ps_dec->u2_total_mbs_coded = 0;
+ }
+ /* Get the field related flags */
+ if(!ps_seq->u1_frame_mbs_only_flag)
+ {
+ u1_field_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: field_pic_flag", u1_field_pic_flag);
+ u1_bottom_field_flag = 0;
+
+ if(u1_field_pic_flag)
+ {
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan_fld;
+ u1_bottom_field_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: bottom_field_flag", u1_bottom_field_flag);
+ }
+ else
+ {
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
+ }
+ }
+ else
+ {
+ u1_field_pic_flag = 0;
+ u1_bottom_field_flag = 0;
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
+ }
+
+ u1_nal_unit_type = SLICE_NAL;
+ if(u1_is_idr_slice)
+ {
+ u1_nal_unit_type = IDR_SLICE_NAL;
+ u4_idr_pic_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_idr_pic_id > 65535) return ERROR_INV_SLICE_HDR_T;
+ COPYTHECONTEXT("Slice Header SVC ext: ", u4_idr_pic_id);
+ }
+
+ /* read delta pic order count information*/
+ i_delta_poc[0] = i_delta_poc[1] = 0;
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ u1_pic_order_cnt_type = ps_seq->u1_pic_order_cnt_type;
+ if(u1_pic_order_cnt_type == 0)
+ {
+ i_temp = ih264d_get_bits_h264(ps_bitstrm, ps_seq->u1_log2_max_pic_order_cnt_lsb_minus);
+ if(i_temp < 0 || i_temp >= ps_seq->i4_max_pic_order_cntLsb) return ERROR_INV_SLICE_HDR_T;
+ s_tmp_poc.i4_pic_order_cnt_lsb = i_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: pic_order_cnt_lsb", s_tmp_poc.i4_pic_order_cnt_lsb);
+
+ if((ps_pps->u1_pic_order_present_flag == 1) && (!u1_field_pic_flag))
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: delta_pic_order_cnt_bottom",
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom);
+ }
+ }
+
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = 0;
+ if(u1_pic_order_cnt_type == 1 && (!ps_seq->u1_delta_pic_order_always_zero_flag))
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: delta_pic_order_cnt[0]",
+ s_tmp_poc.i4_delta_pic_order_cnt[0]);
+
+ if(ps_pps->u1_pic_order_present_flag && !u1_field_pic_flag)
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: delta_pic_order_cnt[1]",
+ s_tmp_poc.i4_delta_pic_order_cnt[1]);
+ }
+ }
+
+ if(ps_pps->u1_redundant_pic_cnt_present_flag)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_REDUNDANT_PIC_CNT) return ERROR_INV_SLICE_HDR_T;
+ u1_redundant_pic_cnt = u4_temp;
+ COPYTHECONTEXT("Slice Header SVC ext: redundant_pic_cnt", u1_redundant_pic_cnt);
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Check if the slice is part of new picture */
+ /*--------------------------------------------------------------------*/
+ /* First slice of a picture is always considered as part of new picture */
+ i1_is_end_of_poc = 1;
+ ps_dec->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC;
+
+ if(ps_dec->u4_first_slice_in_pic == 0)
+ {
+ i1_is_end_of_poc =
+ ih264d_is_end_of_pic(u2_frame_num, u1_nal_ref_idc, &s_tmp_poc, &ps_dec->s_cur_pic_poc,
+ ps_cur_slice, u1_pic_order_cnt_type, u1_nal_unit_type,
+ u4_idr_pic_id, u1_field_pic_flag, u1_bottom_field_flag);
+ if(i1_is_end_of_poc)
+ {
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_INCOMPLETE_FRAME;
+ }
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Check for error in slice and parse the missing/corrupted MB's */
+ /* as skip-MB's in an inserted P-slice */
+ /*--------------------------------------------------------------------*/
+ u1_mbaff = ps_seq->u1_mb_aff_flag && (!u1_field_pic_flag);
+ prev_slice_err = 0;
+
+ if(i1_is_end_of_poc || ps_dec->u1_first_slice_in_stream)
+ {
+ /* If the current slice is not a field or frame number of the current
+ * slice doesn't match with previous slice, and decoder is expecting
+ * to decode a field i.e. ps_dec->u1_top_bottom_decoded is not 0 and
+ * is not (TOP_FIELD_ONLY | BOT_FIELD_ONLY), treat it as a dangling
+ * field */
+ if((u1_field_pic_flag == 0 || u2_frame_num != ps_dec->u2_prv_frame_num) &&
+ ps_dec->u1_top_bottom_decoded != 0 &&
+ ps_dec->u1_top_bottom_decoded != (TOP_FIELD_ONLY | BOT_FIELD_ONLY))
+ {
+ ps_dec->u1_dangling_field = 1;
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ // first slice - dangling field
+ prev_slice_err = 1;
+ }
+ else
+ {
+ // last slice - dangling field
+ prev_slice_err = 2;
+ }
+
+ if(ps_dec->u1_top_bottom_decoded == TOP_FIELD_ONLY)
+ ps_cur_slice->u1_bottom_field_flag = 1;
+ else
+ ps_cur_slice->u1_bottom_field_flag = 0;
+
+ num_mb_skipped =
+ (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &ps_dec->s_cur_pic_poc;
+
+ u1_is_idr_slice = ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL;
+ }
+ else if(ps_dec->u4_first_slice_in_pic)
+ {
+ if(u2_first_mb_in_slice > 0)
+ {
+ // first slice - missing/header corruption
+ prev_slice_err = 1;
+ num_mb_skipped = u2_first_mb_in_slice << u1_mbaff;
+ ps_cur_poc = &s_tmp_poc;
+
+ // initializing slice parameters
+ ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id;
+ ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag;
+ ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+ ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb;
+ ps_cur_slice->u1_nal_unit_type = u1_nal_unit_type;
+ ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt;
+ ps_cur_slice->u1_nal_ref_idc = u1_nal_ref_idc;
+ ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type;
+ ps_cur_slice->u1_mbaff_frame_flag = ps_seq->u1_mb_aff_flag && (!u1_field_pic_flag);
+ }
+ }
+ else
+ {
+ /* since i1_is_end_of_poc is set ,means new frame num is encountered. so
+ * conceal the current frame completely */
+ prev_slice_err = 2;
+ num_mb_skipped =
+ (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &s_tmp_poc;
+ }
+ }
+ else
+ {
+ if((u2_first_mb_in_slice << u1_mbaff) > ps_dec->u2_total_mbs_coded)
+ {
+ // previous slice - missing/corruption
+ prev_slice_err = 2;
+ num_mb_skipped = (u2_first_mb_in_slice << u1_mbaff) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &s_tmp_poc;
+ }
+ else if((u2_first_mb_in_slice << u1_mbaff) < ps_dec->u2_total_mbs_coded)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ }
+ if(prev_slice_err)
+ {
+ ret = isvcd_mark_err_slice_skip((svc_dec_lyr_struct_t *) ps_dec, num_mb_skipped,
+ u1_is_idr_slice, u2_frame_num, ps_cur_poc, prev_slice_err);
+
+ if(ps_dec->u1_dangling_field == 1)
+ {
+ ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
+ ps_dec->u1_first_slice_in_stream = 0;
+ ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
+ return ERROR_DANGLING_FIELD_IN_PIC;
+ }
+
+ if(prev_slice_err == 2)
+ {
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_INCOMPLETE_FRAME;
+ }
+
+ if(ps_dec->u2_total_mbs_coded >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+ {
+ /* return if all MBs in frame are parsed*/
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_IN_LAST_SLICE_OF_PIC;
+ }
+
+ if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+ {
+ ih264d_err_pic_dispbuf_mgr(ps_dec);
+ return ERROR_NEW_FRAME_EXPECTED;
+ }
+
+ if(ret != OK) return ret;
+
+ i1_is_end_of_poc = 0;
+ }
+
+ if(u1_field_pic_flag)
+ {
+ ps_dec->u2_prv_frame_num = u2_frame_num;
+ }
+
+ if(ps_cur_slice->u1_mmco_equalto5)
+ {
+ WORD32 i4_temp_poc;
+ WORD32 i4_top_field_order_poc, i4_bot_field_order_poc;
+ WORD64 i8_result;
+ if(!ps_cur_slice->u1_field_pic_flag) // or a complementary field pair
+ {
+ i4_top_field_order_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ i4_bot_field_order_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ i4_temp_poc = MIN(i4_top_field_order_poc, i4_bot_field_order_poc);
+ }
+ else if(!ps_cur_slice->u1_bottom_field_flag)
+ i4_temp_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ else
+ i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+
+ i8_result = (WORD64) i4_temp_poc - ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_top_field_order_cnt = (WORD32) i8_result;
+ i8_result = (WORD64) i4_temp_poc - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = (WORD32) i8_result;
+ ps_dec->ps_cur_pic->i4_poc = i4_temp_poc;
+ ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
+ }
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ ret = isvcd_decode_pic_order_cnt(u1_is_idr_slice, u2_frame_num, &ps_dec->s_prev_pic_poc,
+ &s_tmp_poc, ps_cur_slice, ps_pps, u1_nal_ref_idc,
+ u1_bottom_field_flag, u1_field_pic_flag, &i4_poc, ps_dec);
+ if(ret != OK) return ret;
+ /* Display seq no calculations */
+ if(i4_poc >= ps_dec->i4_max_poc) ps_dec->i4_max_poc = i4_poc;
+ /* IDR Picture or POC wrap around */
+ if(i4_poc == 0)
+ {
+ WORD64 i8_temp;
+ i8_temp = (WORD64) ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc +
+ ps_dec->u1_max_dec_frame_buffering + 1;
+ /*If i4_prev_max_display_seq overflows integer range, reset it */
+ ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp) ? 0 : i8_temp;
+ ps_dec->i4_max_poc = 0;
+ }
+ }
+
+ /* Increment only if the current slice has atleast 1 more MB */
+ if(ps_dec->u4_first_slice_in_pic == 0 &&
+ (ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice <
+ (UWORD32) (ps_dec->u2_total_mbs_coded >> ps_dec->ps_cur_slice->u1_mbaff_frame_flag)))
+ {
+ ps_dec->ps_parse_cur_slice++;
+ ps_dec->u2_cur_slice_num++;
+ // in the case of single core increment ps_decode_cur_slice
+ if(ps_dec->u1_separate_parse == 0)
+ {
+ ps_dec->ps_decode_cur_slice++;
+ }
+ }
+
+ ps_dec->u1_slice_header_done = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Copy the values read from the bitstream to the slice header and then*/
+ /* If the slice is first slice in picture, then do Start of Picture */
+ /* processing. */
+ /*--------------------------------------------------------------------*/
+ ps_cur_slice->i4_delta_pic_order_cnt[0] = i_delta_poc[0];
+ ps_cur_slice->i4_delta_pic_order_cnt[1] = i_delta_poc[1];
+ ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id;
+ ps_cur_slice->u2_first_mb_in_slice = u2_first_mb_in_slice;
+ ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag;
+ ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+ ps_cur_slice->u1_slice_type = u1_slice_type;
+ ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb;
+
+ ps_cur_slice->u1_nal_unit_type = u1_nal_unit_type;
+ ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt;
+ ps_cur_slice->u1_nal_ref_idc = u1_nal_ref_idc;
+ ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type;
+
+ if(ps_seq->u1_frame_mbs_only_flag)
+ ps_cur_slice->u1_direct_8x8_inference_flag = ps_seq->u1_direct_8x8_inference_flag;
+ else
+ ps_cur_slice->u1_direct_8x8_inference_flag = 1;
+
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ if(B_SLICE == u1_slice_type)
+ {
+ ps_cur_slice->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: direct_spatial_mv_pred_flag",
+ ps_cur_slice->u1_direct_spatial_mv_pred_flag);
+
+ if(ps_cur_slice->u1_direct_spatial_mv_pred_flag)
+ ps_cur_slice->pf_decodeDirect = isvcd_decode_spatial_direct;
+ else
+ ps_cur_slice->pf_decodeDirect = ih264d_decode_temporal_direct;
+ if(!((ps_seq->u1_mb_aff_flag) && (!u1_field_pic_flag)))
+ ps_dec->pf_mvpred = ih264d_mvpred_nonmbaffB;
+ }
+ else
+ {
+ if(!((ps_seq->u1_mb_aff_flag) && (!u1_field_pic_flag))) /*check if this is valid here */
+ ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
+ }
+ }
+
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ if(u2_first_mb_in_slice == 0)
+ {
+ ret = isvcd_start_of_pic(ps_svc_lyr_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
+ if(ret != OK) return ret;
+ /*inter layer buffer intialization */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start;
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_cur_mb =
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base;
+ }
+
+ ps_dec->u4_output_present = 0;
+
+ {
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
+ /* If error code is non-zero then there is no buffer available for
+ display, hence avoid format conversion */
+
+ if(0 != ps_dec->s_disp_op.u4_error_code)
+ {
+ ps_dec->u4_output_present = 0;
+ ps_dec->u4_fmt_conv_cur_row = ps_dec->s_disp_frame_info.u4_y_ht;
+ }
+ else
+ ps_dec->u4_output_present = 1;
+ }
+ if((ps_dec->u1_separate_parse == 1) &&
+ (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER))
+ {
+ if(ps_dec->u4_dec_thread_created == 0)
+ {
+ ithread_create(ps_dec->pv_dec_thread_handle, NULL,
+ (void *) isvcd_decode_picture_thread, (void *) ps_dec);
+
+ ps_dec->u4_dec_thread_created = 1;
+ }
+#ifdef KEEP_THREADS_ACTIVE
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[0] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+#endif
+#ifdef KEEP_THREADS_ACTIVE
+ if(ps_dec->u4_bs_deblk_thread_created)
+ {
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[1] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+#endif
+ }
+ }
+
+ /* INITIALIZATION of fn ptrs for MC and formMbPartInfo functions */
+ {
+ UWORD8 uc_nofield_nombaff;
+
+ uc_nofield_nombaff =
+ ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) &&
+ (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) && (u1_slice_type != B_SLICE) &&
+ (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
+
+ /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
+
+ if(uc_nofield_nombaff)
+ {
+ ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
+ ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
+ }
+ else
+ {
+ ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_mp;
+ ps_dec->p_motion_compensate = ih264d_motion_compensate_mp;
+ }
+ }
+
+ /*
+ * Decide whether to decode the current picture or not
+ */
+ {
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ if(ps_err->u4_frm_sei_sync == u2_frame_num)
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ ps_err->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
+ }
+ ps_err->u4_cur_frm = u2_frame_num;
+ }
+
+ /* Decision for decoding if the picture is to be skipped */
+ {
+ WORD32 i4_skip_b_pic, i4_skip_p_pic;
+
+ i4_skip_b_pic = (ps_dec->u4_skip_frm_mask & B_SLC_BIT) && (B_SLICE == u1_slice_type) &&
+ (0 == u1_nal_ref_idc);
+
+ i4_skip_p_pic = (ps_dec->u4_skip_frm_mask & P_SLC_BIT) && (P_SLICE == u1_slice_type) &&
+ (0 == u1_nal_ref_idc);
+
+ /**************************************************************/
+ /* Skip the B picture if skip mask is set for B picture and */
+ /* Current B picture is a non reference B picture or there is */
+ /* no user for reference B picture */
+ /**************************************************************/
+ if(i4_skip_b_pic)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT;
+ /* Don't decode the picture in SKIP-B mode if that picture is B */
+ /* and also it is not to be used as a reference picture */
+ ps_dec->u1_last_pic_not_decoded = 1;
+
+ return OK;
+ }
+ /**************************************************************/
+ /* Skip the P picture if skip mask is set for P picture and */
+ /* Current P picture is a non reference P picture or there is */
+ /* no user for reference P picture */
+ /**************************************************************/
+ if(i4_skip_p_pic)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT;
+ /* Don't decode the picture in SKIP-P mode if that picture is P */
+ /* and also it is not to be used as a reference picture */
+ ps_dec->u1_last_pic_not_decoded = 1;
+
+ return OK;
+ }
+ }
+
+ {
+ UWORD16 u2_mb_x, u2_mb_y;
+
+ ps_dec->i4_submb_ofst =
+ ((u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) * SUB_BLK_SIZE) -
+ SUB_BLK_SIZE;
+ if(u2_first_mb_in_slice)
+ {
+ UWORD8 u1_mb_aff;
+ UWORD8 u1_field_pic;
+ UWORD16 u2_frm_wd_in_mbs;
+ u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ u1_mb_aff = ps_cur_slice->u1_mbaff_frame_flag;
+ u1_field_pic = ps_cur_slice->u1_field_pic_flag;
+
+ {
+ UWORD32 x_offset;
+ UWORD32 y_offset;
+ UWORD32 u4_frame_stride;
+ tfr_ctxt_t *ps_trns_addr; // = &ps_dec->s_tran_addrecon_parse;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon_parse;
+ }
+ else
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon;
+ }
+ u2_mb_x = MOD(u2_first_mb_in_slice, u2_frm_wd_in_mbs);
+ u2_mb_y = DIV(u2_first_mb_in_slice, u2_frm_wd_in_mbs);
+
+ u2_mb_y <<= u1_mb_aff;
+
+ if((u2_mb_x > u2_frm_wd_in_mbs - 1) || (u2_mb_y > ps_dec->u2_frm_ht_in_mbs - 1))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
+ x_offset = u2_mb_x << 4;
+ y_offset = (u2_mb_y * u4_frame_stride) << 4;
+
+ ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
+
+ u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
+ x_offset >>= 1;
+ y_offset = (u2_mb_y * u4_frame_stride) << 3;
+
+ x_offset *= YUV420SP_FACTOR;
+
+ ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
+ ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
+
+ ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
+ ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
+ ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
+
+ // assign the deblock structure pointers to start of slice
+ if(ps_dec->u1_separate_parse == 1)
+ {
+ ps_dec->ps_deblk_mbn =
+ ps_dec->ps_deblk_pic + (u2_first_mb_in_slice << u1_mb_aff);
+ }
+ else
+ {
+ ps_dec->ps_deblk_mbn =
+ ps_dec->ps_deblk_pic + (u2_first_mb_in_slice << u1_mb_aff);
+ }
+
+ ps_dec->u2_cur_mb_addr = (u2_first_mb_in_slice << u1_mb_aff);
+
+ ps_dec->ps_mv_cur =
+ ps_dec->s_cur_pic.ps_mv + ((u2_first_mb_in_slice << u1_mb_aff) << 4);
+ }
+ }
+ else
+ {
+ tfr_ctxt_t *ps_trns_addr;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon_parse;
+ }
+ else
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon;
+ }
+
+ u2_mb_x = 0xffff;
+ u2_mb_y = 0;
+ // assign the deblock structure pointers to start of slice
+ ps_dec->u2_cur_mb_addr = 0;
+ ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic;
+ ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1;
+ ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2;
+ ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3;
+
+ ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
+ ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
+ ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
+ }
+
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+
+ ps_dec->u2_mbx = (MOD(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby = (DIV(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby <<= ps_cur_slice->u1_mbaff_frame_flag;
+ ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
+ }
+
+ /* RBSP stop bit is used for CABAC decoding*/
+ ps_bitstrm->u4_max_ofst += ps_dec->ps_cur_pps->u1_entropy_coding_mode;
+
+ ps_dec->u1_B = (u1_slice_type == B_SLICE);
+ ps_dec->u4_next_mb_skip = 0;
+
+ ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice = ps_dec->ps_cur_slice->u2_first_mb_in_slice;
+ ps_dec->ps_parse_cur_slice->slice_type = ps_dec->ps_cur_slice->u1_slice_type;
+
+ ps_dec->u4_start_recon_deblk = 1;
+ {
+ WORD32 num_entries;
+ WORD32 size;
+ UWORD8 *pu1_buf;
+
+ num_entries = MAX_FRAMES;
+ if((1 >= ps_dec->ps_cur_sps->u1_num_ref_frames) && (0 == ps_dec->i4_display_delay))
+ {
+ num_entries = 1;
+ }
+ num_entries = ((2 * num_entries) + 1);
+ num_entries *= 2;
+
+ size = num_entries * sizeof(void *);
+ size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ pu1_buf = (UWORD8 *) ps_dec->pv_map_ref_idx_to_poc_buf;
+ pu1_buf += size * ps_dec->u2_cur_slice_num;
+ ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = (void *) pu1_buf;
+ }
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_dec->ps_parse_cur_slice->pv_tu_coeff_data_start = ps_dec->pv_parse_tu_coeff_data;
+ }
+ else
+ {
+ ps_dec->pv_proc_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ }
+
+ ret = ih264d_fix_error_in_dpb(ps_dec);
+ if(ret < 0) return ERROR_DBP_MANAGER_T;
+
+ /*Default initializing default values for some parameters*/
+ ps_svc_slice_params->u1_slice_skip_flag = 0;
+ ps_svc_slice_params->u1_adaptive_base_mode_flag = 0;
+ ps_svc_slice_params->u1_default_base_mode_flag = 0;
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag = 0;
+ ps_svc_slice_params->u1_default_motion_prediction_flag = 0;
+ ps_svc_slice_params->u1_adaptive_residual_prediction_flag = 0;
+ ps_svc_slice_params->u1_default_residual_prediction_flag = 0;
+
+ if(u1_slice_type == I_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= I_SLC_BIT;
+
+ ret = isvcd_parse_eislice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ if(ps_dec->i4_pic_type != B_SLICE && ps_dec->i4_pic_type != P_SLICE)
+ ps_dec->i4_pic_type = I_SLICE;
+ }
+ else if(u1_slice_type == P_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT;
+ ret = isvcd_parse_epslice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ if(ps_dec->i4_pic_type != B_SLICE) ps_dec->i4_pic_type = P_SLICE;
+ }
+ else if(u1_slice_type == B_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT;
+ ret = isvcd_parse_ebslice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ ps_dec->i4_pic_type = B_SLICE;
+ }
+ else
+ return ERROR_INV_SLC_TYPE_T;
+
+ if(ps_dec->u1_slice_header_done)
+ {
+ /* set to zero to indicate a valid slice has been decoded */
+ ps_dec->u1_first_slice_in_stream = 0;
+ }
+
+ if(ret != OK) return ret;
+
+ if(u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ memcpy((void *) ps_dec->ps_dpb_cmds, (void *) (&(ps_dec->s_dpb_cmds_scratch)),
+ sizeof(dpb_commands_t));
+ }
+ }
+
+ /* storing last Mb X and MbY of the slice */
+ ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
+
+ /* End of Picture detection */
+ if(ps_dec->u2_total_mbs_coded >= (ps_seq->u2_max_mb_addr + 1))
+ {
+ ps_dec->u1_pic_decode_done = 1;
+ }
+
+ {
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ if((ps_err->u1_err_flag & REJECT_PB_PICS) && (ps_err->u1_cur_pic_type == PIC_TYPE_I))
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ }
+ }
+
+ PRINT_BIN_BIT_RATIO(ps_dec)
+
+ return ret;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_set_default_slice_header_ext \endif
+*
+* \brief
+* sets the default values for the svc slice header attr
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_set_default_slice_header_ext(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i_status = OK;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ dec_subset_seq_params_t *ps_sps_svc_ext = NULL;
+ ps_seq = ps_pps->ps_sps;
+ ps_seq += MAX_NUM_SEQ_PARAMS;
+ ps_subset_seq =
+ &ps_svc_lyr_dec->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_seq->u1_seq_parameter_set_id];
+ ps_sps_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_y_plus1 =
+ ps_sps_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1;
+
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_x_plus1_flag =
+ ps_sps_svc_ext->u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ }
+
+ ps_svc_slice_params->u4_ref_layer_dq_id = UINT32_MAX;
+ ps_svc_slice_params->u4_disable_inter_layer_deblk_filter_idc = 0;
+ ps_svc_slice_params->u1_scan_idx_start = 0;
+ ps_svc_slice_params->u1_scan_idx_end = 15;
+ ps_svc_slice_params->i4_inter_layer_slice_alpha_c0_offset_div2 = 0;
+ ps_svc_slice_params->i4_inter_layer_slice_beta_offset_div2 = 0;
+ ps_svc_slice_params->u1_constrained_intra_resampling_flag = 0;
+
+ return i_status;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_parse_slice_header \endif
+*
+* \brief
+* parses the svc slice header attr
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_parse_slice_header(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ dec_subset_seq_params_t *ps_sps_svc_ext = NULL;
+ svc_dec_ctxt_t *ps_svcd_ctxt;
+ UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
+ ps_svcd_ctxt = ps_svc_lyr_dec->ps_svcd_ctxt;
+ ps_seq = ps_pps->ps_sps;
+ ps_seq += MAX_NUM_SEQ_PARAMS;
+ ps_subset_seq =
+ &ps_svc_lyr_dec->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_seq->u1_seq_parameter_set_id];
+ ps_sps_svc_ext = &ps_subset_seq->s_sps_svc_ext;
+ ps_svc_slice_params = &ps_svc_lyr_dec->s_svc_slice_params;
+
+ if(!ps_svc_lyr_dec->ps_nal_svc_ext->u1_no_inter_layer_pred_flag &&
+ (0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id))
+ {
+ ps_svc_slice_params->u4_ref_layer_dq_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: u4_ref_layer_dq_id",
+ ps_svc_slice_params->u4_ref_layer_dq_id);
+ if(ps_svc_slice_params->u4_ref_layer_dq_id > MAX_REF_DEP_ID)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_svc_lyr_dec->u1_ref_layer_id = ps_svc_slice_params->u4_ref_layer_dq_id >> 4;
+ if(ps_svc_lyr_dec->u1_ref_layer_id >= ps_svc_lyr_dec->u1_layer_id)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_svc_lyr_dec->ps_dec_svc_ref_layer =
+ &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svc_lyr_dec->u1_ref_layer_id];
+
+ if(ps_sps_svc_ext->u1_inter_layer_deblocking_filter_control_present_flag)
+ {
+ ps_svc_slice_params->u4_disable_inter_layer_deblk_filter_idc =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: u4_disable_inter_layer_deblk_filter_idc",
+ ps_svc_slice_params->u4_disable_inter_layer_deblk_filter_idc);
+
+ if(ps_svc_slice_params->u4_disable_inter_layer_deblk_filter_idc > 6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(1 != ps_svc_slice_params->u4_disable_inter_layer_deblk_filter_idc)
+ {
+ ps_svc_slice_params->i4_inter_layer_slice_alpha_c0_offset_div2 =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_inter_layer_slice_alpha_c0_offset_div2",
+ ps_svc_slice_params->i4_inter_layer_slice_alpha_c0_offset_div2);
+
+ if(ps_svc_slice_params->i4_inter_layer_slice_alpha_c0_offset_div2 > 6 ||
+ ps_svc_slice_params->i4_inter_layer_slice_alpha_c0_offset_div2 < -6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_svc_slice_params->i4_inter_layer_slice_beta_offset_div2 =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_inter_layer_slice_beta_offset_div2",
+ ps_svc_slice_params->i4_inter_layer_slice_beta_offset_div2);
+
+ if(ps_svc_slice_params->i4_inter_layer_slice_beta_offset_div2 > 6 ||
+ ps_svc_slice_params->i4_inter_layer_slice_beta_offset_div2 < -6)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+ }
+
+ ps_svc_slice_params->u1_constrained_intra_resampling_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_constrained_intra_resampling_flag",
+ ps_svc_slice_params->u1_constrained_intra_resampling_flag);
+ if(2 == ps_sps_svc_ext->u1_extended_spatial_scalability_idc)
+ {
+ /* ChromaArrayType = i4_chroma_format_idc if separate_colour_plane_flag
+ * = 0 for all chroma format except 4:4:4 */
+ if(ps_dec->ps_cur_sps->i4_chroma_format_idc >= 0)
+ {
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_x_plus1_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_ref_layer_chroma_phase_x_plus1_flag",
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_x_plus1_flag);
+
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_y_plus1 =
+ ih264d_get_bits_h264(ps_bitstrm, 2);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_ref_layer_chroma_phase_y_plus1",
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_y_plus1);
+
+ if(ps_svc_slice_params->u1_ref_layer_chroma_phase_y_plus1 > 2)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+ else
+ {
+ if(0 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id)
+ {
+ ps_svc_slice_params->u1_ref_layer_chroma_phase_y_plus1 =
+ ps_sps_svc_ext->u1_seq_ref_layer_chroma_phase_y_plus1;
+ }
+ }
+
+ ps_svc_slice_params->i4_scaled_ref_layer_left_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_scaled_ref_layer_left_offset",
+ ps_svc_slice_params->i4_scaled_ref_layer_left_offset);
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_left_offset != 0)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_left_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_svc_slice_params->i4_scaled_ref_layer_left_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_svc_slice_params->i4_scaled_ref_layer_top_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_scaled_ref_layer_top_offset",
+ ps_svc_slice_params->i4_scaled_ref_layer_top_offset);
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_top_offset != 0)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_top_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_svc_slice_params->i4_scaled_ref_layer_top_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_svc_slice_params->i4_scaled_ref_layer_right_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_scaled_ref_layer_right_offset",
+ ps_svc_slice_params->i4_scaled_ref_layer_right_offset);
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_right_offset >= MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_svc_slice_params->i4_scaled_ref_layer_right_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+
+ ps_svc_slice_params->i4_scaled_ref_layer_bottom_offset =
+ ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: i4_scaled_ref_layer_bottom_offset",
+ ps_svc_slice_params->i4_scaled_ref_layer_bottom_offset);
+
+ if(ps_svc_slice_params->i4_scaled_ref_layer_bottom_offset >=
+ MAX_SCLD_REF_LAYER_OFFSET ||
+ ps_svc_slice_params->i4_scaled_ref_layer_bottom_offset < MIN_SCLD_REF_LAYER_OFFSET)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ }
+ else
+ {
+ ps_svc_slice_params->i4_scaled_ref_layer_left_offset =
+ ps_sps_svc_ext->i4_seq_scaled_ref_layer_left_offset;
+ ps_svc_slice_params->i4_scaled_ref_layer_top_offset =
+ ps_sps_svc_ext->i4_seq_scaled_ref_layer_top_offset;
+ ps_svc_slice_params->i4_scaled_ref_layer_right_offset =
+ ps_sps_svc_ext->i4_seq_scaled_ref_layer_right_offset;
+ ps_svc_slice_params->i4_scaled_ref_layer_bottom_offset =
+ ps_sps_svc_ext->i4_seq_scaled_ref_layer_bottom_offset;
+ }
+ }
+
+ if(!ps_svc_lyr_dec->ps_nal_svc_ext->u1_no_inter_layer_pred_flag)
+ {
+ ps_svc_slice_params->u1_slice_skip_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_slice_skip_flag",
+ ps_svc_slice_params->u1_slice_skip_flag);
+
+ if(ps_svc_slice_params->u1_slice_skip_flag)
+ {
+ ps_svc_slice_params->u4_num_mbs_in_slice_minus1 =
+ ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("Slice Header SVC ext: u4_num_mbs_in_slice_minus1",
+ ps_svc_slice_params->u4_num_mbs_in_slice_minus1);
+ }
+ else
+ {
+ ps_svc_slice_params->u1_adaptive_base_mode_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_adaptive_base_mode_flag",
+ ps_svc_slice_params->u1_adaptive_base_mode_flag);
+
+ if(!ps_svc_slice_params->u1_adaptive_base_mode_flag)
+ {
+ ps_svc_slice_params->u1_default_base_mode_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_default_base_mode_flag",
+ ps_svc_slice_params->u1_default_base_mode_flag);
+ }
+ if(!ps_svc_slice_params->u1_default_base_mode_flag)
+ {
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_adaptive_motion_prediction_flag",
+ ps_svc_slice_params->u1_adaptive_motion_prediction_flag);
+
+ if(!ps_svc_slice_params->u1_adaptive_motion_prediction_flag)
+ {
+ ps_svc_slice_params->u1_default_motion_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_default_motion_prediction_flag",
+ ps_svc_slice_params->u1_default_motion_prediction_flag);
+ }
+ }
+ ps_svc_slice_params->u1_adaptive_residual_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_adaptive_residual_prediction_flag",
+ ps_svc_slice_params->u1_adaptive_residual_prediction_flag);
+
+ if(!ps_svc_slice_params->u1_adaptive_residual_prediction_flag)
+ {
+ ps_svc_slice_params->u1_default_residual_prediction_flag =
+ ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_default_residual_prediction_flag",
+ ps_svc_slice_params->u1_default_residual_prediction_flag);
+ }
+ }
+
+ if(ps_sps_svc_ext->u1_adaptive_tcoeff_level_prediction_flag)
+ {
+ ps_svc_slice_params->u1_tcoeff_level_prediction_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_tcoeff_level_prediction_flag",
+ ps_svc_slice_params->u1_tcoeff_level_prediction_flag);
+
+ if(ps_svc_slice_params->u1_tcoeff_level_prediction_flag != 0)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ }
+ }
+
+ if(!ps_sps_svc_ext->u1_slice_header_restriction_flag &&
+ !ps_svc_slice_params->u1_slice_skip_flag)
+ {
+ ps_svc_slice_params->u1_scan_idx_start = ih264d_get_bits_h264(ps_bitstrm, 4);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_scan_idx_start",
+ ps_svc_slice_params->u1_scan_idx_start);
+ ps_svc_slice_params->u1_scan_idx_end = ih264d_get_bits_h264(ps_bitstrm, 4);
+ COPYTHECONTEXT("Slice Header SVC ext: u1_scan_idx_end",
+ ps_svc_slice_params->u1_scan_idx_end);
+
+ if(0 != ps_svc_slice_params->u1_scan_idx_start &&
+ 15 != ps_svc_slice_params->u1_scan_idx_end)
+ return ERROR_SVC_INV_SCAN_IDX;
+ }
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : DecodeSlice \endif
+*
+* \brief
+* Parses a slice
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+
+WORD32 isvcd_parse_decode_slice(UWORD8 u1_is_idr_slice, UWORD8 u1_nal_ref_idc,
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec /* SVC Decoder parameters */
+)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
+ dec_pic_params_t *ps_pps;
+ dec_seq_params_t *ps_seq;
+ dec_svc_seq_params_t *ps_subset_seq;
+ dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
+ pocstruct_t s_tmp_poc = {0};
+ WORD32 i_delta_poc[2] = {0};
+ WORD32 i4_poc = 0;
+ UWORD16 u2_first_mb_in_slice, u2_frame_num;
+ UWORD8 u1_field_pic_flag, u1_redundant_pic_cnt = 0, u1_slice_type;
+ UWORD32 u4_idr_pic_id = 0;
+ UWORD8 u1_bottom_field_flag, u1_pic_order_cnt_type;
+ UWORD8 u1_nal_unit_type;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ WORD8 i1_is_end_of_poc;
+
+ WORD32 ret;
+ WORD32 prev_slice_err, num_mb_skipped;
+ UWORD8 u1_mbaff;
+ pocstruct_t *ps_cur_poc;
+
+ UWORD32 u4_temp;
+ WORD32 i_temp;
+ svc_dec_ctxt_t *psvcd_dec_ctxt;
+ dec_struct_t *ps_dec_cur_lyr_minus_1;
+ svc_dec_lyr_struct_t *ps_svc_cur_lyr_dec_minus_1;
+
+ /* read FirstMbInSlice and slice type*/
+ ps_dec->ps_dpb_cmds->u1_dpb_commands_read_slc = 0;
+ u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u2_first_mb_in_slice > (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ /*we currently don not support ASO*/
+ if(((u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) <= ps_dec->u2_cur_mb_addr) &&
+ (ps_dec->u4_first_slice_in_pic == 0))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ COPYTHECONTEXT("SH: first_mb_in_slice", u2_first_mb_in_slice);
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > 9) return ERROR_INV_SLC_TYPE_T;
+
+ u1_slice_type = u4_temp;
+ COPYTHECONTEXT("SH: slice_type", (u1_slice_type));
+ /* Find Out the Slice Type is 5 to 9 or not then Set the Flag */
+ /* u1_sl_typ_5_9 = 1 .Which tells that all the slices in the Pic*/
+ /* will be of same type of current */
+ if(u1_slice_type > 4)
+ {
+ u1_slice_type -= 5;
+ }
+
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp & MASK_ERR_PIC_SET_ID) return ERROR_INV_SLICE_HDR_T;
+ /* discard slice if pic param is invalid */
+ COPYTHECONTEXT("SH: pic_parameter_set_id", u4_temp);
+ ps_pps = &ps_dec->ps_pps[u4_temp];
+ if(FALSE == ps_pps->u1_is_valid)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ /* slices in a layer should have same PPS id*/
+ if(UINT32_MAX == ps_svc_lyr_dec->u4_pps_id_for_layer)
+ {
+ ps_svc_lyr_dec->u4_pps_id_for_layer = u4_temp;
+ }
+ else if(u4_temp != ps_svc_lyr_dec->u4_pps_id_for_layer)
+ {
+ return ERROR_INV_SLICE_HDR_T;
+ }
+ ps_seq = ps_pps->ps_sps;
+ ps_dec->ps_cur_sps = ps_seq;
+ ps_subset_seq = &ps_svc_lyr_dec->ps_subset_sps[ps_seq->u1_seq_parameter_set_id];
+ ps_svc_lyr_dec->ps_cur_subset_sps = ps_subset_seq;
+ if(!ps_seq) return ERROR_INV_SLICE_HDR_T;
+ if(FALSE == ps_seq->u1_is_valid) return ERROR_INV_SLICE_HDR_T;
+ if(ps_seq->u1_mb_aff_flag) return ERROR_INV_SLICE_HDR_T;
+ if(ps_seq->u1_level_idc > H264_LEVEL_4_2) return ERROR_INV_SLICE_HDR_T;
+ if(!ps_seq->u1_frame_mbs_only_flag) return ERROR_INV_SLICE_HDR_T;
+ if(OK != isvcd_verify_level(ps_seq->u1_level_idc)) return ERROR_INV_SLICE_HDR_T;
+ if(ps_dec->u1_init_dec_flag == 1)
+ {
+ if(ps_dec->u2_frm_wd_in_mbs != ps_seq->u2_frm_wd_in_mbs) return ERROR_INV_SLICE_HDR_T;
+ if(ps_dec->u2_frm_ht_in_mbs != ps_seq->u2_frm_ht_in_mbs) return ERROR_INV_SLICE_HDR_T;
+ }
+
+ if(ps_seq->u1_profile_idc == BASE_PROFILE_IDC)
+ {
+ if(ps_pps->u1_entropy_coding_mode != 0)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+ }
+
+ ps_dec->i4_reorder_depth = ps_subset_seq->i4_reorder_depth;
+ ps_dec->u2_disp_height = ps_subset_seq->u2_disp_height;
+ ps_dec->u2_disp_width = ps_subset_seq->u2_disp_width;
+
+ if(ps_svc_lyr_dec->u1_layer_id > 0)
+ {
+ psvcd_dec_ctxt = ps_svc_lyr_dec->ps_svcd_ctxt;
+ ps_svc_cur_lyr_dec_minus_1 =
+ &psvcd_dec_ctxt->ps_svc_dec_lyr[ps_svc_lyr_dec->u1_layer_id - 1];
+
+ ps_dec_cur_lyr_minus_1 = &ps_svc_cur_lyr_dec_minus_1->s_dec;
+
+ if((ps_dec_cur_lyr_minus_1->u2_pic_wd > ps_subset_seq->u2_pic_wd) ||
+ (ps_dec_cur_lyr_minus_1->u2_pic_ht > ps_subset_seq->u2_pic_ht))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ }
+
+ ps_dec->u2_pic_wd = ps_subset_seq->u2_pic_wd;
+ ps_dec->u2_pic_ht = ps_subset_seq->u2_pic_ht;
+ ps_dec->u4_total_mbs = ps_seq->u2_total_num_of_mbs << (1 - ps_seq->u1_frame_mbs_only_flag);
+
+ /* Determining the Width and Height of Frame from that of Picture */
+ ps_dec->u2_frm_wd_y = ps_subset_seq->u2_frm_wd_y;
+ ps_dec->u2_frm_ht_y = ps_subset_seq->u2_frm_ht_y;
+
+ ps_dec->u2_frm_wd_uv = ps_subset_seq->u2_frm_wd_uv;
+ ps_dec->u2_frm_ht_uv = ps_subset_seq->u2_frm_ht_uv;
+
+ ps_dec->s_pad_mgr.u1_pad_len_y_v = ps_subset_seq->u1_pad_len_y_v;
+ ps_dec->s_pad_mgr.u1_pad_len_cr_v = ps_subset_seq->u1_pad_len_cr_v;
+ ps_dec->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ ps_dec->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
+
+ ps_dec->u2_crop_offset_y = ps_subset_seq->u2_crop_offset_y;
+ ps_dec->u2_crop_offset_uv = ps_subset_seq->u2_crop_offset_uv;
+
+ /* Get the frame num */
+ u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, ps_seq->u1_bits_in_frm_num);
+ COPYTHECONTEXT("SH: frame_num", u2_frame_num);
+
+ if(!ps_dec->u1_first_slice_in_stream && ps_dec->u4_first_slice_in_pic)
+ {
+ pocstruct_t *ps_prev_poc = &ps_dec->s_prev_pic_poc;
+ pocstruct_t *ps_cur_poc = &ps_dec->s_cur_pic_poc;
+
+ ps_dec->u2_mbx = 0xffff;
+ ps_dec->u2_mby = 0;
+
+ if((0 == u1_is_idr_slice) && ps_cur_slice->u1_nal_ref_idc)
+ ps_dec->u2_prev_ref_frame_num = ps_cur_slice->u2_frame_num;
+
+ if(u1_is_idr_slice || ps_cur_slice->u1_mmco_equalto5) ps_dec->u2_prev_ref_frame_num = 0;
+
+ if(ps_dec->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag)
+ {
+ isvcd_decode_gaps_in_frame_num(ps_dec, u2_frame_num);
+ }
+
+ ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst;
+ ps_prev_poc->u2_frame_num = ps_cur_poc->u2_frame_num;
+ ps_prev_poc->u1_mmco_equalto5 = ps_cur_slice->u1_mmco_equalto5;
+ if(ps_cur_slice->u1_nal_ref_idc)
+ {
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb;
+ ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb;
+ ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0];
+ ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1];
+ ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field;
+ }
+
+ ps_dec->u2_total_mbs_coded = 0;
+ }
+ /* Get the field related flags */
+ if(!ps_seq->u1_frame_mbs_only_flag)
+ {
+ u1_field_pic_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: field_pic_flag", u1_field_pic_flag);
+ u1_bottom_field_flag = 0;
+
+ if(u1_field_pic_flag)
+ {
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan_fld;
+ u1_bottom_field_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: bottom_field_flag", u1_bottom_field_flag);
+ }
+ else
+ {
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
+ }
+ }
+ else
+ {
+ u1_field_pic_flag = 0;
+ u1_bottom_field_flag = 0;
+
+ ps_dec->pu1_inv_scan = (UWORD8 *) gau1_ih264d_inv_scan;
+ }
+
+ u1_nal_unit_type = SLICE_NAL;
+ if(u1_is_idr_slice)
+ {
+ u1_nal_unit_type = IDR_SLICE_NAL;
+ u4_idr_pic_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_idr_pic_id > 65535) return ERROR_INV_SLICE_HDR_T;
+ COPYTHECONTEXT("SH: ", u4_idr_pic_id);
+ }
+
+ /* read delta pic order count information*/
+ i_delta_poc[0] = i_delta_poc[1] = 0;
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ u1_pic_order_cnt_type = ps_seq->u1_pic_order_cnt_type;
+ if(u1_pic_order_cnt_type == 0)
+ {
+ i_temp = ih264d_get_bits_h264(ps_bitstrm, ps_seq->u1_log2_max_pic_order_cnt_lsb_minus);
+ if(i_temp < 0 || i_temp >= ps_seq->i4_max_pic_order_cntLsb) return ERROR_INV_SLICE_HDR_T;
+ s_tmp_poc.i4_pic_order_cnt_lsb = i_temp;
+ COPYTHECONTEXT("SH: pic_order_cnt_lsb", s_tmp_poc.i4_pic_order_cnt_lsb);
+
+ if((ps_pps->u1_pic_order_present_flag == 1) && (!u1_field_pic_flag))
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: delta_pic_order_cnt_bottom",
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom);
+ }
+ }
+
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = 0;
+ if(u1_pic_order_cnt_type == 1 && (!ps_seq->u1_delta_pic_order_always_zero_flag))
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: delta_pic_order_cnt[0]", s_tmp_poc.i4_delta_pic_order_cnt[0]);
+
+ if(ps_pps->u1_pic_order_present_flag && !u1_field_pic_flag)
+ {
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ COPYTHECONTEXT("SH: delta_pic_order_cnt[1]", s_tmp_poc.i4_delta_pic_order_cnt[1]);
+ }
+ }
+
+ if(ps_pps->u1_redundant_pic_cnt_present_flag)
+ {
+ u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u4_temp > MAX_REDUNDANT_PIC_CNT) return ERROR_INV_SLICE_HDR_T;
+ u1_redundant_pic_cnt = u4_temp;
+ COPYTHECONTEXT("SH: redundant_pic_cnt", u1_redundant_pic_cnt);
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Check if the slice is part of new picture */
+ /*--------------------------------------------------------------------*/
+ /* First slice of a picture is always considered as part of new picture */
+ i1_is_end_of_poc = 1;
+ ps_dec->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC;
+
+ if(ps_dec->u4_first_slice_in_pic == 0)
+ {
+ i1_is_end_of_poc =
+ ih264d_is_end_of_pic(u2_frame_num, u1_nal_ref_idc, &s_tmp_poc, &ps_dec->s_cur_pic_poc,
+ ps_cur_slice, u1_pic_order_cnt_type, u1_nal_unit_type,
+ u4_idr_pic_id, u1_field_pic_flag, u1_bottom_field_flag);
+ if(i1_is_end_of_poc)
+ {
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_INCOMPLETE_FRAME;
+ }
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* Check for error in slice and parse the missing/corrupted MB's */
+ /* as skip-MB's in an inserted P-slice */
+ /*--------------------------------------------------------------------*/
+ u1_mbaff = ps_seq->u1_mb_aff_flag && (!u1_field_pic_flag);
+ prev_slice_err = 0;
+
+ if(i1_is_end_of_poc || ps_dec->u1_first_slice_in_stream)
+ {
+ /* If the current slice is not a field or frame number of the current
+ * slice doesn't match with previous slice, and decoder is expecting
+ * to decode a field i.e. ps_dec->u1_top_bottom_decoded is not 0 and
+ * is not (TOP_FIELD_ONLY | BOT_FIELD_ONLY), treat it as a dangling
+ * field */
+ if((u1_field_pic_flag == 0 || u2_frame_num != ps_dec->u2_prv_frame_num) &&
+ ps_dec->u1_top_bottom_decoded != 0 &&
+ ps_dec->u1_top_bottom_decoded != (TOP_FIELD_ONLY | BOT_FIELD_ONLY))
+ {
+ ps_dec->u1_dangling_field = 1;
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ // first slice - dangling field
+ prev_slice_err = 1;
+ }
+ else
+ {
+ // last slice - dangling field
+ prev_slice_err = 2;
+ }
+
+ if(ps_dec->u1_top_bottom_decoded == TOP_FIELD_ONLY)
+ ps_cur_slice->u1_bottom_field_flag = 1;
+ else
+ ps_cur_slice->u1_bottom_field_flag = 0;
+
+ num_mb_skipped =
+ (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &ps_dec->s_cur_pic_poc;
+
+ u1_is_idr_slice = ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL;
+ }
+ else if(ps_dec->u4_first_slice_in_pic)
+ {
+ if(u2_first_mb_in_slice > 0)
+ {
+ /* first slice - missing/header corruption */
+ prev_slice_err = 1;
+ num_mb_skipped = u2_first_mb_in_slice << u1_mbaff;
+ ps_cur_poc = &s_tmp_poc;
+
+ /* initializing slice parameters */
+ ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id;
+ ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag;
+ ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+ ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb;
+ ps_cur_slice->u1_nal_unit_type = u1_nal_unit_type;
+ ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt;
+ ps_cur_slice->u1_nal_ref_idc = u1_nal_ref_idc;
+ ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type;
+ ps_cur_slice->u1_mbaff_frame_flag = ps_seq->u1_mb_aff_flag && (!u1_field_pic_flag);
+ }
+ }
+ else
+ {
+ /* since i1_is_end_of_poc is set ,means new frame num is encountered. so
+ * conceal the current frame completely */
+ prev_slice_err = 2;
+ num_mb_skipped =
+ (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &s_tmp_poc;
+ }
+ }
+ else
+ {
+ if((u2_first_mb_in_slice << u1_mbaff) > ps_dec->u2_total_mbs_coded)
+ {
+ // previous slice - missing/corruption
+ prev_slice_err = 2;
+ num_mb_skipped = (u2_first_mb_in_slice << u1_mbaff) - ps_dec->u2_total_mbs_coded;
+ ps_cur_poc = &s_tmp_poc;
+ }
+ else if((u2_first_mb_in_slice << u1_mbaff) < ps_dec->u2_total_mbs_coded)
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+ }
+ if(prev_slice_err)
+ {
+ ret = isvcd_mark_err_slice_skip((svc_dec_lyr_struct_t *) ps_dec, num_mb_skipped,
+ u1_is_idr_slice, u2_frame_num, ps_cur_poc, prev_slice_err);
+
+ if(ps_dec->u1_dangling_field == 1)
+ {
+ ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
+ ps_dec->u1_first_slice_in_stream = 0;
+ ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
+ return ERROR_DANGLING_FIELD_IN_PIC;
+ }
+
+ if(prev_slice_err == 2)
+ {
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_INCOMPLETE_FRAME;
+ }
+
+ if(ps_dec->u2_total_mbs_coded >= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
+ {
+ /* return if all MBs in frame are parsed*/
+ ps_dec->u1_first_slice_in_stream = 0;
+ return ERROR_IN_LAST_SLICE_OF_PIC;
+ }
+
+ if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
+ {
+ ih264d_err_pic_dispbuf_mgr(ps_dec);
+ return ERROR_NEW_FRAME_EXPECTED;
+ }
+
+ if(ret != OK) return ret;
+
+ i1_is_end_of_poc = 0;
+ }
+
+ if(u1_field_pic_flag)
+ {
+ ps_dec->u2_prv_frame_num = u2_frame_num;
+ }
+
+ if(ps_cur_slice->u1_mmco_equalto5 && NULL != ps_dec->ps_cur_pic)
+ {
+ WORD32 i4_temp_poc;
+ WORD32 i4_top_field_order_poc, i4_bot_field_order_poc;
+ WORD64 i8_result;
+ if(!ps_cur_slice->u1_field_pic_flag)
+ {
+ i4_top_field_order_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ i4_bot_field_order_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ i4_temp_poc = MIN(i4_top_field_order_poc, i4_bot_field_order_poc);
+ }
+ else if(!ps_cur_slice->u1_bottom_field_flag)
+ i4_temp_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ else
+ i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+
+ i8_result = (WORD64) i4_temp_poc - ps_dec->ps_cur_pic->i4_top_field_order_cnt;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_top_field_order_cnt = (WORD32) i8_result;
+ i8_result = (WORD64) i4_temp_poc - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = (WORD32) i8_result;
+ ps_dec->ps_cur_pic->i4_poc = i4_temp_poc;
+ ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
+ }
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ ret = isvcd_decode_pic_order_cnt(u1_is_idr_slice, u2_frame_num, &ps_dec->s_prev_pic_poc,
+ &s_tmp_poc, ps_cur_slice, ps_pps, u1_nal_ref_idc,
+ u1_bottom_field_flag, u1_field_pic_flag, &i4_poc, ps_dec);
+ if(ret != OK) return ret;
+ /* Display seq no calculations */
+ if(i4_poc >= ps_dec->i4_max_poc) ps_dec->i4_max_poc = i4_poc;
+ /* IDR Picture or POC wrap around */
+ if(i4_poc == 0)
+ {
+ WORD64 i8_temp;
+ i8_temp = (WORD64) ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc +
+ ps_dec->u1_max_dec_frame_buffering + 1;
+ /*If i4_prev_max_display_seq overflows integer range, reset it */
+ ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp) ? 0 : i8_temp;
+ ps_dec->i4_max_poc = 0;
+ }
+ }
+
+ /* Increment only if the current slice has atleast 1 more MB */
+ if(ps_dec->u4_first_slice_in_pic == 0 &&
+ (ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice <
+ (UWORD32) (ps_dec->u2_total_mbs_coded >> ps_dec->ps_cur_slice->u1_mbaff_frame_flag)))
+ {
+ ps_dec->ps_parse_cur_slice++;
+ ps_dec->u2_cur_slice_num++;
+ // in the case of single core increment ps_decode_cur_slice
+ if(ps_dec->u1_separate_parse == 0)
+ {
+ ps_dec->ps_decode_cur_slice++;
+ }
+ }
+
+ ps_dec->u1_slice_header_done = 0;
+
+ /*--------------------------------------------------------------------*/
+ /* Copy the values read from the bitstream to the slice header and then*/
+ /* If the slice is first slice in picture, then do Start of Picture */
+ /* processing. */
+ /*--------------------------------------------------------------------*/
+ ps_cur_slice->i4_delta_pic_order_cnt[0] = i_delta_poc[0];
+ ps_cur_slice->i4_delta_pic_order_cnt[1] = i_delta_poc[1];
+ ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id;
+ ps_cur_slice->u2_first_mb_in_slice = u2_first_mb_in_slice;
+ ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag;
+ ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
+ ps_cur_slice->u1_slice_type = u1_slice_type;
+ ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb;
+
+ ps_cur_slice->u1_nal_unit_type = u1_nal_unit_type;
+ ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt;
+ ps_cur_slice->u1_nal_ref_idc = u1_nal_ref_idc;
+ ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type;
+
+ if(ps_seq->u1_frame_mbs_only_flag)
+ ps_cur_slice->u1_direct_8x8_inference_flag = ps_seq->u1_direct_8x8_inference_flag;
+ else
+ ps_cur_slice->u1_direct_8x8_inference_flag = 1;
+
+ if(u1_slice_type == B_SLICE)
+ {
+ ps_cur_slice->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
+ COPYTHECONTEXT("SH: direct_spatial_mv_pred_flag",
+ ps_cur_slice->u1_direct_spatial_mv_pred_flag);
+
+ if(ps_cur_slice->u1_direct_spatial_mv_pred_flag)
+ ps_cur_slice->pf_decodeDirect = ih264d_decode_spatial_direct;
+ else
+ ps_cur_slice->pf_decodeDirect = ih264d_decode_temporal_direct;
+ if(!((ps_seq->u1_mb_aff_flag) && (!u1_field_pic_flag)))
+ ps_dec->pf_mvpred = ih264d_mvpred_nonmbaffB;
+ }
+ else
+ {
+ if(!((ps_seq->u1_mb_aff_flag) && (!u1_field_pic_flag)))
+ ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
+ }
+
+ if(ps_dec->u4_first_slice_in_pic)
+ {
+ if(u2_first_mb_in_slice == 0)
+ {
+ ret = isvcd_start_of_pic(ps_svc_lyr_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
+ if(ret != OK) return ret;
+ /*inter layer buffer intialization */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start;
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_cur_mb =
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base;
+ }
+
+ ps_dec->u4_output_present = 0;
+
+ {
+ ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
+ /* If error code is non-zero then there is no buffer available for
+ display, hence avoid format conversion */
+
+ if(0 != ps_dec->s_disp_op.u4_error_code)
+ {
+ ps_dec->u4_output_present = 0;
+ ps_dec->u4_fmt_conv_cur_row = ps_dec->s_disp_frame_info.u4_y_ht;
+ }
+ else
+ ps_dec->u4_output_present = 1;
+ }
+ if(ps_dec->u1_separate_parse == 1)
+ {
+ if(ps_dec->u4_dec_thread_created == 0)
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER)
+ {
+ ithread_create(ps_dec->pv_dec_thread_handle, NULL,
+ (void *) isvcd_decode_picture_thread, (void *) ps_dec);
+
+ ps_dec->u4_dec_thread_created = 1;
+ }
+ else
+ {
+ ithread_create(ps_dec->pv_dec_thread_handle, NULL,
+ (void *) ih264d_decode_picture_thread, (void *) ps_dec);
+
+ ps_dec->u4_dec_thread_created = 1;
+ }
+ }
+#ifdef KEEP_THREADS_ACTIVE
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[0] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+#endif
+#ifdef KEEP_THREADS_ACTIVE
+ if(ps_dec->u4_bs_deblk_thread_created)
+ {
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ps_dec->ai4_process_start[1] = PROC_START;
+ ret = ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
+ RETURN_IF((ret != IV_SUCCESS), ret);
+ }
+#endif
+ }
+ }
+
+ /* INITIALIZATION of fn ptrs for MC and formMbPartInfo functions */
+ {
+ UWORD8 uc_nofield_nombaff;
+
+ uc_nofield_nombaff =
+ ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) &&
+ (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) && (u1_slice_type != B_SLICE) &&
+ (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
+
+ /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
+
+ if(uc_nofield_nombaff)
+ {
+ ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
+ ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
+ }
+ else
+ {
+ ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_mp;
+ ps_dec->p_motion_compensate = ih264d_motion_compensate_mp;
+ }
+ }
+
+ /*
+ * Decide whether to decode the current picture or not
+ */
+ {
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ if(ps_err->u4_frm_sei_sync == u2_frame_num)
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ ps_err->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
+ }
+ ps_err->u4_cur_frm = u2_frame_num;
+ }
+
+ /* Decision for decoding if the picture is to be skipped */
+ {
+ WORD32 i4_skip_b_pic, i4_skip_p_pic;
+
+ i4_skip_b_pic = (ps_dec->u4_skip_frm_mask & B_SLC_BIT) && (B_SLICE == u1_slice_type) &&
+ (0 == u1_nal_ref_idc);
+
+ i4_skip_p_pic = (ps_dec->u4_skip_frm_mask & P_SLC_BIT) && (P_SLICE == u1_slice_type) &&
+ (0 == u1_nal_ref_idc);
+
+ /**************************************************************/
+ /* Skip the B picture if skip mask is set for B picture and */
+ /* Current B picture is a non reference B picture or there is */
+ /* no user for reference B picture */
+ /**************************************************************/
+ if(i4_skip_b_pic)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT;
+ /* Don't decode the picture in SKIP-B mode if that picture is B */
+ /* and also it is not to be used as a reference picture */
+ ps_dec->u1_last_pic_not_decoded = 1;
+
+ return OK;
+ }
+ /**************************************************************/
+ /* Skip the P picture if skip mask is set for P picture and */
+ /* Current P picture is a non reference P picture or there is */
+ /* no user for reference P picture */
+ /**************************************************************/
+ if(i4_skip_p_pic)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT;
+ /* Don't decode the picture in SKIP-P mode if that picture is P */
+ /* and also it is not to be used as a reference picture */
+ ps_dec->u1_last_pic_not_decoded = 1;
+
+ return OK;
+ }
+ }
+
+ {
+ UWORD16 u2_mb_x, u2_mb_y;
+
+ ps_dec->i4_submb_ofst =
+ ((u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) * SUB_BLK_SIZE) -
+ SUB_BLK_SIZE;
+ if(u2_first_mb_in_slice)
+ {
+ UWORD8 u1_mb_aff;
+ UWORD8 u1_field_pic;
+ UWORD16 u2_frm_wd_in_mbs;
+ u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ u1_mb_aff = ps_cur_slice->u1_mbaff_frame_flag;
+ u1_field_pic = ps_cur_slice->u1_field_pic_flag;
+
+ {
+ UWORD32 x_offset;
+ UWORD32 y_offset;
+ UWORD32 u4_frame_stride;
+ tfr_ctxt_t *ps_trns_addr;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon_parse;
+ }
+ else
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon;
+ }
+ u2_mb_x = MOD(u2_first_mb_in_slice, u2_frm_wd_in_mbs);
+ u2_mb_y = DIV(u2_first_mb_in_slice, u2_frm_wd_in_mbs);
+
+ u2_mb_y <<= u1_mb_aff;
+
+ if((u2_mb_x > u2_frm_wd_in_mbs - 1) || (u2_mb_y > ps_dec->u2_frm_ht_in_mbs - 1))
+ {
+ return ERROR_CORRUPTED_SLICE;
+ }
+
+ u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
+ x_offset = u2_mb_x << 4;
+ y_offset = (u2_mb_y * u4_frame_stride) << 4;
+
+ ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
+
+ u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
+ x_offset >>= 1;
+ y_offset = (u2_mb_y * u4_frame_stride) << 3;
+
+ x_offset *= YUV420SP_FACTOR;
+
+ ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
+ ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
+
+ ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
+ ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
+ ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
+
+ /* assign the deblock structure pointers to start of slice */
+ if(ps_dec->u1_separate_parse == 1)
+ {
+ ps_dec->ps_deblk_mbn =
+ ps_dec->ps_deblk_pic + (u2_first_mb_in_slice << u1_mb_aff);
+ }
+ else
+ {
+ ps_dec->ps_deblk_mbn =
+ ps_dec->ps_deblk_pic + (u2_first_mb_in_slice << u1_mb_aff);
+ }
+
+ ps_dec->u2_cur_mb_addr = (u2_first_mb_in_slice << u1_mb_aff);
+
+ ps_dec->ps_mv_cur =
+ ps_dec->s_cur_pic.ps_mv + ((u2_first_mb_in_slice << u1_mb_aff) << 4);
+ }
+ }
+ else
+ {
+ tfr_ctxt_t *ps_trns_addr;
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon_parse;
+ }
+ else
+ {
+ ps_trns_addr = &ps_dec->s_tran_addrecon;
+ }
+
+ u2_mb_x = 0xffff;
+ u2_mb_y = 0;
+ // assign the deblock structure pointers to start of slice
+ ps_dec->u2_cur_mb_addr = 0;
+ ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic;
+ ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv;
+ ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1;
+ ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2;
+ ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3;
+
+ ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
+ ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
+ ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
+ }
+
+ ps_dec->ps_part = ps_dec->ps_parse_part_params;
+
+ ps_dec->u2_mbx = (MOD(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby = (DIV(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs));
+ ps_dec->u2_mby <<= ps_cur_slice->u1_mbaff_frame_flag;
+ ps_dec->i2_prev_slice_mbx = (WORD16) ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = (WORD16) ps_dec->u2_mby;
+ }
+
+ /* RBSP stop bit is used for CABAC decoding*/
+ ps_bitstrm->u4_max_ofst += ps_dec->ps_cur_pps->u1_entropy_coding_mode;
+
+ ps_dec->u1_B = (u1_slice_type == B_SLICE);
+ ps_dec->u4_next_mb_skip = 0;
+
+ ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice = ps_dec->ps_cur_slice->u2_first_mb_in_slice;
+ ps_dec->ps_parse_cur_slice->slice_type = ps_dec->ps_cur_slice->u1_slice_type;
+
+ ps_dec->u4_start_recon_deblk = 1;
+ {
+ WORD32 num_entries;
+ WORD32 size;
+ UWORD8 *pu1_buf;
+
+ num_entries = MAX_FRAMES;
+ if((1 >= ps_dec->ps_cur_sps->u1_num_ref_frames) && (0 == ps_dec->i4_display_delay))
+ {
+ num_entries = 1;
+ }
+ num_entries = ((2 * num_entries) + 1);
+ num_entries *= 2;
+
+ size = num_entries * sizeof(void *);
+ size += PAD_MAP_IDX_POC * sizeof(void *);
+
+ pu1_buf = (UWORD8 *) ps_dec->pv_map_ref_idx_to_poc_buf;
+ pu1_buf += size * ps_dec->u2_cur_slice_num;
+ ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = (void *) pu1_buf;
+ }
+
+ if(ps_dec->u1_separate_parse)
+ {
+ ps_dec->ps_parse_cur_slice->pv_tu_coeff_data_start = ps_dec->pv_parse_tu_coeff_data;
+ }
+ else
+ {
+ ps_dec->pv_proc_tu_coeff_data = ps_dec->pv_parse_tu_coeff_data;
+ }
+
+ ret = ih264d_fix_error_in_dpb(ps_dec);
+ if(ret < 0) return ERROR_DBP_MANAGER_T;
+
+ if(u1_slice_type == I_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= I_SLC_BIT;
+
+ ret = isvcd_parse_islice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ if(ps_dec->i4_pic_type != B_SLICE && ps_dec->i4_pic_type != P_SLICE)
+ ps_dec->i4_pic_type = I_SLICE;
+ }
+ else if(u1_slice_type == P_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT;
+ ret = isvcd_parse_pslice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ if(ps_dec->i4_pic_type != B_SLICE) ps_dec->i4_pic_type = P_SLICE;
+ }
+ else if(u1_slice_type == B_SLICE)
+ {
+ ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT;
+ ret = isvcd_parse_bslice(ps_svc_lyr_dec, u2_first_mb_in_slice);
+ ps_dec->u1_pr_sl_type = u1_slice_type;
+ ps_dec->i4_pic_type = B_SLICE;
+ }
+ else
+ return ERROR_INV_SLC_TYPE_T;
+
+ if(ps_dec->u1_slice_header_done)
+ {
+ /* set to zero to indicate a valid slice has been decoded */
+ ps_dec->u1_first_slice_in_stream = 0;
+ }
+
+ if(ret != OK) return ret;
+
+ if(u1_nal_ref_idc != 0)
+ {
+ if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read)
+ {
+ memcpy((void *) ps_dec->ps_dpb_cmds, (void *) (&(ps_dec->s_dpb_cmds_scratch)),
+ sizeof(dpb_commands_t));
+ }
+ }
+
+ /* storing last Mb X and MbY of the slice */
+ ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
+ ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
+
+ /* End of Picture detection */
+
+ if(ps_dec->u2_total_mbs_coded >= (ps_seq->u2_max_mb_addr + 1))
+ {
+ ps_dec->u1_pic_decode_done = 1;
+ }
+
+ {
+ dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
+ if((ps_err->u1_err_flag & REJECT_PB_PICS) && (ps_err->u1_cur_pic_type == PIC_TYPE_I))
+ {
+ ps_err->u1_err_flag = ACCEPT_ALL_PICS;
+ }
+ }
+
+ PRINT_BIN_BIT_RATIO(ps_dec)
+
+ return ret;
+} \ No newline at end of file
diff --git a/decoder/svc/isvcd_parse_slice.h b/decoder/svc/isvcd_parse_slice.h
new file mode 100644
index 0000000..a17382e
--- /dev/null
+++ b/decoder/svc/isvcd_parse_slice.h
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_parse_slice.h
+ *
+ * @brief
+ * Contains routines that decode a Enhancement slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PARSE_SLICE_H_
+#define _ISVCD_PARSE_SLICE_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_tables.h"
+
+WORD32 isvcd_parse_islice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_islice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_bmb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_parse_bmb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_parse_imb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_mb_type);
+
+WORD32 isvcd_parse_eislice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_eislice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_imb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_type);
+
+WORD32 isvcd_parse_inter_slice_data_cavlc_enh_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_inter_slice_data_cabac_enh_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_inter_slice_data_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_inter_slice_data_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_slice_params_t *ps_slice,
+ UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_eislice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_islice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_pslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_decode_slice(UWORD8 u1_is_idr_slice, UWORD8 u1_nal_ref_idc,
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_parse_slice_header(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_set_default_slice_header_ext(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_start_of_pic(svc_dec_lyr_struct_t *ps_svc_lyr_dec, WORD32 i4_poc,
+ pocstruct_t *ps_temp_poc, UWORD16 u2_frame_num, dec_pic_params_t *ps_pps);
+
+WORD32 isvcd_parse_decode_slice_ext_nal(UWORD8 u1_is_idr_slice, UWORD8 u1_nal_ref_idc,
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_parse_interlayer_resamp_func_init(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ UWORD16 u2_first_mb_in_slice);
+
+#endif /* _ISVCD_PARSE_SLICE_H_ */
diff --git a/decoder/svc/isvcd_pred_residual_recon.c b/decoder/svc/isvcd_pred_residual_recon.c
new file mode 100644
index 0000000..5d00a49
--- /dev/null
+++ b/decoder/svc/isvcd_pred_residual_recon.c
@@ -0,0 +1,541 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_pred_residual_recon.c
+ *
+ * @brief
+ * Contains definition of functions for svc inverse quantization inverse
+ * transformation and resd comp
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_pred_residual_recon_chroma_8x8()
+ * - isvcd_residual_chroma_cb_cr_8x8()
+ * - isvcd_pred_residual_recon_chroma_4x4()
+ * - isvcd_pred_residual_recon_16x16()
+ * - isvcd_pred_residual_recon_4x4()
+ * - isvcd_pred_residual_recon_8x8()
+ * - isvcd_residual_luma_4x4()
+ * - isvcd_residual_luma_8x8()
+ * - isvcd_residual_luma_16x16()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_pred_residual_recon.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_8x8 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_pred_residual_recon_chroma_8x8(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 8; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ for(j = 0; j < 8; j++)
+ {
+ i_macro = *pu1_pred_ptr + *pi2_rsd_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+ }
+
+ pu1_out_ptr += 2; // Interleaved store for output
+ pu1_pred += 2; // Interleaved load for pred buffer
+ pi2_rsd += 2;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_chroma_cb_cr_8x8 */
+/* */
+/* Description : this function computes the nnz from the resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_chroma_cb_cr_8x8(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ WORD16 *pi2_rsd_ptr_Cb = pi2_rsd;
+ WORD16 *pi2_rsd_ptr_Cr = pi2_rsd + 1;
+ WORD16 i, j;
+ WORD32 i4_nnz = 0, ai4_nnz_Cb[2][2] = {0}, ai4_nnz_Cr[2][2] = {0};
+
+ for(i = 0; i < 8; i++)
+ {
+ pi2_rsd_ptr_Cb = pi2_rsd;
+ pi2_rsd_ptr_Cr = pi2_rsd + 1;
+
+ for(j = 0; j < 8; j++)
+ {
+ ai4_nnz_Cb[j >> 2][i >> 2] |= !!(*pi2_rsd_ptr_Cb);
+ ai4_nnz_Cr[j >> 2][i >> 2] |= !!(*pi2_rsd_ptr_Cr);
+ pi2_rsd_ptr_Cb += rsd_strd;
+ pi2_rsd_ptr_Cr += rsd_strd;
+ }
+ pi2_rsd += 2;
+ }
+ i4_nnz = ai4_nnz_Cr[0][0] | (ai4_nnz_Cr[1][0] << 2);
+ i4_nnz |= (ai4_nnz_Cr[0][1] << 1) | (ai4_nnz_Cr[1][1] << 3);
+ i4_nnz <<= 4;
+ i4_nnz |= ai4_nnz_Cb[0][0] | (ai4_nnz_Cb[1][0] << 2);
+ i4_nnz |= (ai4_nnz_Cb[0][1] << 1) | (ai4_nnz_Cb[1][1] << 3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_4x4 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_pred_residual_recon_chroma_4x4(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ for(j = 0; j < 4; j++)
+ {
+ i_macro = *pu1_pred_ptr + *pi2_rsd_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+ }
+
+ pu1_out_ptr += 2; // Interleaved store for output
+ pu1_pred += 2; // Interleaved load for pred buffer
+ pi2_rsd += 2;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_16x16 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_16x16(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ WORD32 i4_nnz = 0, i4_nnz_blk[4][4] = {0};
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 16; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ for(j = 0; j < 16; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+ }
+
+ pu1_out_ptr++;
+ pi2_rsd++;
+ pu1_pred++;
+ }
+
+ for(i = 0; i < 4; i++)
+ {
+ for(j = 0; j < 4; j++)
+ {
+ i4_nnz |= (i4_nnz_blk[j][i]) << (i + (j << 2));
+ }
+ }
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_4x4 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_4x4(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ WORD32 i4_nnz_blk[4][4] = {0};
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 4; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ for(j = 0; j < 4; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+ }
+
+ pu1_out_ptr++;
+ pi2_rsd++;
+ pu1_pred++;
+ }
+
+ return i4_nnz_blk[0][0];
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_8x8 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_8x8(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ WORD32 i4_nnz = 0, i4_nnz_blk[4][4] = {0};
+ UWORD8 *pu1_pred_ptr = pu1_pred;
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ UWORD8 *pu1_out_ptr = pu1_out;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 8; i++)
+ {
+ pu1_pred_ptr = pu1_pred;
+ pi2_rsd_ptr = pi2_rsd;
+ pu1_out = pu1_out_ptr;
+
+ for(j = 0; j < 8; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ i_macro += *pu1_pred_ptr;
+ *pu1_out = CLIP_U8(i_macro);
+ pu1_pred_ptr += pred_strd;
+ pi2_rsd_ptr += rsd_strd;
+ pu1_out += out_strd;
+ }
+
+ pu1_out_ptr++;
+ pi2_rsd++;
+ pu1_pred++;
+ }
+
+ i4_nnz = i4_nnz_blk[0][0] | (i4_nnz_blk[1][0] << 4);
+ i4_nnz |= (i4_nnz_blk[0][1] << 1) | (i4_nnz_blk[1][1] << 5);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_4x4 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_4x4(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ WORD32 i4_nnz_blk[4][4] = {0};
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 4; i++)
+ {
+ pi2_rsd_ptr = pi2_rsd;
+
+ for(j = 0; j < 4; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ pi2_rsd_ptr += rsd_strd;
+ }
+ pi2_rsd++;
+ }
+ return i4_nnz_blk[0][0];
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_8x8 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_8x8(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ WORD32 i4_nnz = 0, i4_nnz_blk[4][4] = {0};
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 8; i++)
+ {
+ pi2_rsd_ptr = pi2_rsd;
+
+ for(j = 0; j < 8; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ pi2_rsd_ptr += rsd_strd;
+ }
+ pi2_rsd++;
+ }
+
+ i4_nnz = i4_nnz_blk[0][0] | (i4_nnz_blk[1][0] << 4);
+ i4_nnz |= (i4_nnz_blk[0][1] << 1) | (i4_nnz_blk[1][1] << 5);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_16x16 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_16x16(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ WORD32 i4_nnz = 0, i4_nnz_blk[4][4] = {0};
+ WORD16 *pi2_rsd_ptr = pi2_rsd;
+ WORD16 i, j;
+ WORD16 i_macro;
+
+ for(i = 0; i < 16; i++)
+ {
+ pi2_rsd_ptr = pi2_rsd;
+
+ for(j = 0; j < 16; j++)
+ {
+ i_macro = *pi2_rsd_ptr;
+ i4_nnz_blk[j >> 2][i >> 2] |= !!i_macro;
+ pi2_rsd_ptr += rsd_strd;
+ }
+ pi2_rsd++;
+ }
+
+ for(i = 0; i < 4; i++)
+ {
+ for(j = 0; j < 4; j++)
+ {
+ i4_nnz |= (i4_nnz_blk[j][i]) << (i + (j << 2));
+ }
+ }
+ return i4_nnz;
+}
diff --git a/decoder/svc/isvcd_pred_residual_recon.h b/decoder/svc/isvcd_pred_residual_recon.h
new file mode 100644
index 0000000..edeface
--- /dev/null
+++ b/decoder/svc/isvcd_pred_residual_recon.h
@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_pred_residual_recon.h
+ *
+ * @brief
+ * Contains declarations for forward and inverse transform paths for SVC
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PRED_RESDUAL_RECON_
+#define _ISVCD_PRED_RESDUAL_RECON_
+
+/*Function prototype declarations*/
+
+typedef WORD32 ih264_residual_ft(WORD16 *pi2_rsd, WORD32 rsd_stride);
+
+typedef WORD32 ih264_residual_chroma_ft(WORD16 *pi2_rsd, WORD32 rsd_stride);
+
+typedef WORD32 ih264_pred_residual_recon_ft(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_stride, WORD32 out_strd);
+
+typedef void ih264_pred_residual_recon_chroma_ft(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_stride,
+ WORD32 out_strd);
+
+ih264_residual_ft isvcd_residual_luma_4x4;
+ih264_residual_ft isvcd_residual_luma_8x8;
+ih264_residual_ft isvcd_residual_luma_16x16;
+ih264_residual_chroma_ft isvcd_residual_chroma_cb_cr_8x8;
+
+ih264_residual_ft isvcd_residual_luma_4x4_sse42;
+ih264_residual_ft isvcd_residual_luma_8x8_sse42;
+ih264_residual_ft isvcd_residual_luma_16x16_sse42;
+ih264_residual_chroma_ft isvcd_residual_chroma_cb_cr_8x8_sse42;
+
+ih264_residual_ft isvcd_residual_luma_4x4_neonintr;
+ih264_residual_ft isvcd_residual_luma_8x8_neonintr;
+ih264_residual_ft isvcd_residual_luma_16x16_neonintr;
+ih264_residual_chroma_ft isvcd_residual_chroma_cb_cr_8x8_neonintr;
+
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_4x4;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_8x8;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_16x16;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_4x4;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_8x8;
+
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_4x4_neonintr;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_8x8_neonintr;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_16x16_neonintr;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_4x4_neonintr;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_8x8_neonintr;
+
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_4x4_sse42;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_8x8_sse42;
+ih264_pred_residual_recon_ft isvcd_pred_residual_recon_16x16_sse42;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_4x4_sse42;
+ih264_pred_residual_recon_chroma_ft isvcd_pred_residual_recon_chroma_8x8_sse42;
+
+#endif /* _ISVCD_PRED_RESDUAL_RECON_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_process_ebslice.c b/decoder/svc/isvcd_process_ebslice.c
new file mode 100644
index 0000000..acf06c7
--- /dev/null
+++ b/decoder/svc/isvcd_process_ebslice.c
@@ -0,0 +1,619 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_process_bslice.c
+ *
+ * @brief
+ * Contains routines that decode B slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_mvpred.h"
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_one_to_one \endif
+*
+* \brief
+* Initializes forward and backward refernce lists for B slice decoding.
+*
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+void isvcd_one_to_one(svc_dec_lyr_struct_t *ps_svc_lyr_dec, struct pic_buffer_t *ps_col_pic,
+ directmv_t *ps_direct, UWORD8 u1_wd_x, WORD32 u2_sub_mb_ofst,
+ dec_mb_info_t *ps_cur_mb_info)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD8 *pu1_col_zero_flag_start, u1_col_mb_pred_mode, u1_num_blks, u1_sub_mb_num;
+ UWORD8 u1_init_colzero_flag;
+ UNUSED(ps_cur_mb_info);
+ pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst;
+ u1_col_mb_pred_mode = pu1_col_zero_flag_start[ps_dec->u1_sub_mb_num];
+ u1_init_colzero_flag = u1_col_mb_pred_mode & 1;
+ u1_col_mb_pred_mode >>= 6;
+ ps_direct->u1_vert_mv_scale = ONE_TO_ONE;
+ ps_direct->u1_col_zeroflag_change = (ps_svc_lyr_dec->u1_base_res_flag) ? 0 : 1;
+
+ if(u1_wd_x == MB_SIZE)
+ {
+ ps_dec->u1_currB_type = (!!u1_col_mb_pred_mode);
+ if(u1_col_mb_pred_mode == PRED_16x16)
+ {
+ ps_direct->i1_num_partitions = 1;
+ ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst;
+ ps_direct->i1_submb_num[0] = 0;
+ ps_direct->i1_partitionsize[0] = PRED_16x16;
+
+ return;
+ }
+ else if(u1_col_mb_pred_mode < PRED_8x8)
+ {
+ ps_direct->i1_num_partitions = 2;
+ ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst;
+ ps_direct->i1_submb_num[0] = 0;
+ ps_direct->i1_partitionsize[0] = u1_col_mb_pred_mode;
+ u1_sub_mb_num = (u1_col_mb_pred_mode == PRED_16x8) ? 8 : 2;
+ ps_direct->i1_submb_num[1] = u1_sub_mb_num;
+ ps_direct->i4_mv_indices[1] = u2_sub_mb_ofst + ps_direct->i1_submb_num[1];
+ ps_direct->i1_partitionsize[1] = u1_col_mb_pred_mode;
+ if((pu1_col_zero_flag_start[u1_sub_mb_num] & 1) != u1_init_colzero_flag)
+ ps_direct->u1_col_zeroflag_change = 1;
+ return;
+ }
+ else
+ {
+ u1_num_blks = 4;
+ }
+ }
+ else
+ {
+ u1_num_blks = 1;
+ }
+
+ {
+ const UWORD8 *pu1_top_lt_mb_part_idx;
+ UWORD8 u1_col_sub_mb_pred_mode, uc_blk, u1_sub_blk, u1_submb_col = 0;
+ UWORD8 u1_num_sub_blks, uc_direct8x8inf, *pu1_col_zero_flag, u1_sub_mb_num;
+ const UWORD8 *pu1_num_sub_mb_part = (const UWORD8 *) gau1_ih264d_num_submb_part;
+ UWORD8 i1_num_partitions = 0, partition_size;
+ WORD32 mv_index;
+ const UWORD8 *pu1_top_lt_sub_mb_idx = gau1_ih264d_submb_indx_mod_sp_drct;
+
+ u1_sub_mb_num = ps_dec->u1_sub_mb_num;
+ uc_direct8x8inf = ps_dec->ps_cur_slice->u1_direct_8x8_inference_flag;
+ pu1_top_lt_mb_part_idx = gau1_ih264d_top_left_mb_part_indx_mod + (PRED_8x8 << 1) + 1;
+
+ for(uc_blk = 0; uc_blk < u1_num_blks; uc_blk++)
+ {
+ partition_size = PRED_8x8;
+ pu1_top_lt_sub_mb_idx = gau1_ih264d_submb_indx_mod_sp_drct;
+ if(uc_direct8x8inf == 1)
+ {
+ u1_submb_col = u1_sub_mb_num | (u1_sub_mb_num >> 1);
+ mv_index = u2_sub_mb_ofst + u1_submb_col;
+ u1_num_sub_blks = 1;
+ }
+ else
+ {
+ /* colMbPart is either 8x8, 8x4, 4x8, 4x4 */
+ pu1_col_zero_flag = pu1_col_zero_flag_start + u1_sub_mb_num;
+ u1_col_sub_mb_pred_mode = *pu1_col_zero_flag;
+ u1_col_sub_mb_pred_mode = (u1_col_sub_mb_pred_mode & 0x30) >> 4;
+ partition_size = (UWORD8) ((u1_col_sub_mb_pred_mode) | (PRED_8x8 << 2));
+ mv_index = u2_sub_mb_ofst + u1_sub_mb_num;
+ pu1_top_lt_sub_mb_idx += (u1_col_sub_mb_pred_mode << 1);
+ u1_num_sub_blks = pu1_num_sub_mb_part[u1_col_sub_mb_pred_mode];
+ }
+
+ for(u1_sub_blk = 0; u1_sub_blk < u1_num_sub_blks; u1_sub_blk++, pu1_top_lt_sub_mb_idx++)
+ {
+ u1_sub_mb_num += *pu1_top_lt_sub_mb_idx;
+ mv_index += *pu1_top_lt_sub_mb_idx;
+ ps_direct->i4_mv_indices[i1_num_partitions] = mv_index;
+ ps_direct->i1_submb_num[i1_num_partitions] = u1_sub_mb_num;
+ ps_direct->i1_partitionsize[i1_num_partitions] = partition_size;
+ i1_num_partitions++;
+ if(!uc_direct8x8inf) u1_submb_col = u1_sub_mb_num;
+ if((pu1_col_zero_flag_start[u1_submb_col] & 1) != u1_init_colzero_flag)
+ ps_direct->u1_col_zeroflag_change = 1;
+ }
+ u1_sub_mb_num = *pu1_top_lt_mb_part_idx++;
+ }
+ ps_direct->i1_num_partitions = i1_num_partitions;
+ }
+}
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_decode_spatial_direct \endif
+ *
+ * \brief
+ * Decodes spatial direct mode.
+ *
+ * \return
+ * None.
+ * Vijay
+ **************************************************************************
+ */
+WORD32 isvcd_decode_spatial_direct(dec_struct_t *ps_dec, UWORD8 u1_wd_x,
+ dec_mb_info_t *ps_cur_mb_info, UWORD8 u1_mb_num)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) ps_dec;
+ mv_pred_t s_mv_pred = {0};
+ mv_pred_t *ps_mv;
+ UWORD8 u1_col_zero_flag, u1_sub_mb_num, u1_direct_zero_pred_flag = 0;
+ UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ mv_pred_t *ps_mv_ntop_start;
+ mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_mb_num << 4);
+ UWORD8 partition_size, sub_partition, u1_mb_partw, u1_mb_parth;
+ UWORD8 i;
+ WORD8 i1_pred, i1_ref_frame0, i1_ref_frame1;
+ struct pic_buffer_t *ps_ref_frame = NULL, *ps_col_pic, *ps_pic_buff0 = NULL,
+ *ps_pic_buff1 = NULL;
+
+ UWORD8 u1_zero_pred_cond_f, u1_zero_pred_cond_b;
+ WORD16 i2_spat_pred_mv[4] = {0};
+ WORD16 *pi2_final_mv0, *pi2_final_mv1;
+ UWORD16 ui2_mask_fwd = 0, ui2_mask_bwd = 0;
+ UWORD32 *pui32_weight_ofsts = NULL;
+ directmv_t s_mvdirect = {0};
+ UWORD8 u1_colz;
+ UWORD8 u1_final_ref_idx = 0;
+ const UWORD8 *pu1_mb_parth = (const UWORD8 *) gau1_ih264d_mb_parth;
+ const UWORD8 *pu1_mb_partw = (const UWORD8 *) gau1_ih264d_mb_partw;
+
+ mv_pred_t s_temp_mv_pred = {0};
+ ps_mv_ntop_start =
+ ps_dec->ps_mv_cur + (u1_mb_num << 4) - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12;
+
+ u1_direct_zero_pred_flag =
+ ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, (ps_mv_nmb_start + ps_dec->u1_sub_mb_num),
+ ps_mv_ntop_start + (ps_dec->u1_sub_mb_num & 0x03), &s_mv_pred,
+ ps_dec->u1_sub_mb_num, (u1_wd_x >> 2), 0, 1, B_DIRECT_SPATIAL);
+
+ i2_spat_pred_mv[0] = s_mv_pred.i2_mv[0];
+ i2_spat_pred_mv[1] = s_mv_pred.i2_mv[1];
+ i2_spat_pred_mv[2] = s_mv_pred.i2_mv[2];
+ i2_spat_pred_mv[3] = s_mv_pred.i2_mv[3];
+
+ i1_ref_frame0 = s_mv_pred.i1_ref_frame[0];
+ i1_ref_frame1 = s_mv_pred.i1_ref_frame[1];
+
+ i1_ref_frame0 = (i1_ref_frame0 < 0) ? -1 : i1_ref_frame0;
+ i1_ref_frame1 = (i1_ref_frame1 < 0) ? -1 : i1_ref_frame1;
+
+ i1_pred = 0;
+
+ {
+ WORD8 u1_ref_idx, u1_ref_idx1;
+ UWORD32 uc_Idx, uc_Idx1;
+ UWORD8 u1_scale_ref =
+ (ps_dec->ps_cur_slice->u1_mbaff_frame_flag && ps_cur_mb_info->u1_mb_field_decodingflag);
+ u1_final_ref_idx = i1_ref_frame0;
+ if(i1_ref_frame0 >= 0)
+ {
+ /* convert RefIdx if it is MbAff */
+ u1_ref_idx = i1_ref_frame0;
+ u1_ref_idx1 = i1_ref_frame0;
+ if(u1_scale_ref)
+ {
+ u1_ref_idx1 = u1_ref_idx >> 1;
+ if((u1_ref_idx & 0x01) != (1 - ps_cur_mb_info->u1_topmb))
+ u1_ref_idx1 += MAX_REF_BUFS;
+ }
+ /* If i1_ref_frame0 < 0 then refIdxCol is obtained from ps_pic_buff1 */
+ ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][u1_ref_idx1];
+ ps_ref_frame = ps_pic_buff0;
+ i1_pred = PRED_L0;
+ }
+
+ if(i1_ref_frame1 >= 0)
+ {
+ /* convert RefIdx if it is MbAff */
+ u1_ref_idx = i1_ref_frame1;
+ u1_ref_idx1 = i1_ref_frame1;
+ if(u1_scale_ref)
+ {
+ u1_ref_idx1 = u1_ref_idx >> 1;
+ if((u1_ref_idx & 0x01) != (1 - ps_cur_mb_info->u1_topmb))
+ u1_ref_idx1 += MAX_REF_BUFS;
+ }
+ ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][u1_ref_idx1];
+ i1_pred = i1_pred | PRED_L1;
+ }
+ if(i1_ref_frame0 < 0)
+ {
+ ps_ref_frame = ps_pic_buff1;
+ u1_final_ref_idx = i1_ref_frame1;
+ }
+
+ u1_zero_pred_cond_f = (u1_direct_zero_pred_flag) || (i1_ref_frame0 < 0);
+ u1_zero_pred_cond_b = (u1_direct_zero_pred_flag) || (i1_ref_frame1 < 0);
+
+ if(ps_dec->ps_cur_pps->u1_wted_bipred_idc)
+ {
+ uc_Idx = ((i1_ref_frame0 < 1) ? 0 : i1_ref_frame0) *
+ ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1];
+ if(u1_scale_ref) uc_Idx >>= 1;
+ uc_Idx1 = (i1_ref_frame1 < 0) ? 0 : i1_ref_frame1;
+ uc_Idx += (u1_scale_ref) ? (uc_Idx1 >> 1) : uc_Idx1;
+ pui32_weight_ofsts = (UWORD32 *) &ps_dec->pu4_wt_ofsts[2 * X3(uc_Idx)];
+
+ if(i1_ref_frame0 < 0) pui32_weight_ofsts += 1;
+
+ if(u1_scale_ref && (ps_dec->ps_cur_pps->u1_wted_bipred_idc == 2))
+ {
+ WORD16 i2_ref_idx;
+ i2_ref_idx = MAX(i1_ref_frame0, 0);
+ i2_ref_idx *= (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] << 1);
+ i2_ref_idx += MAX(i1_ref_frame1, 0);
+ if(!ps_cur_mb_info->u1_topmb)
+ i2_ref_idx += (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] << 1) *
+ (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] << 1);
+ pui32_weight_ofsts = (UWORD32 *) &ps_dec->pu4_mbaff_wt_mat[2 * X3(i2_ref_idx)];
+ }
+ }
+ }
+
+ s_temp_mv_pred.i1_ref_frame[0] = i1_ref_frame0;
+ s_temp_mv_pred.i1_ref_frame[1] = i1_ref_frame1;
+ s_temp_mv_pred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id;
+ s_temp_mv_pred.u1_pic_type = ps_ref_frame->u1_pic_type;
+
+ /**********************************************************************/
+ /* Call the function which gets the number of partitions and */
+ /* partition info of colocated Mb */
+ /**********************************************************************/
+
+ isvcd_one_to_one(ps_svc_lyr_dec, ps_dec->ps_col_pic, &s_mvdirect, u1_wd_x,
+ ps_dec->i4_submb_ofst, ps_cur_mb_info);
+
+ ps_col_pic = ps_dec->ps_col_pic;
+ if((s_mvdirect.u1_col_zeroflag_change == 0) || u1_direct_zero_pred_flag)
+ {
+ WORD16 i2_mv_x, i2_mv_y, i2_mvX1, i2_mvY1;
+ /* Most probable case */
+ u1_col_zero_flag = *(ps_col_pic->pu1_col_zero_flag + s_mvdirect.i4_mv_indices[0]);
+ u1_col_zero_flag = u1_col_zero_flag & 0x01;
+
+ if(u1_zero_pred_cond_f || ((i1_ref_frame0 == 0) && (u1_col_zero_flag == 1)))
+ {
+ i2_mv_x = 0;
+ i2_mv_y = 0;
+ }
+ else
+ {
+ i2_mv_x = i2_spat_pred_mv[0];
+ i2_mv_y = i2_spat_pred_mv[1];
+ }
+
+ if(u1_zero_pred_cond_b || ((i1_ref_frame1 == 0) && (u1_col_zero_flag == 1)))
+ {
+ i2_mvX1 = 0;
+ i2_mvY1 = 0;
+ }
+ else
+ {
+ i2_mvX1 = i2_spat_pred_mv[2];
+ i2_mvY1 = i2_spat_pred_mv[3];
+ }
+
+ u1_sub_mb_num = ps_dec->u1_sub_mb_num;
+ u1_mb_partw = (u1_wd_x >> 2);
+
+ if(i1_ref_frame0 >= 0)
+ {
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD16 i2_mv[2];
+ WORD8 i1_ref_idx = 0;
+
+ i2_mv[0] = i2_mv_x;
+ i2_mv[1] = i2_mv_y;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(i2_mv, u1_mb_partw, u1_mb_partw, u1_sub_mb_num, i1_pred,
+ ps_pred_pkd, ps_pic_buff0->u1_pic_buf_id, i1_ref_idx,
+ pui32_weight_ofsts, ps_pic_buff0->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+
+ if(i1_ref_frame1 >= 0)
+ {
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD16 i2_mv[2];
+ WORD8 i1_ref_idx = 0;
+
+ i2_mv[0] = i2_mvX1;
+ i2_mv[1] = i2_mvY1;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(i2_mv, u1_mb_partw, u1_mb_partw, u1_sub_mb_num, i1_pred,
+ ps_pred_pkd, ps_pic_buff1->u1_pic_buf_id, i1_ref_idx,
+ pui32_weight_ofsts, ps_pic_buff1->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+
+ /* Replication optimisation */
+ s_temp_mv_pred.i2_mv[0] = i2_mv_x;
+ s_temp_mv_pred.i2_mv[1] = i2_mv_y;
+ s_temp_mv_pred.i2_mv[2] = i2_mvX1;
+ s_temp_mv_pred.i2_mv[3] = i2_mvY1;
+
+ /* Calculating colocated zero information */
+ {
+ /*************************************/
+ /* If(bit2 and bit3 set) */
+ /* then */
+ /* (bit0 and bit1) => submmbmode */
+ /* (bit2 and bit3) => mbmode */
+ /* else */
+ /* (bit0 and bit1) => mbmode */
+ /*************************************/
+ /*UWORD8 u1_packed_mb_sub_mb_mode = sub_partition ?
+ (s_mvdirect.i1_partitionsize[0]) : ((s_mvdirect.i1_partitionsize[0]) <<
+ 2);*/
+ UWORD8 u1_packed_mb_sub_mb_mode = (u1_mb_partw == 2) ? 0x03 : 0;
+
+ if(i1_ref_frame0 < 0)
+ {
+ i2_mv_x = i2_mvX1;
+ i2_mv_y = i2_mvY1;
+ }
+
+ /* Change from left shift 4 to 6 - Varun */
+ u1_colz = (ps_cur_mb_info->u1_mb_field_decodingflag << 1) |
+ ((u1_final_ref_idx == 0) && (ABS(i2_mv_x) <= 1) && (ABS(i2_mv_y) <= 1));
+ u1_colz |= (u1_packed_mb_sub_mb_mode << 6);
+ }
+ ps_mv = ps_mv_nmb_start + u1_sub_mb_num;
+ if(ps_mv)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_temp_mv_pred, ps_mv, u1_sub_mb_num, u1_colz, u1_mb_partw,
+ u1_mb_partw);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+
+ if(u1_wd_x == MB_SIZE) ps_dec->u1_currB_type = 0;
+
+ return OK;
+ }
+
+ /***************************************************************************/
+ /* If present MB is 16x16 and the partition of colocated Mb is >= PRED_8x8 */
+ /* i.e 8x8 or less than 8x8 partitions then set up DMA for (0,0) and */
+ /* spatially predicted motion vector and do the multiplexing after */
+ /* motion compensation */
+ /***************************************************************************/
+
+ if((u1_wd_x == MB_SIZE) && (s_mvdirect.i1_num_partitions > 2))
+ {
+ ps_cur_mb_info->u1_Mux = 1;
+ if(i1_ref_frame0 >= 0)
+ {
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD8 i1_ref_idx = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(&(i2_spat_pred_mv[0]), 4, 4, 0, i1_pred, ps_pred_pkd,
+ ps_pic_buff0->u1_pic_buf_id, i1_ref_idx, pui32_weight_ofsts,
+ ps_pic_buff0->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+
+ /****** (0,0) Motion vectors DMA *****/
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD16 i2_mv[2];
+ WORD8 i1_ref_idx = 0;
+
+ i2_mv[0] = 0;
+ i2_mv[1] = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(i2_mv, 4, 4, 0, i1_pred, ps_pred_pkd,
+ ps_pic_buff0->u1_pic_buf_id, i1_ref_idx, pui32_weight_ofsts,
+ ps_pic_buff0->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+ if(i1_ref_frame1 >= 0)
+ {
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD8 i1_ref_idx = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(&(i2_spat_pred_mv[2]), 4, 4, 0, i1_pred, ps_pred_pkd,
+ ps_pic_buff1->u1_pic_buf_id, i1_ref_idx, pui32_weight_ofsts,
+ ps_pic_buff1->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+
+ /****** (0,0) Motion vectors DMA *****/
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD16 i2_mv[2];
+ WORD8 i1_ref_idx = 0;
+
+ i2_mv[0] = 0;
+ i2_mv[1] = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(i2_mv, 4, 4, 0, i1_pred, ps_pred_pkd,
+ ps_pic_buff1->u1_pic_buf_id, i1_ref_idx, pui32_weight_ofsts,
+ ps_pic_buff1->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+ }
+
+ for(i = 0; i < s_mvdirect.i1_num_partitions; i++)
+ {
+ partition_size = s_mvdirect.i1_partitionsize[i];
+ u1_sub_mb_num = s_mvdirect.i1_submb_num[i];
+
+ sub_partition = partition_size >> 2;
+ partition_size &= 0x3;
+ u1_mb_partw = pu1_mb_partw[partition_size];
+ u1_mb_parth = pu1_mb_parth[partition_size];
+ if(sub_partition != 0)
+ {
+ u1_mb_partw >>= 1;
+ u1_mb_parth >>= 1;
+ }
+
+ u1_col_zero_flag = *(ps_col_pic->pu1_col_zero_flag + s_mvdirect.i4_mv_indices[i]);
+ u1_col_zero_flag = u1_col_zero_flag & 0x01;
+
+ /*if(u1_col != u1_col_zero_flag)
+ u1_init = 1;*/
+
+ pi2_final_mv0 = &i2_spat_pred_mv[0];
+ pi2_final_mv1 = &i2_spat_pred_mv[2];
+
+ if(ps_cur_mb_info->u1_Mux != 1)
+ {
+ if(i1_ref_frame0 >= 0)
+ {
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD8 i1_ref_idx = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(pi2_final_mv0, u1_mb_partw, u1_mb_parth, u1_sub_mb_num,
+ i1_pred, ps_pred_pkd, ps_pic_buff0->u1_pic_buf_id,
+ i1_ref_idx, pui32_weight_ofsts,
+ ps_pic_buff0->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+
+ if(i1_ref_frame1 >= 0)
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ WORD8 i1_ref_idx = 0;
+
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(pi2_final_mv1, u1_mb_partw, u1_mb_parth, u1_sub_mb_num,
+ i1_pred, ps_pred_pkd, ps_pic_buff1->u1_pic_buf_id, i1_ref_idx,
+ pui32_weight_ofsts, ps_pic_buff1->u1_pic_type);
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+ }
+
+ /* Replication optimisation */
+ s_temp_mv_pred.i2_mv[0] = pi2_final_mv0[0];
+ s_temp_mv_pred.i2_mv[1] = pi2_final_mv0[1];
+ s_temp_mv_pred.i2_mv[2] = pi2_final_mv1[0];
+ s_temp_mv_pred.i2_mv[3] = pi2_final_mv1[1];
+
+ /* Calculating colocated zero information */
+ {
+ WORD16 i2_mv_x = 0, i2_mv_y = 0;
+ /*************************************/
+ /* If(bit2 and bit3 set) */
+ /* then */
+ /* (bit0 and bit1) => submmbmode */
+ /* (bit2 and bit3) => mbmode */
+ /* else */
+ /* (bit0 and bit1) => mbmode */
+ /*************************************/
+ UWORD8 u1_packed_mb_sub_mb_mode = sub_partition
+ ? (s_mvdirect.i1_partitionsize[i])
+ : ((s_mvdirect.i1_partitionsize[i]) << 2);
+
+ if(i1_ref_frame0 >= 0)
+ {
+ i2_mv_x = pi2_final_mv0[0];
+ i2_mv_y = pi2_final_mv0[1];
+ }
+ else
+ {
+ i2_mv_x = pi2_final_mv1[0];
+ i2_mv_y = pi2_final_mv1[1];
+ }
+
+ u1_colz = (ps_cur_mb_info->u1_mb_field_decodingflag << 1) |
+ ((u1_final_ref_idx == 0) && (ABS(i2_mv_x) <= 1) && (ABS(i2_mv_y) <= 1));
+ u1_colz |= (u1_packed_mb_sub_mb_mode << 4);
+ }
+ ps_mv = ps_mv_nmb_start + u1_sub_mb_num;
+ if(ps_mv)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_temp_mv_pred, ps_mv, u1_sub_mb_num, u1_colz, u1_mb_parth,
+ u1_mb_partw);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ i = 0;
+ if(i1_ref_frame0 >= 0) ps_cur_mb_info->u2_mask[i++] = ui2_mask_fwd;
+ if(i1_ref_frame1 >= 0) ps_cur_mb_info->u2_mask[i] = ui2_mask_bwd;
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_process_ebslice.h b/decoder/svc/isvcd_process_ebslice.h
new file mode 100644
index 0000000..501710c
--- /dev/null
+++ b/decoder/svc/isvcd_process_ebslice.h
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_process_ebslice.h
+ *
+ * @brief
+ * Contains declarations of routines that decode an EB slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PROCESS_EBSLICE_H_
+#define _ISVCD_PROCESS_EBSLICE_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+WORD32 isvcd_parse_ebslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_bslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_mv_pred_ref_tfr_nby2_ebmb(dec_struct_t *ps_svc_lyr_dec, UWORD8 u1_mb_idx,
+ UWORD8 u1_num_mbs);
+
+WORD32 isvcd_parse_bmb_non_direct_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_parse_bmb_non_direct_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_decode_spatial_direct(dec_struct_t *ps_svc_lyr_dec, UWORD8 u1_wd_x,
+ dec_mb_info_t *ps_cur_mb_info, UWORD8 u1_mb_num);
+#endif /* _ISVCD_PROCESS_EBSLICE_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_process_epslice.c b/decoder/svc/isvcd_process_epslice.c
new file mode 100644
index 0000000..d23aa5e
--- /dev/null
+++ b/decoder/svc/isvcd_process_epslice.c
@@ -0,0 +1,2291 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_process_epslice.c
+ *
+ * @brief
+ * Contains routines that decode a I slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "isvcd_mode_mv_resamp.h"
+#include "ih264_debug.h"
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_retrive_infer_mode_mv \endif
+ *
+ * \brief
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+void isvcd_retrive_infer_mode_mv(svc_dec_lyr_struct_t *ps_svc_lyr_dec, mv_pred_t *ps_mvpred,
+ UWORD8 u1_lx, UWORD8 u1_sub_mb_num)
+{
+ mode_motion_ctxt_t *ps_ctxt;
+ mv_pred_t *ps_motion_pred;
+ UWORD8 u1_tmp_lx = (u1_lx << 1);
+
+ ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
+ ps_motion_pred = ps_ctxt->ps_motion_pred_struct;
+ ps_motion_pred += u1_sub_mb_num;
+ ps_mvpred->i2_mv[u1_tmp_lx] = ps_motion_pred->i2_mv[u1_tmp_lx];
+ ps_mvpred->i2_mv[u1_tmp_lx + 1] = ps_motion_pred->i2_mv[u1_tmp_lx + 1];
+
+ return;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_interlyr_motion_mode_pred \endif
+ *
+ * \brief
+ *
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_interlyr_motion_mode_pred(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info,
+ parse_pmbarams_t *ps_mb_part_info,
+ parse_part_params_t *ps_part)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 i4_inter_layer_pred_req_flag;
+ WORD32 i4_listx;
+ WORD32 i4_mb_mode = -1;
+ i4_inter_layer_pred_req_flag = SVCD_FALSE;
+ i4_listx = (ps_dec->ps_cur_slice->u1_slice_type == B_SLICE) ? 2 : 1;
+ /* check Base mode flag and motion predcition flags */
+ if(1 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ i4_inter_layer_pred_req_flag = SVCD_TRUE;
+ }
+ else
+ {
+ UWORD8 u1_mot_pred_flag;
+
+ /* get the packed the motion pred flag of list 0 */
+ u1_mot_pred_flag = ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+
+ /* extract the last 4 bits */
+ u1_mot_pred_flag &= 0x0F;
+
+ if(0 != u1_mot_pred_flag)
+ {
+ i4_inter_layer_pred_req_flag = SVCD_TRUE;
+ }
+
+ /* check for list 1 flags if required */
+ if((2 == i4_listx) && (SVCD_FALSE == i4_inter_layer_pred_req_flag))
+ {
+ /* get the packed the motion pred flag of list 1 */
+ u1_mot_pred_flag = ps_svc_cur_mb_info->au1_motion_pred_flag[1];
+
+ /* extract the last 4 bits */
+ u1_mot_pred_flag &= 0x0F;
+
+ if(0 != u1_mot_pred_flag)
+ {
+ i4_inter_layer_pred_req_flag = SVCD_TRUE;
+ }
+ }
+ }
+
+ if(SVCD_TRUE == i4_inter_layer_pred_req_flag)
+ {
+ mode_motion_ctxt_t *ps_ctxt;
+ mode_motion_lyr_ctxt *ps_lyr_mem;
+
+ ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
+ /* get the current layer ctxt */
+ ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
+
+ ps_ctxt->i4_listx = i4_listx;
+
+ i4_mb_mode =
+ ps_lyr_mem->pf_inter_lyr_pred(ps_svc_lyr_dec->pv_mode_mv_sample_ctxt, ps_cur_mb_info,
+ ps_svc_cur_mb_info, ps_dec, ps_mb_part_info, ps_part);
+ }
+ return i4_mb_mode;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_mv_pred_ref_tfr_nby2_epmb \endif
+ *
+ * \brief
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_mv_pred_ref_tfr_nby2_epmb(dec_struct_t *ps_dec, UWORD8 u1_mb_idx, UWORD8 u1_num_mbs)
+{
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) ps_dec;
+ parse_pmbarams_t *ps_mb_part_info;
+ parse_part_params_t *ps_part;
+ mv_pred_t *ps_mv_nmb, *ps_mv_nmb_start, *ps_mv_ntop, *ps_mv_ntop_start;
+ UWORD32 i, j;
+ const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ WORD32 i2_mv_x, i2_mv_y;
+
+ ps_dec->i4_submb_ofst -= (u1_num_mbs - u1_mb_idx) << 4;
+ ps_mb_part_info = ps_dec->ps_parse_mb_data;
+ ps_part = ps_dec->ps_parse_part_params;
+
+ /* N/2 Mb MvPred and Transfer Setup Loop */
+ for(i = u1_mb_idx; i < u1_num_mbs; i++, ps_mb_part_info++)
+ {
+ UWORD32 u1_colz;
+ UWORD32 u1_field;
+ mv_pred_t s_mvPred = {0};
+ mv_pred_t *ps_mv_pred = &s_mvPred;
+
+ *ps_mv_pred = ps_dec->s_default_mv_pred;
+
+ ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
+
+ /* Restore the slice scratch MbX and MbY context */
+ ps_cur_mb_info = ps_dec->ps_nmb_info + i;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + i;
+ u1_field = ps_cur_mb_info->u1_mb_field_decodingflag;
+
+ ps_mv_nmb_start = ps_dec->ps_mv_cur + (i << 4);
+ ps_dec->u2_mbx = ps_cur_mb_info->u2_mbx;
+ ps_dec->u2_mby = ps_cur_mb_info->u2_mby;
+ ps_dec->u2_mv_2mb[i & 0x1] = 0;
+
+ /* Look for MV Prediction and Reference Transfer in Non-I Mbs */
+ if(!ps_mb_part_info->u1_isI_mb)
+ {
+ UWORD32 u1_blk_no;
+ WORD32 i1_ref_idx, i1_ref_idx1;
+ UWORD32 u1_sub_mb_x, u1_sub_mb_y, u1_sub_mb_num;
+ UWORD32 u1_num_part, u1_num_ref, u1_wd, u1_ht;
+ UWORD32 *pu4_wt_offst, **ppu4_wt_ofst;
+ UWORD32 u1_scale_ref, u4_bot_mb;
+ WORD8 *pi1_ref_idx = ps_mb_part_info->i1_ref_idx[0];
+ pic_buffer_t *ps_ref_frame, **pps_ref_frame;
+ deblk_mb_t *ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + i;
+ WORD32 i4_mb_mode_svc;
+ UWORD8 u1_motion_pred_flag_l0 = ps_svc_cur_mb_info->au1_motion_pred_flag[0];
+
+ /* MB Level initialisations */
+ ps_dec->u4_num_pmbair = i >> u1_mbaff;
+ ps_dec->u1_mb_idx_mv = i;
+ ppu4_wt_ofst = ps_mb_part_info->pu4_wt_offst;
+ pps_ref_frame = ps_dec->ps_ref_pic_buf_lx[0];
+
+ i4_mb_mode_svc = isvcd_interlyr_motion_mode_pred(
+ ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info, ps_mb_part_info, ps_part);
+
+ if((-1 == i4_mb_mode_svc) || (SVC_INTER_MB == i4_mb_mode_svc))
+ {
+ ps_mv_ntop_start =
+ ps_mv_nmb_start - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12;
+
+ u1_num_part = ps_mb_part_info->u1_num_part;
+ ps_cur_deblk_mb->u1_mb_type |= (u1_num_part > 1) << 1;
+ ps_cur_mb_info->u4_pred_info_pkd_idx = ps_dec->u4_pred_info_pkd_idx;
+ ps_cur_mb_info->u1_num_pred_parts = 0;
+
+ /****************************************************/
+ /* weighted u4_ofst pointer calculations, this loop */
+ /* runs maximum 4 times, even in direct cases */
+ /****************************************************/
+ u1_scale_ref = u1_mbaff & u1_field;
+
+ u4_bot_mb = 1 - ps_cur_mb_info->u1_topmb;
+ if(ps_dec->ps_cur_pps->u1_wted_pred_flag)
+ {
+ u1_num_ref = MIN(u1_num_part, 4);
+ for(u1_blk_no = 0; u1_blk_no < u1_num_ref; u1_blk_no++)
+ {
+ i1_ref_idx = pi1_ref_idx[u1_blk_no];
+ if(u1_scale_ref) i1_ref_idx >>= 1;
+ pu4_wt_offst = (UWORD32 *) &ps_dec->pu4_wt_ofsts[2 * X3(i1_ref_idx)];
+ ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst;
+ }
+ }
+ else
+ {
+ ppu4_wt_ofst[0] = NULL;
+ ppu4_wt_ofst[1] = NULL;
+ ppu4_wt_ofst[2] = NULL;
+ ppu4_wt_ofst[3] = NULL;
+ }
+
+ /**************************************************/
+ /* Loop on Partitions */
+ /**************************************************/
+ for(j = 0; j < u1_num_part; j++, ps_part++)
+ {
+ u1_sub_mb_num = ps_part->u1_sub_mb_num;
+ ps_dec->u1_sub_mb_num = u1_sub_mb_num;
+
+ if(PART_NOT_DIRECT != ps_part->u1_is_direct)
+ {
+ /* Mb Skip Mode */
+ /* Setting the default and other members of MvPred Structure */
+ s_mvPred.i2_mv[2] = -1;
+ s_mvPred.i2_mv[3] = -1;
+ s_mvPred.i1_ref_frame[0] = 0;
+ i1_ref_idx = (u1_scale_ref && u4_bot_mb) ? MAX_REF_BUFS : 0;
+ ps_ref_frame = pps_ref_frame[i1_ref_idx];
+ s_mvPred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id;
+ s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type;
+ pu4_wt_offst = (UWORD32 *) &ps_dec->pu4_wt_ofsts[0];
+
+ ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb_start, ps_mv_ntop_start,
+ &s_mvPred, 0, 4, 0, 1, MB_SKIP);
+
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(s_mvPred.i2_mv, 4, 4, 0, PRED_L0, ps_pred_pkd,
+ ps_ref_frame->u1_pic_buf_id,
+ (i1_ref_idx >> u1_scale_ref), pu4_wt_offst,
+ ps_ref_frame->u1_pic_type);
+
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+
+ /* Storing colocated zero information */
+ u1_colz = ((ABS(s_mvPred.i2_mv[0]) <= 1) && (ABS(s_mvPred.i2_mv[1]) <= 1)) +
+ (u1_field << 1);
+
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, u1_colz, 4,
+ 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ else
+ {
+ u1_sub_mb_x = u1_sub_mb_num & 0x03;
+ u1_sub_mb_y = u1_sub_mb_num >> 2;
+ u1_blk_no = (u1_num_part < 4)
+ ? j
+ : (((u1_sub_mb_y >> 1) << 1) + (u1_sub_mb_x >> 1));
+
+ ps_mv_ntop = ps_mv_ntop_start + u1_sub_mb_x;
+ ps_mv_nmb = ps_mv_nmb_start + u1_sub_mb_num;
+
+ u1_wd = ps_part->u1_partwidth;
+ u1_ht = ps_part->u1_partheight;
+
+ /* Populate the colpic info and reference frames */
+ i1_ref_idx = pi1_ref_idx[u1_blk_no];
+ s_mvPred.i1_ref_frame[0] = i1_ref_idx;
+
+ if((1 != ps_svc_cur_mb_info->u1_base_mode_flag) &&
+ (0 == (u1_motion_pred_flag_l0 & (1 << u1_blk_no))))
+ {
+ /********************************************************/
+ /* Predict Mv */
+ /* Add Mv Residuals and store back */
+ /********************************************************/
+ ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb, ps_mv_ntop,
+ &s_mvPred, u1_sub_mb_num, u1_wd, 0, 1,
+ ps_cur_mb_info->u1_mb_mc_mode);
+
+ i2_mv_x = ps_mv_nmb->i2_mv[0];
+ i2_mv_y = ps_mv_nmb->i2_mv[1];
+ i2_mv_x += s_mvPred.i2_mv[0];
+ i2_mv_y += s_mvPred.i2_mv[1];
+ s_mvPred.i2_mv[0] = i2_mv_x;
+ s_mvPred.i2_mv[1] = i2_mv_y;
+ }
+ else
+ {
+ isvcd_retrive_infer_mode_mv(ps_svc_lyr_dec, &s_mvPred, 0,
+ u1_sub_mb_num);
+
+ if(0 != (u1_motion_pred_flag_l0 & (1 << u1_blk_no)))
+ {
+ i2_mv_x = ps_mv_nmb->i2_mv[0];
+ i2_mv_y = ps_mv_nmb->i2_mv[1];
+ i2_mv_x += s_mvPred.i2_mv[0];
+ i2_mv_y += s_mvPred.i2_mv[1];
+ s_mvPred.i2_mv[0] = i2_mv_x;
+ s_mvPred.i2_mv[1] = i2_mv_y;
+ }
+ i2_mv_x = s_mvPred.i2_mv[0];
+ i2_mv_y = s_mvPred.i2_mv[1];
+ }
+ /********************************************************/
+ /* Transfer setup call */
+ /* convert RefIdx if it is MbAff */
+ /* Pass Weight Offset and refFrame */
+ /********************************************************/
+ i1_ref_idx1 = i1_ref_idx >> u1_scale_ref;
+ if(u1_scale_ref && ((i1_ref_idx & 0x01) != u4_bot_mb))
+ i1_ref_idx1 += MAX_REF_BUFS;
+ if(-1 == i1_ref_idx1) return NOT_OK;
+ ps_ref_frame = pps_ref_frame[i1_ref_idx1];
+ pu4_wt_offst = ppu4_wt_ofst[u1_blk_no];
+
+ {
+ pred_info_pkd_t *ps_pred_pkd;
+ ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx;
+ ih264d_fill_pred_info(s_mvPred.i2_mv, u1_wd, u1_ht, u1_sub_mb_num,
+ PRED_L0, ps_pred_pkd, ps_ref_frame->u1_pic_buf_id,
+ (i1_ref_idx >> u1_scale_ref), pu4_wt_offst,
+ ps_ref_frame->u1_pic_type);
+
+ ps_dec->u4_pred_info_pkd_idx++;
+ ps_cur_mb_info->u1_num_pred_parts++;
+ }
+
+ /* Fill colocated info in MvPred structure */
+ s_mvPred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id;
+ s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type;
+
+ /* Calculating colocated zero information */
+ u1_colz = (u1_field << 1) |
+ ((i1_ref_idx == 0) && (ABS(i2_mv_x) <= 1) && (ABS(i2_mv_y) <= 1));
+ u1_colz |= ps_mb_part_info->u1_col_info[u1_blk_no];
+
+ /* Replicate the motion vectors and colzero u4_flag */
+ /* for all sub-partitions */
+
+ if(ps_mv_nmb)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb, u1_sub_mb_num, u1_colz,
+ u1_ht, u1_wd);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+
+ /* to take care of 16 parttitions increment for base mode flag case*/
+ if(1 == ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ ps_part += (MAX_NUM_MB_PART - u1_num_part);
+ }
+ }
+ else
+ {
+ ps_cur_deblk_mb->u1_mb_type |= D_INTRA_IBL;
+ if((ps_svc_lyr_dec->u1_layer_identifier != TARGET_LAYER) &&
+ (DBLK_ENABLED == ps_dec->ps_cur_slice->u1_disable_dblk_filter_idc))
+ {
+ ps_cur_deblk_mb->u1_deblocking_mode = MB_ENABLE_FILTERING;
+ }
+ /* to take care of 16 parttitions increment for base mode flag case*/
+ if(1 != ps_svc_cur_mb_info->u1_base_mode_flag)
+ {
+ return NOT_OK;
+ }
+ {
+ ps_part += (MAX_NUM_MB_PART);
+ }
+ /* Storing colocated zero information */
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0,
+ (UWORD8) (u1_field << 1), 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ else
+ {
+ /* Storing colocated zero information */
+ if(ps_mv_nmb_start)
+ {
+ ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, (UWORD8) (u1_field << 1),
+ 4, 4);
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_update_intra_mb_inter_layer_info \endif
+ *
+ * \brief : IT
+ * This function decodes an Inter MB fornfor ot target base layers
+ * Only for Progressive : saves residual for upper enhancement layers
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+void isvcd_update_intra_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info)
+{
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTRA_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_update_ipcm_mb_inter_layer_info \endif
+*
+* \brief : IT
+* This function decodes an IPM MB fornfor ot target base layers
+* Only for Progressive : saves residual for upper enhancement layers
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+void isvcd_update_ipcm_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info)
+{
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_IPCM_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_update_ibl_mb_inter_layer_info \endif
+*
+* \brief : IT
+* This function decodes an IBL MB fornfor ot target base layers
+* Only for Progressive : saves residual for upper enhancement layers
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+void isvcd_update_ibl_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info)
+{
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_IBL_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_update_inter_mb_inter_layer_info \endif
+*
+* \brief : IT
+* This function decodes an IBL MB fornfor ot target base layers
+* Only for Progressive : saves residual for upper enhancement layers
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+void isvcd_update_inter_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, UWORD8 u1_inference_mode)
+{
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode =
+ u1_inference_mode ? SVC_IBL_MB : SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = ps_cur_mb_info->u2_luma_csbp;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz =
+ (UWORD8) ps_cur_mb_info->u2_chroma_csbp;
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 1))
+ {
+ /* Four bits for Cb in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0x0F;
+ }
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 2))
+ {
+ /* Four bits for Cr in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0xF0;
+ }
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_process_inter_mb_no_rsd_pred_non_target \endif
+ *
+ * \brief : IT
+ * This function decodes an Inter MB fornfor ot target base layers
+ * Only for Progressive : saves residual for upper enhancement layers
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_process_inter_mb_no_rsd_pred_non_target(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_inference_mode)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD16 u2_luma_stride, u2_chroma_stride;
+ WORD16 *pi2_y_coeff, *pi2_luma_res_ptr, *pi2_chroma_res_ptr;
+ UWORD32 u4_luma_dc_only_csbp = 0;
+ UWORD32 u4_luma_dc_only_cbp = 0;
+
+ if(0 != ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ return NOT_OK;
+ }
+ u2_luma_stride = ps_svc_lyr_dec->u2_residual_resample_luma_stride;
+ pi2_luma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 4) * u2_luma_stride);
+
+ u2_chroma_stride = ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
+ pi2_chroma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 3) * u2_chroma_stride);
+
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ u4_luma_dc_only_csbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ if(!ps_dec->ps_cur_pps->u1_entropy_coding_mode)
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff8x8_mb(ps_dec, ps_cur_mb_info);
+ }
+ }
+
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+ /* Inverse Transform and Reconstruction */
+ if(ps_cur_mb_info->u1_cbp & 0x0f)
+ {
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 16; i++)
+ {
+ if(CHECKBIT(ps_cur_mb_info->u2_luma_csbp, i))
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x3) * BLK_SIZE) +
+ (i >> 2) * (u2_luma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_csbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4_dc(
+ pi2_level, pi2_out, u2_luma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4(
+ pi2_level, pi2_out, u2_luma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ WORD16 *pi2_scale_matrix_ptr;
+ WORD32 i;
+
+ pi2_scale_matrix_ptr = ps_dec->s_high_profile.i2_scalinglist8x8[1];
+
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 ai2_tmp[64] = {0};
+ WORD16 *pi16_levelBlock =
+ pi2_y_coeff + (i << 6); /* move to the next 8x8 adding 64 */
+
+ WORD16 *pi2_out =
+ pi2_luma_res_ptr + ((i & 0x1) * BLK8x8SIZE) + (i >> 1) * (u2_luma_stride << 3);
+ if(CHECKBIT(ps_cur_mb_info->u1_cbp, i))
+ {
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_cbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8_dc(
+ pi16_levelBlock, pi2_out, u2_luma_stride,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8(
+ pi16_levelBlock, pi2_out, u2_luma_stride,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Decode Chroma Block */
+ ih264d_unpack_chroma_coeff4x4_mb(ps_dec, ps_cur_mb_info);
+ /*--------------------------------------------------------------------*/
+ /* Chroma Blocks decoding */
+ /*--------------------------------------------------------------------*/
+ {
+ UWORD8 u1_chroma_cbp = (UWORD8) (ps_cur_mb_info->u1_cbp >> 4);
+
+ if(u1_chroma_cbp != CBPC_ALLZERO)
+ {
+ UWORD32 u4_scale_u = ps_cur_mb_info->u1_qpc_div6;
+ UWORD32 u4_scale_v = ps_cur_mb_info->u1_qpcr_div6;
+ UWORD16 u2_chroma_csbp = ps_cur_mb_info->u2_chroma_csbp;
+
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_chroma_res_ptr +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4(
+ pi2_level, pi2_out, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4], u4_scale_u,
+ ai2_tmp, pi2_level);
+ }
+ else if(pi2_level[0] != 0)
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4_dc(
+ pi2_level, pi2_out, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4], u4_scale_u,
+ ai2_tmp, pi2_level);
+ }
+ }
+ }
+ }
+
+ pi2_y_coeff += MB_CHROM_SIZE;
+ u2_chroma_csbp >>= 4;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_chroma_res_ptr + 1 +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4(
+ pi2_level, pi2_out, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5], u4_scale_v,
+ ai2_tmp, pi2_level);
+ }
+ else if(pi2_level[0] != 0)
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4_dc(
+ pi2_level, pi2_out, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5], u4_scale_v,
+ ai2_tmp, pi2_level);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode =
+ u1_inference_mode ? SVC_IBL_MB : SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = ps_cur_mb_info->u2_luma_csbp;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz =
+ (UWORD8) ps_cur_mb_info->u2_chroma_csbp;
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 1))
+ {
+ /* Four bits for Cb in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0x0F;
+ }
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 2))
+ {
+ /* Four bits for Cr in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0xF0;
+ }
+ return OK;
+}
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_process_inter_mb_rsd_pred_non_target \endif
+ *
+ * \brief : IT + Residual :
+ * This function decodes an Inter MB for non target layers
+ * Only for Progressive : saves residual + IT for upper enhancement layers
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_process_inter_mb_rsd_pred_non_target(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_inference_mode,
+ UWORD16 *pu2_res_luma_csbp)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD16 u2_luma_stride, u2_chroma_stride;
+ WORD16 *pi2_y_coeff, *pi2_luma_res_ptr, *pi2_chroma_res_ptr;
+ UWORD32 u4_luma_dc_only_csbp = 0;
+ UWORD32 u4_luma_dc_only_cbp = 0;
+ UWORD16 u2_res_luma_csbp = 0;
+ UWORD16 u2_res_chroma_csbp = 0, u2_res_chroma_nnz = 0;
+ WORD32 ret;
+
+ if(0 != ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ return NOT_OK;
+ }
+ u2_luma_stride = ps_svc_lyr_dec->u2_residual_resample_luma_stride;
+ pi2_luma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 4) * u2_luma_stride);
+
+ u2_chroma_stride = ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
+ pi2_chroma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 3) * u2_chroma_stride);
+
+ // residual prediction SVC
+ ret = isvcd_process_residual_resample_mb(ps_svc_lyr_dec, ps_cur_mb_info);
+ if(ret != OK)
+ {
+ return ret;
+ }
+
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ u4_luma_dc_only_csbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ if(!ps_dec->ps_cur_pps->u1_entropy_coding_mode)
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff8x8_mb(ps_dec, ps_cur_mb_info);
+ }
+ }
+
+ *pu2_res_luma_csbp = 0;
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+ /* Inverse Transform and Reconstruction */
+ if(ps_cur_mb_info->u1_cbp & 0x0f)
+ {
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 16; i++)
+ {
+ if(CHECKBIT(ps_cur_mb_info->u2_luma_csbp, i))
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x3) * BLK_SIZE) +
+ (i >> 2) * (u2_luma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_csbp, i))
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4_dc(
+ pi2_level, pi2_out, pi2_out, u2_luma_stride, u2_luma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ u2_res_luma_csbp = ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4(
+ pi2_level, pi2_out, pi2_out, u2_luma_stride, u2_luma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ else
+ {
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x3) * BLK_SIZE) +
+ (i >> 2) * (u2_luma_stride << 2);
+
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_residual_luma_4x4(pi2_out, u2_luma_stride);
+ }
+ *pu2_res_luma_csbp |= (u2_res_luma_csbp << i);
+ }
+ }
+ else
+ {
+ WORD16 *pi2_scale_matrix_ptr;
+ WORD32 i;
+
+ pi2_scale_matrix_ptr = ps_dec->s_high_profile.i2_scalinglist8x8[1];
+
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 ai2_tmp[64] = {0};
+ WORD16 *pi16_levelBlock =
+ pi2_y_coeff + (i << 6); /* move to the next 8x8 adding 64 */
+
+ WORD16 *pi2_out =
+ pi2_luma_res_ptr + ((i & 0x1) * BLK8x8SIZE) + (i >> 1) * (u2_luma_stride << 3);
+ if(CHECKBIT(ps_cur_mb_info->u1_cbp, i))
+ {
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_cbp, i))
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8_dc(
+ pi16_levelBlock, pi2_out, pi2_out, u2_luma_stride,
+ u2_luma_stride,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ u2_res_luma_csbp = ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8(
+ pi16_levelBlock, pi2_out, pi2_out, u2_luma_stride, u2_luma_stride,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ else
+ {
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x1) * BLK8x8SIZE) +
+ (i >> 1) * (u2_luma_stride << 3);
+
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_residual_luma_8x8(pi2_out, u2_luma_stride);
+ }
+ *pu2_res_luma_csbp |= (u2_res_luma_csbp << (((i >> 1) << 3) + ((i & 0x01) << 1)));
+ }
+ }
+ }
+ else
+ {
+ WORD16 *pi2_out = pi2_luma_res_ptr;
+
+ *pu2_res_luma_csbp = ps_svc_lyr_dec->pf_residual_luma_16x16(pi2_out, u2_luma_stride);
+ }
+
+ /* Decode Chroma Block */
+ ih264d_unpack_chroma_coeff4x4_mb(ps_dec, ps_cur_mb_info);
+ /*--------------------------------------------------------------------*/
+ /* Chroma Blocks decoding */
+ /*--------------------------------------------------------------------*/
+ {
+ UWORD8 u1_chroma_cbp = (UWORD8) (ps_cur_mb_info->u1_cbp >> 4);
+
+ u2_res_chroma_nnz =
+ ps_svc_lyr_dec->pf_residual_chroma_cb_cr_8x8(pi2_chroma_res_ptr, u2_chroma_stride);
+
+ if(u1_chroma_cbp != CBPC_ALLZERO)
+ {
+ UWORD32 u4_scale_u = ps_cur_mb_info->u1_qpc_div6;
+ UWORD32 u4_scale_v = ps_cur_mb_info->u1_qpcr_div6;
+ UWORD16 u2_chroma_csbp = ps_cur_mb_info->u2_chroma_csbp;
+
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_chroma_res_ptr +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ u2_res_chroma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4(
+ pi2_level, pi2_out, pi2_out, u2_chroma_stride, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4],
+ u4_scale_u, ai2_tmp, pi2_level);
+ u2_res_chroma_nnz &= (0XFF ^ (1 << i));
+ u2_res_chroma_nnz |= (u2_res_chroma_csbp << i);
+ }
+ else if(pi2_level[0] != 0)
+ {
+ u2_res_chroma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4_dc(
+ pi2_level, pi2_out, pi2_out, u2_chroma_stride, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4],
+ u4_scale_u, ai2_tmp, pi2_level);
+ u2_res_chroma_nnz &= (0XFF ^ (1 << i));
+ u2_res_chroma_nnz |= (u2_res_chroma_csbp << i);
+ }
+ }
+ }
+ }
+
+ pi2_y_coeff += MB_CHROM_SIZE;
+ u2_chroma_csbp >>= 4;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ WORD16 *pi2_out = pi2_chroma_res_ptr + 1 +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ u2_res_chroma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4(
+ pi2_level, pi2_out, pi2_out, u2_chroma_stride, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5],
+ u4_scale_v, ai2_tmp, pi2_level);
+ u2_res_chroma_nnz &= (0XFF ^ (1 << (i + 4)));
+ u2_res_chroma_nnz |= (u2_res_chroma_csbp << (i + 4));
+ }
+ else if(pi2_level[0] != 0)
+ {
+ u2_res_chroma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4_dc(
+ pi2_level, pi2_out, pi2_out, u2_chroma_stride, u2_chroma_stride,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5],
+ u4_scale_v, ai2_tmp, pi2_level);
+ u2_res_chroma_nnz &= (0XFF ^ (1 << (i + 4)));
+ u2_res_chroma_nnz |= (u2_res_chroma_csbp << (i + 4));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode =
+ u1_inference_mode ? SVC_IBL_MB : SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = *pu2_res_luma_csbp;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = (UWORD8) u2_res_chroma_nnz;
+ return OK;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_process_ii_mb \endif
+*
+* \brief
+* This function decodes an intra inter mb
+*
+* \return
+* 0 on Success and Error code otherwise
+**************************************************************************
+*/
+WORD32 isvcd_process_ii_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num)
+{
+ res_prms_t *ps_res_prms;
+ WORD32 i4_status;
+ UWORD8 u1_ii_mb_mode = 0;
+ mb_coord_t s_mb_coord = {0};
+ mem_element_t s_ref_mb_mode = {0};
+ svc_dec_lyr_struct_t *ps_svc_dec_ref_layer;
+
+ ps_svc_dec_ref_layer = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
+ ps_res_prms = &ps_svc_lyr_dec->s_res_prms;
+ s_mb_coord.u2_mb_x = ps_cur_mb_info->u2_mbx;
+ s_mb_coord.u2_mb_y = ps_cur_mb_info->u2_mby;
+
+ /* Restricted resolution change has significance only */
+ /* at resolution change layer */
+ if(SVCD_FALSE == ps_res_prms->u1_rstrct_res_change_flag)
+ {
+ s_ref_mb_mode.pv_buffer = ps_svc_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
+ s_ref_mb_mode.i4_element_size = sizeof(inter_lyr_mb_prms_t);
+ s_ref_mb_mode.i4_num_element_stride = ps_svc_dec_ref_layer->u2_inter_lyr_mb_prms_stride;
+
+ i4_status = isvcd_ii_pred_compute_flags_mb(ps_svc_lyr_dec->pv_ii_pred_ctxt, &s_ref_mb_mode,
+ &s_mb_coord, ps_cur_mb_info, ps_svc_cur_mb_info,
+ &u1_ii_mb_mode);
+
+ if(OK != i4_status)
+ {
+ return i4_status;
+ }
+ }
+
+ if(SVC_INTRA_INTER_MB == u1_ii_mb_mode)
+ {
+ i4_status = isvcd_process_ibl_mb(ps_svc_lyr_dec, ps_cur_mb_info, u1_mb_num, 1);
+ if(OK != i4_status)
+ {
+ return i4_status;
+ }
+ isvcd_ii_pred_mb(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_decode_recon_tfr_nmb_non_base_lyr \endif
+ *
+ * \brief
+ *
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_decode_recon_tfr_nmb_non_base_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ UWORD8 u1_mb_idx, UWORD8 u1_num_mbs,
+ UWORD8 u1_num_mbs_next, UWORD8 u1_tfr_n_mb,
+ UWORD8 u1_end_of_row)
+{
+ WORD32 i, j;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 u1_end_of_row_next;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ UWORD16 *pu2_res_luma_csbp;
+ const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ const UWORD32 u1_slice_type = ps_dec->ps_cur_slice->u1_slice_type;
+ const WORD32 u1_skip_th =
+ ((u1_slice_type != I_SLICE) ? (ps_dec->u1_B ? B_8x8 : PRED_8x8R0) : -1);
+ const UWORD32 u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (ps_dec->u1_B ? 23 : 5) : 0);
+ WORD32 ret = OK;
+
+ if(!((0 == ps_svc_lyr_dec->u1_base_res_flag) ||
+ ((1 == ps_svc_lyr_dec->u1_base_res_flag) &&
+ (1 == ps_svc_lyr_dec->ps_nal_svc_ext->u1_no_inter_layer_pred_flag))))
+ {
+ return NOT_OK;
+ }
+ /* N Mb MC Loop */
+ for(i = u1_mb_idx; i < u1_num_mbs; i++)
+ {
+ ps_cur_mb_info = ps_dec->ps_nmb_info + i;
+ ps_dec->u4_dma_buf_idx = 0;
+ ps_dec->u4_pred_info_idx = 0;
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
+ {
+ {
+ WORD32 pred_cnt = 0;
+ pred_info_pkd_t *ps_pred_pkd;
+ UWORD32 u4_pred_info_pkd_idx;
+
+ u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
+
+ while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
+ {
+ ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
+
+ ps_dec->p_form_mb_part_info(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
+ ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
+ ps_cur_mb_info);
+ u4_pred_info_pkd_idx++;
+ pred_cnt++;
+ }
+ }
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ps_dec->p_motion_compensate(ps_dec, ps_cur_mb_info);
+ }
+ }
+ else if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
+ {
+ {
+ WORD32 pred_cnt = 0;
+ pred_info_pkd_t *ps_pred_pkd;
+ UWORD32 u4_pred_info_pkd_idx;
+
+ u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
+
+ while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
+ {
+ ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
+
+ ps_dec->p_form_mb_part_info(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
+ ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
+ ps_cur_mb_info);
+
+ u4_pred_info_pkd_idx++;
+ pred_cnt++;
+ }
+ }
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ /* Decode MB skip */
+ ps_dec->p_motion_compensate(ps_dec, ps_cur_mb_info);
+ }
+
+ *pu2_res_luma_csbp = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
+ ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+ }
+ }
+
+ /* N Mb IQ IT RECON Loop */
+ for(j = u1_mb_idx; j < i; j++)
+ {
+ ps_cur_mb_info = ps_dec->ps_nmb_info + j;
+ ps_svc_cur_mb_info = ps_svc_lyr_dec->ps_svc_nmb_info + j;
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_slice_id = (WORD8) ps_dec->u2_cur_slice_num;
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
+ {
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ /* inter intra pred generation */
+ if(SVCD_FALSE == ps_svc_lyr_dec->u1_dyadic_flag)
+ {
+ ret =
+ isvcd_process_ii_mb(ps_svc_lyr_dec, ps_cur_mb_info, ps_svc_cur_mb_info, j);
+ if(ret != OK) return ret;
+ }
+ if(0 == ps_svc_cur_mb_info->u1_residual_prediction_flag)
+ {
+ // IT + Recon
+ ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 0);
+ *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
+ }
+ else
+ {
+ // IT + Residual + Recon
+ ret = isvcd_process_inter_mb_rsd_pred_target_lyr(ps_svc_lyr_dec, ps_cur_mb_info,
+ j, 0, pu2_res_luma_csbp);
+ if(ret != OK) return ret;
+ }
+ }
+ else if(ps_svc_lyr_dec->u1_layer_identifier == MEDIAL_ENHANCEMENT_LAYER)
+ {
+ if(0 == ps_svc_cur_mb_info->u1_residual_prediction_flag)
+ {
+ // IT : to be consumed by Target
+ ret = isvcd_process_inter_mb_no_rsd_pred_non_target(ps_svc_lyr_dec,
+ ps_cur_mb_info, 0);
+ *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
+ if(ret != OK) return ret;
+ }
+ else
+ {
+ // IT + Residual : to be consumed by target
+ ret = isvcd_process_inter_mb_rsd_pred_non_target(ps_svc_lyr_dec, ps_cur_mb_info,
+ 0, pu2_res_luma_csbp);
+ if(ret != OK) return ret;
+ }
+ }
+ else
+ {
+ return NOT_OK;
+ }
+ }
+ else if((ps_cur_mb_info->u1_mb_type != MB_SKIP) && (ps_cur_mb_info->u1_mb_type != MB_INFER))
+ {
+ if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
+ {
+ ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
+ ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_intra_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ else
+ {
+ isvcd_update_ipcm_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ *pu2_res_luma_csbp = 0;
+ }
+ else if(ps_cur_mb_info->u1_mb_type == MB_INFER)
+ {
+ /* inter layer intra prediction : intra upsample, IQ, IT ,deblock */
+ /* Intra resample for IBL mode */
+ ret = isvcd_process_ibl_mb(ps_svc_lyr_dec, ps_cur_mb_info, j, 0);
+ if(ret != OK) return ret;
+ ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 1);
+ *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
+
+ ps_dec->pi1_left_pred_mode[0] = DC;
+ ps_dec->pi1_left_pred_mode[1] = DC;
+ ps_dec->pi1_left_pred_mode[2] = DC;
+ ps_dec->pi1_left_pred_mode[3] = DC;
+
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[0] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[1] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[2] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[3] = DC;
+
+ isvcd_update_ibl_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ if(ps_dec->u4_num_cores < 3)
+ {
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ps_svc_lyr_dec->pf_svc_compute_bs(ps_svc_lyr_dec, ps_cur_mb_info,
+ (UWORD16) (j >> u1_mbaff));
+ }
+ }
+ else if(ps_svc_lyr_dec->u1_layer_identifier == MEDIAL_ENHANCEMENT_LAYER)
+ {
+ if(ps_dec->u4_num_cores < 3)
+ {
+ if(ps_dec->u4_app_disable_deblk_frm == 0)
+ ps_svc_lyr_dec->pf_svc_compute_bs(ps_svc_lyr_dec, ps_cur_mb_info,
+ (UWORD16) (j >> u1_mbaff));
+ }
+ }
+
+ if(ps_dec->u4_use_intrapred_line_copy)
+ {
+ ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
+ }
+ }
+
+ /*MB deblocking*/
+ if(ps_dec->u4_nmb_deblk == 1)
+ {
+ UWORD32 u4_wd_y, u4_wd_uv;
+ tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
+ UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
+ const WORD32 i4_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
+ const WORD32 i4_cr_qp_idx_ofst = ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
+
+ u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
+ u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_mb_idx;
+
+ ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
+ ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
+
+ for(j = u1_mb_idx; j < i; j++)
+ {
+ if(ps_dec->u4_cur_deblk_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ return NOT_OK;
+ }
+ ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
+ u4_wd_y, u4_wd_uv);
+ }
+ }
+
+ if(u1_tfr_n_mb)
+ {
+ /****************************************************************/
+ /* Check for End Of Row in Next iteration */
+ /****************************************************************/
+ u1_end_of_row_next =
+ u1_num_mbs_next && (u1_num_mbs_next <= (ps_dec->u1_recon_mb_grp >> u1_mbaff));
+
+ /****************************************************************/
+ /* Transfer the Following things */
+ /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */
+ /* N-Mb Recon Data ( To Ext Frame Buffer ) */
+ /* N-Mb Intrapredline Data ( Updated Internally) */
+ /* N-Mb MV Data ( To Ext MV Buffer ) */
+ /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */
+ /****************************************************************/
+ ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row, u1_end_of_row_next);
+ ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs;
+ ps_dec->u4_pred_info_idx = 0;
+ ps_dec->u4_dma_buf_idx = 0;
+ }
+ return OK;
+}
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_decode_recon_tfr_nmb_base_lyr \endif
+ *
+ * \brief
+ *
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_decode_recon_tfr_nmb_base_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD8 u1_mb_idx,
+ UWORD8 u1_num_mbs, UWORD8 u1_num_mbs_next,
+ UWORD8 u1_tfr_n_mb, UWORD8 u1_end_of_row)
+{
+ WORD32 j;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 u1_end_of_row_next;
+ dec_mb_info_t *ps_cur_mb_info;
+ const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ const UWORD32 u1_slice_type = ps_dec->ps_cur_slice->u1_slice_type;
+ const WORD32 u1_skip_th =
+ ((u1_slice_type != I_SLICE) ? (ps_dec->u1_B ? B_8x8 : PRED_8x8R0) : -1);
+ const UWORD32 u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (ps_dec->u1_B ? 23 : 5) : 0);
+ WORD32 ret = OK;
+
+ if(1 != ps_svc_lyr_dec->u1_base_res_flag)
+ {
+ return NOT_OK;
+ }
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ return NOT_OK;
+ }
+
+ /* N Mb IQ IT + Residual Store for Inter / + Recon for Intra Loop */
+ for(j = u1_mb_idx; j < u1_num_mbs; j++)
+ {
+ ps_dec->u4_dma_buf_idx = 0;
+ ps_dec->u4_pred_info_idx = 0;
+ ps_cur_mb_info = ps_dec->ps_nmb_info + j;
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_slice_id = (WORD8) ps_dec->u2_cur_slice_num;
+
+ if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
+ {
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
+ ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+ }
+ else if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
+ {
+ /* Only IT : Store Residual (WORD16) for Higher Layers : Base layer*/
+ ret = isvcd_process_inter_mb_no_rsd_pred_non_target(ps_svc_lyr_dec, ps_cur_mb_info, 0);
+ if(ret != OK) return ret;
+ }
+ else if(ps_cur_mb_info->u1_mb_type != MB_SKIP)
+ {
+ if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
+ {
+ ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
+ ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_intra_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ else
+ {
+ isvcd_update_ipcm_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ }
+
+ if(ps_dec->u4_use_intrapred_line_copy)
+ {
+ ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
+ }
+ }
+
+ /*MB deblocking*/
+ if(ps_dec->u4_nmb_deblk == 1)
+ {
+ UWORD32 u4_wd_y, u4_wd_uv;
+ tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
+ UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
+ const WORD32 i4_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
+ const WORD32 i4_cr_qp_idx_ofst = ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
+
+ u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
+ u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
+
+ ps_cur_mb_info = ps_dec->ps_nmb_info + u1_mb_idx;
+
+ ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
+ ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
+
+ for(j = u1_mb_idx; j < u1_num_mbs; j++)
+ {
+ /* IN SVC base layers only intra MB's Need to be deblocked*/
+ deblk_mb_t *ps_top_mb, *ps_left_mb, *ps_cur_mb;
+ ps_cur_mb = ps_dec->ps_cur_deblk_mb;
+ if(!(ps_cur_mb->u1_deblocking_mode & MB_DISABLE_FILTERING))
+ {
+ if(ps_dec->u4_deblk_mb_x)
+ {
+ ps_left_mb = ps_cur_mb - 1;
+ }
+ else
+ {
+ ps_left_mb = NULL;
+ }
+ if(ps_dec->u4_deblk_mb_y != 0)
+ {
+ ps_top_mb = ps_cur_mb - (ps_dec->u2_frm_wd_in_mbs);
+ }
+ else
+ {
+ ps_top_mb = NULL;
+ }
+
+ if(ps_cur_mb->u1_deblocking_mode & MB_DISABLE_LEFT_EDGE) ps_left_mb = NULL;
+ if(ps_cur_mb->u1_deblocking_mode & MB_DISABLE_TOP_EDGE) ps_top_mb = NULL;
+
+ /* Top Horizontal Edge*/
+ if(NULL != ps_top_mb)
+ {
+ if(!(ps_top_mb->u1_mb_type & D_INTRA_MB))
+ {
+ ps_cur_mb->u4_bs_table[0] = 0;
+ }
+ }
+ else
+ {
+ ps_cur_mb->u4_bs_table[0] = 0;
+ }
+
+ /* Left Vertical Edge*/
+ if(NULL != ps_left_mb)
+ {
+ if(!(ps_left_mb->u1_mb_type & D_INTRA_MB))
+ {
+ ps_cur_mb->u4_bs_table[4] = 0;
+ }
+ }
+ else
+ {
+ ps_cur_mb->u4_bs_table[4] = 0;
+ }
+ }
+
+ if(ps_dec->u4_cur_deblk_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ return NOT_OK;
+ }
+
+ ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
+ u4_wd_y, u4_wd_uv);
+ }
+ }
+
+ if(u1_tfr_n_mb)
+ {
+ /****************************************************************/
+ /* Check for End Of Row in Next iteration */
+ /****************************************************************/
+ u1_end_of_row_next =
+ u1_num_mbs_next && (u1_num_mbs_next <= (ps_dec->u1_recon_mb_grp >> u1_mbaff));
+
+ /****************************************************************/
+ /* Transfer the Following things */
+ /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */
+ /* N-Mb Recon Data ( To Ext Frame Buffer ) */
+ /* N-Mb Intrapredline Data ( Updated Internally) */
+ /* N-Mb MV Data ( To Ext MV Buffer ) */
+ /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */
+ /****************************************************************/
+ ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row, u1_end_of_row_next);
+ ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs;
+ ps_dec->u4_pred_info_idx = 0;
+ ps_dec->u4_dma_buf_idx = 0;
+ }
+ return OK;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_process_ibl_mb \endif
+*
+* \brief
+* This function decodes an ibl mb
+*
+*
+* \return
+*
+**************************************************************************
+*/
+WORD32 isvcd_process_ibl_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_mb_num, UWORD8 u1_inter_intra_mode)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ intra_sampling_ctxt_t *ps_ctxt;
+ svc_dec_lyr_struct_t *ps_svc_dec_ref_layer;
+ pic_buffer_t *ps_frame_buf = ps_dec->ps_cur_pic;
+ pic_buffer_t *ps_frame_buf_ref_layer;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ mem_element_t s_ref_mb_mode = {0};
+ mem_element_t s_inp_luma = {0};
+ mem_element_t s_inp_chroma = {0};
+ mem_element_t s_out_luma = {0};
+ mem_element_t s_out_chroma = {0};
+ WORD32 i4_ref_x_luma, i4_ref_y_luma, i4_luma_incr = 0;
+ WORD32 i4_ref_x_chroma, i4_ref_y_chroma, i4_chroma_incr = 0;
+ UWORD32 u4_cur_y_stride, u4_cur_uv_stride;
+ UWORD32 u4_ref_y_stride, u4_ref_uv_stride;
+ WORD32 i4_ref_luma_instra_sample_correction_offset = 0;
+ WORD32 i4_ref_chroma_instra_sample_correction_offset = 0;
+ ref_mb_map_t *ps_x_off_len_luma;
+ ref_mb_map_t *ps_y_off_len_luma;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+ mb_coord_t s_mb_coord = {0};
+ WORD32 ret = OK;
+ UNUSED(u1_mb_num);
+
+ ps_ctxt = (intra_sampling_ctxt_t *) ps_svc_lyr_dec->pv_intra_sample_ctxt;
+ ps_svc_dec_ref_layer = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
+
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ u4_cur_y_stride = ps_dec->u2_frm_wd_y;
+ u4_cur_uv_stride = ps_dec->u2_frm_wd_uv;
+ u4_ref_y_stride = ps_svc_dec_ref_layer->s_dec.u2_frm_wd_y;
+ u4_ref_uv_stride = ps_svc_dec_ref_layer->s_dec.u2_frm_wd_uv;
+
+ ps_frame_buf_ref_layer = ps_svc_dec_ref_layer->s_dec.ps_cur_pic;
+ if(0 == u1_inter_intra_mode)
+ {
+ s_out_luma.pv_buffer = ps_frame_buf->pu1_buf1 + (ps_cur_mb_info->u2_mbx << 4) +
+ (u4_cur_y_stride * (ps_cur_mb_info->u2_mby << 4));
+ s_out_luma.i4_element_size = 1;
+ s_out_luma.i4_num_element_stride = u4_cur_y_stride;
+
+ s_out_chroma.pv_buffer = ps_frame_buf->pu1_buf2 +
+ (ps_cur_mb_info->u2_mbx << 3) * YUV420SP_FACTOR +
+ (u4_cur_uv_stride * (ps_cur_mb_info->u2_mby << 3));
+ s_out_chroma.i4_element_size = 1;
+ s_out_chroma.i4_num_element_stride = u4_cur_uv_stride;
+ }
+ else
+ {
+ if(SVCD_TRUE == ps_svc_lyr_dec->s_res_prms.u1_dyadic_flag)
+ {
+ return NOT_OK;
+ }
+
+ s_out_luma.pv_buffer = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
+ s_out_luma.i4_element_size = 1;
+ s_out_luma.i4_num_element_stride = MB_SIZE;
+
+ s_out_chroma.pv_buffer = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
+ s_out_chroma.i4_element_size = 1;
+ s_out_chroma.i4_num_element_stride = MB_SIZE;
+ }
+
+ /* get the projected locations buffer pointers */
+ {
+ intra_samp_map_ctxt_t *ps_luma_map, *ps_chroma_map;
+
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+
+ ps_x_off_len_luma = ps_luma_map->ps_x_offset_length;
+ ps_y_off_len_luma = ps_luma_map->ps_y_offset_length;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+ }
+ i4_ref_x_luma = ps_svc_lyr_dec->ps_intsam_luma_map_horz[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_ref_y_luma = ps_svc_lyr_dec->ps_intsam_luma_map_vert[ps_cur_mb_info->u2_mby].i2_offset;
+
+ i4_luma_incr = ps_x_off_len_luma[ps_cur_mb_info->u2_mbx].i2_offset - i4_ref_x_luma;
+ i4_luma_incr +=
+ (ps_y_off_len_luma[ps_cur_mb_info->u2_mby].i2_offset - i4_ref_y_luma) * u4_ref_y_stride;
+
+ i4_ref_x_chroma = ps_svc_lyr_dec->ps_intsam_chroma_map_horz[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_ref_y_chroma = ps_svc_lyr_dec->ps_intsam_chroma_map_vert[ps_cur_mb_info->u2_mby].i2_offset;
+
+ i4_chroma_incr = ps_x_off_len_chroma[ps_cur_mb_info->u2_mbx].i2_offset - i4_ref_x_chroma;
+ i4_chroma_incr <<= 1;
+ i4_chroma_incr += (ps_y_off_len_chroma[ps_cur_mb_info->u2_mby].i2_offset - i4_ref_y_chroma) *
+ u4_ref_uv_stride;
+ if(SVCD_FALSE == ps_svc_lyr_dec->s_res_prms.u1_dyadic_flag)
+ {
+ i4_ref_x_luma = CLIP3(0, (ps_svc_dec_ref_layer->s_dec.u2_frm_wd_y - 1), i4_ref_x_luma);
+ i4_ref_y_luma = CLIP3(0, (ps_svc_dec_ref_layer->s_dec.u2_frm_ht_y - 1), i4_ref_y_luma);
+ }
+
+ i4_ref_luma_instra_sample_correction_offset =
+ i4_ref_x_luma + (i4_ref_y_luma) * (WORD32) u4_ref_y_stride;
+
+ s_inp_luma.pv_buffer = ps_frame_buf_ref_layer->pu1_buf1 + i4_luma_incr +
+ i4_ref_luma_instra_sample_correction_offset;
+ s_inp_luma.i4_element_size = 1;
+ s_inp_luma.i4_num_element_stride = u4_ref_y_stride;
+
+ if(SVCD_FALSE == ps_svc_lyr_dec->s_res_prms.u1_dyadic_flag)
+ {
+ i4_ref_x_chroma = CLIP3(0, (ps_svc_dec_ref_layer->s_dec.u2_frm_wd_uv - 1), i4_ref_x_chroma);
+ i4_ref_y_chroma = CLIP3(0, (ps_svc_dec_ref_layer->s_dec.u2_frm_ht_uv - 1), i4_ref_y_chroma);
+ }
+ i4_ref_chroma_instra_sample_correction_offset =
+ (i4_ref_x_chroma << 1) + (i4_ref_y_chroma) * (WORD32) u4_ref_uv_stride;
+
+ s_inp_chroma.pv_buffer = ps_frame_buf_ref_layer->pu1_buf2 + i4_chroma_incr +
+ i4_ref_chroma_instra_sample_correction_offset;
+ s_inp_chroma.i4_element_size = 1;
+ s_inp_chroma.i4_num_element_stride = u4_ref_uv_stride;
+
+ s_ref_mb_mode.pv_buffer = ps_svc_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
+ s_ref_mb_mode.i4_element_size = sizeof(inter_lyr_mb_prms_t);
+ s_ref_mb_mode.i4_num_element_stride = ps_svc_dec_ref_layer->u2_inter_lyr_mb_prms_stride;
+
+ s_mb_coord.u2_mb_x = ps_cur_mb_info->u2_mbx;
+ s_mb_coord.u2_mb_y = ps_cur_mb_info->u2_mby;
+
+ if(SVCD_TRUE == ps_svc_lyr_dec->s_res_prms.u1_dyadic_flag)
+ {
+ ret = isvcd_intra_resamp_mb_dyadic(ps_ctxt, &s_inp_luma, &s_inp_chroma, &s_ref_mb_mode,
+ &s_out_luma, &s_out_chroma, &s_mb_coord, ps_svc_lyr_dec);
+ }
+ else
+ {
+ ret = isvcd_intra_resamp_mb(ps_ctxt, &s_inp_luma, &s_inp_chroma, &s_ref_mb_mode,
+ &s_out_luma, &s_out_chroma, &s_mb_coord);
+ }
+ if(OK != ret) return ret;
+ return OK;
+}
+/*!
+**************************************************************************
+* \if Function name : isvcd_process_residual_resample_mb \endif
+*
+* \brief
+* This function decodes a residual resample mb
+*
+*
+* \return
+*
+**************************************************************************
+*/
+WORD32 isvcd_process_residual_resample_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ svc_dec_lyr_struct_t *ps_svc_dec_ref_layer;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ mem_element_t s_ref_mb_mode = {0};
+ mem_element_t s_inp_luma = {0};
+ mem_element_t s_inp_chroma = {0};
+ mem_element_t s_out_luma = {0};
+ mem_element_t s_out_chroma = {0};
+
+ /* projected locations pointer */
+ ref_mb_map_t *ps_x_off_len_luma;
+ ref_mb_map_t *ps_y_off_len_luma;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+ WORD32 i4_ref_x_luma, i4_ref_y_luma;
+ WORD32 i4_ref_x_chroma, i4_ref_y_chroma;
+ WORD32 i4_ref_luma_ressam_correction_offset = 0;
+ WORD32 i4_ref_chroma_ressam_correction_offset = 0;
+ WORD32 i4_inp_luma_stride, i4_inp_chroma_stride;
+ WORD32 i4_out_luma_stride, i4_out_chroma_stride;
+ WORD32 i4_inp_luma_offset = 0, i4_inp_chroma_offset = 0;
+ WORD32 ret;
+
+ ps_svc_dec_ref_layer = ps_svc_lyr_dec->ps_dec_svc_ref_layer;
+ ps_ctxt = (residual_sampling_ctxt_t *) ps_svc_lyr_dec->pv_residual_sample_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ i4_inp_luma_stride = ps_svc_dec_ref_layer->u2_residual_resample_luma_stride;
+ i4_inp_chroma_stride = ps_svc_dec_ref_layer->u2_residual_resample_chroma_stride;
+ i4_out_luma_stride = ps_svc_lyr_dec->u2_residual_resample_luma_stride;
+ i4_out_chroma_stride = ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
+
+ {
+ residual_samp_map_ctxt_t *ps_luma_map, *ps_chroma_map;
+
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ ps_x_off_len_luma = ps_luma_map->ps_x_offset_length;
+ ps_y_off_len_luma = ps_luma_map->ps_y_offset_length;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+ }
+ i4_ref_x_luma = ps_svc_lyr_dec->ps_ressam_luma_map_horz[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_ref_y_luma = ps_svc_lyr_dec->ps_ressam_luma_map_vert[ps_cur_mb_info->u2_mby].i2_offset;
+
+ i4_ref_x_chroma = ps_svc_lyr_dec->ps_ressam_chroma_map_horz[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_ref_y_chroma = ps_svc_lyr_dec->ps_ressam_chroma_map_vert[ps_cur_mb_info->u2_mby].i2_offset;
+
+ i4_ref_x_luma = CLIP3(0, (ps_lyr_ctxt->i4_ref_width - 1), i4_ref_x_luma);
+ i4_ref_y_luma = CLIP3(0, (ps_lyr_ctxt->i4_ref_height - 1), i4_ref_y_luma);
+ i4_ref_x_chroma = CLIP3(0, ((ps_lyr_ctxt->i4_ref_width >> 1) - 1), i4_ref_x_chroma);
+ i4_ref_y_chroma = CLIP3(0, ((ps_lyr_ctxt->i4_ref_height >> 1) - 1), i4_ref_y_chroma);
+
+ {
+ WORD32 i4_offset_x, i4_offset_y;
+
+ i4_offset_x = ps_x_off_len_luma[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_offset_y = ps_y_off_len_luma[ps_cur_mb_info->u2_mby].i2_offset;
+
+ /* check for offsets inside frame dimensions */
+ if(0 <= i4_offset_x)
+ {
+ /* validity of pointer passed */
+ if(!(i4_offset_x >= i4_ref_x_luma))
+ {
+ return NOT_OK;
+ }
+ i4_inp_luma_offset += (i4_offset_x - i4_ref_x_luma);
+ }
+
+ if(0 <= i4_offset_y)
+ {
+ /* validity of pointer passed */
+ if(!(i4_offset_y >= i4_ref_y_luma))
+ {
+ return NOT_OK;
+ }
+ i4_inp_luma_offset += (i4_offset_y - i4_ref_y_luma) * i4_inp_luma_stride;
+ }
+
+ i4_offset_x = ps_x_off_len_chroma[ps_cur_mb_info->u2_mbx].i2_offset;
+ i4_offset_y = ps_y_off_len_chroma[ps_cur_mb_info->u2_mby].i2_offset;
+
+ /* check for offsets inside frame dimensions */
+ if(0 <= i4_offset_x)
+ {
+ /* validity of pointer passed */
+ if(!(i4_offset_x >= i4_ref_x_chroma))
+ {
+ return NOT_OK;
+ }
+ i4_inp_chroma_offset += (i4_offset_x - i4_ref_x_chroma) << 1;
+ }
+
+ if(0 <= i4_offset_y)
+ {
+ /* validity of pointer passed */
+ if(!(i4_offset_y >= i4_ref_y_chroma))
+ {
+ return NOT_OK;
+ }
+ i4_inp_chroma_offset += (i4_offset_y - i4_ref_y_chroma) * (i4_inp_chroma_stride << 1);
+ }
+ }
+
+ i4_ref_luma_ressam_correction_offset = i4_ref_x_luma + (i4_ref_y_luma) *i4_inp_luma_stride;
+
+ s_inp_luma.pv_buffer = ps_svc_dec_ref_layer->pi2_il_residual_resample_mb_luma_frm_start +
+ i4_inp_luma_offset + i4_ref_luma_ressam_correction_offset;
+ s_inp_luma.i4_element_size = 1;
+ s_inp_luma.i4_num_element_stride = i4_inp_luma_stride;
+
+ i4_ref_chroma_ressam_correction_offset =
+ (i4_ref_x_chroma << 1) + (i4_ref_y_chroma) *i4_inp_chroma_stride;
+
+ s_inp_chroma.pv_buffer = ps_svc_dec_ref_layer->pi2_il_residual_resample_mb_chroma_frm_start +
+ i4_inp_chroma_offset + i4_ref_chroma_ressam_correction_offset;
+ s_inp_chroma.i4_element_size = 1;
+ s_inp_chroma.i4_num_element_stride = i4_inp_luma_stride;
+
+ s_ref_mb_mode.pv_buffer = ps_svc_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
+ s_ref_mb_mode.i4_element_size = sizeof(inter_lyr_mb_prms_t);
+ s_ref_mb_mode.i4_num_element_stride = ps_svc_dec_ref_layer->u2_inter_lyr_mb_prms_stride;
+
+ s_out_luma.i4_element_size = 1;
+ s_out_luma.pv_buffer =
+ ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start +
+ ((ps_cur_mb_info->u2_mbx << 4) +
+ (i4_out_luma_stride * (ps_cur_mb_info->u2_mby << 4)) * s_out_luma.i4_element_size);
+
+ s_out_luma.i4_num_element_stride = i4_out_luma_stride;
+
+ s_out_chroma.i4_element_size = 1;
+ s_out_chroma.pv_buffer =
+ ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start +
+ ((ps_cur_mb_info->u2_mbx << 4) +
+ (i4_out_chroma_stride * (ps_cur_mb_info->u2_mby << 3)) * s_out_chroma.i4_element_size);
+ s_out_chroma.i4_num_element_stride = i4_out_chroma_stride;
+
+ ret = ps_lyr_ctxt->pf_residual_samp_mb(ps_ctxt, &s_inp_luma, &s_inp_chroma, &s_ref_mb_mode,
+ &s_out_luma, &s_out_chroma, ps_cur_mb_info->u2_mbx,
+ ps_cur_mb_info->u2_mby);
+ if(ret != OK)
+ {
+ return ret;
+ }
+ return OK;
+}
+
+/*!
+ **************************************************************************
+ * \if Function name : isvcd_process_inter_mb_rsd_pred_target_lyr \endif
+ *
+ * \brief IT+ Residual + Recon
+ * This function decodes an Inter MB.
+ *
+ *
+ * \return
+ * 0 on Success and Error code otherwise
+ **************************************************************************
+ */
+WORD32 isvcd_process_inter_mb_rsd_pred_target_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_inference_mode,
+ UWORD16 *pu2_res_luma_csbp)
+{
+ UWORD8 *pu1_rec_y, *pu1_rec_u;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ UWORD32 ui_rec_width, u4_recwidth_cr;
+ UWORD16 u2_luma_stride, u2_chroma_stride;
+ WORD16 *pi2_y_coeff, *pi2_luma_res_ptr, *pi2_chroma_res_ptr;
+ UWORD32 u1_mb_field_decoding_flag;
+ const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD32 uc_botMb;
+ UWORD32 u4_num_pmbair;
+ tfr_ctxt_t *ps_frame_buf = ps_dec->ps_frame_buf_ip_recon;
+ UWORD32 u4_luma_dc_only_csbp = 0;
+ UWORD32 u4_luma_dc_only_cbp = 0;
+ UWORD16 u2_res_luma_csbp = 0;
+ WORD32 ret;
+
+ if(0 != ps_dec->ps_cur_slice->u1_mbaff_frame_flag)
+ {
+ return NOT_OK;
+ }
+ uc_botMb = 1 - ps_cur_mb_info->u1_topmb;
+ u4_num_pmbair = (u1_mb_num >> u1_mbaff);
+ u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag;
+
+ pu1_rec_y = ps_frame_buf->pu1_dest_y + (u4_num_pmbair << 4);
+ pu1_rec_u = ps_frame_buf->pu1_dest_u + (u4_num_pmbair << 3) * YUV420SP_FACTOR;
+ ui_rec_width = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag;
+ u4_recwidth_cr = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag;
+
+ u2_luma_stride = ps_svc_lyr_dec->u2_residual_resample_luma_stride;
+ pi2_luma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 4) * u2_luma_stride);
+
+ u2_chroma_stride = ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
+ pi2_chroma_res_ptr = ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start +
+ (ps_cur_mb_info->u2_mbx << 4) +
+ ((ps_cur_mb_info->u2_mby << 3) * u2_chroma_stride);
+
+ ret = isvcd_process_residual_resample_mb(ps_svc_lyr_dec, ps_cur_mb_info);
+ if(ret != OK)
+ {
+ return ret;
+ }
+ if(u1_mbaff)
+ {
+ if(uc_botMb)
+ {
+ pu1_rec_y += (u1_mb_field_decoding_flag ? (ui_rec_width >> 1) : (ui_rec_width << 4));
+ pu1_rec_u +=
+ (u1_mb_field_decoding_flag ? (u4_recwidth_cr >> 1) : (u4_recwidth_cr << 3));
+ }
+ }
+
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ u4_luma_dc_only_csbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ if(!ps_dec->ps_cur_pps->u1_entropy_coding_mode)
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, ps_cur_mb_info, 0);
+ }
+ else
+ {
+ u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff8x8_mb(ps_dec, ps_cur_mb_info);
+ }
+ }
+
+ *pu2_res_luma_csbp = 0;
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+
+ /* Inverse Transform and Reconstruction */
+ if(ps_cur_mb_info->u1_cbp & 0x0f)
+ {
+ if(!ps_cur_mb_info->u1_tran_form8x8)
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 16; i++)
+ {
+ if(CHECKBIT(ps_cur_mb_info->u2_luma_csbp, i))
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ UWORD8 *pu1_pred_sblk =
+ pu1_rec_y + ((i & 0x3) * BLK_SIZE) + (i >> 2) * (ui_rec_width << 2);
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x3) * BLK_SIZE) +
+ (i >> 2) * (u2_luma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_csbp, i))
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4_dc(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, ui_rec_width,
+ u2_luma_stride, ui_rec_width,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, ui_rec_width,
+ u2_luma_stride, ui_rec_width,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[3],
+ ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ else
+ {
+ UWORD8 *pu1_pred_sblk =
+ pu1_rec_y + ((i & 0x3) * BLK_SIZE) + (i >> 2) * (ui_rec_width << 2);
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x3) * BLK_SIZE) +
+ (i >> 2) * (u2_luma_stride << 2);
+
+ u2_res_luma_csbp = ps_svc_lyr_dec->pf_pred_residual_recon_luma_4x4(
+ pu1_pred_sblk, pi2_out, pu1_pred_sblk, ui_rec_width, u2_luma_stride,
+ ui_rec_width);
+ }
+ *pu2_res_luma_csbp |= (u2_res_luma_csbp << i);
+ }
+ }
+ else
+ {
+ WORD16 *pi2_scale_matrix_ptr;
+ WORD32 i;
+
+ pi2_scale_matrix_ptr = ps_dec->s_high_profile.i2_scalinglist8x8[1];
+
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 ai2_tmp[64] = {0};
+ WORD16 *pi16_levelBlock =
+ pi2_y_coeff + (i << 6); /* move to the next 8x8 adding 64 */
+
+ UWORD8 *pu1_pred_sblk =
+ pu1_rec_y + ((i & 0x1) * BLK8x8SIZE) + (i >> 1) * (ui_rec_width << 3);
+ WORD16 *pi2_out =
+ pi2_luma_res_ptr + ((i & 0x1) * BLK8x8SIZE) + (i >> 1) * (u2_luma_stride << 3);
+ if(CHECKBIT(ps_cur_mb_info->u1_cbp, i))
+ {
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u4_luma_dc_only_cbp, i))
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8_dc(
+ pi16_levelBlock, pu1_pred_sblk, pi2_out, pu1_pred_sblk,
+ ui_rec_width, u2_luma_stride, ui_rec_width,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ else
+ {
+ u2_res_luma_csbp =
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8(
+ pi16_levelBlock, pu1_pred_sblk, pi2_out, pu1_pred_sblk,
+ ui_rec_width, u2_luma_stride, ui_rec_width,
+ gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6],
+ (UWORD16 *) pi2_scale_matrix_ptr, ps_cur_mb_info->u1_qp_div6,
+ ai2_tmp, 0, NULL);
+ }
+ }
+ }
+ else
+ {
+ UWORD8 *pu1_pred_sblk =
+ pu1_rec_y + ((i & 0x1) * BLK8x8SIZE) + (i >> 1) * (ui_rec_width << 3);
+ WORD16 *pi2_out = pi2_luma_res_ptr + ((i & 0x1) * BLK8x8SIZE) +
+ (i >> 1) * (u2_luma_stride << 3);
+
+ u2_res_luma_csbp = ps_svc_lyr_dec->pf_pred_residual_recon_luma_8x8(
+ pu1_pred_sblk, pi2_out, pu1_pred_sblk, ui_rec_width, u2_luma_stride,
+ ui_rec_width);
+ }
+ *pu2_res_luma_csbp |= (u2_res_luma_csbp << (((i >> 1) << 3) + ((i & 0x01) << 1)));
+ }
+ }
+ }
+ else
+ {
+ UWORD8 *pu1_pred_sblk = pu1_rec_y;
+ WORD16 *pi2_out = pi2_luma_res_ptr;
+
+ *pu2_res_luma_csbp = ps_svc_lyr_dec->pf_pred_residual_recon_luma_16x16(
+ pu1_pred_sblk, pi2_out, pu1_pred_sblk, ui_rec_width, u2_luma_stride, ui_rec_width);
+ }
+
+ /* Decode Chroma Block */
+ ih264d_unpack_chroma_coeff4x4_mb(ps_dec, ps_cur_mb_info);
+ /*--------------------------------------------------------------------*/
+ /* Chroma Blocks decoding */
+ /*--------------------------------------------------------------------*/
+ {
+ UWORD8 u1_chroma_cbp = (UWORD8) (ps_cur_mb_info->u1_cbp >> 4);
+
+ if(u1_chroma_cbp != CBPC_ALLZERO)
+ {
+ UWORD32 u4_scale_u = ps_cur_mb_info->u1_qpc_div6;
+ UWORD32 u4_scale_v = ps_cur_mb_info->u1_qpcr_div6;
+ UWORD16 u2_chroma_csbp = ps_cur_mb_info->u2_chroma_csbp;
+
+ pi2_y_coeff = ps_dec->pi2_coeff_data;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ UWORD8 *pu1_pred_sblk = pu1_rec_u + ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u4_recwidth_cr << 2);
+ WORD16 *pi2_out = pi2_chroma_res_ptr +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4], u4_scale_u,
+ ai2_tmp, pi2_level);
+ }
+ else if(pi2_level[0] != 0)
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4_dc(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[4], u4_scale_u,
+ ai2_tmp, pi2_level);
+ }
+ else
+ {
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_4x4(
+ pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr);
+ }
+ }
+ }
+ }
+
+ pi2_y_coeff += MB_CHROM_SIZE;
+ u2_chroma_csbp >>= 4;
+
+ {
+ UWORD32 i;
+ WORD16 ai2_tmp[16] = {0};
+ for(i = 0; i < 4; i++)
+ {
+ WORD16 *pi2_level = pi2_y_coeff + (i << 4);
+ UWORD8 *pu1_pred_sblk = pu1_rec_u + 1 +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u4_recwidth_cr << 2);
+ WORD16 *pi2_out = pi2_chroma_res_ptr + 1 +
+ ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) +
+ (i >> 1) * (u2_chroma_stride << 2);
+ PROFILE_DISABLE_IQ_IT_RECON()
+ {
+ if(CHECKBIT(u2_chroma_csbp, i))
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5], u4_scale_v,
+ ai2_tmp, pi2_level);
+ }
+ else if(pi2_level[0] != 0)
+ {
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4_dc(
+ pi2_level, pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr,
+ gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6],
+ (UWORD16 *) ps_dec->s_high_profile.i2_scalinglist4x4[5], u4_scale_v,
+ ai2_tmp, pi2_level);
+ }
+ else
+ {
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_4x4(
+ pu1_pred_sblk, pi2_out, pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Cr*/
+ {
+ UWORD8 *pu1_pred_sblk = pu1_rec_u;
+ WORD16 *pi2_out = pi2_chroma_res_ptr;
+
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_8x8(pu1_pred_sblk, pi2_out,
+ pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr);
+ }
+
+ /* Cb*/
+ {
+ UWORD8 *pu1_pred_sblk = pu1_rec_u + 1;
+ WORD16 *pi2_out = pi2_chroma_res_ptr + 1;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_8x8(pu1_pred_sblk, pi2_out,
+ pu1_pred_sblk, u4_recwidth_cr,
+ u2_chroma_stride, u4_recwidth_cr);
+ }
+ }
+ }
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode =
+ u1_inference_mode ? SVC_IBL_MB : SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size = ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = ps_cur_mb_info->u2_luma_csbp;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz =
+ (UWORD8) ps_cur_mb_info->u2_chroma_csbp;
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 1))
+ {
+ /* Four bits for Cb in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0x0F;
+ }
+ if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag, 2))
+ {
+ /* Four bits for Cr in DC only cbp */
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz |= 0xF0;
+ }
+ return (0);
+}
diff --git a/decoder/svc/isvcd_process_epslice.h b/decoder/svc/isvcd_process_epslice.h
new file mode 100644
index 0000000..0330dd1
--- /dev/null
+++ b/decoder/svc/isvcd_process_epslice.h
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_process_epslice.h
+ *
+ * @brief
+ * Contains declarations of routines that decode an EP slice type
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_PROCESS_EPSLICE_H_
+#define _ISVCD_PROCESS_EPSLICE_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+WORD32 isvcd_parse_epslice(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_first_mb_in_slice);
+
+WORD32 isvcd_parse_pmb_cabac(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_parse_pmb_cavlc(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_num_mbsNby2);
+WORD32 isvcd_process_ibl_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_mb_num, UWORD8 u1_inter_intra_mode);
+
+WORD32 isvcd_process_residual_resample_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info);
+
+WORD32 isvcd_process_inter_mb_no_rsd_pred_non_target(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_inference_mode);
+
+WORD32 isvcd_process_inter_mb_rsd_pred_non_target(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_inference_mode,
+ UWORD16 *pu2_res_luma_csbp);
+
+WORD32 isvcd_process_inter_mb_rsd_pred_target_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, UWORD8 u1_mb_num,
+ UWORD8 u1_inference_mode,
+ UWORD16 *pu2_res_luma_csbp);
+
+WORD32 isvcd_mv_pred_ref_tfr_nby2_epmb(dec_struct_t *ps_dec, UWORD8 u1_num_mbs,
+ UWORD8 u1_num_mbsNby2);
+
+WORD32 isvcd_decode_recon_tfr_nmb_non_base_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ UWORD8 u1_mb_idx, UWORD8 u1_num_mbs,
+ UWORD8 u1_num_mbs_next, UWORD8 u1_tfr_n_mb,
+ UWORD8 u1_end_of_row);
+WORD32 isvcd_decode_recon_tfr_nmb_base_lyr(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD8 u1_mb_idx,
+ UWORD8 u1_num_mbs, UWORD8 u1_num_mbs_next,
+ UWORD8 u1_tfr_n_mb, UWORD8 u1_end_of_row);
+void isvcd_retrive_infer_mode_mv(svc_dec_lyr_struct_t *ps_svc_lyr_dec, mv_pred_t *ps_mvpred,
+ UWORD8 u1_lx, UWORD8 u1_sub_mb_num);
+
+void isvcd_update_intra_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info);
+
+void isvcd_update_ipcm_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info);
+
+void isvcd_update_ibl_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info);
+void isvcd_update_inter_mb_inter_layer_info(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info,
+ UWORD8 u1_inference_mode);
+void isvcd_ii_pred_mb(void *pv_svc_dec, dec_mb_info_t *ps_cur_mb_info);
+
+WORD32 isvcd_mark_err_slice_skip(svc_dec_lyr_struct_t *ps_svc_lyr_dec, WORD32 num_mb_skip,
+ UWORD8 u1_is_idr_slice, UWORD16 u2_frame_num,
+ pocstruct_t *ps_cur_poc, WORD32 prev_slice_err);
+
+void isvcd_one_to_one(svc_dec_lyr_struct_t *ps_svc_lyr_dec, struct pic_buffer_t *ps_col_pic,
+ directmv_t *ps_direct, UWORD8 u1_wd_x, WORD32 u2_sub_mb_ofst,
+ dec_mb_info_t *ps_cur_mb_info);
+
+WORD32 isvcd_process_ii_mb(svc_dec_lyr_struct_t *ps_svc_lyr_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num);
+#endif /* _ISVCD_PROCESS_EPSLICE_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_resamp_svc.c b/decoder/svc/isvcd_resamp_svc.c
new file mode 100644
index 0000000..32c5f97
--- /dev/null
+++ b/decoder/svc/isvcd_resamp_svc.c
@@ -0,0 +1,4304 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_resamp_svc.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "isvcd_resamp_svc.h"
+#include "ih264_debug.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_get_ceil_log2 */
+/* */
+/* Description : this function returns the CeilLog2 of the given number */
+/* */
+/* */
+/* Inputs : i4_input : input number */
+/* Globals : none */
+/* Processing : it calculate the bits and returns it */
+/* */
+/* Outputs : none */
+/* Returns : ceil of log to base 2 */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 05 04 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 svcd_get_ceil_log2(WORD32 i4_input)
+{
+ WORD32 i4_bits = 0;
+
+ /* check for negative number */
+ ASSERT(i4_input >= 0);
+
+ i4_input--;
+ while(i4_input > 0)
+ {
+ i4_bits++;
+ i4_input >>= 1;
+ } /* endof while input > 0 loop */
+ return (i4_bits);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_2d_memset */
+/* */
+/* Description : Function performs 2D memset operation */
+/* */
+/* */
+/* Inputs : 1. Buffer pointer */
+/* 2. width */
+/* 3. Height */
+/* 4. Stride */
+/* 5. value */
+/* Globals : None */
+/* Processing : calls memset fucntion */
+/* */
+/* Outputs : Updates the buffer */
+/* Returns : status */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 24 06 2009 Kishore Draft */
+/* */
+/*****************************************************************************/
+void svcd_2d_memset(void *pv_buf, WORD32 i4_width, WORD32 i4_ht, WORD32 i4_stride, WORD32 i4_val)
+{
+ WORD32 i4_y;
+ UWORD8 *pu1_buf;
+
+ pu1_buf = (UWORD8 *) pv_buf;
+
+ for(i4_y = 0; i4_y < i4_ht; i4_y++)
+ {
+ memset(pu1_buf, i4_val, i4_width);
+
+ /* Increment the pointer */
+ pu1_buf += i4_stride;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_copy_data */
+/* */
+/* Description : this module copies the data from source to destination */
+/* the amount of data to be copied is passed as input */
+/* */
+/* Inputs : pu1_src : pointer to the source buffer */
+/* u2_src_stride : source buffer stride */
+/* pu1_dst : pointer to the destination buffer */
+/* u2_dst_stride : destination buffer stride */
+/* u4_num_bytes : number of bytes to be copied */
+/* u4_num_lines : number of lines to be copied */
+/* Globals : none */
+/* Processing : it does a memcpy from source to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : both buffers are assumed to be 2-D buffers */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 29 04 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_copy_data(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst, WORD32 i4_dst_stride,
+ WORD32 i4_num_bytes, WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines;
+
+ ASSERT(NULL != pu1_src);
+ ASSERT(NULL != pu1_dst);
+
+ /* loop for copy all the lines requried */
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ memcpy(pu1_dst, pu1_src, i4_num_bytes);
+ pu1_src += i4_src_stride;
+ pu1_dst += i4_dst_stride;
+ }
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_copy_data_semiplanr */
+/* */
+/* Description : this module copies the data from source to destination */
+/* the amount of data to be copied is passed as input */
+/* */
+/* Inputs : pu1_src : pointer to the source buffer */
+/* i4_src_stride : source buffer stride */
+/* pu1_dst1 : pointer to the destination buffer 1 */
+/* pu1_dst2 : pointer to the destination buffer 2 */
+/* i4_dst_stride : destination buffer stride */
+/* i4_num_bytes : number of bytes to be copied */
+/* i4_num_lines : number of lines to be copied */
+/* Globals : none */
+/* Processing : it does a memcpy from source to destination */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* Issues : both buffers are assumed to be 2-D buffers */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 29 04 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_copy_data_semiplanr(UWORD8 *pu1_src, WORD32 i4_src_stride, UWORD8 *pu1_dst1,
+ UWORD8 *pu1_dst2, WORD32 i4_dst_stride, WORD32 i4_num_bytes,
+ WORD32 i4_num_lines)
+{
+ WORD32 i4_vert_lines, u4_i;
+
+ if(NULL == pu1_src) ||(NULL == pu1_dst1) ||(NULL == pu1_dst2)){return;}
+
+ /* loop for copy all the lines requried */
+ for(i4_vert_lines = 0; i4_vert_lines < i4_num_lines; i4_vert_lines++)
+ {
+ for(u4_i = 0; u4_i < i4_num_bytes; u4_i++)
+ {
+ *(pu1_dst1 + u4_i) = *(pu1_src + (2 * u4_i));
+ *(pu1_dst2 + u4_i) = *(pu1_src + (2 * u4_i) + 1);
+ }
+
+ pu1_src += i4_src_stride;
+ pu1_dst1 += i4_dst_stride;
+ pu1_dst2 += i4_dst_stride;
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_get_ref_layer_avlblty_dyadic */
+/* */
+/* Description : This function is used to find the mb type of the */
+/* corresponding MB in the reference layer for dyadic cases */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra samp context */
+/* pi1_ref_mb_modes : ref mb modes buffer pointer */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_ref_mb_x : reference MB location X */
+/* i4_ref_mb_y : reference MB location Y */
+/* pi4_mb_type : pointer to store the mb type */
+/* i1_curr_slice_id : slice id of current MB */
+/* i1_cons_intr_samp_flag :constrained intra resampling flag*/
+/* Globals : none */
+/* Processing : it derives the bit corresponding to reference MB and */
+/* stores the mbtype as INTRA if the bit is set */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_get_ref_layer_avlblty_dyadic(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_ref_mb_x,
+ WORD32 i4_ref_mb_y, WORD32 *pi4_avlblty,
+ WORD8 i1_curr_slice_id, WORD8 i1_cons_intr_samp_flag)
+{
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 i1_mb_mode;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes += (i4_ref_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_ref_mb_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ if(0 > i1_mb_mode)
+ {
+ /* INTER */
+ *pi4_avlblty = 0;
+ }
+ else
+ {
+ /* INTRA */
+ *pi4_avlblty = 1;
+ }
+
+ /* if constrained intra flag is 1 then check for same slice id */
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ if(1 == *pi4_avlblty)
+ {
+ /* check for different slice idc */
+ if(i1_mb_mode != i1_curr_slice_id)
+ {
+ /* store the mode as not available for upsampling */
+ *pi4_avlblty = 0;
+ }
+ }
+ }
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_diagonal_construct_dyadic */
+/* */
+/* Description : This function fills the unavaible pixels in the reference*/
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray : popinter to reference array */
+/* i4_refarray_wd: width of the reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : constructed pixel */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+UWORD8 svcd_diagonal_construct_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xd_index,
+ WORD32 i4_yd_index, UWORD8 *pu1_refarray,
+ WORD32 i4_refarray_wd)
+{
+ WORD32 i4_diff_hor_ver, i4_sgn_xy;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_samp1, i4_samp2, i4_samp3;
+ WORD32 i4_result;
+ UWORD8 *pu1_tmp;
+
+ i4_diff_hor_ver = ABS(i4_xd_index) - ABS(i4_yd_index);
+ i4_sgn_xy = SIGN(i4_xd_index * i4_yd_index);
+
+ if(i4_diff_hor_ver > 0)
+ {
+ i4_xc = i4_x - (i4_sgn_xy * i4_yd_index);
+ i4_yc = i4_y - i4_yd_index;
+
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc - 1];
+ i4_samp2 = pu1_tmp[i4_xc];
+ i4_samp3 = pu1_tmp[i4_xc + 1];
+ }
+ else if(i4_diff_hor_ver < 0)
+ {
+ i4_xc = i4_x - i4_xd_index;
+ i4_yc = i4_y - (i4_sgn_xy * i4_xd_index);
+
+ pu1_tmp = pu1_refarray + ((i4_yc - 1) * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp2 = pu1_tmp[i4_xc];
+ pu1_tmp += i4_refarray_wd;
+ i4_samp3 = pu1_tmp[i4_xc];
+ }
+ else
+ {
+ WORD32 i4_ref_xd, i4_ref_yd;
+
+ i4_ref_xd = i4_x - i4_xd_index;
+ i4_ref_yd = i4_y - i4_yd_index;
+
+ i4_xc = i4_ref_xd + SIGN(i4_xd_index);
+ i4_yc = i4_ref_yd + SIGN(i4_yd_index);
+
+ pu1_tmp = pu1_refarray + (i4_ref_yd * i4_refarray_wd);
+
+ i4_samp1 = pu1_tmp[i4_xc];
+ i4_samp2 = pu1_tmp[i4_ref_xd];
+ pu1_tmp = pu1_refarray + (i4_yc * i4_refarray_wd);
+ i4_samp3 = pu1_tmp[i4_ref_xd];
+ }
+
+ i4_result = (i4_samp1 + (i4_samp2 << 1) + i4_samp3 + 2) >> 2;
+
+ pu1_tmp = pu1_refarray + (i4_y * i4_refarray_wd);
+ /* Store the filled sample */
+ pu1_tmp[i4_x] = i4_result;
+
+ return (i4_result);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_corner_samp_dyadic */
+/* */
+/* Description : This function fills the corner sample in the reference */
+/* array with diagonally constructed samples */
+/* Inputs : i4_x :current position in reference array X to be filled */
+/* i4_y :current position in reference array Y to be filled */
+/* i4_xd_index : diagonal index in horizontal direction */
+/* i4_yd_index : diagonal index in vertical direction */
+/* pu1_refarray_y : pointer to luma reference array */
+/* pu1_refarray_cb : pointer to Cb reference array */
+/* pu1_refarray_cr : pointer to Cr reference array */
+/* Globals : none */
+/* Processing : Fills the sample which is unavailable with filtered */
+/* diagonal samples */
+/* Outputs : pixel filled */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_corner_samp_dyadic(WORD32 i4_x, WORD32 i4_y, WORD32 i4_xD, WORD32 i4_yD,
+ UWORD8 *pu1_refarray_y, UWORD8 *pu1_refarray_cb,
+ UWORD8 *pu1_refarray_cr)
+{
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+ WORD32 i4_xc, i4_yc;
+ WORD32 i4_c_xc, i4_c_yc;
+ WORD32 i4_samp1, i4_samp2;
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_ref_xD = i4_x - i4_xD;
+ i4_ref_yD = i4_y - i4_yD;
+ i4_xc = i4_ref_xD + SIGN(i4_xD);
+ i4_yc = i4_ref_yD + SIGN(i4_yD);
+
+ /* Luma */
+ pu1_tmp_src = pu1_refarray_y + (i4_yc * DYADIC_REF_W_Y);
+ i4_samp1 = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src = pu1_refarray_y + (i4_ref_yD * DYADIC_REF_W_Y);
+ i4_samp2 = pu1_tmp_src[i4_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Chroma */
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xc = i4_c_ref_xD + SIGN(i4_xD);
+ i4_c_yc = i4_c_ref_yD + SIGN(i4_yD);
+
+ /* Cb */
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+
+ /* Cr */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_yc * DYADIC_REF_W_C);
+ i4_samp1 = pu1_tmp_src[i4_c_ref_xD];
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ i4_samp2 = pu1_tmp_src[i4_c_xc];
+ pu1_tmp_dst = pu1_tmp_src;
+ pu1_tmp_dst[i4_c_ref_xD] = (i4_samp1 + i4_samp2 + 1) >> 1;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_reflayer_construction_dyadic */
+/* */
+/* Description : This function constructs the reference array buffer */
+/* for dyadic cases used for intra resampling of a */
+/* component in an MB */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_mb_mode_map : ref layer mb mode buffer desc */
+/* pu1_inp_luma : luma input (reference layer data) */
+/* pu1_inp_chroma : chroma input (reference layer data) */
+/* i4_inp_luma_stride : luma input buffer stride */
+/* i4_inp_chroma_stride : chroma input buffer stride */
+/* i4_top : indicates whether the core 8x8 reference block */
+/* is one of 0 and 1 or one of 2 and 3 */
+/* i4_left : indicates whether the core 8x8 reference block */
+/* is one of 0 and 2 or one of 1 and 3 */
+/* ps_ref_mb_coord : coordinates of the reference MB */
+/* Globals : none */
+/* Processing : it fills the reference layer data if they are falling in */
+/* INTRA MB region. If all the pixels are not filled it */
+/* calls the border extension algorithm to fill them */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 02 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_reflayer_construction_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_mb_mode_map,
+ UWORD8 *pu1_inp_luma, UWORD8 *pu1_inp_chroma,
+ WORD32 i4_inp_luma_stride, WORD32 i4_inp_chroma_stride,
+ WORD32 i4_top, WORD32 i4_left, UWORD16 u2_mb_x,
+ UWORD16 u2_mb_y)
+{
+ /* Index variables */
+ WORD32 i4_x, i4_y;
+ WORD32 i4_x0, i4_y0;
+ WORD32 i4_xc0, i4_yc0;
+ WORD32 i4_ref_xD, i4_ref_yD;
+ WORD32 i4_c_ref_xD, i4_c_ref_yD;
+
+ /* --------------------------------------------------------------------- */
+ /* Context and reference layer related variables */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_mbaddr_x;
+
+ /* --------------------------------------------------------------------- */
+ /* Temp Variables for Mapping context */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_ref_wd_in_mbs;
+ WORD32 i4_ref_ht_in_mbs;
+ WORD32 i4_refarray_wd_luma, i4_refarray_wd_chroma;
+ WORD32 i4_refarray_ht_luma, i4_refarray_ht_chroma;
+ WORD32 i4_avlblty;
+ WORD8 i1_cons_intr_samp_flag;
+ WORD8 i1_slice_id;
+ WORD8 i1_corner_samp_avlbl_flag;
+ UWORD8 u1_ny_avlblty;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+ UWORD8 *pu1_refarray_luma;
+ UWORD8 *pu1_refarray_cb, *pu1_refarray_cr;
+
+ /* --------------------------------------------------------------------- */
+ /* Derivation of local variables */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode_map->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode_map->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode_map->i4_element_size;
+
+ /* --------------------------------------------------------------------- */
+ /* get the constrained intra resampling flag */
+ /* --------------------------------------------------------------------- */
+ i1_cons_intr_samp_flag = ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag;
+
+ ASSERT(NULL != pi1_ref_mb_modes);
+
+ i4_ref_wd_in_mbs = ps_lyr_ctxt->i4_ref_width >> 4;
+ i4_ref_ht_in_mbs = ps_lyr_ctxt->i4_ref_height >> 4;
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ /* --------------------------------------------------------------------- */
+ /* Get the coordinates of the reference layer MB */
+ /* --------------------------------------------------------------------- */
+ i4_mbaddr_x = u2_mb_x;
+ i4_mbaddr_y = u2_mb_y;
+
+ /* --------------------------------------------------------------------- */
+ /* Getting the size of the valid area of ref array to be brought in */
+ /* --------------------------------------------------------------------- */
+ i4_refarray_wd_luma = 20;
+ i4_refarray_ht_luma = 20;
+ i4_refarray_wd_chroma = i4_refarray_wd_luma >> 1;
+ i4_refarray_ht_chroma = i4_refarray_ht_luma >> 1;
+
+ /* --------------------------------------------------------------------- */
+ /* Derivation of ref slice MB idc */
+ /* --------------------------------------------------------------------- */
+ if(1 == i1_cons_intr_samp_flag)
+ {
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD8 *pi1_ref_mb_mode_tmp;
+ WORD8 i1_mb_mode;
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_mode_tmp = pi1_ref_mb_modes;
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_mode_tmp += (i4_mbaddr_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_mode_tmp;
+ i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
+
+ /* The reference layer MB should be intra */
+ ASSERT(i1_mb_mode >= 0);
+ i1_slice_id = i1_mb_mode;
+ }
+ else
+ {
+ /* set to non valid value */
+ i1_slice_id = -1;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Bring in the reference array */
+ /* --------------------------------------------------------------------- */
+ {
+ UWORD8 *pu1_src, *pu1_dst;
+ WORD32 i4_src_stride, i4_dst_stride;
+
+ /* Copy luma */
+ i4_src_stride = i4_inp_luma_stride;
+ i4_dst_stride = DYADIC_REF_W_Y;
+ pu1_src = pu1_inp_luma;
+ pu1_dst = pu1_refarray_luma;
+ svcd_copy_data(pu1_src, i4_src_stride, pu1_dst, i4_dst_stride, i4_refarray_wd_luma,
+ i4_refarray_ht_luma);
+ // Semi planar
+ i4_src_stride = i4_inp_chroma_stride;
+ i4_dst_stride = DYADIC_REF_W_C;
+ pu1_src = pu1_inp_chroma;
+ svcd_copy_data_semiplanr(pu1_src, i4_src_stride, pu1_refarray_cb, pu1_refarray_cr,
+ i4_dst_stride, i4_refarray_wd_chroma, i4_refarray_ht_chroma);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Get the availability of 5 neighboring MBs */
+ /* --------------------------------------------------------------------- */
+ {
+ /* mb_x + left, mb_y + top */
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty = i4_avlblty;
+
+ /* mb_x + left, mb_y */
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 1);
+
+ /* mb_x, mb_y + top */
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 2);
+
+ /* mb_x - left, mb_y + top */
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x - i4_left, i4_mbaddr_y + i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 3);
+
+ /* mb_x + left, mb_y - top */
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x + i4_left, i4_mbaddr_y - i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ u1_ny_avlblty += (i4_avlblty << 4);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Filling the unavailable samples, if any */
+ /* --------------------------------------------------------------------- */
+ if(0x7 == u1_ny_avlblty)
+ {
+ /* All are available, exit */
+ return;
+ }
+
+ if(!(u1_ny_avlblty & 0x7))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Set the 4 corner samples to (x-xD,y-yD) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Set the corner sample of Cb and Cr to (x-xD,y-yD) */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ }
+
+ if(!(u1_ny_avlblty & 0x5))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD), ..., (x0+7,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), (x0+1,y0+1), ..., (x0+7,y0+1) */
+ i4_x0 = 2;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ }
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ for(i4_x = i4_x0; i4_x < i4_x0 + 8; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src[i4_x];
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ pu1_tmp_dst1[i4_x] = pu1_tmp_src1[i4_x];
+ pu1_tmp_dst2[i4_x] = pu1_tmp_src2[i4_x];
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x3))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0); */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1); ... ;*/
+ /* copy (ref_xD,y0+7) to (x0,y0+7) and (x0+1,y0+7) */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ }
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src;
+
+ for(i4_y = i4_y0; i4_y < i4_y0 + 8; i4_y++)
+ {
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst1 += DYADIC_REF_W_Y;
+ }
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+ pu1_tmp_src1 += DYADIC_REF_W_C;
+ pu1_tmp_src2 += DYADIC_REF_W_C;
+ pu1_tmp_dst1 += DYADIC_REF_W_C;
+ pu1_tmp_dst2 += DYADIC_REF_W_C;
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x4))
+ {
+ if(!(u1_ny_avlblty & 0x8))
+ {
+ /* (mb_x-left,mb_y+top) not available */
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD) and (x0+1,ref_yD) to (x0,y0) and (x0+1,y0), and */
+ /* to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_x0];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_x0 + 1];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_xc0];
+
+ } /* if (mb_x-left,mb_y+top) not available */
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 u1_filled_samp;
+
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x - i4_left, i4_mbaddr_y, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 - i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+ i4_ref_xD = i4_x0 - (i4_left * 7) - (i4_left >> 1);
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if not available */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ svcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ }
+ }
+
+ if(!(u1_ny_avlblty & 0x2))
+ {
+ if(!(u1_ny_avlblty & 0x10))
+ {
+ UWORD8 *pu1_tmp_src, *pu1_tmp_dst;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0), (x0+1,y0), and */
+ /* copy (ref_xD,y0+1) to (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ pu1_tmp_src += DYADIC_REF_W_Y;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+
+ pu1_tmp_dst[i4_x0] = pu1_tmp_src[i4_ref_xD];
+ pu1_tmp_dst[i4_x0 + 1] = pu1_tmp_src[i4_ref_xD];
+
+ /* Cb copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+
+ /* Cr copy */
+ pu1_tmp_src = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst = pu1_tmp_src;
+
+ pu1_tmp_dst[i4_xc0] = pu1_tmp_src[i4_c_ref_xD];
+
+ } /* if (mb_x+left,mb_y-top) not available */
+ else
+ {
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 u1_filled_samp;
+
+ svcd_get_ref_layer_avlblty_dyadic(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_mbaddr_x, i4_mbaddr_y - i4_top, &i4_avlblty,
+ i1_slice_id, i1_cons_intr_samp_flag);
+ i1_corner_samp_avlbl_flag = i4_avlblty;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 - i4_top;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - (i4_top * 7) - (i4_top >> 1);
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ svcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call diagonal consrtuction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ }
+ }
+
+ if(u1_ny_avlblty & 1)
+ {
+ if(!(u1_ny_avlblty & 2))
+ {
+ /* (mb_x+left,mb_y) is unavailable */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 4) >> 2;
+
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 2;
+ i4_ref_yD = 1;
+ if(i4_top > 0)
+ {
+ i4_y0 += 8;
+ i4_ref_yD = 18;
+ }
+
+ i4_ref_xD = i4_x0 - (i4_left) - (i4_left >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Fill corner sample if unavailable */
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ svcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 8 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 */
+ /* (x0,y0) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0+1), ..., (x0,y0+7) and */
+ /* (x0+1,y0), ..., (x0+1,y0+6) */
+ for(i4_y = i4_y0 + 1; i4_y < i4_y0 + 8; i4_y++)
+ {
+ i4_yD++;
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ }
+
+ /* (x0+1,y0+7) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x0 + 1, i4_y0 + 7, i4_xD + 1, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 */
+ /* (x0+1,y0) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0 + 1, i4_y0, i4_xD + 1, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 7; i4_y++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x0, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst += DYADIC_REF_W_Y;
+ pu1_tmp_dst[i4_x0 + 1] = u1_filled_samp;
+ i4_yD++;
+ }
+ /* (x0,y0+7) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0, i4_y0 + 7, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_y = i4_yc0; i4_y < i4_yc0 + 4; i4_y++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_y, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_yD++;
+ }
+
+ } /* (mb_x+left,mb_y) is unavailable */
+
+ if(!(u1_ny_avlblty & 4))
+ {
+ /* (mb_x,mb_y+top) is unavailable */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 *pu1_tmp_dst;
+ UWORD8 u1_filled_samp;
+
+ i1_corner_samp_avlbl_flag = (u1_ny_avlblty & 2) >> 1;
+
+ i4_y0 = 9 + (i4_top << 3) + (i4_top);
+ i4_x0 = 2;
+ i4_ref_xD = 1;
+ if(i4_left > 0)
+ {
+ i4_x0 += 8;
+ i4_ref_xD = 18;
+ }
+
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ if(!i1_corner_samp_avlbl_flag)
+ {
+ svcd_corner_samp_dyadic(i4_x0, i4_y0, i4_xD, i4_yD, pu1_refarray_luma,
+ pu1_refarray_cb, pu1_refarray_cr);
+ }
+
+ /* Call the diagonal construction for the 2 rows */
+ if(i4_top == i4_left)
+ {
+ /* if top * left = 1 */
+ /* (x0,y0) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0+1,y0), ..., (x0+7,y0) and */
+ /* (x0,y0+1), ..., (x0+6,y0+1) */
+ for(i4_x = i4_x0 + 1; i4_x < i4_x0 + 8; i4_x++)
+ {
+ i4_xD++;
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ pu1_tmp_dst[i4_x - 1] = u1_filled_samp;
+ }
+
+ /* (x0+7,y0+1) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x0 + 7, i4_y0 + 1, i4_xD, i4_yD + 1, pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+ else
+ {
+ /* top * left = -1 */
+ /* (x0,y0+1) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0, i4_y0 + 1, i4_xD, i4_yD + 1,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst = pu1_refarray_luma + ((i4_y0 + 1) * DYADIC_REF_W_Y);
+
+ /* (x0,y0), ..., (x0,y0+6) and */
+ /* (x0+1,y0+1), ..., (x0+1,y0+7) */
+ for(i4_x = i4_x0; i4_x < i4_x0 + 7; i4_x++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x, i4_y0, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+
+ pu1_tmp_dst[i4_x + 1] = u1_filled_samp;
+ i4_xD++;
+ }
+ /* (x0+7,y0) */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x0 + 7, i4_y0, i4_xD, i4_yD,
+ pu1_refarray_luma, DYADIC_REF_W_Y);
+ }
+
+ /* For Cb and Cr */
+ for(i4_x = i4_xc0; i4_x < i4_xc0 + 4; i4_x++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_x, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+ i4_c_xD++;
+ }
+
+ } /* (mb_x,mb_y+top) is unavailable */
+ } /* if (mb_x+left,mb_y+top) not available */
+ else
+ {
+ UWORD8 *pu1_tmp_dst1, *pu1_tmp_dst2;
+ UWORD8 *pu1_tmp_src1, *pu1_tmp_src2;
+
+ if(0x02 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) available, (mb_x,mb_y+top) unavailable */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ /* Copy (x0,ref_yD), (x0+1,ref_yD) to */
+ /* (x0,y0), (x0+1,y0), and (x0,y0+1), (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_ref_yD * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst2 = pu1_tmp_dst1 + DYADIC_REF_W_Y;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src1[i4_x0];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src1[i4_x0 + 1];
+
+ /* Cb and Cr copy */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_c_ref_yD * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_xc0];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_xc0];
+
+ } /* if (mb_x+left,mb_y) available, (mb_x,mb_y+top) unavailable */
+ else if(0x04 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) unavailable, (mb_x,mb_y+top) available */
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+
+ /* Copy (ref_xD,y0) to (x0,y0) and (x0+1,y0) */
+ /* copy (ref_xD,y0+1) to (x0,y0+1) and (x0+1,y0+1) */
+ pu1_tmp_src1 = pu1_refarray_luma + (i4_y0 * DYADIC_REF_W_Y);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_tmp_src1 + DYADIC_REF_W_Y;
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_x0] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst1[i4_x0 + 1] = pu1_tmp_src1[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0] = pu1_tmp_src2[i4_ref_xD];
+ pu1_tmp_dst2[i4_x0 + 1] = pu1_tmp_src2[i4_ref_xD];
+
+ /* Copy Cb and Cr */
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+ i4_c_ref_xD = i4_ref_xD >> 1;
+
+ pu1_tmp_src1 = pu1_refarray_cb + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst1 = pu1_tmp_src1;
+ pu1_tmp_src2 = pu1_refarray_cr + (i4_yc0 * DYADIC_REF_W_C);
+ pu1_tmp_dst2 = pu1_tmp_src2;
+
+ pu1_tmp_dst1[i4_xc0] = pu1_tmp_src1[i4_c_ref_xD];
+ pu1_tmp_dst2[i4_xc0] = pu1_tmp_src2[i4_c_ref_xD];
+
+ } /* if (mb_x+left,mb_y) unavailable, (mb_x,mb_y+top) available */
+ else if(0x6 == (u1_ny_avlblty & 0x6))
+ {
+ /* (mb_x+left,mb_y) available, (mb_x,mb_y+top) available */
+ WORD32 i4_xD, i4_yD;
+ WORD32 i4_c_xD, i4_c_yD;
+ UWORD8 u1_filled_samp;
+
+ i4_y0 = 9 + (i4_top << 3) + i4_top;
+ i4_x0 = 9 + (i4_left << 3) + i4_left;
+
+ i4_ref_xD = i4_x0 - i4_left - (i4_left >> 1);
+ i4_ref_yD = i4_y0 - i4_top - (i4_top >> 1);
+
+ i4_xD = i4_x0 - i4_ref_xD;
+ i4_yD = i4_y0 - i4_ref_yD;
+ i4_xc0 = i4_x0 >> 1;
+ i4_yc0 = i4_y0 >> 1;
+
+ i4_c_ref_xD = i4_ref_xD >> 1;
+ i4_c_ref_yD = i4_ref_yD >> 1;
+ i4_c_xD = i4_xc0 - i4_c_ref_xD;
+ i4_c_yD = i4_yc0 - i4_c_ref_yD;
+
+ /* Call diagonal construction for luma */
+ for(i4_y = i4_y0; i4_y < i4_y0 + 2; i4_y++)
+ {
+ for(i4_x = i4_x0; i4_x < i4_x0 + 2; i4_x++)
+ {
+ u1_filled_samp = svcd_diagonal_construct_dyadic(
+ i4_x, i4_y, i4_xD, i4_yD, pu1_refarray_luma, DYADIC_REF_W_Y);
+ i4_xD++;
+ }
+ i4_yD++;
+ i4_xD -= 2;
+ }
+
+ /* Call diagonal construction for chroma */
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cb, DYADIC_REF_W_C);
+
+ u1_filled_samp = svcd_diagonal_construct_dyadic(i4_xc0, i4_yc0, i4_c_xD, i4_c_yD,
+ pu1_refarray_cr, DYADIC_REF_W_C);
+
+ } /* if (mb_x+left,mb_y) available, (mb_x,mb_y+top) available */
+ } /* (mb_x+left,mb_y+top) available */
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_interpolate_base_luma_dyadic */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* intra resampling for dyadic scaling ratios */
+/* Inputs : pu1_inp_buf : ptr to the 12x12 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 12x16 buffer to hold the */
+/* vertically interpolated data */
+/* pu1_out_buf : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_interpolate_base_luma_dyadic(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1, i4_samp_2, i4_samp_3;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ /* Filter coefficient values for phase 4 */
+ i4_coeff_0 = -3;
+ i4_coeff_1 = 28;
+ i4_coeff_2 = 8;
+ i4_coeff_3 = -1;
+
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 12; i4_x++)
+ {
+ /* y = 0, y_phase = 12 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_2 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_3 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase 12 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Increment the output ptr */
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+ } /* End of loop over y */
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = pu1_inp[i4_x];
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ } /* End of loop over x */
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ /* x = 0, x_phase = 12 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+ i4_samp_2 = *pi2_tmp++;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* since x_phase 12 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_1 += 512;
+ i4_rslt_1 >>= 10;
+
+ /* Store the output */
+ pu1_out[0] = CLIPUCHAR(i4_rslt_1);
+
+ for(i4_x = 1; i4_x < 15; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ /* x_phase is 4 for odd values of x */
+ /* and 12 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_3;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_2 * i4_coeff_1;
+ i4_rslt_2 += i4_samp_3 * i4_coeff_0;
+ i4_rslt_2 += 512;
+
+ i4_rslt_1 >>= 10;
+ i4_rslt_2 >>= 10;
+
+ /* Store the output */
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+ pu1_out[i4_x + 1] = CLIPUCHAR(i4_rslt_2);
+ } /* End of loop over x */
+
+ /* x = 15 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = i4_samp_2;
+ i4_samp_2 = i4_samp_3;
+ i4_samp_3 = *pi2_tmp++;
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+ i4_rslt_1 += i4_samp_2 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_3 * i4_coeff_3;
+ i4_rslt_1 += 512;
+
+ i4_rslt_1 >>= 10;
+
+ /* Store the output */
+ pu1_out[i4_x] = CLIPUCHAR(i4_rslt_1);
+
+ /* Increment the output ptr */
+ pu1_out += i4_out_stride;
+ } /* End of loop over y */
+
+} /* svcd_interpolate_base_luma_dyadic */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_vert_interpol_chroma_dyadic_1 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* 1 2 */
+/* 2 1 */
+/* 2 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_vert_interpol_chroma_dyadic_1(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ /* y = 0, y_phase = phase_0 */
+ i4_samp_0 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ /* since y_phase = phase_0 for y = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Increment the output ptr */
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 7; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ /* Store the output */
+ pi2_tmp[i4_x] = i4_rslt_1;
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ } /* End of loop over x */
+} /* svcd_vert_interpol_chroma_dyadic_1 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_vert_interpol_chroma_dyadic_2 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* 0 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_vert_interpol_chroma_dyadic_2(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+ pi2_tmp = pi2_tmp_filt_buf;
+ } /* End of loop over x */
+} /* svcd_vert_interpol_chroma_dyadic_2 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_vert_interpol_chroma_dyadic_3 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 13 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_vert_interpol_chroma_dyadic_3(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf;
+
+ /* Vertical interpolation */
+ for(i4_x = 0; i4_x < 6; i4_x++)
+ {
+ i4_samp_1 = pu1_inp[i4_x];
+ pu1_inp += i4_src_stride;
+
+ for(i4_y = 0; i4_y < 8; i4_y += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = pu1_inp[i4_x];
+
+ /* y_phase is phase_1 for odd values of y */
+ /* and phase_0 for even values of y */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Storing the results */
+ pi2_tmp[i4_x] = i4_rslt_1;
+ pi2_tmp += i4_filt_stride;
+ pi2_tmp[i4_x] = i4_rslt_2;
+
+ /* Incrementing the pointers */
+ pi2_tmp += i4_filt_stride;
+ pu1_inp += i4_src_stride;
+
+ } /* End of loop over y */
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ } /* End of loop over x */
+} /* svcd_vert_interpol_chroma_dyadic_3 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_horz_interpol_chroma_dyadic_1 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* horizontal intra resampling for dyadic scaling ratios for*/
+/* chroma with following ref_lyr_chroma_phase_x_plus1_flag */
+/* and chroma_phase_x_plus1_flag: */
+/* ref_lyr cur_lyr */
+/* 0 0 */
+/* 1 0 */
+/* 1 1 */
+/* Inputs : pi2_tmp_filt_buf : ptr to the 6x8 buffer containing the */
+/* vertically interpolated data */
+/* pu1_out_buf : pointer to the output buffer */
+/* i4_out_stride : output buffer stride */
+/* i4_phase_0 : x phase for even values of x */
+/* i4_phase_1 : x phase for odd values of x */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_horz_interpol_chroma_dyadic_1(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y++)
+ {
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_0 = *pi2_tmp++;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_0 for x = 0 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+
+ /* Store the output */
+ pu1_out[0] = i4_rslt_1;
+
+ for(i4_x = 1; i4_x < 7; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* x_phase is phase_1 for odd values of x */
+ /* and phase_0 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_1;
+
+ /* Rounding to 8-bit values */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+ i4_rslt_2 += 32;
+ i4_rslt_2 >>= 6;
+
+ /* Storing the results */
+ pu1_out[2 * i4_x] = i4_rslt_1;
+ pu1_out[2 * (i4_x + 1)] = i4_rslt_2;
+
+ } /* End of loop over y */
+
+ /* y = 7, y_phase = phase_1 */
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* since x_phase = phase_1 for x = 7 */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_3;
+
+ /* Round to 8-bit value */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+
+ /* Store the output */
+ pu1_out[2 * 7] = i4_rslt_1;
+
+ /* Incrementing the output ptr */
+ pu1_out += i4_dst_stride;
+ } /* End of loop over x */
+} /* svcd_horz_interpol_chroma_dyadic_1 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_horz_interpol_chroma_dyadic_2 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* horizontal intra resampling for dyadic scaling ratios for*/
+/* chroma with following ref_lyr_chroma_phase_x_plus1_flag */
+/* and chroma_phase_x_plus1_flag: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* Inputs : pi2_tmp_filt_buf : ptr to the 6x8 buffer containing the */
+/* vertically interpolated data */
+/* pu1_out_buf : pointer to the output buffer */
+/* i4_out_stride : output buffer stride */
+/* i4_phase_0 : x phase for even values of x */
+/* i4_phase_1 : x phase for odd values of x */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_horz_interpol_chroma_dyadic_2(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_samp_0, i4_samp_1;
+ WORD32 i4_rslt_1, i4_rslt_2;
+ WORD32 i4_filt_stride, i4_dst_stride;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf + 1;
+ i4_filt_stride = 6;
+ i4_dst_stride = i4_out_stride;
+
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 8; i4_y++)
+ {
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_1 = *pi2_tmp++;
+
+ for(i4_x = 0; i4_x < 8; i4_x += 2)
+ {
+ i4_samp_0 = i4_samp_1;
+ i4_samp_1 = *pi2_tmp++;
+
+ /* x_phase is phase_1 for odd values of x */
+ /* and phase_0 for even values of x */
+ i4_rslt_1 = i4_samp_0 * i4_coeff_0;
+ i4_rslt_1 += i4_samp_1 * i4_coeff_1;
+
+ i4_rslt_2 = i4_samp_0 * i4_coeff_2;
+ i4_rslt_2 += i4_samp_1 * i4_coeff_3;
+
+ /* Rounding to 8-bit values */
+ i4_rslt_1 += 32;
+ i4_rslt_1 >>= 6;
+ i4_rslt_2 += 32;
+ i4_rslt_2 >>= 6;
+
+ /* Storing the results */
+ pu1_out[2 * i4_x] = i4_rslt_1;
+ pu1_out[2 * (i4_x + 1)] = i4_rslt_2;
+
+ } /* End of loop over x */
+
+ /* Incrementing the ptrs */
+ pi2_tmp += 1;
+ pu1_out += i4_dst_stride;
+ } /* End of loop over y */
+} /* svcd_horz_interpol_chroma_dyadic_2 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_intra_samp_mb_dyadic */
+/* */
+/* Description : MB level function which performs the intra resampling */
+/* of data of an MB (luma and chroma inclusive) for dyadic */
+/* scaling ratios */
+/* */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_mb_mode_map : ref layer mb mode map buff desc */
+/* ps_curr_luma : current layer out luma buffer desc */
+/* ps_curr_chroma : current layer out chroma buffer desc */
+/* x,y : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interpolation function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 12 2010 Nithya creation */
+/* */
+/*****************************************************************************/
+void svcd_intra_samp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, void *pv_dec)
+{
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ UWORD8 *pu1_inp_luma, *pu1_inp_chroma;
+ UWORD8 *pu1_out_luma, *pu1_out_chroma;
+ UWORD8 *pu1_out_cb, *pu1_out_cr;
+ UWORD8 *pu1_refarray_luma, *pu1_refarray_cb, *pu1_refarray_cr;
+ WORD16 *pi2_tmp_filt_buf;
+ WORD32 i4_inp_luma_stride, i4_inp_chroma_stride;
+ WORD32 i4_out_luma_stride, i4_out_chroma_stride;
+ UWORD16 u2_mb_x_ref, u2_mb_y_ref;
+ dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+
+ /* --------------------------------------------------------------------- */
+ /* Intra resampling ctxt pointers */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ res_prms_t *ps_res_prms;
+
+ /* --------------------------------------------------------------------- */
+ /* reference and current layer MB coordinates */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_scaled_mb_x, i4_scaled_mb_y;
+ WORD32 i4_top, i4_left;
+
+ ps_svc_slice_params = &ps_slice->s_svc_slice_params;
+ /* --------------------------------------------------------------------- */
+ /* Pointer derivation */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ ps_res_prms = ps_ctxt->ps_res_prms;
+
+ /* --------------------------------------------------------------------- */
+ /* MB coordinate derivation */
+ /* --------------------------------------------------------------------- */
+ i4_scaled_mb_x = u2_mb_x - (ps_svc_slice_params->i4_scaled_ref_layer_left_offset >> 4);
+ // (ps_res_prms->s_ref_lyr_scaled_offset.i2_left >> 4); SVC_DEC_EXT_REVIEW
+ i4_scaled_mb_y = u2_mb_y - (ps_svc_slice_params->i4_scaled_ref_layer_top_offset >> 4);
+ //(ps_res_prms->s_ref_lyr_scaled_offset.i2_top >> 4); SVC_DEC_EXT_REVIEW
+
+ if(i4_scaled_mb_x & 0x1)
+ {
+ i4_left = 1;
+ }
+ else
+ {
+ i4_left = -1;
+ }
+ if(i4_scaled_mb_y & 0x1)
+ {
+ i4_top = 1;
+ }
+ else
+ {
+ i4_top = -1;
+ }
+
+ u2_mb_x_ref = (i4_scaled_mb_x >> 1);
+ u2_mb_y_ref = (i4_scaled_mb_y >> 1);
+
+ /* --------------------------------------------------------------------- */
+ /* Reference Array Consrtuction - luma and chroma */
+ /* --------------------------------------------------------------------- */
+
+ pu1_inp_luma = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_inp_chroma = (UWORD8 *) ps_ref_chroma->pv_buffer;
+
+ i4_inp_luma_stride = ps_ref_luma->i4_num_element_stride;
+ i4_inp_chroma_stride = ps_ref_chroma->i4_num_element_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ svcd_reflayer_construction_dyadic(pv_intra_samp_ctxt, ps_ref_mb_mode_map, pu1_inp_luma,
+ pu1_inp_chroma, i4_inp_luma_stride, i4_inp_chroma_stride,
+ i4_top, i4_left, u2_mb_x_ref, u2_mb_y_ref);
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_refarray_luma = ps_ctxt->pu1_refarray_buffer;
+ if(1 == i4_top)
+ {
+ pu1_refarray_luma += (DYADIC_REF_W_Y << 3);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_luma += 8;
+ }
+ pu1_out_luma = (UWORD8 *) ps_curr_luma->pv_buffer;
+ i4_out_luma_stride = ps_curr_luma->i4_num_element_stride;
+ pi2_tmp_filt_buf = (WORD16 *) ps_ctxt->pi4_temp_interpolation_buffer;
+
+ svcd_interpolate_base_luma_dyadic(pu1_refarray_luma, pi2_tmp_filt_buf, pu1_out_luma,
+ i4_out_luma_stride);
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA INTERPOLATION */
+ /* --------------------------------------------------------------------- */
+ pu1_out_chroma = (UWORD8 *) ps_curr_chroma->pv_buffer;
+ i4_out_chroma_stride =
+ ps_curr_chroma->i4_num_element_stride; // << 1; SVC_DEC_REVIEW_INTRA_RESAMPLE
+
+ /* CB */
+ pu1_out_cb = pu1_out_chroma;
+ pu1_refarray_cb = ps_ctxt->pu1_refarray_cb;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cb += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cb += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_chroma_interpol(pu1_refarray_cb, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_chroma_interpol(pi2_tmp_filt_buf, pu1_out_cb, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+
+ /* CR */
+ pu1_out_cr = pu1_out_chroma + 1;
+ // (i4_out_chroma_stride >> 1); SVC_DEC_REVIEW_INTRA_RESAMPLE
+ pu1_refarray_cr = ps_ctxt->pu1_refarray_cr;
+
+ if(1 == i4_top)
+ {
+ pu1_refarray_cr += (DYADIC_REF_W_C << 2);
+ }
+ if(1 == i4_left)
+ {
+ pu1_refarray_cr += 4;
+ }
+
+ /* Vertical interpolation */
+ ps_lyr_ctxt->pf_vert_chroma_interpol(pu1_refarray_cr, pi2_tmp_filt_buf,
+ ps_lyr_ctxt->i4_y_phase_0, ps_lyr_ctxt->i4_y_phase_1);
+
+ /* Horizontal interpolation */
+ ps_lyr_ctxt->pf_horz_chroma_interpol(pi2_tmp_filt_buf, pu1_out_cr, i4_out_chroma_stride,
+ ps_lyr_ctxt->i4_x_phase_0, ps_lyr_ctxt->i4_x_phase_1);
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_residual_chroma_dyadic_alt */
+/* */
+/* Description : this fucntion does the upsampling of chroma residuals for*/
+/* Dyadic cases and specific chroma phase cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* i4_start_bit_pos : bit position in the byte of packed */
+/* sign values */
+/* Globals : none */
+/* Processing : it does the upsampling with intial phase values */
+/* */
+/* Outputs : Upsampled residuals for chroma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2010 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_residual_chroma_dyadic_alt(void *pv_residual_samp_ctxt, UWORD16 u2_mb_x, UWORD16 u2_mb_y,
+ mem_element_t *ps_ref_mb_mode, UWORD8 *pu1_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, UWORD8 *pu1_inp_bitmap,
+ WORD32 i4_inp_bitmap_stride, WORD32 i4_cr_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ /* ----------------- Processing ------------------------------- */
+ {
+ ref_pixel_map_t *ps_pos_phase;
+ residual_samp_map_ctxt_t *ps_chroma_map;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+
+ WORD32 i4_i;
+ UWORD8 *pu1_ref_data_byte, *pu1_ref_sign_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_phase1, i4_phase2;
+ WORD32 i4_start_bit_pos = 0;
+ WORD32 i4_offset_x, i4_offset_y;
+ WORD32 i4_chrm_horz_int_mode, i4_chrm_vert_int_mode;
+ WORD32 i4_horz_intp_ctr = SUB_BLOCK_HEIGHT;
+
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
+
+ {
+ UWORD8 u1_mask;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_chrm_nnz;
+ WORD32 i4_num_element_stride;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms, *ps_inter_lyr_mb_prms_curr;
+
+ u1_mask = (SVCD_TRUE == i4_cr_flag) ? 0xF0 : 0x0F;
+
+ /* Top Left */
+ i4_mb_x = i4_offset_x >> 3;
+ i4_mb_y = i4_offset_y >> 3;
+
+ /* get the location of the byte which has the current mb mode */
+ ps_inter_lyr_mb_prms = ps_ref_mb_mode->pv_buffer;
+ i4_num_element_stride = ps_ref_mb_mode->i4_num_element_stride;
+
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+
+ i4_chrm_nnz = ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Top Right */
+ i4_mb_x = (i4_offset_x + 4) >> 3;
+
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Bottom Left */
+ i4_mb_x = i4_offset_x >> 3;
+ i4_mb_y = (i4_offset_y + 4) >> 3;
+
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Bottom Right */
+ i4_mb_x = (i4_offset_x + 4) >> 3;
+
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ if(0 == i4_chrm_nnz)
+ {
+ return;
+ }
+ }
+
+ i4_chrm_horz_int_mode = ps_lyr_ctxt->i4_chrm_horz_int_mode;
+ i4_chrm_vert_int_mode = ps_lyr_ctxt->i4_chrm_vert_int_mode;
+
+ if(0 == i4_chrm_horz_int_mode)
+ {
+ if(i4_offset_x >= 0)
+ {
+ pu1_inp_data++;
+ if(0 == ((i4_offset_x + 1) & 7))
+ {
+ pu1_inp_bitmap++;
+ }
+ }
+ }
+
+ if(0 == i4_chrm_vert_int_mode)
+ {
+ if(i4_offset_y >= 0)
+ {
+ pu1_inp_data += i4_inp_data_stride;
+ pu1_inp_bitmap += i4_inp_bitmap_stride;
+ }
+ }
+ else
+ {
+ /* extra additional row of interpolation required for this case */
+ i4_horz_intp_ctr++;
+ }
+
+ /* set the appropriate bit pos */
+ if(1 == (u2_mb_x & 1))
+ {
+ i4_start_bit_pos = 4;
+ }
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pu1_ref_data_byte = pu1_inp_data;
+ pu1_ref_sign_byte = pu1_inp_bitmap;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
+
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ /* interchange the phase values for corner case */
+ if(1 == i4_chrm_horz_int_mode)
+ {
+ WORD32 i4_temp;
+ i4_temp = i4_phase1;
+ i4_phase1 = i4_phase2;
+ i4_phase2 = i4_temp;
+ }
+
+ for(i4_i = 0; i4_i < i4_horz_intp_ctr; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ UWORD8 u1_sign;
+ UWORD8 u1_sign_byte = *pu1_ref_sign_byte;
+
+ i2_coeff1 = (WORD16) (pu1_ref_data_byte[0]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_start_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ if(0 == i4_chrm_horz_int_mode)
+ {
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+ }
+
+ {
+ /* unroll count 1 */
+ i2_coeff2 = (WORD16) (pu1_ref_data_byte[1]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 1));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* unroll count 2 */
+ i2_coeff1 = (WORD16) (pu1_ref_data_byte[2]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 2));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
+
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
+
+ /* unroll count 3 */
+ i2_coeff2 = (WORD16) (pu1_ref_data_byte[3]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 3));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 4;
+
+ if(1 == i4_chrm_horz_int_mode)
+ {
+ WORD32 i4_bit_pos = i4_start_bit_pos + 4;
+
+ if(8 == i4_bit_pos)
+ {
+ u1_sign_byte = *(pu1_ref_sign_byte + 1);
+ i4_bit_pos = 0;
+ }
+
+ i2_coeff1 = (WORD16) (pu1_ref_data_byte[4]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+ }
+
+ /* vertical loop updates */
+ pu1_ref_data_byte = pu1_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ pu1_ref_sign_byte += i4_inp_bitmap_stride;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ /* interchange the phase values for corner case */
+ if(0 != i4_chrm_vert_int_mode)
+ {
+ WORD32 i4_temp;
+ i4_temp = i4_phase1;
+ i4_phase1 = i4_phase2;
+ i4_phase2 = i4_temp;
+ }
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD16 *pi2_out;
+ WORD32 *pi4_ref_array_temp;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+ pi2_out = pi2_out_res;
+ pi4_ref_array_temp = pi4_ref_array;
+
+ /* populate the first inter sample */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ if(1 != i4_chrm_vert_int_mode)
+ {
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ if(2 == i4_chrm_vert_int_mode)
+ {
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ {
+ /* unroll count 1 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 2 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 3 */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 4 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 5 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 6 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+ }
+
+ if(2 != i4_chrm_vert_int_mode)
+ {
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 8) >> 4;
+
+ if(1 == i4_chrm_vert_int_mode)
+ {
+ pi2_out += i4_out_res_stride;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ }
+ }
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_residual_chroma_dyadic */
+/* */
+/* Description : this fucntion does the upsampling of chroma residuals for*/
+/* Dyadic cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* i4_start_bit_pos : bit position in the byte of packed */
+/* sign values */
+/* Globals : none */
+/* Processing : it does the upsampling with intial phase values */
+/* */
+/* Outputs : Upsampled residuals for chroma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2010 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_residual_chroma_dyadic(void *pv_residual_samp_ctxt, UWORD8 *pu1_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, UWORD8 *pu1_inp_bitmap,
+ WORD32 i4_inp_bitmap_stride, WORD32 i4_start_bit_pos)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ /* ----------------- Processing ------------------------------- */
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_ref_data_byte, *pu1_ref_sign_byte;
+ WORD32 *pi4_ref_array;
+ ref_pixel_map_t *ps_pos_phase;
+ WORD32 i4_phase1, i4_phase2;
+
+ pu1_ref_data_byte = pu1_inp_data;
+ pu1_ref_sign_byte = pu1_inp_bitmap;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ UWORD8 u1_sign;
+ UWORD8 u1_sign_byte = *pu1_ref_sign_byte;
+
+ i2_coeff1 = (WORD16) (pu1_ref_data_byte[0]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_start_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+
+ {
+ /* unroll count 1 */
+ i2_coeff2 = (WORD16) (pu1_ref_data_byte[1]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 1));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 2 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* unroll count 3 */
+ i2_coeff1 = (WORD16) (pu1_ref_data_byte[2]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 2));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
+
+ /* unroll count 4 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
+
+ /* unroll count 5 */
+ i2_coeff2 = (WORD16) (pu1_ref_data_byte[3]);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, (i4_start_bit_pos + 3));
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 6 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 4;
+
+ /* vertical loop uopdates */
+ pu1_ref_data_byte = pu1_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ pu1_ref_sign_byte += i4_inp_bitmap_stride;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD16 *pi2_out;
+ WORD32 *pi4_ref_array_temp;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+ pi2_out = pi2_out_res;
+ pi4_ref_array_temp = pi4_ref_array;
+
+ /* populate the first inter sample */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ {
+ /* unroll count 1 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 2 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 3 */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 4 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 5 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 6 */
+ *pi2_out =
+ ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+ }
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 8) >> 4;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_residual_luma_dyadic */
+/* */
+/* Description : this fucntion does the upsampling of luma residuals for */
+/* Dyadic cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* ps_ref_mb_mode : reference mb mode pointer of base layer */
+/* ps_coord : mb co-ordinate pointer */
+/* Globals : none */
+/* Processing : it does the upsampling with fixed phase values and */
+/* reference layer transform size */
+/* Outputs : Upsampled residuals for luma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2010 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_residual_luma_dyadic(void *pv_residual_samp_ctxt, UWORD8 *pu1_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, UWORD8 *pu1_inp_bitmap,
+ WORD32 i4_inp_bitmap_stride, mem_element_t *ps_ref_mb_mode,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
+ WORD32 i4_ref_tx_size)
+
+{
+ WORD16 *pi2_refarray_buffer;
+ WORD32 i4_start_bit_pos = 0;
+ WORD32 i4_blk_ctr;
+ residual_sampling_ctxt_t *ps_ctxt;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ pi2_refarray_buffer = ps_ctxt->pi2_refarray_buffer;
+
+ /* based on transform size the counter and interpolation width and */
+ /* height are intialised as follows */
+
+ if((i4_ref_tx_size) && (0 != i4_ref_nnz))
+ {
+ UWORD8 *pu1_ref_data_byte, *pu1_ref_sign_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i, i4_j;
+
+ pu1_ref_data_byte = pu1_inp_data;
+ pu1_ref_sign_byte = pu1_inp_bitmap;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ UWORD8 u1_sign;
+ WORD32 i4_bit_pos = i4_start_bit_pos;
+ UWORD8 u1_sign_byte = *pu1_ref_sign_byte;
+
+ i2_coeff1 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ i4_bit_pos++;
+ i2_coeff2 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i2_coeff1 = i2_coeff2;
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ /* vertical loop uopdates */
+ pu1_ref_data_byte = pu1_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ pu1_ref_sign_byte += i4_inp_bitmap_stride;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < MB_WIDTH; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi4_ref_array_temp += MB_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out = ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_1 = i4_horz_samp_2;
+ }
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ UWORD8 *pu1_ref_data_byte, *pu1_ref_sign_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i;
+
+ /* if reference layer is not coded then no processing */
+ if(0 != (i4_ref_nnz & 0x1))
+ {
+ pu1_ref_data_byte = pu1_inp_data;
+ pu1_ref_sign_byte = pu1_inp_bitmap;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ UWORD8 u1_sign;
+ WORD32 i4_bit_pos = i4_start_bit_pos;
+ UWORD8 u1_sign_byte = *pu1_ref_sign_byte;
+ ;
+
+ i2_coeff1 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ {
+ /* unroll count 1 */
+ i4_bit_pos++;
+ i2_coeff2 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ /* unroll count 2 */
+ i4_bit_pos++;
+ i2_coeff1 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff1 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ /* unroll count 3 */
+ i4_bit_pos++;
+ i2_coeff2 = (WORD16) (*pu1_ref_data_byte++);
+ u1_sign = (UWORD8) GET_BIT(u1_sign_byte, i4_bit_pos);
+
+ /* if signed number */
+ if(u1_sign)
+ {
+ i2_coeff2 |= 0xFF00;
+ }
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 2;
+
+ /* vertical loop uopdates */
+ pu1_ref_data_byte = pu1_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ pu1_ref_sign_byte += i4_inp_bitmap_stride;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ {
+ /* unroll loop count 1 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 2 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 3 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ pi2_out_res += BLOCK_WIDTH;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ i4_start_bit_pos = 0;
+ pu1_inp_data -= SUB_BLOCK_WIDTH;
+ pu1_inp_data += (i4_inp_data_stride * SUB_BLOCK_HEIGHT);
+ pi2_out_res -= MB_WIDTH;
+ pi2_out_res += (i4_out_res_stride * BLOCK_HEIGHT);
+ pu1_inp_bitmap += (i4_inp_bitmap_stride * SUB_BLOCK_HEIGHT);
+ i4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pu1_inp_data += SUB_BLOCK_WIDTH;
+ i4_start_bit_pos = SUB_BLOCK_WIDTH;
+ }
+
+ i4_ref_nnz >>= 1;
+ } /* end of loop over all the blocks */
+ }
+ return;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_residual_samp_mb_dyadic */
+/* */
+/* Description : MB level function whcih perform the residual resampling */
+/* of data of an MB (luma and chroma insclusive) */
+/* for Dyadic cases */
+/* Inputs : pv_residual_samp_ctxt : residual sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_luma_bitmap : ref layer luma bit map buffer desc */
+/* ps_ref_chroma_bitmap : ref layer chroma bit map buff des */
+/* ps_ref_mb_mode : ref layer mb mode map buff desc */
+/* ps_out_luma : current layer out luma buffer desc */
+/* ps_out_chroma : current layer out chroma buffer desc */
+/* x,y : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interplaotion function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_residual_samp_mb_dyadic(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_luma_bitmap,
+ mem_element_t *ps_ref_chroma_bitmap,
+ mem_element_t *ps_ref_mb_mode, mem_element_t *ps_out_luma,
+ mem_element_t *ps_out_chroma, UWORD16 u2_mb_x, UWORD16 u2_mb_y)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ UWORD8 *pu1_inp;
+ UWORD8 *pu1_inp_bitmap;
+ WORD16 *pi2_out;
+ WORD32 i4_inp_stride;
+ WORD32 i4_inp_bitmap_stride;
+ WORD32 i4_out_stride;
+ WORD32 i4_bit_pos = 0;
+ WORD32 i4_luma_nnz;
+ WORD32 i4_chroma_nnz;
+ WORD32 i4_tx_size;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ pu1_inp = (UWORD8 *) ps_ref_luma->pv_buffer;
+ pu1_inp_bitmap = (UWORD8 *) ps_ref_luma_bitmap->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_luma->pv_buffer;
+
+ i4_inp_stride = ps_ref_luma->i4_num_element_stride;
+ i4_inp_bitmap_stride = ps_ref_luma_bitmap->i4_num_element_stride;
+ i4_out_stride = ps_out_luma->i4_num_element_stride;
+
+ /* set the output buffer to 0 since not all block will be upsampled */
+ svcd_2d_memset(pi2_out, (MB_WIDTH << 1), MB_HEIGHT, (i4_out_stride << 1), 0);
+
+ {
+ WORD32 i4_offset_x, i4_offset_y;
+ residual_samp_map_ctxt_t *ps_luma_map;
+ ref_mb_map_t *ps_x_off_len_luma;
+ ref_mb_map_t *ps_y_off_len_luma;
+
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_x_off_len_luma = ps_luma_map->ps_x_offset_length;
+ ps_y_off_len_luma = ps_luma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_luma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_luma[u2_mb_y].i2_offset;
+
+ {
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD32 i4_mb_x, i4_mb_y;
+ UWORD16 u2_luma_mask = 0x0033;
+ UWORD8 u1_chrm_mask = 0x11;
+ WORD32 i4_luma_rt_sft_amt = 0;
+ WORD32 i4_chrm_rt_sft_amt = 0;
+
+ i4_mb_x = ((i4_offset_x + 1) >> MB_WIDTH_SHIFT);
+ i4_mb_y = ((i4_offset_y + 1) >> MB_HEIGHT_SHIFT);
+
+ /* get the location of the byte which has the current mb mode */
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_ref_mb_mode->pv_buffer;
+ ps_inter_lyr_mb_prms += i4_mb_x;
+ ps_inter_lyr_mb_prms += i4_mb_y * ps_ref_mb_mode->i4_num_element_stride;
+
+ /* get the approp block in base layer in horz direction */
+ if(0 != ((i4_offset_x + 1) & 15))
+ {
+ u2_luma_mask <<= 2;
+ i4_luma_rt_sft_amt += 2;
+
+ u1_chrm_mask <<= 1;
+ i4_chrm_rt_sft_amt += 1;
+ }
+ /* get the approp block in base layer in vert direction */
+ if(0 != ((i4_offset_y + 1) & 15))
+ {
+ u2_luma_mask <<= 8;
+ i4_luma_rt_sft_amt += 8;
+
+ u1_chrm_mask <<= 2;
+ i4_chrm_rt_sft_amt += 2;
+ }
+
+ /* extract the nnz and store it */
+ i4_luma_nnz = (ps_inter_lyr_mb_prms->u2_luma_nnz & u2_luma_mask) >> i4_luma_rt_sft_amt;
+
+ i4_chroma_nnz =
+ (ps_inter_lyr_mb_prms->u1_chroma_nnz & u1_chrm_mask) >> i4_chrm_rt_sft_amt;
+
+ i4_tx_size = GET_BIT(ps_inter_lyr_mb_prms->i1_mb_mode, 1);
+ }
+
+ /* since in dyadic case the window width and height will be 10x10 */
+ /* and the window start offsets will be always 1 column left and */
+ /* 1 row above the block boundary. so the pointer and the required */
+ /* positions are appropriately modified */
+ if(i4_offset_x >= 0)
+ {
+ pu1_inp++;
+ pu1_inp_bitmap++;
+ }
+
+ if(i4_offset_y >= 0)
+ {
+ pu1_inp += i4_inp_stride;
+ pu1_inp_bitmap += i4_inp_bitmap_stride;
+ }
+
+ svcd_residual_luma_dyadic(pv_residual_samp_ctxt, pu1_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, pu1_inp_bitmap, i4_inp_bitmap_stride,
+ ps_ref_mb_mode, u2_mb_x, u2_mb_y, i4_luma_nnz, i4_tx_size);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ /* CB */
+ pu1_inp = (UWORD8 *) ps_ref_chroma->pv_buffer;
+ pu1_inp_bitmap = (UWORD8 *) ps_ref_chroma_bitmap->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_chroma->pv_buffer;
+
+ i4_inp_stride = ps_ref_chroma->i4_num_element_stride << 1;
+ i4_inp_bitmap_stride = ps_ref_chroma_bitmap->i4_num_element_stride << 1;
+ i4_out_stride = ps_out_chroma->i4_num_element_stride << 1;
+
+ /* set the output buffer to 0 since not all block will be upsampled */
+ svcd_2d_memset(pi2_out, (BLOCK_WIDTH << 1), MB_HEIGHT, (i4_out_stride), 0);
+
+ /* choose the appropriate chroma processing routine */
+ if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
+ {
+ WORD32 i4_offset_x, i4_offset_y;
+ residual_samp_map_ctxt_t *ps_chroma_map;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
+
+ /* since in dyadic case the window width and height will be 6x6 */
+ /* and the window start offsets will be always 1 column left and */
+ /* 1 row above the block boundary. so the pointer and the required */
+ /* positions are appropriately modified */
+ if(i4_offset_x >= 0)
+ {
+ pu1_inp++;
+ if(0 == ((i4_offset_x + 1) & 7))
+ {
+ pu1_inp_bitmap++;
+ }
+ else
+ {
+ i4_bit_pos = 4;
+ }
+ }
+
+ if(i4_offset_y >= 0)
+ {
+ pu1_inp += i4_inp_stride;
+ pu1_inp_bitmap += i4_inp_bitmap_stride;
+ }
+
+ if(0 != (i4_chroma_nnz & 0x01))
+ {
+ svcd_residual_chroma_dyadic(pv_residual_samp_ctxt, pu1_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, pu1_inp_bitmap, i4_inp_bitmap_stride,
+ i4_bit_pos);
+ }
+ }
+ else
+ {
+ svcd_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y, ps_ref_mb_mode,
+ pu1_inp, i4_inp_stride, pi2_out, i4_out_stride,
+ pu1_inp_bitmap, i4_inp_bitmap_stride, SVCD_FALSE);
+ }
+
+ /* CR */
+ pu1_inp += (i4_inp_stride >> 1);
+ pu1_inp_bitmap += (i4_inp_bitmap_stride >> 1);
+ pi2_out += (i4_out_stride >> 1);
+
+ if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
+ {
+ if(0 != (i4_chroma_nnz & 0x10))
+ {
+ svcd_residual_chroma_dyadic(pv_residual_samp_ctxt, pu1_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, pu1_inp_bitmap, i4_inp_bitmap_stride,
+ i4_bit_pos);
+ }
+ }
+ else
+ {
+ svcd_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y, ps_ref_mb_mode,
+ pu1_inp, i4_inp_stride, pi2_out, i4_out_stride,
+ pu1_inp_bitmap, i4_inp_bitmap_stride, SVCD_TRUE);
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svc_intra_resamp_generate_segment_lookup */
+/* */
+/* Description : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* */
+/* Inputs : pv_lookup_table : look up table */
+/* i4_dimension : dimension of the block which is used in*/
+/* resampling process. */
+/* i4_mb_size : size of the mb */
+/* Globals : None */
+/* Processing : This function generates segment lookup used to derive */
+/* segments which have to be be intra resampled */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 03 03 2011 A.D.Almeida Creation */
+/* */
+/*****************************************************************************/
+void svc_intra_resamp_generate_segment_lookup(seg_lookup_desc_t *ps_seg_lookup_table,
+ WORD32 i4_dimension, WORD32 i4_mb_size,
+ WORD32 i4_shift_val)
+{
+ WORD32 i4_x;
+ WORD32 i4_position, i4_dist_prev_mb, i4_dist_next_mb;
+ UWORD8 u1_seg_dim;
+ UWORD8 u1_num_sgmts;
+ WORD32 i4_block_size = i4_mb_size >> 1;
+ UWORD8 u1_offset = 0;
+ seg_lookup_desc_t *ps_segments;
+ seg_description_t *ps_seg_desc;
+
+ memset(ps_seg_lookup_table, 0, i4_mb_size * sizeof(seg_lookup_desc_t));
+
+ for(i4_x = 0; i4_x < i4_mb_size; i4_x++)
+ {
+ ps_segments = &ps_seg_lookup_table[i4_x];
+ ps_seg_desc = ps_segments->s_segments;
+ i4_position = i4_x;
+
+ if(i4_x >= i4_block_size)
+ {
+ /* set the fourth bit so that later it can be directly OR ed */
+ ps_segments->u4_start_pos = 8;
+ }
+ else
+ {
+ ps_segments->u4_start_pos = 0;
+ }
+
+ u1_num_sgmts = 0;
+ u1_offset = 0;
+
+ while(i4_position < (i4_x + i4_dimension))
+ {
+ /* check and fill the nearest mb boundry flag */
+ if((i4_position & (i4_mb_size - 1)) < i4_block_size)
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = -1;
+ }
+ else
+ {
+ ps_seg_desc->i1_nearst_mb_bdry = 1;
+ }
+
+ /* find the distance from the previous MB for start of segment*/
+ i4_dist_prev_mb = (i4_position & (i4_mb_size - 1));
+
+ ps_seg_desc->i1_dist_idx =
+ ((i4_dist_prev_mb >= i4_mb_size >> 1) ? (i4_mb_size - i4_dist_prev_mb)
+ : -(i4_dist_prev_mb + 1));
+
+ /* find the size of the segment */
+ u1_seg_dim = (i4_block_size - (i4_position & (i4_block_size - 1)));
+ i4_position += u1_seg_dim;
+ if(i4_position > (i4_x + i4_dimension))
+ {
+ i4_position = (i4_x + i4_dimension);
+ u1_seg_dim = (i4_position & (i4_block_size - 1));
+ }
+
+ /* find the distance from the next MB for end of segment */
+ i4_dist_next_mb = (i4_position & (i4_mb_size - 1));
+
+ ps_seg_desc->u1_seg_dim = u1_seg_dim;
+ ps_seg_desc->u1_seg_off = u1_offset;
+
+ /* check if the segment has a adjoining MB edge */
+ if(i4_dist_prev_mb == 0)
+ {
+ if(0 == u1_num_sgmts)
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else if(i4_dist_next_mb == 0)
+ {
+ if(i4_position == (i4_x + i4_dimension))
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 1 << i4_shift_val;
+ }
+ }
+ else
+ {
+ ps_seg_desc->u1_mb_adjoin = 0;
+ }
+
+ /* Updations */
+ u1_offset += u1_seg_dim;
+ u1_num_sgmts++;
+ ps_seg_desc++;
+ }
+
+ /* fill the number of segments for this position */
+ ps_segments->u1_num_segments = u1_num_sgmts;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_intra_samp_populate_list */
+/* */
+/* Description : This is a seq or frame level init function which fills */
+/* all offsets, projected locations arrays based on */
+/* the two resolutions and cropping parameters */
+/* Inputs : refer ot doxygen comments below */
+/* Globals : none */
+/* Processing : it projects the locations and computes the values */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_intra_samp_populate_list(intra_samp_map_ctxt_t *ps_map_ctxt, res_prms_t *ps_curr_res_prms,
+ res_prms_t *ps_ref_res_prms, WORD32 i4_chroma_flag,
+ dec_struct_t *ps_dec)
+{
+ /* --------------------------------------------------------------------- */
+ /* Local variables required for finding the mapping between the layers */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_shift_x, i4_shift_y, i4_scale_x, i4_scale_y, i4_offset_x, i4_offset_y;
+ WORD32 i4_add_x, i4_add_y, i4_delta_x, i4_delta_y, i4_refphase_x, i4_refphase_y;
+ WORD32 i4_phase_x, i4_phase_y, i4_sub_wd, i4_sub_ht, i4_mb_wd, i4_mb_ht;
+ WORD32 i4_horz_dim, i4_vert_dim, i4_tmp;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+ ref_mb_map_t *ps_x_off_len, *ps_y_off_len;
+ WORD32 i4_ref_wd, i4_ref_ht, i4_scaled_wd, i4_scaled_ht, i4_curr_lyr_width, i4_curr_lyr_height;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Flag Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_ref_layer_field_pic_flag, i4_field_pic_flag, i4_frame_mbs_only_flag;
+ WORD32 i4_ref_layer_frame_Mbs_only_flag, i4_field_Mb_flag, i4_bot_field_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Cropping Parameters Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_scaled_ref_layer_left_offset, i4_scaled_ref_layer_top_offset;
+ WORD32 i4_scaled_ref_layer_right_offset, i4_scaled_ref_layer_bottom_offset;
+ dec_seq_params_t *ps_sps;
+ ps_sps = ps_dec->ps_cur_sps;
+
+ /* --------------------------------------------------------------------- */
+ /* Hardcoding flag information (assuming no field support) */
+ /* --------------------------------------------------------------------- */
+ i4_ref_layer_field_pic_flag = SVCD_FALSE;
+ i4_field_pic_flag = SVCD_FALSE;
+ i4_frame_mbs_only_flag = SVCD_TRUE;
+ i4_field_Mb_flag = SVCD_FALSE;
+ i4_bot_field_flag = SVCD_FALSE;
+ i4_ref_layer_frame_Mbs_only_flag = SVCD_TRUE;
+ i4_horz_dim = 0;
+ i4_vert_dim = 0;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointer and Paramater are intialized - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_base_width;
+ WORD32 i4_base_height;
+ WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
+ WORD32 i4_ref_layer_chroma_phase_y_plus1;
+ WORD32 i4_chroma_phase_x_plus1_flag;
+ WORD32 i4_chroma_phase_y_plus1;
+
+ /* ------------------------------------------------------------- */
+ /* HARD CODED FOR 420 */
+ /* ------------------------------------------------------------- */
+ WORD32 i4_sub_wd_chroma = 2;
+ WORD32 i4_sub_ht_chroma = 2;
+
+ i4_base_width = ps_ref_res_prms->i4_res_width;
+ i4_base_height = ps_ref_res_prms->i4_res_height;
+
+ i4_ref_layer_chroma_phase_x_plus1_flag =
+ ps_curr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+ i4_ref_layer_chroma_phase_y_plus1 = ps_curr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_phase_x_plus1_flag = ps_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag;
+ i4_chroma_phase_y_plus1 = ps_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1;
+ i4_scaled_ref_layer_bottom_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_bot;
+ i4_scaled_ref_layer_left_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
+ i4_scaled_ref_layer_top_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
+ i4_scaled_ref_layer_right_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_rt;
+
+ /* ----------------------------------------------------------------- */
+ /* Computing Effective Frame Dimensions */
+ /* ------------------------------------------------------------------*/
+ i4_ref_wd = (i4_base_width >> i4_chroma_flag);
+ i4_ref_ht = (i4_base_height >> i4_chroma_flag) * (1 + i4_ref_layer_field_pic_flag);
+
+ i4_scaled_wd = ps_curr_res_prms->u2_scaled_ref_width;
+ i4_scaled_ht = ps_curr_res_prms->u2_scaled_ref_height;
+
+ i4_scaled_wd = (i4_scaled_wd >> i4_chroma_flag);
+ i4_scaled_ht = (i4_scaled_ht >> i4_chroma_flag) * (1 + i4_field_pic_flag);
+
+ if(1 == i4_chroma_flag)
+ {
+ i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1_flag - 1;
+ i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
+ i4_phase_x = i4_chroma_phase_x_plus1_flag - 1;
+ i4_phase_y = i4_chroma_phase_y_plus1 - 1;
+ i4_sub_wd = i4_sub_wd_chroma;
+ i4_sub_ht = i4_sub_ht_chroma;
+ i4_mb_wd = MB_WIDTH >> 1;
+ i4_mb_ht = MB_HEIGHT >> 1;
+ }
+ else
+ {
+ i4_refphase_x = 0;
+ i4_refphase_y = 0;
+ i4_phase_x = 0;
+ i4_phase_y = 0;
+ i4_sub_wd = 1;
+ i4_sub_ht = 1;
+ i4_mb_wd = MB_WIDTH;
+ i4_mb_ht = MB_HEIGHT;
+ }
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Derive shift x and y based on level idd */
+ /* --------------------------------------------------------------------- */
+ if(ps_sps->u1_level_idc <= 30)
+ {
+ i4_shift_x = 16;
+ i4_shift_y = 16;
+ }
+ else
+ {
+ i4_shift_x = 31 - svcd_get_ceil_log2(i4_ref_wd);
+ i4_shift_y = 31 - svcd_get_ceil_log2(i4_ref_ht);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* The following condition is not true in our case for time being */
+ /* --------------------------------------------------------------------- */
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) || (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_phase_y = i4_phase_y + 4 * i4_bot_field_flag;
+
+ if(1 == i4_ref_layer_frame_Mbs_only_flag)
+ i4_refphase_y = (2 * i4_refphase_y) + 2;
+ else
+ i4_refphase_y = i4_refphase_y + (4 * i4_bot_field_flag);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Dx and Dy Computation - Ratio of the base and enhance layer width */
+ /* --------------------------------------------------------------------- */
+ i4_scale_x = ((i4_ref_wd << i4_shift_x) + (i4_scaled_wd >> 1)) / (i4_scaled_wd);
+ i4_scale_y = ((i4_ref_ht << i4_shift_y) + (i4_scaled_ht >> 1)) / (i4_scaled_ht);
+
+ i4_offset_x = i4_scaled_ref_layer_left_offset / i4_sub_wd;
+ i4_add_x = (((i4_ref_wd * (2 + i4_phase_x)) << (i4_shift_x - 2)) + (i4_scaled_wd >> 1)) /
+ i4_scaled_wd +
+ (1 << (i4_shift_x - 5));
+ i4_delta_x = 4 * (2 + i4_refphase_x);
+
+ if((SVCD_TRUE == i4_frame_mbs_only_flag) && (SVCD_TRUE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / i4_sub_ht;
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (i4_shift_y - 2)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (i4_shift_y - 5));
+ i4_delta_y = 4 * (2 + i4_refphase_y);
+ }
+ else
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / (2 * i4_sub_ht);
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (i4_shift_y - 3)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (i4_shift_y - 5));
+ i4_delta_y = 2 * (2 + i4_refphase_y);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Intializing Local Pointers - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+
+ i4_curr_lyr_width = ps_curr_res_prms->i4_res_width >> i4_chroma_flag;
+ i4_curr_lyr_height = ps_curr_res_prms->i4_res_height >> i4_chroma_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Dyadic Scaling Ratios Handling */
+ /* --------------------------------------------------------------------- */
+ if(1 == ps_curr_res_prms->u1_dyadic_flag)
+ {
+ WORD32 i4_refarray_wd, i4_x_offset;
+ WORD32 i4_refarray_ht, i4_y_offset;
+ WORD32 i4_crp_wd_lt, i4_crp_ht_top;
+ WORD32 i4_crp_wd_rt, i4_crp_ht_bot;
+ WORD32 i4_ref_lyr_wd, i4_ref_lyr_ht;
+ WORD32 i4_ref_x, i4_ref_y;
+ WORD32 i4_ofst;
+ WORD32 i4_i, i4_j;
+
+ /* Hard coded for dyadic case */
+ i4_refarray_wd = 20 >> i4_chroma_flag;
+ i4_ofst = -2 >> i4_chroma_flag;
+ i4_crp_wd_lt = i4_scaled_ref_layer_left_offset >> i4_chroma_flag;
+ i4_crp_wd_rt = i4_scaled_ref_layer_right_offset >> i4_chroma_flag;
+ i4_ref_lyr_wd = (i4_curr_lyr_width >> 1);
+
+ i4_ref_x = 0;
+ for(i4_i = 0; i4_i < i4_curr_lyr_width; i4_i += (i4_mb_wd << 1))
+ {
+ i4_x_offset = MAX(i4_ofst, (i4_ref_x + i4_ofst));
+ i4_x_offset = MIN(i4_x_offset, (i4_ref_lyr_wd - i4_ofst));
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+ ps_x_off_len++;
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+ ps_x_off_len++;
+ if(i4_i >= i4_crp_wd_lt)
+ {
+ if(i4_i <= (i4_curr_lyr_width - i4_crp_wd_rt))
+ {
+ i4_ref_x += i4_mb_wd;
+ }
+ }
+ }
+
+ i4_refarray_ht = 20 >> i4_chroma_flag;
+ i4_crp_ht_top = i4_scaled_ref_layer_top_offset >> i4_chroma_flag;
+ i4_crp_ht_bot = i4_scaled_ref_layer_bottom_offset >> i4_chroma_flag;
+ i4_ref_lyr_ht = (i4_curr_lyr_height >> 1);
+
+ i4_ref_y = 0;
+ for(i4_j = 0; i4_j < i4_curr_lyr_height; i4_j += (i4_mb_ht << 1))
+ {
+ i4_y_offset = MAX(i4_ofst, (i4_ref_y + i4_ofst));
+ i4_y_offset = MIN(i4_y_offset, (i4_ref_lyr_ht - i4_ofst));
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+ ps_y_off_len++;
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+ ps_y_off_len++;
+ if(i4_j >= i4_crp_ht_top)
+ {
+ if(i4_j <= (i4_curr_lyr_height - i4_crp_ht_bot))
+ {
+ i4_ref_y += i4_mb_ht;
+ }
+ }
+ }
+
+ /* No need to process further, return */
+ return;
+ } /* If dyadic path */
+
+ /* Proposed Algo for Optimization */
+ {
+ WORD32 i4_max, i4_min;
+ ref_min_max_map_t *ps_x_min_max;
+ ref_min_max_map_t *ps_y_min_max;
+ WORD32 i4_i, i4_j;
+
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+ ps_y_min_max = ps_map_ctxt->ps_y_min_max;
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetX refArrayW Xmin and Xmax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_i = 0; i4_i < i4_curr_lyr_width; i4_i = i4_i + i4_mb_wd)
+ {
+ WORD32 i4_refarray_wd, i4_xr_index;
+ WORD32 i4_x_refmin16;
+ WORD32 i4_x_refmax16;
+ WORD32 i4_x_offset;
+
+ i4_x_refmin16 = (WORD64) (((WORD64) (i4_i - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ (i4_shift_x - 4)) -
+ i4_delta_x;
+
+ i4_x_refmax16 =
+ (WORD64) (((WORD64) (i4_i + i4_mb_wd - 1 - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ (i4_shift_x - 4)) -
+ i4_delta_x;
+
+ /* ------------------------------------------------------------- */
+ /* Modified AC205 */
+ /* Minimum width required - So adding 2 pixels on each side */
+ /* ------------------------------------------------------------- */
+ i4_refarray_wd = ((i4_x_refmax16 + 15) >> 4) - (i4_x_refmin16 >> 4) + 1 + 4;
+
+ /* ------------------------------------------------------------- */
+ /* Setting the offset 2 pixels before */
+ /* ------------------------------------------------------------- */
+ i4_x_offset = (i4_x_refmin16 >> 4) - 2;
+
+ /* ------------------------------------------------------------- */
+ /* Modifying the values based on the location */
+ /* ------------------------------------------------------------- */
+ i4_min = i4_x_offset;
+ i4_xr_index = i4_min - ((i4_min / i4_mb_wd) * i4_mb_wd);
+
+ if(i4_xr_index < (i4_mb_wd >> 1))
+ {
+ i4_refarray_wd = i4_refarray_wd + (i4_mb_wd >> 1);
+ i4_x_offset = i4_x_offset - (i4_mb_wd >> 1);
+ }
+
+ i4_max = ((i4_x_refmax16 + 15) >> 4) + 2;
+ i4_xr_index = i4_max - ((i4_max / i4_mb_wd) * i4_mb_wd);
+
+ if(i4_xr_index >= (i4_mb_wd >> 1)) i4_refarray_wd = i4_refarray_wd + (i4_mb_wd >> 1);
+
+ /* ------------------------------------------------------------- */
+ /* Filling the arrays with offset, min, max and refArray dim */
+ /* ------------------------------------------------------------- */
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = i4_refarray_wd;
+
+ ps_x_min_max->i2_min_pos = (i4_x_refmin16 >> 4) - i4_x_offset;
+ ps_x_min_max->i2_max_pos = ((i4_x_refmax16 + 15) >> 4) - i4_x_offset;
+
+ i4_tmp = (WORD32) (ps_x_min_max->i2_max_pos - ps_x_min_max->i2_min_pos) +
+ (4 >> i4_chroma_flag);
+ if(i4_tmp > i4_horz_dim)
+ {
+ i4_horz_dim = i4_tmp;
+ }
+
+ /* increment the pointer */
+ ps_x_off_len++;
+ ps_x_min_max++;
+
+ } /* end of loop over scaled width */
+
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetY refArrayH Ymin and Ymax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_j = 0; i4_j < i4_curr_lyr_height; i4_j = i4_j + i4_mb_ht)
+ {
+ WORD32 i4_refarray_ht, i4_yr_index;
+ WORD32 i4_y_refmin16;
+ WORD32 i4_y_refmax16;
+ WORD32 i4_y_offset;
+
+ i4_y_refmin16 = (WORD64) (((WORD64) (i4_j - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ (i4_shift_y - 4)) -
+ i4_delta_y;
+
+ i4_y_refmax16 =
+ (WORD64) (((WORD64) (i4_j + i4_mb_ht - 1 - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ (i4_shift_y - 4)) -
+ i4_delta_y;
+
+ /* ------------------------------------------------------------- */
+ /* Modified AC205 */
+ /* Minimum width required - So adding 2 pixels on each side */
+ /* ------------------------------------------------------------- */
+ i4_refarray_ht = ((i4_y_refmax16 + 15) >> 4) - (i4_y_refmin16 >> 4) + 1 + 4;
+
+ /* ------------------------------------------------------------- */
+ /* Setting the offset 2 pixels before */
+ /* ------------------------------------------------------------- */
+ i4_y_offset = (i4_y_refmin16 >> 4) - 2;
+
+ /* ------------------------------------------------------------- */
+ /* Modifying the values based on the location */
+ /* ------------------------------------------------------------- */
+ i4_min = i4_y_offset;
+
+ i4_yr_index = i4_min - ((i4_min / i4_mb_ht) * i4_mb_ht);
+
+ if(i4_yr_index < (i4_mb_ht >> 1))
+ {
+ i4_refarray_ht = i4_refarray_ht + (i4_mb_ht >> 1);
+ i4_y_offset = i4_y_offset - (i4_mb_ht >> 1);
+ }
+
+ i4_max = ((i4_y_refmax16 + 15) >> 4) + 2;
+ i4_yr_index = i4_max - ((i4_max / i4_mb_ht) * i4_mb_ht);
+
+ if(i4_yr_index >= (i4_mb_ht >> 1)) i4_refarray_ht = i4_refarray_ht + (i4_mb_ht >> 1);
+
+ /* ------------------------------------------------------------- */
+ /* Filling the arrays with offset, min, max and refArray dim */
+ /* ------------------------------------------------------------- */
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = i4_refarray_ht;
+
+ ps_y_min_max->i2_min_pos = (i4_y_refmin16 >> 4) - i4_y_offset;
+ ps_y_min_max->i2_max_pos = ((i4_y_refmax16 + 15) >> 4) - i4_y_offset;
+
+ i4_tmp = (WORD32) (ps_y_min_max->i2_max_pos - ps_y_min_max->i2_min_pos) +
+ (4 >> i4_chroma_flag);
+ if(i4_tmp > i4_vert_dim)
+ {
+ i4_vert_dim = i4_tmp;
+ }
+
+ /* increment the pointer */
+ ps_y_off_len++;
+ ps_y_min_max++;
+ } /* end of loop over scaled height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Xref and Xphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+
+ {
+ ref_pixel_map_t *ps_x_pos_phase;
+ WORD32 i4_xc;
+ WORD32 i4_offset_x_index;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+
+ for(i4_xc = 0; i4_xc < i4_curr_lyr_width; i4_xc++)
+ {
+ WORD32 i4_x_offset;
+ WORD32 i4_x_ref16;
+
+ i4_offset_x_index = i4_xc / i4_mb_wd;
+
+ i4_x_offset = ps_x_off_len[i4_offset_x_index].i2_offset;
+
+ i4_x_ref16 = (WORD64) (((WORD64) (i4_xc - i4_offset_x) * i4_scale_x + i4_add_x) >>
+ (i4_shift_x - 4)) -
+ i4_delta_x;
+
+ /* store the values */
+ ps_x_pos_phase->i2_ref_pos = (i4_x_ref16 >> 4) - i4_x_offset;
+ ps_x_pos_phase->i2_phase = i4_x_ref16 & 15;
+
+ /* increment the pointer */
+ ps_x_pos_phase++;
+
+ } /* end of loop over scaled width */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Yref and Yphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_yc;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ for(i4_yc = 0; i4_yc < i4_curr_lyr_height; i4_yc++)
+ {
+ WORD32 i4_y_offset;
+ WORD32 i4_y_ref16;
+ WORD32 i4_offset_y_index;
+
+ i4_offset_y_index = i4_yc / i4_mb_ht;
+
+ i4_y_offset = ps_y_off_len[i4_offset_y_index].i2_offset;
+
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) ||
+ (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - i4_field_Mb_flag);
+ }
+
+ i4_y_ref16 = (WORD64) (((WORD64) (i4_yc - i4_offset_y) * i4_scale_y + i4_add_y) >>
+ (i4_shift_y - 4)) -
+ i4_delta_y;
+
+ ps_y_pos_phase->i2_ref_pos = (i4_y_ref16 >> 4) - i4_y_offset;
+ ps_y_pos_phase->i2_phase = i4_y_ref16 & 15;
+
+ /* increment the pointer */
+ ps_y_pos_phase++;
+
+ } /* end of loop over scaled height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Corresponding Diagonal Location */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD16 *pi2_xd_index;
+ WORD16 *pi2_yd_index;
+ WORD16 *pi2_ya_index;
+ WORD32 i4_i, i4_j;
+
+ pi2_xd_index = ps_map_ctxt->pi2_xd_index;
+ pi2_yd_index = ps_map_ctxt->pi2_yd_index;
+ pi2_ya_index = ps_map_ctxt->pi2_ya_index;
+
+ for(i4_i = 0; i4_i < i4_mb_wd; i4_i++)
+ {
+ *(pi2_xd_index + i4_i) = ((i4_i >= i4_mb_wd >> 1) ? (i4_i - i4_mb_wd) : (i4_i + 1));
+
+ } /* end of loop over MB width */
+
+ for(i4_j = 0; i4_j < i4_mb_ht; i4_j++)
+ {
+ *(pi2_yd_index + i4_j) = ((i4_j >= i4_mb_ht >> 1) ? (i4_j - i4_mb_ht) : (i4_j + 1));
+
+ *(pi2_ya_index + i4_j) =
+ *(pi2_yd_index + i4_j) - ((i4_mb_ht >> 1 + 1) * (SIGN(*(pi2_yd_index + i4_j))));
+
+ } /* end of loop over MB height */
+ }
+
+ /* generate the lookup to generate horizontal segments */
+ svc_intra_resamp_generate_segment_lookup(ps_map_ctxt->ps_seg_lookup_horz, i4_horz_dim, i4_mb_wd,
+ 3);
+
+ /* generate the lookup to generate vertical segments */
+ svc_intra_resamp_generate_segment_lookup(ps_map_ctxt->ps_seg_lookup_vert, i4_vert_dim, i4_mb_ht,
+ 4);
+
+ return;
+} /* end of function "svcd_intra_samp_populate_list"*/
+
+void svcd_intra_samp_populate_res_prms(void *pv_dec)
+
+{
+ dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
+ res_prms_t *ps_curr_lyr_res_prms;
+ ps_curr_lyr_res_prms = &ps_dec->s_res_prms;
+
+ ps_curr_lyr_res_prms->i4_res_width = ps_dec->u2_pic_wd;
+ ps_curr_lyr_res_prms->i4_res_height = ps_dec->u2_pic_ht;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset << 1;
+ ps_curr_lyr_res_prms->u2_scaled_ref_width =
+ (ps_dec->u2_frm_wd_in_mbs << 4) - (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt);
+
+ ps_curr_lyr_res_prms->u2_scaled_ref_height =
+ (ps_dec->u2_frm_ht_in_mbs << 4) - (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot);
+
+ ps_curr_lyr_res_prms->u1_cropping_change_flag = 0;
+ if(2 == ps_dec->ps_cur_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc)
+ {
+ ps_curr_lyr_res_prms->u1_cropping_change_flag = 1;
+
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_scaled_ref_layer_left_offset << 1;
+
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_scaled_ref_layer_top_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_scaled_ref_layer_right_offset << 1;
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_scaled_ref_layer_bottom_offset << 1;
+ ps_curr_lyr_res_prms->u2_scaled_ref_width =
+ (ps_dec->u2_frm_wd_in_mbs << 4) -
+ (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_left +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_rt);
+
+ ps_curr_lyr_res_prms->u2_scaled_ref_height =
+ (ps_dec->u2_frm_ht_in_mbs << 4) -
+ (ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_top +
+ ps_curr_lyr_res_prms->s_ref_lyr_scaled_offset.i2_bot);
+ }
+
+ ps_curr_lyr_res_prms->u1_rstrct_res_change_flag = SVCD_TRUE;
+
+ ps_curr_lyr_res_prms->u1_disable_inter_lyr_dblk_filter_idc =
+ ps_dec->ps_cur_slice->s_svc_slice_params.u4_disable_inter_layer_deblk_filter_idc;
+ ps_curr_lyr_res_prms->i1_inter_lyr_alpha_c0_offset =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_inter_layer_slice_alpha_c0_offset_div2;
+ ps_curr_lyr_res_prms->i1_inter_lyr_beta_offset =
+ ps_dec->ps_cur_slice->s_svc_slice_params.i4_inter_layer_slice_beta_offset_div2;
+ ps_curr_lyr_res_prms->i1_constrained_intra_rsmpl_flag =
+ ps_dec->ps_cur_slice->s_svc_slice_params.u1_constrained_intra_resampling_flag;
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1 =
+ ps_dec->ps_cur_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
+ ps_curr_lyr_res_prms->u1_direct_8x8_inference_flag =
+ ps_dec->ps_cur_sps->u1_direct_8x8_inference_flag;
+
+ ps_curr_lyr_res_prms->u1_remap_req_flag = 1;
+ ps_curr_lyr_res_prms->u1_dyadic_flag = ps_dec->u1_dyadic_flag;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : svcd_intra_samp_res_init */
+/* */
+/* Description : this function calculates the scale factors and initialise*/
+/* the context structure */
+/* */
+/* Inputs : pv_intra_samp_ctxt: handle to private structure */
+/* ps_curr_lyr_res_prms: pointer to current resolution */
+/* params */
+/* ps_ref_lyr_res_prms : pointer to ref resolution params */
+/* Globals : none */
+/* Processing : it stores the layer dimensions */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2009 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void svcd_intra_samp_res_init(void *pv_intra_samp_ctxt, res_prms_t *ps_curr_lyr_res_prms,
+ ref_mb_map_t **pps_luma_map_horz, ref_mb_map_t **pps_chroma_map_horz,
+ ref_mb_map_t **pps_luma_map_vert, ref_mb_map_t **pps_chroma_map_vert,
+ void *pv_dec)
+
+{
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ dec_seq_params_t *ps_sps;
+ dec_struct_t *ps_dec = (dec_struct_t *) pv_dec;
+ dec_struct_t *ps_dec_ref_layer;
+ dec_slice_params_t *ps_slice = ps_dec->ps_cur_slice;
+ dec_slice_svc_ext_params_t *ps_svc_slice_params = NULL;
+ ps_svc_slice_params = &ps_slice->s_svc_slice_params;
+ ps_sps = ps_dec->ps_cur_sps;
+ ps_dec_ref_layer = ps_dec->ps_dec_ref_layer;
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+
+ /* if called for base resolution store default values */
+ if(SVCD_TRUE == ps_dec->u1_base_res_flag)
+ {
+ *pps_luma_map_horz = NULL;
+ *pps_chroma_map_horz = NULL;
+ *pps_luma_map_vert = NULL;
+ *pps_chroma_map_vert = NULL;
+ ps_ctxt->i4_res_lyr_id = -1;
+ ps_ctxt->i4_ref_width = ps_dec->u2_pic_wd;
+ ps_ctxt->i4_ref_height = ps_dec->u2_pic_ht;
+
+ /* Note: The stride option is provided for bringing in data at NMB */
+ /* level. Hence to set a NMB level stride refSample array buffer */
+ /* have to be increased */
+ ps_ctxt->i4_refarray_stride = REF_ARRAY_WIDTH;
+ return;
+ }
+
+ /* derive the current sps */
+
+ /* store the res id appropriately */
+ ps_ctxt->i4_res_lyr_id = ps_dec->u1_layer_id - 1;
+
+ /* store the resolution params */
+ ps_ctxt->ps_res_prms = ps_curr_lyr_res_prms;
+
+ /* get the current layer ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_dec->u1_layer_id - 1];
+
+ ps_ctxt->i4_res_lyr_id = ps_dec->u1_layer_id - 1;
+ /* get the width and heights */
+ ps_lyr_ctxt->i4_curr_width = ps_dec->u2_pic_wd;
+ ps_lyr_ctxt->i4_curr_height = ps_dec->u2_pic_ht;
+ ps_lyr_ctxt->i4_ref_width = ps_ctxt->i4_ref_width;
+ ps_lyr_ctxt->i4_ref_height = ps_ctxt->i4_ref_height;
+ ps_lyr_ctxt->i1_constrained_intra_rsmpl_flag =
+ ps_svc_slice_params->u1_constrained_intra_resampling_flag;
+
+ /* store the structure pointer containing projected locations */
+ *pps_luma_map_horz = ps_lyr_ctxt->s_luma_map_ctxt.ps_x_offset_length;
+ *pps_chroma_map_horz = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_offset_length;
+ *pps_luma_map_vert = ps_lyr_ctxt->s_luma_map_ctxt.ps_y_offset_length;
+ *pps_chroma_map_vert = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_offset_length;
+
+ /* check for recomputation of mapping required */
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ res_prms_t s_ref_res_prms = {0};
+ WORD32 i4_chroma_x_phase, i4_chroma_y_phase;
+ WORD32 i4_ref_chroma_x_phase, i4_ref_chroma_y_phase;
+ WORD32 i4_x_phase_0, i4_x_phase_1;
+ WORD32 i4_y_phase_0, i4_y_phase_1;
+ WORD32 i4_vert_flag;
+
+ /* store the reference layer resolution width and height */
+ s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
+ s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
+
+ /* call the frame level projections calculation function */
+ svcd_intra_samp_populate_list(&ps_lyr_ctxt->s_luma_map_ctxt, ps_curr_lyr_res_prms,
+ &s_ref_res_prms, 0, ps_dec);
+
+ svcd_intra_samp_populate_list(&ps_lyr_ctxt->s_chroma_map_ctxt, ps_curr_lyr_res_prms,
+ &s_ref_res_prms, 1, ps_dec);
+
+ /* Compute the chroma xPhase and yPhase values */
+ if(1 == ps_curr_lyr_res_prms->u1_dyadic_flag)
+ {
+ i4_ref_chroma_x_phase = ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+ i4_ref_chroma_y_phase = ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_x_phase = ps_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag;
+ i4_chroma_y_phase = ps_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1;
+
+ i4_x_phase_0 = i4_chroma_x_phase - (i4_ref_chroma_x_phase << 1);
+ i4_x_phase_1 = (3 + i4_x_phase_0) & 0x7;
+ i4_x_phase_0 += 7;
+ i4_x_phase_0 &= 0x7;
+ i4_y_phase_0 = i4_chroma_y_phase - (i4_ref_chroma_y_phase << 1);
+ i4_y_phase_1 = (3 + i4_y_phase_0) & 0x7;
+ i4_y_phase_0 += 7;
+ i4_y_phase_0 &= 0x7;
+
+ ps_lyr_ctxt->i4_x_phase_0 = i4_x_phase_0;
+ ps_lyr_ctxt->i4_x_phase_1 = i4_x_phase_1;
+ ps_lyr_ctxt->i4_y_phase_0 = i4_y_phase_0;
+ ps_lyr_ctxt->i4_y_phase_1 = i4_y_phase_1;
+
+ /* Choose the appropriate chroma interpolation functions */
+ if((0 == i4_ref_chroma_x_phase) && (1 == i4_chroma_x_phase))
+ {
+ ps_lyr_ctxt->pf_horz_chroma_interpol = (&svcd_horz_interpol_chroma_dyadic_2);
+ }
+ else
+ {
+ ps_lyr_ctxt->pf_horz_chroma_interpol = (&svcd_horz_interpol_chroma_dyadic_1);
+ }
+
+ i4_vert_flag = 0;
+ if(0 == i4_ref_chroma_y_phase)
+ {
+ if((1 == i4_chroma_y_phase) || (2 == i4_chroma_y_phase))
+ {
+ i4_vert_flag = 1;
+ }
+ }
+ else if((2 == i4_ref_chroma_y_phase) && (0 == i4_chroma_y_phase))
+ {
+ i4_vert_flag = 2;
+ }
+
+ if(1 == i4_vert_flag)
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = (&svcd_vert_interpol_chroma_dyadic_2);
+ }
+ else if(2 == i4_vert_flag)
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = (&svcd_vert_interpol_chroma_dyadic_3);
+ }
+ else
+ {
+ ps_lyr_ctxt->pf_vert_chroma_interpol = (&svcd_vert_interpol_chroma_dyadic_1);
+ }
+ }
+ }
+ else
+ {
+ /* should take false value */
+ ASSERT(SVCD_FALSE == ps_curr_lyr_res_prms->u1_remap_req_flag);
+ }
+
+ /* Set the border values of ref_mb_modes to 0xFF */
+ {
+ inter_lyr_mb_prms_t *ps_tmp_prms, *ps_tmp_prms_2;
+ inter_lyr_mb_prms_t *ps_ref_mb_prms;
+ WORD32 i4_stride;
+ WORD32 i4_ref_ht_in_mbs, i4_ref_wd_in_mbs;
+ WORD32 i4_i;
+
+ /* Derive the reference mb mode map */
+
+ ps_ref_mb_prms = ps_dec_ref_layer->ps_inter_lyr_mb_prms_frm_start;
+ i4_stride =
+ ps_dec_ref_layer->u2_inter_lyr_mb_prms_stride; // SVC_DEC_REVIEW_INTRA_RESAMPLE;
+
+ i4_ref_ht_in_mbs = (ps_lyr_ctxt->i4_ref_height >> 4);
+ i4_ref_wd_in_mbs = (ps_lyr_ctxt->i4_ref_width >> 4);
+
+ /* Set the first border row to 0xFF */
+ ps_tmp_prms = (ps_ref_mb_prms - 1 - i4_stride);
+
+ for(i4_i = 0; i4_i < (i4_ref_wd_in_mbs + 2); i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += 1;
+ }
+
+ /* Set the left and right border pixels of each row to 0 */
+ ps_tmp_prms = ps_ref_mb_prms - 1;
+
+ for(i4_i = 0; i4_i < i4_ref_ht_in_mbs; i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms_2 = ps_tmp_prms + (i4_ref_wd_in_mbs + 1);
+ ps_tmp_prms_2->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += i4_stride;
+ }
+
+ /* Set the last border row to 0xFF */
+ for(i4_i = 0; i4_i < (i4_ref_wd_in_mbs + 2); i4_i++)
+ {
+ ps_tmp_prms->i1_mb_mode = (WORD8) 0xFF;
+ ps_tmp_prms += 1;
+ }
+ }
+
+ /* store the current layer width and height to context */
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+
+ return;
+}
diff --git a/decoder/svc/isvcd_resamp_svc.h b/decoder/svc/isvcd_resamp_svc.h
new file mode 100644
index 0000000..d311563
--- /dev/null
+++ b/decoder/svc/isvcd_resamp_svc.h
@@ -0,0 +1,570 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_process_pslice.h
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_RESAMP_SVC_H_
+#define _ISVCD_RESAMP_SVC_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_structs.h"
+
+#define SVCD_FALSE 0
+#define SVCD_TRUE 1
+
+#define MAP_BUFF_WIDTH 48
+#define MAP_BUFF_HEIGHT 48
+#define INTERMEDIATE_BUFF_WIDTH 48
+#define INTERMEDIATE_BUFF_HEIGHT (MB_HEIGHT + 4)
+
+#define MAX_REF_ARR_WD_HT 48
+
+#define MAX_REF_IDX_ARRAY (MAX_REF_ARR_WD_HT + MB_WIDTH)
+#define DYADIC_REF_W_Y 20
+#define DYADIC_REF_H_Y 20
+#define DYADIC_REF_W_C 10
+#define DYADIC_REF_H_C 10
+
+#define SUB_BLOCK_WIDTH 4
+#define SUB_BLOCK_HEIGHT 4
+#define SUB_BLOCK_SIZE (SUB_BLOCK_WIDTH * SUB_BLOCK_HEIGHT)
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
+#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
+#define MB_WIDTH 16
+#define MB_HEIGHT 16
+#define CLIPUCHAR(x) CLIP3(0, 255, (x))
+#define MB_WIDTH_SHIFT 4
+#define MB_HEIGHT_SHIFT 4
+
+#define REF_ARRAY_WIDTH 48
+#define REF_ARRAY_HEIGHT 48
+#define MAX_PIX_FILL_LUMA 4
+#define MAX_PIX_FILL_CHROMA 2
+
+typedef void (*pf_vert_interpol_chroma_dyadic)(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1);
+
+typedef void (*pf_horz_interpol_chroma_dyadic)(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1);
+
+typedef struct
+{
+ void *pv_buffer; /*!< Buffer pointer */
+ WORD32 i4_element_size; /*!< size of the structure or unit */
+ WORD32 i4_num_element_stride; /*!< Stride of buffer in terms of number of elements */
+} mem_element_t;
+
+typedef struct
+{
+ UWORD8 u1_seg_dim; /*!< describes segment dimension */
+ UWORD8 u1_seg_off; /*!< describes offset from start */
+ UWORD8 u1_mb_adjoin; /*!< describes whether mb is adjoining
+ the segment 0 => not adjoining
+ 1 => adjoining */
+
+ WORD8 i1_dist_idx; /*!< distance to nearest MB */
+
+ WORD8 i1_nearst_mb_bdry; /*!< describes the nearest mb boundary
+ +1 => rightMB/bottomMB
+ -1 => leftMB/topMB */
+} seg_description_t;
+
+typedef struct
+{
+ UWORD8 u1_num_segments; /*!< place holder to store the number of segments */
+
+ UWORD8 u4_start_pos; /*!< this variable indicates where is
+ start locatiion of the segment with
+ respect to less the block_width or
+ greater than block width */
+
+ seg_description_t s_segments[4]; /*!< place holder to store per segment description */
+} seg_lookup_desc_t;
+typedef struct
+{
+ WORD16 i2_min_pos; /*!< place holder to store the projected
+ MIN referecne position for a MB in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+ WORD16 i2_max_pos; /*!< place holder to store the projected
+ MAX referecne position for a MB in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+} ref_min_max_map_t;
+
+typedef struct
+{
+ WORD16 i2_left; /*!< Horizontal offset of upper left luma sample
+ after resampling process on reference
+ layer with respect to upper left luma
+ sample of current layer.
+ */
+ WORD16 i2_top; /*!< Vertical offset of upper left luma pixel
+ after resampling process on reference
+ layer
+ */
+ WORD16 i2_rt; /*!< Horizontal offset of bottom right luma
+ sample after resampling process on
+ reference layer with respect to bottom
+ right luma sample.
+ */
+ WORD16 i2_bot; /*!< Vertical offset of bottom right luma
+ pixel after resampling process on
+ reference layer
+ */
+} ref_lyr_scaled_offset_t;
+
+typedef struct
+{
+ UWORD8 i2_ref_pos; /*!< place holder to store the projected
+ referecne position for a pixel in
+ current layer. can be used to store
+ either horizontal or vertical positions
+ */
+ UWORD8 i2_phase; /*!< place holder to store the projected
+ phase for a pixel in current layer.
+ can be used to store either
+ horizontal or vertical phase
+ */
+} ref_pixel_map_t;
+
+typedef struct
+{
+ WORD16 i2_offset; /*!< place holder to store the projected
+ start point of reference window
+ for each MB in current layer.can be
+ used to store either horizontal or
+ vertical offset
+ */
+ WORD16 i2_length; /*!< place holder to store reference array
+ length of the reference window
+ for each MB in current layer.can be
+ used to store either horizontal width
+ or vertical height
+ */
+} ref_mb_map_t;
+
+typedef struct
+{
+ /* used for mapping purpose */
+ ref_pixel_map_t *ps_x_pos_phase; /*!< buffers to store the projected
+ referecne X and phase X for each
+ pixel in current layer in
+ horizontal direction
+ */
+ ref_pixel_map_t *ps_y_pos_phase; /*!< buffers to store the projected
+ referecne Y and phase Y for each
+ pixel in current layer in
+ vertical direction
+ */
+ ref_mb_map_t *ps_x_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array width in
+ horizontal direction for each MB in
+ current layer
+ */
+ ref_mb_map_t *ps_y_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array height in
+ vertical direction for each MB in
+ current layer
+ */
+} residual_samp_map_ctxt_t;
+
+typedef struct
+{
+ residual_samp_map_ctxt_t s_luma_map_ctxt; /*!< map structure for luma
+ projected locations
+ for curr resolution layer
+ */
+ residual_samp_map_ctxt_t s_chroma_map_ctxt; /*!< map structure for chroma
+ projected locations
+ for curr resolution layer
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ WORD32 i4_curr_width; /*!< current layer width in
+ terms luma samples
+ */
+ WORD32 i4_curr_height; /*!< current layer height in
+ terms luma samples
+ */
+ WORD32 i4_dyadic_flag; /*!< flag to indicate whether
+ the upscaling factor is 2
+ in both directions
+
+ /* following variables are for Dyadic cases only */
+ WORD32 i4_chrm_alt_proc; /*!< Alternate processing
+ for chroma for specific
+ values of phases
+ */
+
+ WORD32 i4_chrm_vert_int_mode; /*!< Chroma horizontal
+ interpolation alternate
+ mode
+ */
+
+ WORD32 i4_chrm_horz_int_mode; /*!<Chroma vertical
+ interpolation alternate
+ modes
+ */
+} res_lyr_ctxt;
+
+typedef struct
+{
+ res_lyr_ctxt as_res_lyrs[MAX_NUM_RES_LYRS]; /*!< Array of resolutoin layer
+ ctxt.The first strcuture in the
+ array will be used for storing
+ the "second resolution" map in
+ an access unit w.r.t to its
+ base resolution, and for base
+ resolution nothing will be
+ computed or stored
+ */
+ void *ps_sps; /*!< pointer to array of SPS
+ */
+
+ WORD16 *pi2_refarray_buffer; /*!< buffer to store the reference
+ layer data before residual
+ sampling
+ */
+
+ UWORD8 *pu1_ref_x_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+ UWORD8 *pu1_ref_y_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+
+ WORD32 i4_res_lyr_id; /*!< resolution id of the layer
+ which is to be processed
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+} residual_sampling_ctxt_t;
+
+typedef struct
+{
+ WORD32 i4_res_width; /*!< Frame width of top most layer in the
+ resolution. It's expressed in terms
+ of luma samples.
+ */
+ WORD32 i4_res_height; /*!< Frame height of top most layer in the
+ resolution. It's expressed in terms
+ of luma samples.
+ */
+ ref_lyr_scaled_offset_t s_ref_lyr_scaled_offset; /*!< Scaled offset
+ parameters of reference layer considering
+ bottom most layer of the resolution as
+ current layer. Offsets are with respect
+ to upper left luma samples in top most
+ layer in the resolution.
+ */
+ UWORD16 u2_scaled_ref_width; /*!< Considering bottom most layer of the
+ resolution as current layer, scaled
+ width of reference layer in terms of
+ luma pixels. It's inferred parameter
+ based on reference layer offsets.
+ */
+ UWORD16 u2_scaled_ref_height; /*!< Considering bottom most layer of the
+ resolution as current layer, scaled
+ height of reference layer in terms of
+ luma pixels. It's inferred parameter
+ based on reference layer offsets.
+ */
+ UWORD8 u1_rstrct_res_change_flag; /*!< restrictedResolutionChangeFlag for
+ bottom most layer of the resolution. It's
+ a inferred parameter.
+ */
+ UWORD8 u1_cropping_change_flag; /*!< croppingChangeFlag for bottom most
+ layer of the resolution. It's a inferred
+ parameter.
+ */
+ UWORD8 u1_disable_inter_lyr_dblk_filter_idc; /*!< Mode of operation for
+ inter layer de-blocking. It shall be
+ set for bottom most layer of the top
+ resolution. By top resolution, it
+ referes to the resolution just above
+ the current spatial resolution. This
+ shall be valid for all resolutions
+ except target resolution.
+ */
+ WORD8 i1_inter_lyr_alpha_c0_offset; /*!< specifies the offset used in
+ accessing the alpha and tC0 deblocking
+ filter tables for filtering operations
+ in inter layer de-blocking. Applicable
+ for bottom most layer of the top
+ resolution. By top resolution, it referes
+ to the resolution just above the current
+ spatial resolution. This shall be valid
+ for resolutions except target resolution.
+ */
+ WORD8 i1_inter_lyr_beta_offset; /*!< specifies the offset used in
+ accessing the beta deblocking filter table
+ for filtering operations in inter layer
+ de-blocking. Applicable for bottom most
+ layer of the top resolution. By top
+ resolution, it referes to the resolution
+ just above the current spatial resolution.
+ This shall be valid for resolutions
+ except target resolution.
+ */
+ WORD8 i1_constrained_intra_rsmpl_flag; /*!< Constrained intra resampling
+ flag. Range is [0,1].
+ */
+ WORD8 i1_ref_lyr_chroma_phase_x_plus1_flag; /*!< specifies the horizontal
+ phase shift of the chroma components in
+ units of half luma samples of a layer
+ frame for the layer pictures that may be
+ used for inter-layer prediction
+ */
+
+ WORD8 i1_ref_lyr_chroma_phase_y_plus1; /*!< specifies the vertical phase
+ shift of the chroma components in units of
+ half luma samples of a layer frame for the
+ layer pictures that may be used for
+ inter-layer prediction
+ */
+ UWORD8 u1_direct_8x8_inference_flag; /*!< Direct 8x8 inference flag
+ . Range is [0,1].
+ */
+
+ UWORD8 u1_remap_req_flag; /*!< this flag signifies to the
+ upsampling modules whether the Map
+ buffers have to recomputed for current
+ access unit or to retain the previous
+ access units values
+ */
+ UWORD8 u1_dyadic_flag; /*!< this flag signifies the scaling
+ ratios are 2 in both directions
+ and the cropping is MB aligned
+ */
+} res_prms_t;
+
+typedef struct
+{
+ ref_pixel_map_t *ps_x_pos_phase; /*!< buffers to store the projected
+ referecne X and phase X for each
+ pixel in current layer in
+ horizontal direction
+ */
+ ref_pixel_map_t *ps_y_pos_phase; /*!< buffers to store the projected
+ referecne Y and phase Y for each
+ pixel in current layer in
+ vertical direction
+ */
+ ref_mb_map_t *ps_x_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array width in
+ horizontal direction for each MB in
+ current layer
+ */
+ ref_mb_map_t *ps_y_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array height in
+ vertical direction for each MB in
+ current layer
+ */
+ ref_min_max_map_t *ps_x_min_max;
+ /*!< Buffer to store the projected
+ MIN and MAX referecne position for a
+ MB in current layer in
+ horizontal direction
+ */
+
+ ref_min_max_map_t *ps_y_min_max;
+ /*!< Buffer to store the projected
+ MIN and MAX referecne position for a
+ MB in current layer in
+ Vertical direction
+ */
+
+ WORD16 *pi2_xd_index; /*!< buffers to store the projected
+ XD for each pixel in an MB
+ */
+ WORD16 *pi2_yd_index; /*!< buffers to store the projected
+ YD for each pixel in an MB
+ */
+ WORD16 *pi2_ya_index; /*!< buffers to store the projected
+ YA for each pixel in an MB
+ */
+
+ seg_lookup_desc_t *ps_seg_lookup_horz; /*!< buffers to store lookup for
+ horizontal segment description */
+
+ seg_lookup_desc_t *ps_seg_lookup_vert; /*!< buffers to store lookup for
+ vertical segment description */
+
+ UWORD8 *pu1_refarray_x_idx; /*!< buffers to store lookup for
+ x indexes to get availability
+ from 4x4 availability grid */
+
+ UWORD8 *pu1_refarray_y_idx; /*!< buffers to store lookup for
+ y indexes to get availability
+ from 4x4 availability grid */
+} intra_samp_map_ctxt_t;
+
+typedef struct
+{
+ intra_samp_map_ctxt_t s_luma_map_ctxt; /*!< map structure for luma
+ projected locations
+ for curr resolution layer
+ */
+ intra_samp_map_ctxt_t s_chroma_map_ctxt; /*!< map structure for chroma
+ projected locations
+ for curr resolution layer
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ WORD32 i4_curr_width; /*!< current layer width in
+ terms luma samples
+ */
+ WORD32 i4_curr_height; /*!< current layer height in
+ terms luma samples
+ */
+ WORD8 i1_constrained_intra_rsmpl_flag; /*!< Constrained intra resampling
+ flag. Range is [0,1].
+ */
+ WORD32 i4_x_phase_0; /*!< Chroma xPhase for even
+ values of x for dyadic cases
+ */
+ WORD32 i4_x_phase_1; /*!< Chroma xPhase for odd
+ values of x for dyadic cases
+ */
+ WORD32 i4_y_phase_0; /*!< Chroma yPhase for even
+ values of y for dyadic cases
+ */
+ WORD32 i4_y_phase_1; /*!< Chroma yPhase for odd
+ values of y for dyadic cases
+ */
+ pf_vert_interpol_chroma_dyadic pf_vert_chroma_interpol;
+ /*!< Vertical interpolation
+ function for chroma
+ */
+ pf_horz_interpol_chroma_dyadic pf_horz_chroma_interpol;
+ /*!< Horizontal interpolation
+ function for chroma
+ */
+} intra_samp_lyr_ctxt;
+typedef struct
+{
+ intra_samp_lyr_ctxt as_res_lyrs[MAX_NUM_RES_LYRS]; /*!< Array of resolution
+ layer ctxt.
+ The first strcuture in the
+ array will be used for storing
+ the "second resolution" map in
+ an access unit w.r.t to its
+ base resolution, and for base
+ resolution nothing will be
+ computed or stored
+ */
+ void *ps_sps; /*!< pointer to array of SPS
+ */
+
+ UWORD8 *pu1_refarray_buffer; /*!< buffer to store the reference
+ layer data before intra
+ sampling
+ */
+ UWORD8 *pu1_refarray_cb; /*!< buffer to hold the reference
+ layer Cb data before intra
+ resampling (used for dyadic
+ cases only)
+ */
+ UWORD8 *pu1_refarray_cr; /*!< buffer to hold the reference
+ layer Cr data before intra
+ resampling (used for dyadic
+ cases only)
+ */
+ WORD32 *pi4_temp_interpolation_buffer; /*!< intermideate buffer
+ for interpolation
+ */
+
+ WORD32 i4_res_lyr_id; /*!< resolution id of the layer
+ which is to be processed
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_refarray_stride; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ res_prms_t *ps_res_prms; /*!< Current resolution params
+ */
+} intra_sampling_ctxt_t;
+
+void svcd_intra_samp_mb_dyadic(void *pv_intra_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode_map,
+ mem_element_t *ps_curr_luma, mem_element_t *ps_curr_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, void *ps_dec);
+
+void svcd_residual_samp_mb_dyadic(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_luma_bitmap,
+ mem_element_t *ps_ref_chroma_bitmap,
+ mem_element_t *ps_ref_mb_mode, mem_element_t *ps_out_luma,
+ mem_element_t *ps_out_chroma, UWORD16 u2_mb_x, UWORD16 u2_mb_y);
+
+void svcd_intra_samp_populate_res_prms(void *ps_dec);
+
+void svcd_intra_samp_res_init(void *pv_intra_samp_ctxt, res_prms_t *ps_curr_lyr_res_prms,
+ ref_mb_map_t **pps_luma_map_horz, ref_mb_map_t **pps_chroma_map_horz,
+ ref_mb_map_t **pps_luma_map_vert, ref_mb_map_t **pps_chroma_map_vert,
+ void *ps_dec);
+
+#endif /* _ISVCD_RESAMP_SVC_H_ */
diff --git a/decoder/svc/isvcd_residual_resamp.c b/decoder/svc/isvcd_residual_resamp.c
new file mode 100644
index 0000000..c444402
--- /dev/null
+++ b/decoder/svc/isvcd_residual_resamp.c
@@ -0,0 +1,2649 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_residual_resamp.c
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_residual_chroma_dyadic_alt()
+ * - isvcd_residual_chroma_dyadic()
+ * - isvcd_residual_luma_dyadic()
+ * - isvcd_ref_layer_ptr_incr()
+ * - isvcd_residual_reflayer_const_non_boundary_mb()
+ * - isvcd_residual_reflayer_const_boundary_mb()
+ * - isvcd_residual_reflayer_const()
+ * - isvcd_interpolate_residual()
+ * - isvcd_residual_samp_mb()
+ * - isvcd_residual_samp_mb_dyadic()
+ * - isvcd_residual_samp_populate_list()
+ * - isvcd_residual_samp_res_init()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_mvpred.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_cabac.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_utils.h"
+#include "ih264d_parse_islice.h"
+#include "ih264d_process_bslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264_debug.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_chroma_dyadic_alt */
+/* */
+/* Description : this fucntion does the upsampling of chroma residuals for*/
+/* Dyadic cases and specific chroma phase cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* i4_start_bit_pos : bit position in the byte of packed */
+/* sign values */
+/* Globals : none */
+/* Processing : it does the upsampling with intial phase values */
+/* */
+/* Outputs : Upsampled residuals for chroma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_residual_chroma_dyadic_alt(void *pv_residual_samp_ctxt, UWORD16 u2_mb_x, UWORD16 u2_mb_y,
+ mem_element_t *ps_ref_mb_mode, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, WORD32 i4_cr_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ /* ----------------- Processing ------------------------------- */
+ {
+ ref_pixel_map_t *ps_pos_phase;
+ residual_samp_map_ctxt_t *ps_chroma_map;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+ WORD32 i4_i;
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_phase1, i4_phase2;
+ WORD32 i4_offset_x, i4_offset_y;
+ WORD32 i4_chrm_horz_int_mode, i4_chrm_vert_int_mode;
+ WORD32 i4_horz_intp_ctr = SUB_BLOCK_HEIGHT;
+
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
+
+ {
+ UWORD8 u1_mask;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_chrm_nnz;
+ WORD32 i4_num_element_stride;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms, *ps_inter_lyr_mb_prms_curr;
+
+ u1_mask = (SVCD_TRUE == i4_cr_flag) ? 0xF0 : 0x0F;
+
+ /* Top Left */
+ i4_mb_x = i4_offset_x >> 3;
+ i4_mb_y = i4_offset_y >> 3;
+
+ /* get the location of the byte which has the current mb mode */
+ ps_inter_lyr_mb_prms = ps_ref_mb_mode->pv_buffer;
+ i4_num_element_stride = ps_ref_mb_mode->i4_num_element_stride;
+
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+ i4_chrm_nnz = ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Top Right */
+ i4_mb_x = (i4_offset_x + 4) >> 3;
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Bottom Left */
+ i4_mb_x = i4_offset_x >> 3;
+ i4_mb_y = (i4_offset_y + 4) >> 3;
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+
+ /* Bottom Right */
+ i4_mb_x = (i4_offset_x + 4) >> 3;
+ ps_inter_lyr_mb_prms_curr = ps_inter_lyr_mb_prms + i4_mb_x;
+ ps_inter_lyr_mb_prms_curr += i4_mb_y * i4_num_element_stride;
+
+ i4_chrm_nnz |= ps_inter_lyr_mb_prms_curr->u1_chroma_nnz & u1_mask;
+ if(0 == i4_chrm_nnz)
+ {
+ return;
+ }
+ }
+
+ i4_chrm_horz_int_mode = ps_lyr_ctxt->i4_chrm_horz_int_mode;
+ i4_chrm_vert_int_mode = ps_lyr_ctxt->i4_chrm_vert_int_mode;
+
+ if(0 == i4_chrm_horz_int_mode)
+ {
+ if(i4_offset_x >= 0)
+ {
+ pi2_inp_data++;
+ }
+ }
+
+ if(0 == i4_chrm_vert_int_mode)
+ {
+ if(i4_offset_y >= 0)
+ {
+ pi2_inp_data += i4_inp_data_stride;
+ }
+ }
+ else
+ {
+ /* extra additional row of interpolation required for this case */
+ i4_horz_intp_ctr++;
+ }
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi2_ref_data_byte = pi2_inp_data;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
+
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ /* interchange the phase values for corner case */
+ if(1 == i4_chrm_horz_int_mode)
+ {
+ WORD32 i4_temp;
+ i4_temp = i4_phase1;
+ i4_phase1 = i4_phase2;
+ i4_phase2 = i4_temp;
+ }
+
+ for(i4_i = 0; i4_i < i4_horz_intp_ctr; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[0]);
+
+ if(0 == i4_chrm_horz_int_mode)
+ {
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+ }
+
+ /* unroll count 1 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[2]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* unroll count 2 */
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
+
+ /* unroll count 3 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[6]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 4;
+
+ if(1 == i4_chrm_horz_int_mode)
+ {
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+ }
+
+ /* vertical loop updates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ /* interchange the phase values for corner case */
+ if(0 != i4_chrm_vert_int_mode)
+ {
+ WORD32 i4_temp;
+ i4_temp = i4_phase1;
+ i4_phase1 = i4_phase2;
+ i4_phase2 = i4_temp;
+ }
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD16 *pi2_out;
+ WORD32 *pi4_ref_array_temp;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+ pi2_out = pi2_out_res;
+ pi4_ref_array_temp = pi4_ref_array;
+
+ /* populate the first inter sample */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ if(1 != i4_chrm_vert_int_mode)
+ {
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ if(2 == i4_chrm_vert_int_mode)
+ {
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ /* unroll count 1 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 2 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 3 */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 4 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 5 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 6 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ if(2 != i4_chrm_vert_int_mode)
+ {
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 8) >> 4;
+
+ if(1 == i4_chrm_vert_int_mode)
+ {
+ pi2_out += i4_out_res_stride;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ }
+ }
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res += 2;
+ }
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_chroma_dyadic */
+/* */
+/* Description : this fucntion does the upsampling of chroma residuals for*/
+/* Dyadic cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* i4_start_bit_pos : bit position in the byte of packed */
+/* sign values */
+/* Globals : none */
+/* Processing : it does the upsampling with intial phase values */
+/* */
+/* Outputs : Upsampled residuals for chroma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_residual_chroma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ /* ----------------- Processing ------------------------------- */
+ {
+ WORD32 i4_i;
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ ref_pixel_map_t *ps_pos_phase;
+ WORD32 i4_phase1, i4_phase2;
+
+ pi2_ref_data_byte = pi2_inp_data;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_pos_phase;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[0]);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+
+ /* unroll count 1 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[2]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 2 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* unroll count 3 */
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
+
+ /* unroll count 4 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
+
+ /* unroll count 5 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[6]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 6 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 4;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_ctxt->pi2_refarray_buffer;
+ ps_pos_phase = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_pos_phase;
+ i4_phase1 = ps_pos_phase[0].i2_phase;
+ i4_phase2 = (i4_phase1 + 8) & 0x0F;
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD16 *pi2_out;
+ WORD32 *pi4_ref_array_temp;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+ pi2_out = pi2_out_res;
+ pi4_ref_array_temp = pi4_ref_array;
+
+ /* populate the first inter sample */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 1 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 2 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 3 */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLOCK_WIDTH;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 4 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 5 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 6 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 8) >> 4;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res += 2;
+ }
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_dyadic */
+/* */
+/* Description : this fucntion does the upsampling of luma residuals for */
+/* Dyadic cases */
+/* */
+/* Inputs : pv_residual_samp_ctxt : Residual upsampling context */
+/* pu1_inp_data : input 8 bit data pointer */
+/* i4_inp_data_stride : input buffer stride */
+/* pi2_out_res : output 16 bit buffer pointer */
+/* i4_out_res_stride : Output buffer stride */
+/* pu1_inp_bitmap : input packed sign bit data pointer */
+/* i4_inp_bitmap_stride : sign bit buffer stride */
+/* ps_ref_mb_mode : reference mb mode pointer of base layer */
+/* ps_coord : mb co-ordinate pointer */
+/* Globals : none */
+/* Processing : it does the upsampling with fixed phase values and */
+/* reference layer transform size */
+/* Outputs : Upsampled residuals for luma */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 09 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_residual_luma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, mem_element_t *ps_ref_mb_mode,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
+ WORD32 i4_ref_tx_size)
+
+{
+ WORD16 *pi2_refarray_buffer;
+ WORD32 i4_blk_ctr;
+ residual_sampling_ctxt_t *ps_ctxt;
+
+ UNUSED(ps_ref_mb_mode);
+ UNUSED(u2_mb_x);
+ UNUSED(u2_mb_y);
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ pi2_refarray_buffer = ps_ctxt->pi2_refarray_buffer;
+
+ /* based on transform size the counter and interpolation width and */
+ /* height are intialised as follows */
+ if((i4_ref_tx_size) && (0 != i4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i, i4_j;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+ for(i4_i = 0; i4_i < BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i2_coeff1 = i2_coeff2;
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < MB_WIDTH; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi4_ref_array_temp += MB_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ *pi2_out = ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_1 = i4_horz_samp_2;
+ }
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i;
+
+ /* if reference layer is not coded then no processing */
+ if(0 != (i4_ref_nnz & 0x1))
+ {
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < SUB_BLOCK_HEIGHT; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 2;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLOCK_WIDTH; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 1 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 2 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 3 */
+ pi4_ref_array_temp += BLOCK_WIDTH;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ pi2_out_res += BLOCK_WIDTH;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= SUB_BLOCK_WIDTH;
+ pi2_inp_data += (i4_inp_data_stride * SUB_BLOCK_HEIGHT);
+ pi2_out_res -= MB_WIDTH;
+ pi2_out_res += (i4_out_res_stride * BLOCK_HEIGHT);
+ i4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += SUB_BLOCK_WIDTH;
+ }
+
+ i4_ref_nnz >>= 1;
+
+ } /* end of loop over all the blocks */
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_ref_layer_ptr_incr */
+/* */
+/* Description : this function returns the pointer increments for */
+/* the operand2 of the bilinear interpolation */
+/* Inputs : pi1_ref_mb_modes : reference mb modes */
+/* i4_ref_mode_stride : mb mode buffer stride */
+/* i4_element_size : size of reference mb mode */
+/* i4_x_offset : ref offset x */
+/* i4_y_offset : ref offset y */
+/* i4_refary_wd : reference array width */
+/* i4_refary_ht : reference array height */
+/* pu1_ref_x_ptr_incr : ptr increment buffer for x */
+/* pu1_ref_y_ptr_incr : ptr increment buffer for y */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it calculates the increment as per the transform size */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 18 08 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_ref_layer_ptr_incr(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_x_offset, WORD32 i4_y_offset,
+ WORD32 i4_refary_wd, WORD32 i4_refary_ht,
+ UWORD8 *pu1_ref_x_ptr_incr, UWORD8 *pu1_ref_y_ptr_incr,
+ WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_x_idx, i4_y_idx;
+ WORD32 i4_prev_x, i4_prev_y;
+ WORD32 i4_const_val;
+ WORD32 i4_pos_x, i4_pos_y;
+ WORD32 i4_trans_size;
+ WORD32 i4_act_ary_wd, i4_act_ary_ht;
+ WORD32 i4_and_const;
+ UWORD8 *pu1_incr_x, *pu1_incr_y;
+ WORD32 i4_mb_sft;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD8 *pi1_ref_mb_modes_incr;
+ WORD8 *pi1_ref_mb_modes_incr_temp;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD32 i4_mb_x_strt, i4_mb_y_strt;
+ WORD32 i4_mb_quard1_part_x, i4_mb_quard1_part_y;
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_tx_size, i4_tx_size_q0, i4_tx_size_q1, i4_tx_size_q2, i4_tx_size_q3;
+ WORD8 i1_mb_mode_q0, i1_mb_mode_q1, i1_mb_mode_q2, i1_mb_mode_q3;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ /* Memset to 1 the increment buffers */
+ memset(pu1_ref_x_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
+ memset(pu1_ref_y_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
+
+ /* Initialise actual width and height */
+ i4_act_ary_wd = i4_refary_wd;
+ i4_act_ary_ht = i4_refary_ht;
+
+ /* Initialize x and y */
+ i4_x = 0;
+ i4_y = 0;
+ i4_prev_y = 0;
+ i4_mb_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
+
+ /* Loop over all MBs in the reference array */
+ if(0 == i4_chroma_flag)
+ {
+ i4_x_ref = i4_x_offset + 0;
+ i4_y_ref = i4_y_offset + 0;
+ i4_mb_x_strt = i4_x_ref % i4_mb_wd;
+ i4_mb_y_strt = i4_y_ref % i4_mb_ht;
+ i4_mb_quard1_part_x = i4_mb_wd - i4_mb_x_strt;
+ i4_mb_quard1_part_y = i4_mb_ht - i4_mb_y_strt;
+
+ if(!(i4_mb_quard1_part_x >= 0))
+ {
+ return NOT_OK;
+ }
+ if(!(i4_mb_quard1_part_y >= 0))
+ {
+ return NOT_OK;
+ }
+
+ /* Take care of negative offsets */
+ if(i4_x_ref > 0)
+ {
+ i4_mb_x = (i4_x_ref >> i4_mb_sft);
+ }
+ else
+ {
+ i4_mb_x = 0;
+ }
+ if(i4_y_ref > 0)
+ {
+ i4_mb_y = (i4_y_ref >> i4_mb_sft);
+ }
+ else
+ {
+ i4_mb_y = 0;
+ }
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes_incr = pi1_ref_mb_modes + (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes_incr += (i4_mb_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr;
+ i1_mb_mode_q0 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ i4_tx_size_q0 =
+ (i1_mb_mode_q0 <= SVC_INTER_MB)
+ ? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1 : ps_inter_lyr_mb_prms->i1_tx_size)
+ : 1;
+
+ pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr;
+ if(i4_mb_quard1_part_x > 0)
+ {
+ pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + i4_element_size;
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q1 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ i4_tx_size_q1 =
+ (i1_mb_mode_q1 <= SVC_INTER_MB)
+ ? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
+ : ps_inter_lyr_mb_prms->i1_tx_size)
+ : 1;
+ }
+
+ if(i4_mb_quard1_part_y > 0)
+ {
+ pi1_ref_mb_modes_incr_temp =
+ pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q2 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ i4_tx_size_q2 =
+ (i1_mb_mode_q2 <= SVC_INTER_MB)
+ ? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
+ : ps_inter_lyr_mb_prms->i1_tx_size)
+ : 1;
+ }
+
+ if((i4_mb_quard1_part_x > 0) && (i4_mb_quard1_part_y > 0))
+ {
+ pi1_ref_mb_modes_incr_temp =
+ pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size) + i4_element_size;
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q3 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ i4_tx_size_q3 =
+ (i1_mb_mode_q3 <= SVC_INTER_MB)
+ ? ((ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1
+ : ps_inter_lyr_mb_prms->i1_tx_size)
+ : 1;
+ }
+
+ do
+ {
+ WORD32 i4_idx;
+ WORD32 i4_wd, i4_ht;
+ WORD32 i4_max_pos_x, i4_max_pos_y;
+
+ i4_prev_x = i4_x;
+ i4_x_ref = i4_x_offset + i4_x;
+ i4_y_ref = i4_y_offset + i4_y;
+ i4_tx_size = i4_tx_size_q0;
+ if(i4_x >= i4_mb_quard1_part_x)
+ {
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ i4_tx_size = i4_tx_size_q1;
+ }
+ else if(i4_y >= i4_mb_quard1_part_y)
+ {
+ i4_tx_size = i4_tx_size_q3;
+ }
+ }
+ else if(i4_x < i4_mb_quard1_part_x)
+ {
+ if(i4_y >= i4_mb_quard1_part_y)
+ {
+ i4_tx_size = i4_tx_size_q2;
+ }
+ }
+
+ /* Get the transform size as 4 or 8 */
+ i4_trans_size = ((i4_tx_size + 1) << 2);
+ i4_const_val = i4_trans_size - 1;
+ i4_and_const = i4_const_val;
+
+ /* Fill horizontal tx block edges of current reference mb with 0 */
+ pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
+ pu1_incr_x += (i4_y * i4_refary_wd);
+ i4_ht = (16 - (i4_y_ref & 0xF));
+ i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
+
+ i4_x_idx = i4_x;
+ i4_pos_x = i4_x_ref & 0xF;
+ i4_max_pos_x = 16;
+ i4_x += (16 - i4_pos_x);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_x & i4_and_const));
+ i4_x_idx += i4_idx;
+
+ while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_x + i4_idx;
+ for(i4_i = 0; i4_i < i4_ht; i4_i++)
+ {
+ /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr += i4_refary_wd;
+ }
+
+ /* Updates */
+ i4_pos_x += i4_trans_size;
+ pu1_incr_x += i4_trans_size;
+ i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
+ }
+
+ /* Fill vertical tx block edges of current reference mb with 0 */
+ pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
+ pu1_incr_y += (i4_y * i4_refary_wd);
+ i4_wd = (16 - (i4_x_ref & 0xF));
+ i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
+ i4_y_idx = i4_y;
+ i4_pos_y = i4_y_ref & 0xF;
+ i4_max_pos_y = 16;
+ i4_y += (16 - i4_pos_y);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_y & i4_and_const));
+ i4_y_idx += i4_idx;
+
+ while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
+ for(i4_i = 0; i4_i < i4_wd; i4_i++)
+ {
+ /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr++;
+ }
+
+ /* Updates */
+ i4_pos_y += i4_trans_size;
+ pu1_incr_y += i4_trans_size * i4_refary_wd;
+ i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
+ }
+
+ /* Loop updates */
+ if(i4_x < i4_act_ary_wd)
+ {
+ i4_y = i4_prev_y;
+ }
+ else if(i4_y < i4_act_ary_ht)
+ {
+ i4_prev_y = i4_y;
+ i4_x = 0;
+ }
+
+ } while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
+
+ } /* End of if 0 == i4_chroma_flag */
+ else
+ {
+ /* Set the transform size as 4 */
+ i4_trans_size = 4;
+ i4_const_val = 3;
+
+ do
+ {
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_idx;
+ WORD32 i4_wd, i4_ht;
+ WORD32 i4_max_pos_x, i4_max_pos_y;
+
+ i4_prev_x = i4_x;
+ i4_x_ref = i4_x_offset + i4_x;
+ i4_y_ref = i4_y_offset + i4_y;
+
+ /* Fill horizontal tx block edges of current reference mb with 0 */
+ pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
+ pu1_incr_x += (i4_y * i4_refary_wd);
+ i4_ht = (8 - (i4_y_ref & 0x7));
+ i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
+ i4_x_idx = i4_x;
+ i4_pos_x = i4_x_ref & 0x7;
+ i4_max_pos_x = 8;
+ i4_x += (8 - i4_pos_x);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_x & 0x3));
+ i4_x_idx += i4_idx;
+
+ while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_x + i4_idx;
+ for(i4_i = 0; i4_i < i4_ht; i4_i++)
+ {
+ /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr += i4_refary_wd;
+ }
+
+ /* Updates */
+ i4_pos_x += i4_trans_size;
+ pu1_incr_x += i4_trans_size;
+ i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
+ }
+
+ /* Fill vertical tx block edges of current reference mb with 0 */
+ pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
+ pu1_incr_y += (i4_y * i4_refary_wd);
+ i4_wd = (8 - (i4_x_ref & 0x7));
+ i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
+ i4_y_idx = i4_y;
+ i4_pos_y = i4_y_ref & 0x7;
+ i4_max_pos_y = 8;
+ i4_y += (8 - i4_pos_y);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_y & 0x3));
+ i4_y_idx += i4_idx;
+
+ while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
+ for(i4_i = 0; i4_i < i4_wd; i4_i++)
+ {
+ /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr++;
+ }
+
+ /* Updates */
+ i4_pos_y += i4_trans_size;
+ pu1_incr_y += i4_trans_size * i4_refary_wd;
+ i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
+ }
+
+ /* Loop updates */
+ if(i4_x < i4_act_ary_wd)
+ {
+ i4_y = i4_prev_y;
+ }
+ else if(i4_y < i4_act_ary_ht)
+ {
+ i4_prev_y = i4_y;
+ i4_x = 0;
+ }
+
+ } while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
+
+ } /* End of chroma */
+ return OK;
+
+} /* End of "isvcd_ref_layer_ptr_incr" */
+
+void isvcd_residual_reflayer_const_non_boundary_mb(
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
+ WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_ref_mb_type;
+ WORD16 *pi2_ref_data_byte;
+ WORD16 *pi2_ref_array_temp;
+
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_refarray_wd; i4_x++)
+ {
+ i4_y_ref = i4_y;
+ i4_x_ref = i4_x;
+
+ i4_ref_mb_type = i4_ref_mb_type_q0;
+ if(i4_x >= i4_mb_quard1_part_x)
+ {
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ i4_ref_mb_type = i4_ref_mb_type_q1;
+ }
+ else if(i4_y >= i4_mb_quard1_part_y)
+ {
+ i4_ref_mb_type = i4_ref_mb_type_q3;
+ }
+ }
+ else if(i4_x < i4_mb_quard1_part_x)
+ {
+ if(i4_y >= i4_mb_quard1_part_y)
+ {
+ i4_ref_mb_type = i4_ref_mb_type_q2;
+ }
+ }
+
+ /****************************************************************/
+ /* Reference layer Residual Buffer is maintained as 8-bit data */
+ /* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
+ /* and sign of the data sample is extracted depending upon bit */
+ /* postition. */
+ /****************************************************************/
+
+ /* update the buffer pointers to appropriate locations */
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ /* extract the residual value and fill the buffer */
+ if(SVC_INTER_MB == i4_ref_mb_type)
+ {
+ /* derive the reference data pointers */
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ /* store the residual value */
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ /* if non inter MB then store the 0 */
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+}
+
+void isvcd_residual_reflayer_const_boundary_mb(WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride,
+ WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_wd,
+ WORD32 i4_ref_ht, WORD32 i4_x_offset,
+ WORD32 i4_y_offset, WORD32 i4_ref_mb_type_q0,
+ WORD32 i4_ref_mb_type_q1, WORD32 i4_ref_mb_type_q2,
+ WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_x, i4_y;
+ WORD16 *pi2_ref_data_byte;
+ WORD16 *pi2_ref_array_temp;
+
+ /*Quard 0*/
+ for(i4_y = 0; i4_y < i4_mb_quard1_part_y; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_mb_quard1_part_x; i4_x++)
+ {
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
+
+ /****************************************************************/
+ /* Reference layer Residual Buffer is maintained as 8-bit data */
+ /* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
+ /* and sign of the data sample is extracted depending upon bit */
+ /* postition. */
+ /****************************************************************/
+
+ /* update the buffer pointers to appropriate locations */
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ /* extract the residual value and fill the buffer */
+ if(SVC_INTER_MB == i4_ref_mb_type_q0)
+ {
+ /* input pointer will be pointing to (xoffset,yoffset) */
+ /* So subtract the correction to reference location */
+ if(0 <= i4_x_offset)
+ {
+ /* if only inside frame dimension */
+ i4_x_ref = i4_x_ref - i4_x_offset;
+ }
+
+ if(0 <= i4_y_offset)
+ {
+ /* if only inside frame dimension */
+ i4_y_ref = i4_y_ref - i4_y_offset;
+ }
+ /* derive the reference data pointers */
+
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ /* store the residual value */
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ /* if non inter MB then store the 0 */
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+
+ /*Quard 1*/
+ for(i4_y = 0; i4_y < i4_mb_quard1_part_y; i4_y++)
+ {
+ for(i4_x = i4_mb_quard1_part_x; i4_x < i4_refarray_wd; i4_x++)
+ {
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
+
+ /****************************************************************/
+ /* Reference layer Residual Buffer is maintained as 8-bit data */
+ /* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
+ /* and sign of the data sample is extracted depending upon bit */
+ /* postition. */
+ /****************************************************************/
+
+ /* update the buffer pointers to appropriate locations */
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ /* extract the residual value and fill the buffer */
+ if(SVC_INTER_MB == i4_ref_mb_type_q1)
+ {
+ /* input pointer will be pointing to (xoffset,yoffset) */
+ /* So subtract the correction to reference location */
+ if(0 <= i4_x_offset)
+ {
+ /* if only inside frame dimension */
+ i4_x_ref = i4_x_ref - i4_x_offset;
+ }
+ if(0 <= i4_y_offset)
+ {
+ /* if only inside frame dimension */
+ i4_y_ref = i4_y_ref - i4_y_offset;
+ }
+ /* derive the reference data pointers */
+
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ /* store the residual value */
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ /* if non inter MB then store the 0 */
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+
+ /*Quard 2*/
+ for(i4_y = i4_mb_quard1_part_y; i4_y < i4_refarray_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_mb_quard1_part_x; i4_x++)
+ {
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
+
+ /****************************************************************/
+ /* Reference layer Residual Buffer is maintained as 8-bit data */
+ /* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
+ /* and sign of the data sample is extracted depending upon bit */
+ /* postition. */
+ /****************************************************************/
+
+ /* update the buffer pointers to appropriate locations */
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ /* extract the residual value and fill the buffer */
+ if(SVC_INTER_MB == i4_ref_mb_type_q2)
+ {
+ /* input pointer will be pointing to (xoffset,yoffset) */
+ /* So subtract the correction to reference location */
+ if(0 <= i4_x_offset)
+ {
+ /* if only inside frame dimension */
+ i4_x_ref = i4_x_ref - i4_x_offset;
+ }
+ if(0 <= i4_y_offset)
+ {
+ /* if only inside frame dimension */
+ i4_y_ref = i4_y_ref - i4_y_offset;
+ }
+ /* derive the reference data pointers */
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ /* store the residual value */
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ /* if non inter MB then store the 0 */
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+
+ /*Quard 3*/
+ for(i4_y = i4_mb_quard1_part_y; i4_y < i4_refarray_ht; i4_y++)
+ {
+ for(i4_x = i4_mb_quard1_part_x; i4_x < i4_refarray_wd; i4_x++)
+ {
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
+
+ /****************************************************************/
+ /* Reference layer Residual Buffer is maintained as 8-bit data */
+ /* Buffer and 1-bit sign bit packed buffer. Sign Byte is read */
+ /* and sign of the data sample is extracted depending upon bit */
+ /* postition. */
+ /****************************************************************/
+
+ /* update the buffer pointers to appropriate locations */
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ /* extract the residual value and fill the buffer */
+ if(SVC_INTER_MB == i4_ref_mb_type_q3)
+ {
+ /* input pointer will be pointing to (xoffset,yoffset) */
+ /* So subtract the correction to reference location */
+ if(0 <= i4_x_offset)
+ {
+ /* if only inside frame dimension */
+ i4_x_ref = i4_x_ref - i4_x_offset;
+ }
+ if(0 <= i4_y_offset)
+ {
+ /* if only inside frame dimension */
+ i4_y_ref = i4_y_ref - i4_y_offset;
+ }
+ /* derive the reference data pointers */
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ /* store the residual value */
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ /* if non inter MB then store the 0 */
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_reflayer_const */
+/* */
+/* Description : This function constructs the reference array buffer */
+/* used for residual resampling of a component in an MB */
+/* */
+/* Inputs : pv_residual_samp_ctxt: intra sampling context */
+/* pu1_inp : input (reference layer data) */
+/* i4_inp_stride : input buffer stride */
+/* pu1_inp_bitmap : input (reference layer sign bits) */
+/* i4_inp_stride : input buffer stride */
+/* ps_ref_mb_mode : ref layer mb mode buffer desc */
+/* pi4_refarr_wd : pointer to store the reference array WD */
+/* pi4_refarr_ht : pointer to store the reference array HT */
+/* pi4_x_offset : pointer to store the reference X offset */
+/* pi4_y_offset : pointer to store the reference Y offset */
+/* ps_coord : mb co-ordinate structure */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it fills the reference layer data if they are falling in */
+/* INTRA MB region. If all the pixels are not filled it */
+/* calls the border extension algorithm to fill them */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 07 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_residual_reflayer_const(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, mem_element_t *ps_ref_mb_mode,
+ WORD32 *pi4_refarr_wd, mb_coord_t *ps_coord,
+ WORD32 i4_chroma_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ WORD8 *pi1_ref_mb_modes;
+ WORD32 i4_ref_mode_stride;
+ WORD32 i4_element_size;
+ WORD32 i4_ref_wd;
+ WORD32 i4_ref_ht;
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refarray_wd;
+ WORD32 i4_refarray_ht;
+ WORD8 i1_edge_mb;
+ WORD16 *pi2_ref_array;
+ WORD32 i4_mb_sft;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_mb_x_strt, i4_mb_y_strt;
+ WORD32 i4_mb_quard1_part_x, i4_mb_quard1_part_y;
+ WORD8 *pi1_ref_mb_modes_incr;
+ WORD8 *pi1_ref_mb_modes_incr_temp;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_ref_mb_type_q0, i4_ref_mb_type_q1, i4_ref_mb_type_q2, i4_ref_mb_type_q3;
+ WORD8 i1_mb_mode_q0, i1_mb_mode_q1, i1_mb_mode_q2, i1_mb_mode_q3;
+ WORD32 ret;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
+
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode->pv_buffer;
+ i4_ref_mode_stride = ps_ref_mb_mode->i4_num_element_stride;
+ i4_element_size = ps_ref_mb_mode->i4_element_size;
+
+ if(NULL == pi1_ref_mb_modes)
+ {
+ return NOT_OK;
+ }
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ /* ----------------------------------------------------------------- */
+ /* Deriving the parameters required for further processing */
+ /* ----------------------------------------------------------------- */
+ {
+ ref_mb_map_t *ps_x_off_len;
+ ref_mb_map_t *ps_y_off_len;
+ WORD32 i4_mbaddr_x;
+ WORD32 i4_mbaddr_y;
+ WORD32 i4_base_width;
+ WORD32 i4_base_height;
+ residual_samp_map_ctxt_t *ps_map_ctxt;
+
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ else
+ ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
+
+ i4_mbaddr_y = ps_coord->u2_mb_y;
+ i4_mbaddr_x = ps_coord->u2_mb_x;
+ i4_base_width = ps_lyr_ctxt->i4_ref_width;
+ i4_base_height = ps_lyr_ctxt->i4_ref_height;
+ i4_ref_wd = i4_base_width >> i4_chroma_flag;
+ i4_ref_ht = i4_base_height >> i4_chroma_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Extracting information from the mapping context */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+ i4_x_offset = ps_x_off_len[i4_mbaddr_x].i2_offset;
+ i4_y_offset = ps_y_off_len[i4_mbaddr_y].i2_offset;
+ i4_refarray_wd = ps_x_off_len[i4_mbaddr_x].i2_length;
+ i4_refarray_ht = ps_y_off_len[i4_mbaddr_y].i2_length;
+ }
+
+ /* Call the module to fill the increments based on transform blocks */
+ ret = isvcd_ref_layer_ptr_incr(pi1_ref_mb_modes, i4_ref_mode_stride, i4_element_size,
+ i4_x_offset, i4_y_offset, i4_refarray_wd, i4_refarray_ht,
+ ps_ctxt->pu1_ref_x_ptr_incr, ps_ctxt->pu1_ref_y_ptr_incr,
+ i4_chroma_flag);
+
+ if(ret != OK)
+ {
+ return ret;
+ }
+ i4_mb_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
+
+ /* --------------------------------------------------------------------- */
+ /* MB Level Resampling for the MB - Pointers sent for MB in both layers */
+ /* This has been written according to the dyadic case */
+ /* --------------------------------------------------------------------- */
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, 0 + i4_y_offset));
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, 0 + i4_x_offset));
+ i4_mb_x_strt = i4_x_ref % i4_mb_wd;
+ i4_mb_y_strt = i4_y_ref % i4_mb_ht;
+
+ i4_mb_quard1_part_x = i4_mb_wd - i4_mb_x_strt;
+ i4_mb_quard1_part_y = i4_mb_ht - i4_mb_y_strt;
+ if(!(i4_mb_quard1_part_x >= 0))
+ {
+ return NOT_OK;
+ }
+ if(!(i4_mb_quard1_part_y >= 0))
+ {
+ return NOT_OK;
+ }
+
+ i4_mb_x = (i4_x_ref >> i4_mb_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_sft);
+
+ /* get the location of the byte which has the current mb mode */
+ pi1_ref_mb_modes_incr = pi1_ref_mb_modes + (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes_incr += (i4_mb_x * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr;
+ i1_mb_mode_q0 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ i1_mb_mode_q1 = i1_mb_mode_q0;
+ i1_mb_mode_q2 = i1_mb_mode_q0;
+ i1_mb_mode_q3 = i1_mb_mode_q0;
+
+ pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr;
+ if(i4_mb_quard1_part_x > 0)
+ {
+ pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + i4_element_size;
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q1 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ }
+
+ if(i4_mb_quard1_part_y > 0)
+ {
+ pi1_ref_mb_modes_incr_temp = pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size);
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q2 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ }
+
+ if((i4_mb_quard1_part_x > 0) && (i4_mb_quard1_part_y > 0))
+ {
+ pi1_ref_mb_modes_incr_temp =
+ pi1_ref_mb_modes_incr + (i4_ref_mode_stride * i4_element_size) + i4_element_size;
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes_incr_temp;
+ i1_mb_mode_q3 = ps_inter_lyr_mb_prms->i1_mb_mode;
+ }
+
+ i4_ref_mb_type_q0 = (i1_mb_mode_q0 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
+ i4_ref_mb_type_q1 = (i1_mb_mode_q1 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
+ i4_ref_mb_type_q2 = (i1_mb_mode_q2 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
+ i4_ref_mb_type_q3 = (i1_mb_mode_q3 <= SVC_INTER_MB) ? SVC_INTER_MB : SVC_INTRA_MB;
+
+ i1_edge_mb = (ps_coord->u2_mb_x == 0 || ps_coord->u2_mb_y == 0 ||
+ (ps_coord->u2_mb_x == ((ps_lyr_ctxt->i4_curr_width >> MB_WIDTH_SHIFT) - 1)) ||
+ (ps_coord->u2_mb_y == ((ps_lyr_ctxt->i4_curr_height >> MB_HEIGHT_SHIFT) - 1)));
+ if(i1_edge_mb)
+ {
+ ps_ctxt->pf_residual_reflayer_const_boundary_mb(
+ pi2_inp_data, i4_inp_data_stride, pi2_ref_array, i4_refarray_wd, i4_refarray_ht,
+ i4_ref_wd, i4_ref_ht, i4_x_offset, i4_y_offset, i4_ref_mb_type_q0, i4_ref_mb_type_q1,
+ i4_ref_mb_type_q2, i4_ref_mb_type_q3, i4_mb_quard1_part_x, i4_mb_quard1_part_y,
+ i4_chroma_flag);
+ }
+ else
+ {
+ ps_ctxt->pf_residual_reflayer_const_non_boundary_mb(
+ pi2_inp_data, i4_inp_data_stride, pi2_ref_array, i4_refarray_wd, i4_refarray_ht,
+ i4_ref_mb_type_q0, i4_ref_mb_type_q1, i4_ref_mb_type_q2, i4_ref_mb_type_q3,
+ i4_mb_quard1_part_x, i4_mb_quard1_part_y, i4_chroma_flag);
+ }
+ /* store the values into the place holders */
+ *pi4_refarr_wd = i4_refarray_wd;
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_residual */
+/* */
+/* Description : This function takes the refernce array buffer and perform*/
+/* interpolation of a component to find the residual */
+/* resampled value */
+/* Inputs : pv_residual_samp_ctxt : residual sampling context */
+/* pi2_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 07 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_residual(void *pv_residual_samp_ctxt, WORD16 *pi2_out, WORD32 i4_out_stride,
+ WORD32 i4_refarray_wd, UWORD16 u2_mb_x, UWORD16 u2_mb_y,
+ WORD32 i4_chroma_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ residual_samp_map_ctxt_t *ps_map_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ WORD32 i4_temp_array_ht;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD16 *pi2_ref_array;
+ UWORD8 *pu1_ref_x_ptr_incr, *pu1_ref_y_ptr_incr;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
+ pu1_ref_x_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr;
+ pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_y_ptr_incr;
+
+ /* --------------------------------------------------------------------- */
+ /* Extracting information from the mapping context */
+ /* --------------------------------------------------------------------- */
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ else
+ ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+ i4_temp_array_ht = i4_mb_ht;
+ i4_frm_mb_y = u2_mb_y * i4_mb_ht;
+ i4_frm_mb_x = u2_mb_x * i4_mb_wd;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation */
+ /* --------------------------------------------------------------------- */
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ for(i4_x = 0; i4_x < (i4_mb_wd); i4_x++)
+ {
+ WORD32 i4_i;
+ WORD32 i4_y_ref;
+ WORD32 i4_y_phase;
+ WORD32 i4_x_ref;
+ WORD32 i4_x_phase;
+ WORD32 i4_x_ref_round;
+ WORD16 *pi2_out_curr;
+ WORD32 ai4_temp_pred[2] = {0};
+ UWORD8 *pu1_ref_y_ptr_incr_temp;
+ WORD32 *pi4_temp_pred;
+ UWORD8 u1_incr_y;
+ WORD16 i2_res;
+
+ /* derive the current output pointer */
+ pi2_out_curr = pi2_out + (i4_x << i4_chroma_flag) + (i4_y * i4_out_stride);
+
+ /* -------------------------------------------------------------- */
+ /* Finding the offset */
+ /* -------------------------------------------------------------- */
+ i4_y_ref = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos;
+ i4_y_phase = ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ i4_x_ref = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ i4_x_phase = ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+
+ /* horizontal processing*/
+ for(i4_i = 0; i4_i < 2; i4_i++)
+ {
+ UWORD8 *pu1_ref_x_ptr_incr_temp;
+ UWORD8 u1_incr;
+ WORD16 *pi2_ref_array_1, *pi2_ref_array_2;
+
+ /* derive appropriate pointers */
+ pu1_ref_x_ptr_incr_temp = pu1_ref_x_ptr_incr + i4_x_ref;
+ pu1_ref_x_ptr_incr_temp += ((i4_y_ref + i4_i) * i4_refarray_wd);
+ u1_incr = *pu1_ref_x_ptr_incr_temp;
+ pi2_ref_array_1 = pi2_ref_array + i4_x_ref;
+ pi2_ref_array_1 += ((i4_y_ref + i4_i) * i4_refarray_wd);
+
+ if(!u1_incr)
+ {
+ pi2_ref_array_1 += (i4_x_phase >> 3);
+ }
+
+ pi2_ref_array_2 = pi2_ref_array_1 + u1_incr;
+ ai4_temp_pred[i4_i] =
+ (16 - i4_x_phase) * (*pi2_ref_array_1) + i4_x_phase * (*pi2_ref_array_2);
+ }
+
+ /* vertical processing */
+ i4_x_ref_round = (i4_x_ref + (i4_x_phase >> 3));
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + i4_x_ref_round + (i4_y_ref * i4_refarray_wd);
+ u1_incr_y = *pu1_ref_y_ptr_incr_temp;
+
+ pi4_temp_pred = &ai4_temp_pred[0];
+ if(!u1_incr_y)
+ {
+ pi4_temp_pred += (i4_y_phase >> 3);
+ }
+
+ i2_res = (((16 - i4_y_phase) * pi4_temp_pred[0] +
+ i4_y_phase * pi4_temp_pred[u1_incr_y] + 128) >>
+ 8);
+
+ /* store back the final residual */
+ *pi2_out_curr = i2_res;
+ } /* end of loop over width */
+ } /* end of loop over height */
+
+ return;
+} /* End of Interpolation Function */
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_samp_mb */
+/* */
+/* Description : MB level function whcih perform the residual resampling */
+/* of data of an MB (luma and chroma insclusive) */
+/* */
+/* Inputs : pv_residual_samp_ctxt : residual sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_luma_bitmap : ref layer luma bit map buffer desc */
+/* ps_ref_chroma_bitmap : ref layer chroma bit map buff des */
+/* ps_ref_mb_mode : ref layer mb mode map buff desc */
+/* ps_out_luma : current layer out luma buffer desc */
+/* ps_out_chroma : current layer out chroma buffer desc */
+/* ps_mb_coord : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interplaotion function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_residual_samp_mb(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
+ mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y)
+{
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ residual_sampling_ctxt_t *ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ WORD16 *pi2_inp;
+ WORD16 *pi2_out;
+ WORD32 i4_inp_stride;
+ WORD32 i4_out_stride;
+ WORD32 i4_refarray_wd;
+ mb_coord_t s_mb_coord = {0};
+ WORD32 ret;
+ s_mb_coord.u2_mb_x = u2_mb_x;
+ s_mb_coord.u2_mb_y = u2_mb_y;
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ pi2_inp = (WORD16 *) ps_ref_luma->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_luma->pv_buffer;
+ i4_inp_stride = ps_ref_luma->i4_num_element_stride;
+ i4_out_stride = ps_out_luma->i4_num_element_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
+ ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 0);
+
+ if(ret != OK) return ret;
+ /* ---- Interpolation process for Residual prediction ------ */
+ ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
+ s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 0);
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ /* CB */
+ pi2_inp = (WORD16 *) ps_ref_chroma->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_chroma->pv_buffer;
+ i4_inp_stride = ps_ref_chroma->i4_num_element_stride;
+ i4_out_stride = ps_out_chroma->i4_num_element_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
+ ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 1);
+
+ if(ret != OK) return ret;
+ /* ---- Interpolation process for Residual prediction ------ */
+ ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
+ s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 1);
+
+ /* CR */
+ pi2_inp += 1;
+ pi2_out += 1;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ ret = isvcd_residual_reflayer_const(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
+ ps_ref_mb_mode, &i4_refarray_wd, &s_mb_coord, 1);
+
+ if(ret != OK) return ret;
+ /* ---- Interpolation process for Residual prediction --------- */
+ ps_ctxt->pf_interpolate_residual(pv_residual_samp_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
+ s_mb_coord.u2_mb_x, s_mb_coord.u2_mb_y, 1);
+ return OK;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_samp_mb_dyadic */
+/* */
+/* Description : MB level function whcih perform the residual resampling */
+/* of data of an MB (luma and chroma insclusive) */
+/* for Dyadic cases */
+/* Inputs : pv_residual_samp_ctxt : residual sampling context */
+/* ps_ref_luma : reference layer luma data buffer desc */
+/* ps_ref_chroma : reference layer chroma data buffer desc */
+/* ps_ref_luma_bitmap : ref layer luma bit map buffer desc */
+/* ps_ref_chroma_bitmap : ref layer chroma bit map buff des */
+/* ps_ref_mb_mode : ref layer mb mode map buff desc */
+/* ps_out_luma : current layer out luma buffer desc */
+/* ps_out_chroma : current layer out chroma buffer desc */
+/* ps_mb_coord : current mb coorinate */
+/* Globals : none */
+/* Processing : it calls the reference layer construction followed by */
+/* interplaotion function for luma and cb and cr */
+/* Outputs : inter resampled data of current MB */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_residual_samp_mb_dyadic(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
+ mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ /* --------------------------------------------------------------------- */
+ /* I/O buffer params */
+ /* --------------------------------------------------------------------- */
+ WORD16 *pi2_inp;
+ WORD16 *pi2_out;
+ WORD32 i4_inp_stride;
+ WORD32 i4_out_stride;
+ WORD32 i4_luma_nnz;
+ WORD32 i4_chroma_nnz;
+ WORD32 i4_tx_size;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ pi2_inp = (WORD16 *) ps_ref_luma->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_luma->pv_buffer;
+ i4_inp_stride = ps_ref_luma->i4_num_element_stride;
+ i4_out_stride = ps_out_luma->i4_num_element_stride;
+
+ {
+ WORD32 i4_offset_x, i4_offset_y;
+ residual_samp_map_ctxt_t *ps_luma_map;
+ ref_mb_map_t *ps_x_off_len_luma;
+ ref_mb_map_t *ps_y_off_len_luma;
+
+ ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
+ ps_x_off_len_luma = ps_luma_map->ps_x_offset_length;
+ ps_y_off_len_luma = ps_luma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_luma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_luma[u2_mb_y].i2_offset;
+
+ {
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
+ WORD32 i4_mb_x, i4_mb_y;
+ UWORD16 u2_luma_mask = 0x0033;
+ UWORD8 u1_chrm_mask = 0x11;
+ WORD32 i4_luma_rt_sft_amt = 0;
+ WORD32 i4_chrm_rt_sft_amt = 0;
+
+ i4_mb_x = ((i4_offset_x + 1) >> MB_WIDTH_SHIFT);
+ i4_mb_y = ((i4_offset_y + 1) >> MB_HEIGHT_SHIFT);
+
+ /* get the location of the byte which has the current mb mode */
+ ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) ps_ref_mb_mode->pv_buffer;
+ ps_inter_lyr_mb_prms += i4_mb_x;
+ ps_inter_lyr_mb_prms += i4_mb_y * ps_ref_mb_mode->i4_num_element_stride;
+
+ /* get the approp block in base layer in horz direction */
+ if(0 != ((i4_offset_x + 1) & 15))
+ {
+ u2_luma_mask <<= 2;
+ i4_luma_rt_sft_amt += 2;
+ u1_chrm_mask <<= 1;
+ i4_chrm_rt_sft_amt += 1;
+ }
+ /* get the approp block in base layer in vert direction */
+ if(0 != ((i4_offset_y + 1) & 15))
+ {
+ u2_luma_mask <<= 8;
+ i4_luma_rt_sft_amt += 8;
+
+ u1_chrm_mask <<= 2;
+ i4_chrm_rt_sft_amt += 2;
+ }
+
+ /* extract the nnz and store it */
+ i4_luma_nnz = (ps_inter_lyr_mb_prms->u2_luma_nnz & u2_luma_mask) >> i4_luma_rt_sft_amt;
+ i4_chroma_nnz =
+ (ps_inter_lyr_mb_prms->u1_chroma_nnz & u1_chrm_mask) >> i4_chrm_rt_sft_amt;
+ i4_tx_size =
+ (ps_inter_lyr_mb_prms->i1_tx_size < 0) ? 1 : ps_inter_lyr_mb_prms->i1_tx_size;
+ }
+
+ /* since in dyadic case the window width and height will be 10x10 */
+ /* and the window start offsets will be always 1 column left and */
+ /* 1 row above the block boundary. so the pointer and the required */
+ /* positions are appropriately modified */
+ if(i4_offset_x >= 0)
+ {
+ pi2_inp++;
+ }
+
+ if(i4_offset_y >= 0)
+ {
+ pi2_inp += i4_inp_stride;
+ }
+
+ ps_ctxt->pf_residual_luma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, ps_ref_mb_mode, u2_mb_x, u2_mb_y,
+ i4_luma_nnz, i4_tx_size);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* CHROMA PROCESSING */
+ /* --------------------------------------------------------------------- */
+ /* CB */
+ pi2_inp = (WORD16 *) ps_ref_chroma->pv_buffer;
+ pi2_out = (WORD16 *) ps_out_chroma->pv_buffer;
+ i4_inp_stride = ps_ref_chroma->i4_num_element_stride;
+ i4_out_stride = ps_out_chroma->i4_num_element_stride;
+
+ /* choose the appropriate chroma processing routine */
+ if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
+ {
+ WORD32 i4_offset_x, i4_offset_y;
+ residual_samp_map_ctxt_t *ps_chroma_map;
+ ref_mb_map_t *ps_x_off_len_chroma;
+ ref_mb_map_t *ps_y_off_len_chroma;
+
+ ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ ps_x_off_len_chroma = ps_chroma_map->ps_x_offset_length;
+ ps_y_off_len_chroma = ps_chroma_map->ps_y_offset_length;
+
+ /* get the actual offset for the buffers */
+ i4_offset_x = ps_x_off_len_chroma[u2_mb_x].i2_offset;
+ i4_offset_y = ps_y_off_len_chroma[u2_mb_y].i2_offset;
+
+ /* since in dyadic case the window width and height will be 6x6 */
+ /* and the window start offsets will be always 1 column left and */
+ /* 1 row above the block boundary. so the pointer and the required */
+ /* positions are appropriately modified */
+ if(i4_offset_x >= 0)
+ {
+ pi2_inp += 2;
+ }
+
+ if(i4_offset_y >= 0)
+ {
+ pi2_inp += i4_inp_stride;
+ }
+
+ if(0 != (i4_chroma_nnz & 0x01))
+ {
+ ps_ctxt->pf_residual_chroma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
+ pi2_out, i4_out_stride);
+ }
+ }
+ else
+ {
+ ps_ctxt->pf_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y,
+ ps_ref_mb_mode, pi2_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, SVCD_FALSE);
+ }
+
+ /* CR */
+ pi2_inp += 1;
+ pi2_out += 1;
+
+ if(SVCD_FALSE == ps_lyr_ctxt->i4_chrm_alt_proc)
+ {
+ if(0 != (i4_chroma_nnz & 0x10))
+ {
+ ps_ctxt->pf_residual_chroma_dyadic(pv_residual_samp_ctxt, pi2_inp, i4_inp_stride,
+ pi2_out, i4_out_stride);
+ }
+ }
+ else
+ {
+ ps_ctxt->pf_residual_chroma_dyadic_alt(pv_residual_samp_ctxt, u2_mb_x, u2_mb_y,
+ ps_ref_mb_mode, pi2_inp, i4_inp_stride, pi2_out,
+ i4_out_stride, SVCD_TRUE);
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_samp_populate_list */
+/* */
+/* Description : This is a seq or frame level init function which fills */
+/* all offsets, projected locations arrays based on */
+/* the two resolutions and cropping parameters */
+/* Inputs : refer to doxygen comments below */
+/* Globals : none */
+/* Processing : it projects the locations and computes the values */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 07 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+void isvcd_residual_samp_populate_list(residual_samp_map_ctxt_t *ps_map_ctxt,
+ dec_seq_params_t *ps_sps,
+ dec_svc_seq_params_t *ps_subset_sps,
+ res_prms_t *ps_curr_res_prms, res_prms_t *ps_ref_res_prms,
+ WORD32 i4_chroma_flag)
+{
+ /* --------------------------------------------------------------------- */
+ /* Local variables required for finding the mapping between the layers */
+ /* --------------------------------------------------------------------- */
+ UWORD32 u4_shift_x;
+ UWORD32 u4_shift_y;
+ UWORD32 u4_scale_x;
+ UWORD32 u4_scale_y;
+ WORD32 i4_offset_x;
+ WORD32 i4_offset_y;
+ WORD32 i4_add_x;
+ WORD32 i4_add_y;
+ WORD32 i4_delta_x;
+ WORD32 i4_delta_y;
+ WORD32 i4_refphase_x;
+ WORD32 i4_refphase_y;
+ WORD32 i4_phase_x;
+ WORD32 i4_phase_y;
+ WORD32 i4_sub_wd;
+ WORD32 i4_sub_ht;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ /* --------------------------------------------------------------------- */
+ /* Local Pointer Declaration for arrays in Mapping context */
+ /* --------------------------------------------------------------------- */
+ ref_mb_map_t *ps_x_off_len;
+ ref_mb_map_t *ps_y_off_len;
+ UWORD32 i4_ref_wd;
+ UWORD32 i4_ref_ht;
+ UWORD32 i4_scaled_wd;
+ UWORD32 i4_scaled_ht;
+ WORD32 i4_curr_lyr_width;
+ WORD32 i4_curr_lyr_height;
+
+ /* --------------------------------------------------------------------- */
+ /* Local Flag Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_ref_layer_field_pic_flag;
+ WORD32 i4_field_pic_flag;
+ WORD32 i4_frame_mbs_only_flag;
+ WORD32 i4_ref_layer_frame_Mbs_only_flag;
+ WORD32 i4_field_Mb_flag;
+ WORD32 i4_bot_field_flag;
+
+ /* --------------------------------------------------------------------- */
+ /* Cropping Parameters Declaration */
+ /* --------------------------------------------------------------------- */
+ WORD32 i4_scaled_ref_layer_left_offset;
+ WORD32 i4_scaled_ref_layer_top_offset;
+
+ /* --------------------------------------------------------------------- */
+ /* Hardcoding flag information (assuming no field support) */
+ /* --------------------------------------------------------------------- */
+ i4_ref_layer_field_pic_flag = SVCD_FALSE;
+ i4_field_pic_flag = SVCD_FALSE;
+ i4_frame_mbs_only_flag = SVCD_TRUE;
+ i4_field_Mb_flag = SVCD_FALSE;
+ i4_bot_field_flag = SVCD_FALSE;
+ i4_ref_layer_frame_Mbs_only_flag = SVCD_TRUE;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointer and Paramater are intialized - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_base_width;
+ WORD32 i4_base_height;
+ WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
+ WORD32 i4_ref_layer_chroma_phase_y_plus1;
+ WORD32 i4_chroma_phase_x_plus1_flag;
+ WORD32 i4_chroma_phase_y_plus1;
+
+ /* ------------------------------------------------------------- */
+ /* HARD CODED FOR 420 */
+ /* ------------------------------------------------------------- */
+ WORD32 i4_sub_wd_chroma = 2;
+ WORD32 i4_sub_ht_chroma = 2;
+
+ i4_base_width = ps_ref_res_prms->i4_res_width;
+ i4_base_height = ps_ref_res_prms->i4_res_height;
+
+ i4_ref_layer_chroma_phase_x_plus1_flag =
+ ps_curr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+ i4_ref_layer_chroma_phase_y_plus1 = ps_curr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_phase_x_plus1_flag =
+ ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ i4_chroma_phase_y_plus1 =
+ ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
+ i4_scaled_ref_layer_left_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_left;
+ i4_scaled_ref_layer_top_offset = ps_curr_res_prms->s_ref_lyr_scaled_offset.i2_top;
+
+ /* ----------------------------------------------------------------- */
+ /* Computing Effective Frame Dimensions */
+ /* ------------------------------------------------------------------*/
+ i4_ref_wd = (i4_base_width >> i4_chroma_flag);
+ i4_ref_ht = (i4_base_height >> i4_chroma_flag) * (1 + i4_ref_layer_field_pic_flag);
+ i4_scaled_wd = ps_curr_res_prms->u2_scaled_ref_width;
+ i4_scaled_ht = ps_curr_res_prms->u2_scaled_ref_height;
+ i4_scaled_wd = (i4_scaled_wd >> i4_chroma_flag);
+ i4_scaled_ht = (i4_scaled_ht >> i4_chroma_flag) * (1 + i4_field_pic_flag);
+
+ if(1 == i4_chroma_flag)
+ {
+ i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1_flag - 1;
+ i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
+ i4_phase_x = i4_chroma_phase_x_plus1_flag - 1;
+ i4_phase_y = i4_chroma_phase_y_plus1 - 1;
+ i4_sub_wd = i4_sub_wd_chroma;
+ i4_sub_ht = i4_sub_ht_chroma;
+ i4_mb_wd = MB_WIDTH >> 1;
+ i4_mb_ht = MB_HEIGHT >> 1;
+ }
+ else
+ {
+ i4_refphase_x = 0;
+ i4_refphase_y = 0;
+ i4_phase_x = 0;
+ i4_phase_y = 0;
+ i4_sub_wd = 1;
+ i4_sub_ht = 1;
+ i4_mb_wd = MB_WIDTH;
+ i4_mb_ht = MB_HEIGHT;
+ }
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Derive shift x and y based on level idd */
+ /* --------------------------------------------------------------------- */
+ if(ps_sps->u1_level_idc <= 30)
+ {
+ u4_shift_x = 16;
+ u4_shift_y = 16;
+ }
+ else
+ {
+ u4_shift_x = 31 - isvcd_get_ceil_log2(i4_ref_wd);
+ u4_shift_y = 31 - isvcd_get_ceil_log2(i4_ref_ht);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* The following condition is not true in our case for time being */
+ /* --------------------------------------------------------------------- */
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) || (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_phase_y = i4_phase_y + 4 * i4_bot_field_flag;
+
+ if(1 == i4_ref_layer_frame_Mbs_only_flag)
+ i4_refphase_y = (2 * i4_refphase_y) + 2;
+ else
+ i4_refphase_y = i4_refphase_y + (4 * i4_bot_field_flag);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Dx and Dy Computation - Ratio of the base and enhance layer width */
+ /* --------------------------------------------------------------------- */
+ u4_scale_x = ((i4_ref_wd << u4_shift_x) + (i4_scaled_wd >> 1)) / (i4_scaled_wd);
+
+ u4_scale_y = ((i4_ref_ht << u4_shift_y) + (i4_scaled_ht >> 1)) / (i4_scaled_ht);
+
+ i4_offset_x = i4_scaled_ref_layer_left_offset / i4_sub_wd;
+ i4_add_x = (((i4_ref_wd * (2 + i4_phase_x)) << (u4_shift_x - 2)) + (i4_scaled_wd >> 1)) /
+ i4_scaled_wd +
+ (1 << (u4_shift_x - 5));
+ i4_delta_x = 4 * (2 + i4_refphase_x);
+
+ if((SVCD_TRUE == i4_frame_mbs_only_flag) && (SVCD_TRUE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / i4_sub_ht;
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (u4_shift_y - 2)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (u4_shift_y - 5));
+ i4_delta_y = 4 * (2 + i4_refphase_y);
+ }
+ else
+ {
+ i4_offset_y = i4_scaled_ref_layer_top_offset / (2 * i4_sub_ht);
+ i4_add_y = (((i4_ref_ht * (2 + i4_phase_y)) << (u4_shift_y - 3)) + (i4_scaled_ht >> 1)) /
+ i4_scaled_ht +
+ (1 << (u4_shift_y - 5));
+ i4_delta_y = 2 * (2 + i4_refphase_y);
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Intializing Local Pointers - Chroma and Luma */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+ i4_curr_lyr_width = ps_curr_res_prms->i4_res_width >> i4_chroma_flag;
+ i4_curr_lyr_height = ps_curr_res_prms->i4_res_height >> i4_chroma_flag;
+
+ {
+ WORD32 i4_i, i4_j;
+
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetX refArrayW Xmin and Xmax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_i = 0; i4_i < i4_curr_lyr_width; i4_i = i4_i + i4_mb_wd)
+ {
+ WORD32 i4_x_refmin16;
+ WORD32 i4_x_refmax16;
+ WORD32 i4_x_offset;
+
+ i4_x_refmin16 = (WORD64) (((WORD64) ((i4_i - i4_offset_x) * u4_scale_x) + i4_add_x) >>
+ ((WORD32) (u4_shift_x - 4))) -
+ i4_delta_x;
+
+ i4_x_refmax16 =
+ (WORD64) (((WORD64) (i4_i + i4_mb_wd - 1 - i4_offset_x) * u4_scale_x + i4_add_x) >>
+ ((WORD32) (u4_shift_x - 4))) -
+ i4_delta_x;
+
+ /* AC205 */
+ i4_x_offset = i4_x_refmin16 >> 4;
+ ps_x_off_len->i2_offset = i4_x_offset;
+ ps_x_off_len->i2_length = (i4_x_refmax16 >> 4) - i4_x_offset + 2;
+
+ /* increment the pointer */
+ ps_x_off_len++;
+
+ } /* end of loop over current layer width */
+
+ /* ----------------------------------------------------------------- */
+ /* Computation of offsetY refArrayH Ymin and Ymax Lists */
+ /* ----------------------------------------------------------------- */
+ for(i4_j = 0; i4_j < i4_curr_lyr_height; i4_j = i4_j + i4_mb_ht)
+ {
+ WORD32 i4_y_refmin16;
+ WORD32 i4_y_refmax16;
+ WORD32 i4_y_offset;
+
+ i4_y_refmin16 = (WORD64) (((WORD64) (i4_j - i4_offset_y) * u4_scale_y + i4_add_y) >>
+ ((WORD32) (u4_shift_y - 4))) -
+ i4_delta_y;
+
+ i4_y_refmax16 =
+ (WORD64) (((WORD64) (i4_j + i4_mb_ht - 1 - i4_offset_y) * u4_scale_y + i4_add_y) >>
+ ((WORD32) (u4_shift_y - 4))) -
+ i4_delta_y;
+
+ /* AC205 */
+ i4_y_offset = i4_y_refmin16 >> 4;
+ ps_y_off_len->i2_offset = i4_y_offset;
+ ps_y_off_len->i2_length = (i4_y_refmax16 >> 4) - i4_y_offset + 2;
+
+ /* increment the pointer */
+ ps_y_off_len++;
+
+ } /* end of loop over current layer height */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Xref and Xphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ ps_x_off_len = ps_map_ctxt->ps_x_offset_length;
+ ps_y_off_len = ps_map_ctxt->ps_y_offset_length;
+
+ {
+ WORD32 i4_xc;
+ WORD32 i4_offset_x_index;
+ ref_pixel_map_t *ps_x_pos_phase;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+
+ for(i4_xc = 0; i4_xc < i4_curr_lyr_width; i4_xc++)
+ {
+ WORD32 i4_x_offset;
+ WORD32 i4_x_ref16;
+
+ i4_offset_x_index = i4_xc / i4_mb_wd;
+ i4_x_offset = ps_x_off_len[i4_offset_x_index].i2_offset;
+ i4_x_ref16 = (WORD64) (((WORD64) (i4_xc - i4_offset_x) * u4_scale_x + i4_add_x) >>
+ ((WORD32) (u4_shift_x - 4))) -
+ i4_delta_x;
+
+ /* store the values */
+ ps_x_pos_phase->i2_ref_pos = (i4_x_ref16 >> 4) - i4_x_offset;
+ ps_x_pos_phase->i2_phase = (i4_x_ref16 - (16 * i4_x_offset)) & 15;
+
+ /* increment the pointer */
+ ps_x_pos_phase++;
+ } /* end of loop over scaled width */
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* Computation of Yref and Yphase List as per standard */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 i4_yc;
+ WORD32 i4_offset_y_index;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ for(i4_yc = 0; i4_yc < i4_curr_lyr_height; i4_yc++)
+ {
+ WORD32 i4_y_offset;
+ WORD32 i4_y_ref16;
+
+ i4_offset_y_index = i4_yc / i4_mb_ht;
+ i4_y_offset = ps_y_off_len[i4_offset_y_index].i2_offset;
+
+ if((SVCD_FALSE == i4_frame_mbs_only_flag) ||
+ (SVCD_FALSE == i4_ref_layer_frame_Mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - i4_field_Mb_flag);
+ }
+
+ i4_y_ref16 = (WORD64) ((((WORD64) (i4_yc - i4_offset_y) * u4_scale_y + i4_add_y) >>
+ ((WORD32) (u4_shift_y - 4))) -
+ i4_delta_y);
+ ps_y_pos_phase->i2_ref_pos = (i4_y_ref16 >> 4) - i4_y_offset;
+ ps_y_pos_phase->i2_phase = (i4_y_ref16 - (16 * i4_y_offset)) & 15;
+
+ /* increment the pointer */
+ ps_y_pos_phase++;
+ } /* end of loop over scaled height */
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_samp_res_init */
+/* */
+/* Description : this function calculates the scale factors and initialise*/
+/* the context structure */
+/* */
+/* Inputs : pv_residual_samp_ctxt: handle to private structure */
+/* ps_curr_lyr_res_prms: pointer to current resolution */
+/* params */
+/* Globals : none */
+/* Processing : it stores the layer dimensions */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 06 2021 vijayakumar creation */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_residual_samp_res_init(void *pv_svc_dec)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ dec_seq_params_t *ps_sps;
+ dec_svc_seq_params_t *ps_subset_sps;
+ svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+
+ void *pv_residual_samp_ctxt = ps_svc_lyr_dec->pv_residual_sample_ctxt;
+ res_prms_t *ps_curr_lyr_res_prms = &ps_svc_lyr_dec->s_res_prms;
+ ref_mb_map_t **pps_luma_map_horz = &ps_svc_lyr_dec->ps_ressam_luma_map_horz;
+ ref_mb_map_t **pps_chroma_map_horz = &ps_svc_lyr_dec->ps_ressam_chroma_map_horz;
+ ref_mb_map_t **pps_luma_map_vert = &ps_svc_lyr_dec->ps_ressam_luma_map_vert;
+ ref_mb_map_t **pps_chroma_map_vert = &ps_svc_lyr_dec->ps_ressam_chroma_map_vert;
+
+ if((NULL == pv_residual_samp_ctxt) || (NULL == ps_curr_lyr_res_prms) ||
+ (NULL == pps_luma_map_horz) || (NULL == pps_chroma_map_horz) ||
+ (NULL == pps_luma_map_vert) || (NULL == pps_chroma_map_vert))
+ {
+ return NOT_OK;
+ }
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+
+ /* if called for base resolution store deafult values */
+ if(SVCD_TRUE == ps_svc_lyr_dec->u1_base_res_flag)
+ {
+ *pps_luma_map_horz = NULL;
+ *pps_chroma_map_horz = NULL;
+ *pps_luma_map_vert = NULL;
+ *pps_chroma_map_vert = NULL;
+ ps_ctxt->i4_res_lyr_id = -1;
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+ return OK;
+ }
+
+ /* derive the current sps */
+ ps_sps = ps_dec->ps_cur_sps;
+ ps_subset_sps = ps_svc_lyr_dec->ps_cur_subset_sps;
+
+ /* store the res id appropriately */
+ ps_ctxt->i4_res_lyr_id = ps_svc_lyr_dec->u1_layer_id - 1;
+
+ /* get the current layer ctxt */
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_svc_lyr_dec->u1_layer_id - 1];
+
+ /* get the width and heights */
+ ps_lyr_ctxt->i4_curr_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_lyr_ctxt->i4_curr_height = ps_curr_lyr_res_prms->i4_res_height;
+ ps_lyr_ctxt->i4_ref_width = ps_ctxt->i4_ref_width;
+ ps_lyr_ctxt->i4_ref_height = ps_ctxt->i4_ref_height;
+
+ /* store the strcuture pointer containing projected locations */
+ *pps_luma_map_horz = ps_lyr_ctxt->s_luma_map_ctxt.ps_x_offset_length;
+ *pps_chroma_map_horz = ps_lyr_ctxt->s_chroma_map_ctxt.ps_x_offset_length;
+ *pps_luma_map_vert = ps_lyr_ctxt->s_luma_map_ctxt.ps_y_offset_length;
+ *pps_chroma_map_vert = ps_lyr_ctxt->s_chroma_map_ctxt.ps_y_offset_length;
+
+ /* check for recomputation of mapping required */
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ res_prms_t s_ref_res_prms = {0};
+
+ /* store the reference layer resolution width and height */
+ s_ref_res_prms.i4_res_width = ps_ctxt->i4_ref_width;
+ s_ref_res_prms.i4_res_height = ps_ctxt->i4_ref_height;
+
+ /* call the frame level projections calculation function */
+ isvcd_residual_samp_populate_list(&ps_lyr_ctxt->s_luma_map_ctxt, ps_sps, ps_subset_sps,
+ ps_curr_lyr_res_prms, &s_ref_res_prms, 0);
+ isvcd_residual_samp_populate_list(&ps_lyr_ctxt->s_chroma_map_ctxt, ps_sps, ps_subset_sps,
+ ps_curr_lyr_res_prms, &s_ref_res_prms, 1);
+
+ /* default values for flags */
+ ps_lyr_ctxt->pf_residual_samp_mb = &isvcd_residual_samp_mb;
+ ps_lyr_ctxt->i4_chrm_horz_int_mode = 0;
+ ps_lyr_ctxt->i4_chrm_vert_int_mode = 0;
+ ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_FALSE;
+
+ /* Store the Dyadic flag */
+ ps_lyr_ctxt->i4_dyadic_flag = ps_curr_lyr_res_prms->u1_dyadic_flag;
+
+ /* set the appropriate chroma processing routine based on */
+ /* phase values */
+ if(SVCD_TRUE == ps_curr_lyr_res_prms->u1_dyadic_flag)
+ {
+ WORD32 i4_ref_layer_chroma_phase_x_plus1_flag;
+ WORD32 i4_ref_layer_chroma_phase_y_plus1;
+ WORD32 i4_chroma_phase_x_plus1_flag;
+ WORD32 i4_chroma_phase_y_plus1;
+
+ ps_lyr_ctxt->pf_residual_samp_mb = &isvcd_residual_samp_mb_dyadic;
+ i4_ref_layer_chroma_phase_x_plus1_flag =
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_x_plus1_flag;
+ i4_ref_layer_chroma_phase_y_plus1 =
+ ps_curr_lyr_res_prms->i1_ref_lyr_chroma_phase_y_plus1;
+ i4_chroma_phase_x_plus1_flag =
+ ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ i4_chroma_phase_y_plus1 =
+ ps_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1;
+ if((0 == i4_ref_layer_chroma_phase_x_plus1_flag) && (1 == i4_chroma_phase_x_plus1_flag))
+ {
+ ps_lyr_ctxt->i4_chrm_horz_int_mode = 1;
+ ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
+ }
+
+ if((0 == i4_ref_layer_chroma_phase_y_plus1) && (1 == i4_chroma_phase_y_plus1))
+ {
+ ps_lyr_ctxt->i4_chrm_vert_int_mode = 1;
+ ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
+ }
+
+ if((0 == i4_ref_layer_chroma_phase_y_plus1) && (2 == i4_chroma_phase_y_plus1))
+ {
+ ps_lyr_ctxt->i4_chrm_vert_int_mode = 1;
+ ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
+ }
+
+ if((2 == i4_ref_layer_chroma_phase_y_plus1) && (0 == i4_chroma_phase_y_plus1))
+ {
+ ps_lyr_ctxt->i4_chrm_vert_int_mode = 2;
+ ps_lyr_ctxt->i4_chrm_alt_proc = SVCD_TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* should take false value */
+ if(SVCD_FALSE != ps_curr_lyr_res_prms->u1_remap_req_flag)
+ {
+ return NOT_OK;
+ }
+ }
+
+ /* store the current layer width and height to context */
+ ps_ctxt->i4_ref_width = ps_curr_lyr_res_prms->i4_res_width;
+ ps_ctxt->i4_ref_height = ps_curr_lyr_res_prms->i4_res_height;
+
+ /* assert on max ranges of width and shift values */
+ if((ps_lyr_ctxt->i4_curr_width > H264_MAX_FRAME_WIDTH) ||
+ (ps_lyr_ctxt->i4_ref_width > H264_MAX_FRAME_WIDTH) ||
+ (ps_lyr_ctxt->i4_curr_height > H264_MAX_FRAME_HEIGHT) ||
+ (ps_lyr_ctxt->i4_ref_height > H264_MAX_FRAME_HEIGHT))
+ {
+ return NOT_OK;
+ }
+ return OK;
+} \ No newline at end of file
diff --git a/decoder/svc/isvcd_residual_resamp.h b/decoder/svc/isvcd_residual_resamp.h
new file mode 100644
index 0000000..9057930
--- /dev/null
+++ b/decoder/svc/isvcd_residual_resamp.h
@@ -0,0 +1,238 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#ifndef _ISVCD_RESIDUAL_RESAMP_H_
+#define _ISVCD_RESIDUAL_RESAMP_H_
+
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_residual_resamp.h
+ *
+ * @brief
+ * Contains routines that resample for SVC resampling
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+
+#define REF_ARRAY_WIDTH_RES_SAMP (MB_WIDTH + 6)
+#define REF_ARRAY_HEIGHT_RES_SAMP (MB_HEIGHT + 6)
+
+typedef void i264_residual_reflayer_const_non_boundary_mb(
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
+ WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag);
+
+typedef void i264_residual_reflayer_const_boundary_mb(
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_wd, WORD32 i4_ref_ht, WORD32 i4_x_offset,
+ WORD32 i4_y_offset, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
+ WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag);
+
+typedef void i264_interpolate_residual(void *pv_residual_samp_ctxt, WORD16 *pi2_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd, UWORD16 u2_mb_x,
+ UWORD16 u2_mb_y, WORD32 i4_chroma_flag);
+
+typedef void i264_residual_luma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, mem_element_t *ps_ref_mb_mode,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
+ WORD32 i4_ref_tx_size);
+
+typedef void i264_residual_chroma_dyadic(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride);
+
+typedef void i264_residual_chroma_dyadic_alt(void *pv_residual_samp_ctxt, UWORD16 u2_mb_x,
+ UWORD16 u2_mb_y, mem_element_t *ps_ref_mb_mode,
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride,
+ WORD16 *pi2_out_res, WORD32 i4_out_res_stride,
+ WORD32 i4_cr_flag);
+
+/*C Declarations*/
+i264_residual_luma_dyadic isvcd_residual_luma_dyadic;
+i264_residual_chroma_dyadic isvcd_residual_chroma_dyadic;
+i264_residual_chroma_dyadic_alt isvcd_residual_chroma_dyadic_alt;
+
+i264_interpolate_residual isvcd_interpolate_residual;
+i264_residual_reflayer_const_non_boundary_mb isvcd_residual_reflayer_const_non_boundary_mb;
+i264_residual_reflayer_const_boundary_mb isvcd_residual_reflayer_const_boundary_mb;
+
+/*ARM Declarations*/
+i264_residual_luma_dyadic isvcd_residual_luma_dyadic_neonintr;
+i264_interpolate_residual isvcd_interpolate_residual_neonintr;
+i264_residual_reflayer_const_non_boundary_mb isvcd_residual_reflayer_const_non_boundary_mb_neonintr;
+
+/*x86 Declarations*/
+i264_residual_luma_dyadic isvcd_residual_luma_dyadic_sse42;
+i264_interpolate_residual isvcd_interpolate_residual_sse42;
+i264_residual_reflayer_const_non_boundary_mb isvcd_residual_reflayer_const_non_boundary_mb_sse42;
+
+typedef WORD32 ftype_residual_samp_mb(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
+ mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y);
+
+WORD32 isvcd_residual_samp_mb_dyadic(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
+ mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y);
+
+WORD32 isvcd_residual_samp_mb(void *pv_residual_samp_ctxt, mem_element_t *ps_ref_luma,
+ mem_element_t *ps_ref_chroma, mem_element_t *ps_ref_mb_mode,
+ mem_element_t *ps_out_luma, mem_element_t *ps_out_chroma,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y);
+
+typedef struct
+{
+ /* used for mapping purpose */
+ ref_pixel_map_t *ps_x_pos_phase; /*!< buffers to store the projected
+ referecne X and phase X for each
+ pixel in current layer in
+ horizontal direction
+ */
+ ref_pixel_map_t *ps_y_pos_phase; /*!< buffers to store the projected
+ referecne Y and phase Y for each
+ pixel in current layer in
+ vertical direction
+ */
+ ref_mb_map_t *ps_x_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array width in
+ horizontal direction for each MB in
+ current layer
+ */
+ ref_mb_map_t *ps_y_offset_length; /*!< buffers to store the projected
+ start point of reference window and
+ reference array height in
+ vertical direction for each MB in
+ current layer
+ */
+} residual_samp_map_ctxt_t;
+
+typedef struct
+{
+ residual_samp_map_ctxt_t s_luma_map_ctxt; /*!< map structure for luma
+ projected locations
+ for curr resolution layer
+ */
+ residual_samp_map_ctxt_t s_chroma_map_ctxt; /*!< map structure for chroma
+ projected locations
+ for curr resolution layer
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+ WORD32 i4_curr_width; /*!< current layer width in
+ terms luma samples
+ */
+ WORD32 i4_curr_height; /*!< current layer height in
+ terms luma samples
+ */
+ WORD32 i4_dyadic_flag; /*!< flag to indicate whether
+ the upscaling factor is 2
+ in both directions
+ */
+ ftype_residual_samp_mb *pf_residual_samp_mb; /*!< function pointer
+ for dyadic optimization*/
+
+ /* following variables are for Dyadic cases only */
+ WORD32 i4_chrm_alt_proc; /*!< Alternate processing
+ for chroma for specific
+ values of phases
+ */
+
+ WORD32 i4_chrm_vert_int_mode; /*!< Chroma horizontal
+ interpolation alternate
+ mode
+ */
+
+ WORD32 i4_chrm_horz_int_mode; /*!<Chroma vertical
+ interpolation alternate
+ modes
+ */
+} res_lyr_ctxt;
+
+typedef struct
+{
+ res_lyr_ctxt as_res_lyrs[MAX_NUM_RES_LYRS]; /*!< Array of resolutoin layer
+ ctxt.The first strcuture in the
+ array will be used for storing
+ the "second resolution" map in
+ an access unit w.r.t to its
+ base resolution, and for base
+ resolution nothing will be
+ computed or stored
+ */
+
+ WORD16 *pi2_refarray_buffer; /*!< buffer to store the reference
+ layer data before residual
+ sampling
+ */
+
+ UWORD8 *pu1_ref_x_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+ UWORD8 *pu1_ref_y_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+
+ WORD32 i4_res_lyr_id; /*!< resolution id of the layer
+ which is to be processed
+ */
+ WORD32 i4_ref_width; /*!< reference layer width in
+ terms luma samples
+ */
+
+ WORD32 i4_ref_height; /*!< reference layer height in
+ terms luma samples
+ */
+
+ /*Dyadic Residual Resamp*/
+ i264_residual_luma_dyadic *pf_residual_luma_dyadic;
+ i264_residual_chroma_dyadic *pf_residual_chroma_dyadic;
+ i264_residual_chroma_dyadic_alt *pf_residual_chroma_dyadic_alt;
+
+ /*Non-dyadic Residual Resamp*/
+ i264_interpolate_residual *pf_interpolate_residual;
+ i264_residual_reflayer_const_non_boundary_mb *pf_residual_reflayer_const_non_boundary_mb;
+ i264_residual_reflayer_const_boundary_mb *pf_residual_reflayer_const_boundary_mb;
+} residual_sampling_ctxt_t;
+
+WORD32 isvcd_residual_samp_res_init(void *pv_dec);
+
+#endif /* _ISVCD_RESIDUAL_RESAMP_H_ */
diff --git a/decoder/svc/isvcd_structs.h b/decoder/svc/isvcd_structs.h
new file mode 100644
index 0000000..1959202
--- /dev/null
+++ b/decoder/svc/isvcd_structs.h
@@ -0,0 +1,724 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_structs.h
+ *
+ * @brief
+ * Contains structures required for decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_STRUCTS_H_
+#define _ISVCD_STRUCTS_H_
+
+#include "isvcd_defs.h"
+#include "isvcd_cabac.h"
+#include "ih264d_structs.h"
+#include "isvcd_iquant_itrans_residual_recon.h"
+#include "isvcd_iquant_itrans_residual.h"
+#include "isvcd_iquant_itrans.h"
+#include "isvcd_pred_residual_recon.h"
+
+#include "isvcd_nal.h"
+#include "isvcd_nal_structs.h"
+#include "isvcd_nal_parse.h"
+#include "isvcd_nal_parse_structs.h"
+
+#include "isvcd_intra_resamp.h"
+#include "isvcd_ii_pred.h"
+#include "isvcd_residual_resamp.h"
+
+#include "isvcd_vui.h"
+
+#define NUM_MB_PARTS 4
+#define NUM_SUB_MB_PARTS 4
+#define NUM_INTRA_SUB_BLOCKS 16
+#define MAX_NUM_MB_PART NUM_MB_PARTS *NUM_SUB_MB_PARTS
+
+#define ANNEX_B 0 /*!< Annex B stream*/
+#define NON_ANNEX_B 1 /*!< Non Annex B RFC stream */
+
+#define BUFFER_ALIGN_4 4
+
+#define MAX_VCL_NAL_BUFF_SIZE (1024 * 1024 * 2)
+#define MAX_NON_VCL_NAL_BUFF_SIZE (1024 * 1024)
+#define MAX_SCLD_REF_LAYER_OFFSET 32768
+#define MIN_SCLD_REF_LAYER_OFFSET -32768
+#define MAX_SVC_NAL_UNIT_TYPE 31
+/*! Nal unit svc extennsion parameters */
+
+struct _SvcDecLyrStruct;
+
+typedef struct
+{
+ UWORD8 u1_nal_ref_idc; /** NAL ref idc of the Slice NAL unit */
+ UWORD8 u1_svc_ext_flag; /** svc nal extension */
+ UWORD8 u1_idr_flag; /** IDR picture when dependency_id = maximum value of
+ dependency_id */
+ UWORD8 u1_priority_id; /** priority identifier for the NAL unit */
+ UWORD8 u1_no_inter_layer_pred_flag; /** Usage of the inter-layer prediction */
+ UWORD8 u1_dependency_id; /** dependency identifier for the NAL unit */
+ UWORD8 u1_quality_id; /** quality identifier for the NAL unit */
+ UWORD8 u1_temporal_id; /** temporal identifier for the NAL unit */
+ UWORD8 u1_use_ref_base_pic_flag; /** specifies reference pictures for inter
+ prediction */
+ UWORD8 u1_discardable_flag; /** current NAL unit is not used in dependant
+ decoding */
+ UWORD8 u1_output_flag; /** decoded picture output and removal process */
+
+} dec_nal_unit_svc_ext_params_t;
+
+/* Structure to contain information about reference base pic marking */
+typedef struct
+{
+ UWORD8 u1_adaptive_ref_base_pic_marking_mode_flag;
+ UWORD32 u4_memory_management_base_control_operation;
+ UWORD32 u4_difference_of_base_pic_nums_minus1;
+ UWORD32 u4_long_term_base_pic_num;
+
+} dec_ref_base_pic_marking_params_t;
+
+/*! Sequence level parameters svc extension */
+
+typedef struct
+{
+ /** Presence of deblocking filter for inter-layer prediction in the slice
+ * header */
+ UWORD8 u1_inter_layer_deblocking_filter_control_present_flag;
+ UWORD8 u1_extended_spatial_scalability_idc; /** Geometrical parameters for the
+ resampling processes */
+ /** horizontal phase shift of the chroma components in units of half luma
+ * samples*/
+ UWORD8 u1_chroma_phase_x_plus1_flag;
+ /** vertical phase shift of the chroma components in units of half luma
+ * samples */
+ UWORD8 u1_chroma_phase_y_plus1;
+ /* horizontal phase shift of chroma in units of half luma samples used for
+ * inter-layer prediction */
+ UWORD8 u1_seq_ref_layer_chroma_phase_x_plus1_flag;
+ /* vertical phase shift of chroma in units of half luma samples used for
+ * inter-layer prediction */
+ UWORD8 u1_seq_ref_layer_chroma_phase_y_plus1;
+ WORD32 i4_seq_scaled_ref_layer_left_offset; /** horizontal left offset */
+ WORD32 i4_seq_scaled_ref_layer_top_offset; /** vertical top offset */
+ WORD32 i4_seq_scaled_ref_layer_right_offset; /**horizontal right offset */
+ WORD32 i4_seq_scaled_ref_layer_bottom_offset; /** vertical bottom offset */
+ UWORD8 u1_seq_tcoeff_level_prediction_flag; /** presence of the syntax element
+ adaptive_tcoeff_level_prediction_flag
+ */
+ UWORD8 u1_adaptive_tcoeff_level_prediction_flag; /** presence of
+ tcoeff_level_prediction_flag
+ */
+ /** specifies presence of syntax elements in slice headers that refer to the
+ * subset sequence parameter set */
+ UWORD8 u1_slice_header_restriction_flag;
+ UWORD8 u1_svc_vui_parameters_present_flag;
+ svc_vui_ext_t *ps_svc_vui_ext;
+} dec_subset_seq_params_t;
+
+typedef struct
+{
+ WORD32 i4_left_offset; /*!< Scaled horizontal offset of the top left
+ corner luma sample of reference layer from
+ the top left corner luma sample of the current
+ layer. (In the units of num MBs) */
+ WORD32 i4_rt_offset; /*!< Scaled horizontal offset of the bottom right
+ corner luma sample of reference layer from
+ the top left corner luma sample of the
+ current layer. (In the units of num MBs) */
+ WORD32 i4_top_offset; /*!< Scaled vertical offset of the top left
+ corner luma sample of reference layer from
+ the top left corner luma sample of the current
+ layer. (In the units of num MBs) */
+ WORD32 i4_bot_offset; /*!< Scaled vertical offset of the bottom right
+ corner luma sample of reference layer from
+ the top left corner luma sample of the current
+ layer. (In the units of num MBs) */
+} dec_svc_crop_wnd_offset_t;
+
+typedef struct
+{
+ UWORD32 u4_ref_layer_dq_id;
+ UWORD32 u4_disable_inter_layer_deblk_filter_idc;
+ WORD32 i4_inter_layer_slice_alpha_c0_offset_div2;
+ WORD32 i4_inter_layer_slice_beta_offset_div2;
+ UWORD8 u1_constrained_intra_resampling_flag;
+ UWORD8 u1_ref_layer_chroma_phase_x_plus1_flag;
+ UWORD8 u1_ref_layer_chroma_phase_y_plus1;
+
+ WORD32 i4_scaled_ref_layer_left_offset;
+ WORD32 i4_scaled_ref_layer_right_offset;
+ WORD32 i4_scaled_ref_layer_top_offset;
+ WORD32 i4_scaled_ref_layer_bottom_offset;
+ UWORD8 u1_slice_skip_flag;
+ UWORD32 u4_num_mbs_in_slice_minus1;
+ UWORD8 u1_adaptive_base_mode_flag;
+ UWORD8 u1_default_base_mode_flag;
+ UWORD8 u1_adaptive_motion_prediction_flag;
+ UWORD8 u1_default_motion_prediction_flag;
+ UWORD8 u1_adaptive_residual_prediction_flag;
+ UWORD8 u1_default_residual_prediction_flag;
+ UWORD8 u1_tcoeff_level_prediction_flag;
+ UWORD8 u1_scan_idx_start;
+ UWORD8 u1_scan_idx_end;
+ UWORD8 u1_base_pred_weight_table_flag;
+ dec_ref_base_pic_marking_params_t s_ref_base_pic_marking_svc_ext;
+ UWORD8 u1_store_ref_base_pic_flag; /* specifies when dependency_id is equal to
+ the max value of the VCL NAL units of
+ the coded picture */
+
+} dec_slice_svc_ext_params_t;
+
+/* Prefix NAL unit svc extension parameters*/
+
+typedef struct
+{
+ dec_nal_unit_svc_ext_params_t s_nal_svc_ext;
+ dec_ref_base_pic_marking_params_t s_ref_base_pic_marking_svc_ext;
+ UWORD8 u1_store_ref_base_pic_flag; /* specifies when dependency_id is equal to
+ the max value of the VCL NAL units of
+ the coded picture */
+ UWORD8 u1_additional_prefix_nal_unit_ext_flag; /* To indicate whether additional nal unit
+ extension data flag syntax elements */
+ UWORD8 u1_additional_prefix_nal_unit_ext_data_flag; /*Used for FUTURE USE */
+
+} dec_prefix_nal_unit_svc_ext_params_t;
+
+typedef enum
+{
+ LIST_0 = 0,
+ LIST_1 = 1,
+ NUM_REF_LISTS
+} REF_LIST_T;
+
+typedef enum
+{
+ INTRA_16x16 = 0,
+ INTRA_NXN
+} INTRA_MB_PRED_MODE_T;
+
+/* Transform type */
+typedef enum
+{
+ T_4X4 = 0,
+ T_8X8,
+ T_PCM
+} TRANSFORM_TYPE_T;
+
+typedef struct
+{
+ vcl_node_t *ps_top_node; /*!< VCL node corresponding to top most
+ layer in the access unit.
+ */
+ vcl_node_t *ps_bot_node; /*!< VCL node corresponding to
+ bottom most layer to be decoded in the
+ access unit. This parameter keeps updated
+ during course of decoding from base layer
+ till top most layer.
+ */
+
+ WORD32 i4_num_res_lyrs; /*!< Number of layers with
+ different resolutions. Layers with spatial
+ resoluton change flag equal to 0 are
+ considered to be of same resolution as
+ reference layer's resolution.
+ */
+ /* following 2 parameter will be updated only if */
+ /* the picture boundary is detected due to difference */
+ /* in slice header syntax */
+
+ UWORD16 u2_frm_num_next; /*!< frame number of the next
+ slice after picture boundary detection
+ */
+ WORD8 i1_nal_ref_id_next; /*!< nal ref id of the next slice after picture boundary detection
+ range [-1,3]; -1 says the picture boundary is detected
+ by DQID of the layers
+ */
+} vcl_nal_t;
+
+typedef struct
+{
+ WORD32 i4_num_non_vcl_nals; /*!< Total number of non vcl nals that are
+ extracted from the bitstream.
+ */
+
+ non_vcl_buf_hdr_t *ps_first_non_vcl_nal; /*!< This shall point to first NON VCL NAL
+ that is extracted from the input bitstream. This
+ shall be set to NULL if there are no VCL NALs
+ present in the bitstream in a access unit */
+
+} non_vcl_nal_t;
+
+typedef struct
+{
+ WORD16 i2_mv_x; /*!< motion vectors in horizontal direction
+ QPEL units
+ */
+ WORD16 i2_mv_y; /*!< motion vectors in vertical direction QPEL
+ units
+ */
+} mot_vec_t;
+
+typedef struct
+{
+ mot_vec_t as_mv[NUM_SUB_MB_PARTS];
+ WORD32 i4_ref_idx;
+} mb_part_mv_t;
+
+typedef struct
+{
+ /*
+ PRED_16X16,
+ PRED_16X8,
+ PRED_8X16,
+ PRED_8X8,
+ */
+ UWORD8 u1_part_type;
+
+ UWORD8 u1_mv_cnt;
+ /*
+ 0-1 bits : 1st partition
+ 2-3 bits : 2nd partition
+ 4-5 bits : 3rd partition
+ 6-7 bits : 4th partition
+
+ Value
+ 00 : B_DIRECT
+ 01 : L0
+ 10 : L1
+ 11 : BiPred
+ */
+ UWORD8 u1_pred_mode; /* Pred mode shall have valid value till
+ mode motion prediction only. Hence this value shall
+ not be used for the motion compensation
+ */
+ UWORD8 au1_mot_pred_flags[2];
+ UWORD8 au1_sub_mb_part_ht_wd[NUM_MB_PARTS * NUM_SUB_MB_PARTS];
+ UWORD8 au1_sub_mb_num[NUM_MB_PARTS * NUM_SUB_MB_PARTS >> 1];
+ WORD8 ai1_sub_mb_part_type[NUM_MB_PARTS];
+ mb_part_mv_t as_mb_part_dmv[2][NUM_MB_PARTS];
+} inter_mb_prms_t; /* We need to improve on commenting */
+
+typedef struct
+{
+ /*
+ 0 : I_16x16
+ 1 : I_NXN
+ */
+ WORD32 i4_pred_mode;
+ WORD32 i4_chroma_intra_pred_mode;
+ WORD8 ai1_rem_intra_pred_mode[NUM_INTRA_SUB_BLOCKS];
+} intra_mb_prms_t; /* We need to improve on commenting */
+
+typedef union
+{
+ inter_mb_prms_t s_inter;
+ intra_mb_prms_t s_intra;
+} mb_prms_ext_t;
+
+typedef struct
+{
+ UWORD8 u1_chroma_nnz; /*! NNZs of Chroma. Here each bit corresonds
+ to a NNZs of 4x4 sub block. Lower 4 bits are
+ used for Cb and upper are used for Cr */
+ UWORD16 u2_luma_nnz; /*! NNZs of Luma. Here each bit corresonds
+ to a NNZs of 4x4 sub block in raster scan
+ order. */
+ WORD8 i1_mb_mode; /*! MB mode of an MB */
+
+ WORD8 i1_tx_size; /*! transform size of an MB */
+
+ WORD8 i1_slice_id;
+} inter_lyr_mb_prms_t;
+
+/* the following 2 structures are used store certain parameters */
+/* across units for each layer or each dependency layer */
+typedef struct
+{
+ WORD32 i4_updated_sts; /*!< flag to indicate whether the
+ params have been updated
+ */
+ WORD32 i4_ref_dq_id; /*!< place to hold the ref_dqid of previous
+ access unit
+ */
+ WORD32 i4_nal_ref_id; /*!< place to hold the nal_ref_id of previous
+ access unit
+ */
+ UWORD16 u2_frm_num; /*!< place to hold the frame number of
+ previous access unit will be used to
+ handle Errors in "frame_num"
+ syntax elements
+ */
+} prev_au_prms_t;
+
+typedef struct
+{
+ WORD32 i4_updated_sts; /*!< flag to indicate whether the
+ params have been updated
+ */
+
+ UWORD8 u1_pps_id; /*!< PPS ID of an access unit for a particular
+ layer. will be used in concealment of
+ Errors in next access unit
+ */
+
+ UWORD8 u1_sps_id; /*!< SPS ID of an access unit for a particular
+ layer. will be used in concealment of
+ Errors in next access unit
+ */
+
+} prev_au_sps_pps_t;
+
+typedef enum
+{
+ /*CABAC SVC related flags*/
+ CABAC_BASE_MODE_FLAG = 460,
+ CABAC_MOT_PRED_FLAG0 = 463,
+ CABAC_MOT_PRED_FLAG1 = 464,
+ CABAC_RES_PRED_FLAG = 465
+
+} svc_cabac_table_num_t;
+
+typedef struct
+{
+ dec_seq_params_t *ps_seq;
+ dec_subset_seq_params_t s_sps_svc_ext;
+
+ /* sequence associated frame paramateres*/
+ WORD32 i4_reorder_depth;
+ UWORD16 u2_disp_height;
+ UWORD16 u2_disp_width;
+ UWORD16 u2_pic_wd;
+ UWORD16 u2_pic_ht;
+ UWORD16 u2_frm_wd_y;
+ UWORD16 u2_frm_ht_y;
+ UWORD16 u2_frm_wd_uv;
+ UWORD16 u2_frm_ht_uv;
+ UWORD8 u1_pad_len_y_v;
+ UWORD8 u1_pad_len_cr_v;
+ UWORD16 u2_crop_offset_y;
+ UWORD16 u2_crop_offset_uv;
+} dec_svc_seq_params_t;
+
+typedef struct
+{
+ /*svc related flags*/
+ UWORD8 u1_base_mode_flag;
+ UWORD8 u1_residual_prediction_flag;
+ UWORD8 u1_crop_window_flag;
+ UWORD8 au1_motion_pred_flag[2];
+} dec_svc_mb_info_t;
+
+typedef struct _SvcDecLyrStruct
+{
+ dec_struct_t s_dec;
+
+ /*Pred + Res = Target when csbp is zero*/
+ ih264_pred_residual_recon_ft *pf_pred_residual_recon_luma_4x4;
+
+ ih264_pred_residual_recon_ft *pf_pred_residual_recon_luma_8x8;
+
+ ih264_pred_residual_recon_ft *pf_pred_residual_recon_luma_16x16;
+
+ ih264_pred_residual_recon_chroma_ft *pf_pred_residual_recon_chroma_4x4;
+
+ ih264_pred_residual_recon_chroma_ft *pf_pred_residual_recon_chroma_8x8;
+
+ /* IT + Res + Recon*/
+ ih264_iquant_itrans_residual_recon_ft *pf_iquant_itrans_residual_recon_luma_4x4;
+
+ ih264_iquant_itrans_residual_recon_ft *pf_iquant_itrans_residual_recon_luma_4x4_dc;
+
+ ih264_iquant_itrans_residual_recon_ft *pf_iquant_itrans_residual_recon_luma_8x8;
+
+ ih264_iquant_itrans_residual_recon_ft *pf_iquant_itrans_residual_recon_luma_8x8_dc;
+
+ ih264_iquant_itrans_residual_recon_chroma_ft *pf_iquant_itrans_residual_recon_chroma_4x4;
+
+ ih264_iquant_itrans_residual_recon_chroma_ft *pf_iquant_itrans_residual_recon_chroma_4x4_dc;
+
+ /* Res nnz*/
+ ih264_residual_ft *pf_residual_luma_4x4;
+ ih264_residual_ft *pf_residual_luma_8x8;
+ ih264_residual_ft *pf_residual_luma_16x16;
+
+ ih264_residual_chroma_ft *pf_residual_chroma_cb_cr_8x8;
+
+ /*IT + residual */
+ ih264_iquant_itrans_residual_ft *pf_iquant_itrans_residual_luma_4x4;
+
+ ih264_iquant_itrans_residual_ft *pf_iquant_itrans_residual_luma_4x4_dc;
+
+ ih264_iquant_itrans_residual_ft *pf_iquant_itrans_residual_luma_8x8;
+
+ ih264_iquant_itrans_residual_ft *pf_iquant_itrans_residual_luma_8x8_dc;
+
+ ih264_iquant_itrans_residual_chroma_ft *pf_iquant_itrans_residual_chroma_4x4;
+
+ ih264_iquant_itrans_residual_chroma_ft *pf_iquant_itrans_residual_chroma_4x4_dc;
+
+ /* IT */
+ ih264_iquant_itrans_ft *pf_iquant_itrans_luma_4x4;
+
+ ih264_iquant_itrans_ft *pf_iquant_itrans_luma_4x4_dc;
+
+ ih264_iquant_itrans_ft *pf_iquant_itrans_luma_8x8;
+
+ ih264_iquant_itrans_ft *pf_iquant_itrans_luma_8x8_dc;
+
+ ih264_iquant_itrans_chroma_ft *pf_iquant_itrans_chroma_4x4;
+
+ ih264_iquant_itrans_chroma_ft *pf_iquant_itrans_chroma_4x4_dc;
+
+ /**
+ *SVC extension parsing strcture place holders
+ */
+ dec_nal_unit_svc_ext_params_t *ps_nal_svc_ext;
+ dec_prefix_nal_unit_svc_ext_params_t s_pre_nal_unit_svc_ext;
+ dec_svc_crop_wnd_offset_t *ps_crop_wnd_offset;
+ UWORD8 *apu1_crop_wnd_flag[MAX_DEP_LYRS_IN_RES];
+
+ /**
+ *contexts for the CABAC related parsing
+ */
+ bin_ctxt_model_t *ps_base_mode_flag;
+ bin_ctxt_model_t *ps_motion_prediction_flag_l0;
+ bin_ctxt_model_t *ps_motion_prediction_flag_l1;
+ bin_ctxt_model_t *ps_residual_prediction_flag;
+
+ /**
+ * Function pointers to read Params common to CAVLC and CABAC
+ */
+ WORD32(*pf_parse_inter_mb_svc_ext)
+ (struct _SvcDecLyrStruct *ps_dec, dec_mb_info_t *ps_cur_mb_info,
+ dec_svc_mb_info_t *ps_svc_cur_mb_info, UWORD8 u1_mb_num, UWORD8 u1_num_mbsNby2);
+
+ WORD32(*pf_parse_inter_slice_svc_ext)
+ (struct _SvcDecLyrStruct *ps_dec, dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+ /**
+ * Function pointers to parse inter slice data
+ */
+
+ WORD32(*pf_parse_svc_inter_slice)
+ (struct _SvcDecLyrStruct *ps_dec, dec_slice_params_t *ps_slice, UWORD16 u2_first_mb_in_slice);
+
+ /* inter layer precition buffers */
+
+ /* 4x4 level */
+ mv_pred_t *ps_il_pred_mv_bank_buf_base;
+
+ /* 16x16 level */
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms_base;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms_frm_start;
+ inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms_cur_mb;
+ UWORD16 u2_inter_lyr_mb_prms_stride;
+ UWORD32 u4_inter_lyr_mb_prms_size; /* in Bytes */
+
+ /* full frame size : -255 -255 */
+ WORD16 *pi2_il_residual_resample_luma_base;
+ WORD16 *pi2_il_residual_resample_chroma_base;
+ WORD16 *pi2_il_residual_resample_mb_luma_frm_start;
+ WORD16 *pi2_il_residual_resample_mb_chroma_frm_start;
+
+ UWORD16 u2_residual_resample_luma_stride;
+ UWORD16 u2_residual_resample_chroma_stride;
+ UWORD32 u4_residual_resample_luma_size; /* in Bytes */
+ UWORD32 u4_residual_resample_chroma_size; /* in Bytes */
+
+ mv_pred_t *ps_il_pred_mv_bank_buf_cur_mb;
+
+ UWORD8 *pu1_crop_wnd_flag;
+ /*
+ * Layer info flag - Base layer; Intermediate Enhancement Layers; Target
+ * Enhacement Layer.
+ */
+ UWORD8 u1_layer_identifier;
+ /* layer id of the current layer */
+ UWORD8 u1_layer_id;
+ /* flag to indicate if spatial layers are dyadic */
+ UWORD8 u1_dyadic_flag;
+ /* flag to indicate if current layer is base layer */
+ UWORD8 u1_base_res_flag;
+ /* reference layer for inter layer prediction, no quality layers */
+ UWORD8 u1_ref_layer_id;
+
+ UWORD8 u1_restricted_res_change_flag;
+
+ res_prms_t s_res_prms;
+
+ void *pv_ref_lyr_offset;
+ void *pv_mode_mv_sample_ctxt;
+ void *pv_ii_pred_ctxt;
+ void *pv_residual_sample_ctxt;
+
+ void *pv_intra_sample_ctxt;
+ /*!< projected locations buffer pointer exported by Intra Upsampling module
+ for luma this buffer contains the projected offsets and window width in
+ reference layer for each MB (in horizontal direction) of current resolution
+ layer.*/
+ ref_mb_map_t *ps_intsam_luma_map_horz;
+
+ /*!< projected locations buffer pointer exported by Intra Upsampling module
+ for chroma this buffer contains the projected offsets and window width in
+ reference layer
+ for each MB (in horizontal direction) of current resolution layer.*/
+ ref_mb_map_t *ps_intsam_chroma_map_horz;
+
+ /*!< projected locations buffer pointer exported by Intra Upsampling module
+ for luma this buffer contains the projected offsets and window width in
+ reference layer for each MB (in vertical direction) of current resolution
+ layer. */
+ ref_mb_map_t *ps_intsam_luma_map_vert;
+
+ /*!< projected locations buffer pointer exported by Intra Upsampling module
+ for chroma this buffer contains the projected offsets and window width in
+ reference layer for each MB (in vertical direction) of current resolution
+ layer. */
+ ref_mb_map_t *ps_intsam_chroma_map_vert;
+
+ /*!< projected locations buffer pointer exported by Residual Upsampling module
+ for luma. this buffer contains the projected offsets and window width in
+ reference layer for each MB (in horizontal direction) of current resolution
+ layer. */
+ ref_mb_map_t *ps_ressam_luma_map_horz;
+
+ /*!< projected locations buffer pointer exported by Residual Upsampling module
+ for chroma. this buffer contains the projected offsets and window width in
+ reference layer
+ for each MB (in horizontal direction) of current resolution layer. */
+ ref_mb_map_t *ps_ressam_chroma_map_horz;
+
+ /*!< projected locationscbuffer pointercexported by Residual Upsampling
+ modulec for chroma. this buffer contains the projected offsets and window
+ width in reference layer for each MB (in vertical direction) ofv current
+ resolution layer. */
+ ref_mb_map_t *ps_ressam_luma_map_vert;
+
+ /*!< projected locationscbuffer pointerccexported by Residual Upsampling
+ module for chroma.cthis buffer contains the projected offsets and window width
+ in reference layer for each MB (in vertical direction) of current resolution
+ layer.*/
+ ref_mb_map_t *ps_ressam_chroma_map_vert;
+
+ /* pointer to decoder layer referered by current layer */
+ void *ps_dec_svc_ref_layer;
+ /* pointer to master context */
+ void *ps_svcd_ctxt;
+
+ UWORD8 u1_inter_lyr_disable_dblk_filter_idc;
+ WORD8 i1_inter_lyr_slice_alpha_c0_offset;
+ WORD8 i1_inter_lyr_slice_beta_offset;
+
+ UWORD8 *pu1_ii_resamp_buffer_luma;
+ UWORD8 *pu1_ii_resamp_buffer_chroma;
+
+ dec_slice_svc_ext_params_t s_svc_slice_params;
+ dec_svc_seq_params_t *ps_subset_sps;
+ dec_svc_seq_params_t *ps_cur_subset_sps;
+ void *pv_scratch_subset_sps;
+
+ /* Variables Required for N MB design */
+ dec_svc_mb_info_t *ps_svc_nmb_info;
+
+ dec_svc_mb_info_t *ps_svc_frm_mb_info;
+
+ void (*pf_svc_compute_bs)(struct _SvcDecLyrStruct *ps_svc_lyr_dec,
+ struct _DecMbInfo *ps_cur_mb_info, const UWORD16 u2_mbxn_mb);
+
+ UWORD16 *pu2_frm_res_luma_csbp;
+ WORD32 i4_frm_res_luma_csbp_stride;
+
+ UWORD8 *pu1_svc_base_mode_flag;
+ WORD32 i4_frm_svc_base_mode_cabac_stride;
+ WORD32 i4_frm_svc_base_mode_cabac_size;
+ UWORD32 u4_pps_id_for_layer;
+ UWORD8 u1_error_in_cur_frame;
+} svc_dec_lyr_struct_t;
+
+typedef struct
+{
+ /* common parameters for all layers in SVC */
+ UWORD32 u4_num_cores;
+ IVD_ARCH_T e_processor_arch;
+ IVD_SOC_T e_processor_soc;
+ UWORD8 u1_target_layer_id;
+ UWORD8 u1_cur_layer_id;
+
+ /* dcode context for all layers in SVC */
+ svc_dec_lyr_struct_t *ps_svc_dec_lyr;
+
+ dec_pic_params_t *ps_pps;
+ dec_seq_params_t *ps_sps;
+ dec_svc_seq_params_t *ps_subset_sps;
+ struct _sei *ps_sei;
+ struct _sei *ps_sei_parse;
+
+ /* attributes related to set tgt layer api func */
+ WORD32 u1_tgt_dep_id;
+ WORD32 u1_tgt_quality_id;
+ WORD32 u1_tgt_temp_id;
+ WORD32 u1_tgt_priority_id;
+
+ ref_lyr_scaled_offset_t as_ref_lyr_offsets[MAX_NUM_RES_LYRS];
+
+ void *pv_ref_lyr_offset;
+ void *pv_mode_mv_sample_ctxt;
+ void *pv_ii_pred_ctxt;
+ void *pv_residual_sample_ctxt;
+ void *pv_intra_sample_ctxt;
+
+ void *pv_nal_parse_ctxt;
+ non_vcl_nal_t s_non_vcl_nal; /*!< NON VCL nal structure */
+ vcl_nal_t s_vcl_nal; /*!< VCL nal structure */
+
+ /*!< array to store the Did of bottom most layer in each resolution */
+ WORD32 ai4_dq_id_map[MAX_NUM_RES_LYRS];
+ WORD32 i4_error_code;
+ void *pv_vcl_nal_buff;
+ void *pv_non_vcl_nal_buff;
+
+ /*!< array of structure to store the reference layer DQID,
+ poc syntax and frame num, for each depedency id
+ present in an access unit this will be used as reference
+ for the next access unit */
+ prev_au_prms_t as_au_prms_dep[MAX_DEPENDENCY_LYRS];
+ /*!< array to store the pps id for each layer in a resolution */
+ prev_au_sps_pps_t as_pps_sps_prev_au[MAX_TOTAL_LYRS];
+
+ WORD32 i4_eos_flag;
+ UWORD8 u1_prev_num_res_layers;
+ UWORD32 u4_num_sps_ctr;
+ UWORD32 u4_num_pps_ctr;
+ UWORD8 u1_parse_nal_unit_error;
+ UWORD8 u1_exit_till_next_IDR;
+ UWORD8 u1_pre_parse_in_flush;
+} svc_dec_ctxt_t;
+
+#endif /*_ISVCD_STRUCTS_H_*/ \ No newline at end of file
diff --git a/decoder/svc/isvcd_tables.h b/decoder/svc/isvcd_tables.h
new file mode 100644
index 0000000..fa4f374
--- /dev/null
+++ b/decoder/svc/isvcd_tables.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_tables.h
+ *
+ * @brief
+ * Declaration of all tables used by h264 decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_TABLES_H_
+#define _ISVCD_TABLES_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_cabac.h"
+#include "isvcd_cabac.h"
+
+/*****************************************************************************/
+/* Cabac tables for context initialization depending upon type of Slice, */
+/* cabac init Idc value and Qp. */
+/*****************************************************************************/
+extern const UWORD8 gau1_isvcd_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE]
+ [NUM_CABAC_CTXTS_SVC];
+
+#endif /*TABLES_H*/
diff --git a/decoder/svc/isvcd_thread_compute_bs.c b/decoder/svc/isvcd_thread_compute_bs.c
new file mode 100644
index 0000000..a2f75bb
--- /dev/null
+++ b/decoder/svc/isvcd_thread_compute_bs.c
@@ -0,0 +1,319 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_thread_compute_bs.c
+ *
+ * @brief
+ * Contains routines that for multi-thread decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264d_error_handler.h"
+#include "ih264d_debug.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_thread_compute_bs.h"
+#include "isvcd_thread_compute_bs.h"
+#include "ithread.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_tables.h"
+#include "ih264d_format_conv.h"
+#include "ih264d_defs.h"
+
+UWORD16 ih264d_update_csbp_8x8(UWORD16 u2_luma_csbp);
+void ih264d_fill_bs2_horz_vert(UWORD32 *pu4_bs, /* Base pointer of BS table */
+ WORD32 u4_left_mb_csbp, /* csbp of left mb */
+ WORD32 u4_top_mb_csbp, /* csbp of top mb */
+ WORD32 u4_cur_mb_csbp, /* csbp of current mb */
+ const UWORD32 *pu4_packed_bs2, const UWORD16 *pu2_4x4_v2h_reorder);
+void isvcd_fill_bs_ibl(deblk_mb_t *ps_deblk_mb, UWORD8 u1_top_mb_type, UWORD8 u1_left_mb_type,
+ dec_mb_info_t *ps_cur_mb_info, UWORD16 *pu2_curr_res_luma_csbp,
+ UWORD16 *pu2_left_res_luma_csbp, UWORD16 *pu2_top_res_luma_csbp);
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_compute_bs_non_mbaff_thread */
+/* */
+/* Description : This function computes the pointers of left,top & current*/
+/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function
+ * for*/
+/* : Boundary Strength Calculation .this function is used */
+/* : BS being calculated in separate thread */
+/* Inputs : pointer to decoder context,cur_mb_info,u4_mb_num */
+/* Processing : */
+/* */
+/* Outputs : Produces the Boundary Strength for Current Mb */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* ITTIAM */
+/*****************************************************************************/
+
+void isvcd_compute_bs_non_mbaff_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mb_num)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* Mvpred and Nnz for top and Courrent */
+ mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred;
+ /* deblk_mb_t Params */
+ deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */
+ deblkmb_neighbour_t *ps_deblk_top_mb;
+
+ /* Reference Index to POC mapping*/
+ void **apv_map_ref_idx_to_poc;
+ UWORD32 u4_leftmbtype;
+
+ UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp;
+
+ /* Set of flags */
+ UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld;
+ UWORD32 u4_cur_mb_ibl;
+ UWORD32 u1_cur_mb_type;
+ UWORD32 *pu4_bs_table;
+
+ UWORD16 *pu2_curr_res_luma_csbp;
+ UWORD16 *pu2_left_res_luma_csbp;
+ UWORD16 *pu2_top_res_luma_csbp;
+
+ /* Neighbour availability */
+ /* Initialization */
+ const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx;
+ const UWORD32 u2_mby = ps_cur_mb_info->u2_mby;
+ const UWORD32 u1_pingpong = u2_mbx & 0x01;
+
+ PROFILE_DISABLE_BOUNDARY_STRENGTH()
+ ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx;
+
+ /* Pointer assignment for Current DeblkMB, Current Mv Pred */
+ ps_cur_mb_params = ps_dec->ps_deblk_pic + u4_mb_num;
+ ps_cur_mv_pred = ps_dec->s_cur_pic.ps_mv + (u4_mb_num << 4);
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_curr_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_curr_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ pu2_left_res_luma_csbp = pu2_curr_res_luma_csbp - (ps_cur_mb_info->u2_mbx != 0);
+ pu2_top_res_luma_csbp = pu2_curr_res_luma_csbp - ((ps_cur_mb_info->u2_mby != 0) *
+ ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride);
+
+ apv_map_ref_idx_to_poc = (void **) ps_dec->ps_computebs_cur_slice->ppv_map_ref_idx_to_poc + 1;
+ u1_cur_mb_type = ps_cur_mb_params->u1_mb_type;
+ u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type;
+ ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type;
+
+ ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp;
+ ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+ ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp;
+ ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp;
+
+ /* if no deblocking required for current Mb then continue */
+ /* Check next Mbs in Mb group */
+ if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING)
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+ {
+ /* Store Parameter for Top MvPred refernce frame Address */
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ }
+
+ return;
+ }
+
+ /* Flag for extra left Edge */
+ ps_cur_mb_params->u1_single_call = 1;
+
+ /* Update the Left deblk_mb_t and Left MvPred Parameters */
+ if(!u2_mbx)
+ {
+ u4_leftmbtype = 0;
+
+ /* Initialize the ps_left_mv_pred with Junk but Valid Location */
+ /* to avoid invalid memory access */
+ /* this is read only pointer */
+ ps_left_mv_pred = ps_cur_mv_pred + 3;
+ }
+ else
+ {
+ u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type;
+
+ /* Come to Left Most Edge of the MB */
+ ps_left_mv_pred = ps_cur_mv_pred - (1 << 4) + 3;
+ }
+
+ if(!u2_mby) u1_top_mb_typ = 0;
+
+ /* MvPred Pointer Calculation */
+ ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 4) + 12;
+ u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB;
+ u4_cur_mb_ibl = u1_cur_mb_type & D_INTRA_IBL;
+ u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB);
+ /* Compute BS function */
+ pu4_bs_table = ps_cur_mb_params->u4_bs_table;
+
+ u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp;
+ u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp;
+ u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp;
+
+ /* Compute BS function */
+ if((ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_HIGH_PROFILE_IDC) ||
+ (ps_dec->ps_cur_sps->u1_profile_idc == SCALABLE_BASELINE_PROFILE_IDC))
+ {
+ if(ps_cur_mb_info->u1_tran_form8x8 == 1)
+ {
+ u2_cur_csbp = ih264d_update_csbp_8x8(ps_cur_mb_info->ps_curmb->u2_luma_csbp);
+ ps_cur_mb_info->ps_curmb->u2_luma_csbp = u2_cur_csbp;
+ }
+ }
+ u2_cur_csbp |= *pu2_curr_res_luma_csbp;
+ u2_left_csbp |= *pu2_left_res_luma_csbp;
+ u2_top_csbp |= *pu2_top_res_luma_csbp;
+
+ if(u4_cur_mb_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ pu4_bs_table[1] = 0x03030303;
+ pu4_bs_table[2] = 0x03030303;
+ pu4_bs_table[3] = 0x03030303;
+ pu4_bs_table[5] = 0x03030303;
+ pu4_bs_table[6] = 0x03030303;
+ pu4_bs_table[7] = 0x03030303;
+ }
+ else
+ {
+ isvcd_fill_bs_ibl(ps_cur_mb_params, u1_top_mb_typ, u4_leftmbtype, ps_cur_mb_info,
+ pu2_curr_res_luma_csbp, pu2_left_res_luma_csbp, pu2_top_res_luma_csbp);
+
+ if(!u4_cur_mb_ibl)
+ {
+ UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16);
+ UWORD32 u4_is_b = (ps_dec->ps_computebs_cur_slice->slice_type == B_SLICE);
+ UWORD32 u4_bs_0, u4_bs_4;
+
+ u4_bs_0 = pu4_bs_table[0];
+ u4_bs_4 = pu4_bs_table[4];
+
+ ih264d_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp,
+ gau4_ih264d_packed_bs2, gau2_ih264d_4x4_v2h_reorder);
+
+ if(u4_leftmbtype & D_INTRA_MB)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ }
+ else if(u4_leftmbtype & D_INTRA_IBL)
+ {
+ pu4_bs_table[4] = u4_bs_4;
+ }
+
+ if(u1_top_mb_typ & D_INTRA_MB)
+ {
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ }
+ else if(u1_top_mb_typ & D_INTRA_IBL)
+ {
+ pu4_bs_table[0] = u4_bs_0;
+ }
+
+ ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16](
+ ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, pu4_bs_table,
+ ps_left_mv_pred, &(ps_dec->ps_left_mvpred_addr[u1_pingpong][1]),
+ ps_cur_mb_info->ps_top_mb->u4_pic_addrress, (4 >> u4_cur_mb_fld));
+ }
+ }
+
+ {
+ void **pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF;
+ {
+ /* Store Parameter for Top MvPred refernce frame Address */
+ void **ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress;
+ WORD8 *p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame;
+ WORD8 *p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame;
+
+ /* Store Left addresses for Next Mb */
+ void **ppv_left_mv_pred_addr = ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add;
+ WORD8 *p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame;
+
+ ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]];
+ ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]];
+
+ ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]];
+ ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+ ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]];
+
+ ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]];
+ ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]];
+
+ /* Storing the leftMbtype for next Mb */
+ ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type;
+ }
+ }
+
+ /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */
+ if(ps_cur_mb_info->u1_tran_form8x8)
+ {
+ pu4_bs_table[1] = 0;
+ pu4_bs_table[3] = 0;
+ pu4_bs_table[5] = 0;
+ pu4_bs_table[7] = 0;
+ }
+}
diff --git a/decoder/svc/isvcd_thread_compute_bs.h b/decoder/svc/isvcd_thread_compute_bs.h
new file mode 100644
index 0000000..f4c1f00
--- /dev/null
+++ b/decoder/svc/isvcd_thread_compute_bs.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_thread_compute_bs.h
+ *
+ * @brief
+ * Contains routines that for multi-thread decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_THREAD_COMPUTE_BS_H_
+#define _ISVCD_THREAD_COMPUTE_BS_H_
+
+void isvcd_compute_bs_non_mbaff_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
+ dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mb_num);
+
+#endif /*_ISVCD_THREAD_COMPUTE_BS_H_ */ \ No newline at end of file
diff --git a/decoder/svc/isvcd_thread_parse_decode.c b/decoder/svc/isvcd_thread_parse_decode.c
new file mode 100644
index 0000000..9df58f0
--- /dev/null
+++ b/decoder/svc/isvcd_thread_parse_decode.c
@@ -0,0 +1,608 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_thread_parse_decode.c
+ *
+ * @brief
+ * Contains routines that for multi-thread decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264d_error_handler.h"
+#include "ih264d_debug.h"
+#include "ithread.h"
+#include "ih264d_defs.h"
+#include "ih264d_debug.h"
+#include "ih264d_tables.h"
+#include "isvcd_structs.h"
+#include "ih264d_defs.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_thread_parse_decode.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_process_pslice.h"
+#include "isvcd_process_epslice.h"
+#include "ih264d_process_intra_mb.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_format_conv.h"
+#include "isvcd_thread_parse_decode.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_decode_recon_tfr_nmb_thread */
+/* */
+/* Description : */
+/* : */
+/* : */
+/* Inputs : */
+/* Processing :Only for Target Layer processing */
+/* */
+/* Outputs : */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* ITTIAM */
+/*****************************************************************************/
+WORD32 isvcd_decode_recon_tfr_nmb_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD8 u1_num_mbs,
+ UWORD8 u1_num_mbs_next, UWORD8 u1_end_of_row)
+{
+ WORD32 i, j;
+ dec_mb_info_t *ps_cur_mb_info;
+ dec_svc_mb_info_t *ps_svc_cur_mb_info;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ UWORD32 u1_slice_type, u1_B;
+ WORD32 u1_skip_th;
+ UWORD32 u1_ipcm_th;
+ UWORD32 u4_cond;
+ UWORD16 u2_slice_num, u2_cur_dec_mb_num;
+ UWORD32 u4_mb_num;
+ WORD32 nop_cnt = 8 * 128;
+ UWORD16 *pu2_res_luma_csbp;
+ WORD32 ret;
+ u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type;
+
+ u1_B = (u1_slice_type == B_SLICE);
+ u1_skip_th = ((u1_slice_type != I_SLICE) ? (u1_B ? B_8x8 : PRED_8x8R0) : -1);
+ u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0);
+ u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num;
+
+ while(1)
+ {
+ UWORD32 u4_max_mb =
+ (UWORD32) (ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1;
+ u4_mb_num = u2_cur_dec_mb_num;
+ /*introducing 1 MB delay*/
+ u4_mb_num = MIN(u4_mb_num + u1_num_mbs + 1, u4_max_mb);
+
+ CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
+ if(u4_cond)
+ {
+ break;
+ }
+ else
+ {
+ if(nop_cnt > 0)
+ {
+ nop_cnt -= 128;
+ NOP(128);
+ }
+ else
+ {
+ if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
+ (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
+ {
+ ps_dec->u4_fmt_conv_num_rows =
+ MIN(FMT_CONV_NUM_ROWS,
+ (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ }
+ else
+ {
+ nop_cnt = 8 * 128;
+ ithread_yield();
+ }
+ if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
+ {
+ return NOT_OK;
+ }
+ }
+ }
+ }
+
+ /* N Mb MC Loop */
+ for(i = 0; i < u1_num_mbs; i++)
+ {
+ u4_mb_num = u2_cur_dec_mb_num;
+ GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num, u2_slice_num);
+
+ if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread)
+ {
+ ps_dec->u4_cur_slice_decode_done = 1;
+ break;
+ }
+
+ ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num];
+
+ ps_dec->u4_dma_buf_idx = 0;
+ ps_dec->u4_pred_info_idx = 0;
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
+ {
+ WORD32 pred_cnt = 0;
+ pred_info_pkd_t *ps_pred_pkd;
+ UWORD32 u4_pred_info_pkd_idx;
+
+ u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
+
+ while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
+ {
+ ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
+
+ ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
+ ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
+ ps_cur_mb_info);
+
+ u4_pred_info_pkd_idx++;
+ pred_cnt++;
+ }
+ ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
+ }
+ else if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
+ {
+ WORD32 pred_cnt = 0;
+ pred_info_pkd_t *ps_pred_pkd;
+ UWORD32 u4_pred_info_pkd_idx;
+
+ u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
+
+ while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
+ {
+ ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
+
+ ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
+ ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
+ ps_cur_mb_info);
+
+ u4_pred_info_pkd_idx++;
+ pred_cnt++;
+ }
+ /* Decode MB skip */
+ ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
+
+ *pu2_res_luma_csbp = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
+ ps_cur_mb_info->u1_tran_form8x8;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
+ }
+
+ u2_cur_dec_mb_num++;
+ }
+
+ /* N Mb IQ IT RECON Loop */
+ for(j = 0; j < i; j++)
+ {
+ ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num];
+ ps_svc_cur_mb_info = &ps_svc_lyr_dec->ps_svc_frm_mb_info[ps_dec->cur_dec_mb_num];
+
+ if(NULL == ps_cur_mb_info->ps_curmb)
+ {
+ return NOT_OK;
+ }
+
+ /*Pointer assignment for Residual NNZ */
+ pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
+ pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
+ (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
+
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_slice_id = (WORD8) ps_dec->u2_cur_slice_num;
+
+ if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
+ {
+ if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
+ {
+ {
+ /* inter intra pred generation */
+ if(SVCD_FALSE == ps_svc_lyr_dec->u1_dyadic_flag)
+ {
+ ret = isvcd_process_ii_mb(ps_svc_lyr_dec, ps_cur_mb_info,
+ ps_svc_cur_mb_info, j);
+ if(ret != OK) return ret;
+ }
+ if(0 == ps_svc_cur_mb_info->u1_residual_prediction_flag)
+ {
+ /* IT + Recon */
+ ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 0);
+ *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
+ }
+ else
+ {
+ /* IT + Residual + Recon */
+ ret = isvcd_process_inter_mb_rsd_pred_target_lyr(
+ ps_svc_lyr_dec, ps_cur_mb_info, j, 0, pu2_res_luma_csbp);
+ if(ret != OK) return ret;
+ }
+ }
+ }
+
+ else if((ps_cur_mb_info->u1_mb_type != MB_SKIP) &&
+ (ps_cur_mb_info->u1_mb_type != MB_INFER))
+ {
+ if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
+ {
+ ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
+ ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_intra_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ else
+ {
+ isvcd_update_ipcm_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+ *pu2_res_luma_csbp = 0;
+ }
+ else if(ps_cur_mb_info->u1_mb_type == MB_INFER)
+ {
+ /* inter layer intra prediction : intra upsample, IQ, IT ,deblock */
+ {
+ /* Intra resample for IBL mode */
+ ret = isvcd_process_ibl_mb(ps_svc_lyr_dec, ps_cur_mb_info, j, 0);
+ if(ret != OK) return ret;
+ /* Pass intra resample as pred to Recon generation */
+ ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
+ isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 1);
+ *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
+ }
+ ps_dec->pi1_left_pred_mode[0] = DC;
+ ps_dec->pi1_left_pred_mode[1] = DC;
+ ps_dec->pi1_left_pred_mode[2] = DC;
+ ps_dec->pi1_left_pred_mode[3] = DC;
+
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[0] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[1] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[2] = DC;
+ ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[3] = DC;
+
+ isvcd_update_ibl_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
+ }
+
+ if(ps_dec->u4_use_intrapred_line_copy == 1)
+ ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
+ }
+
+ DATA_SYNC();
+
+ u4_mb_num = ps_cur_mb_info->u2_mbx + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby;
+ UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num);
+ ps_dec->cur_dec_mb_num++;
+ }
+
+ /*N MB deblocking*/
+ if(ps_dec->u4_nmb_deblk == 1)
+ {
+ UWORD32 u4_wd_y, u4_wd_uv;
+ tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
+ UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
+ const WORD32 i4_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
+ const WORD32 i4_cr_qp_idx_ofst = ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
+
+ u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
+ u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
+
+ ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_deblk_mb_num];
+
+ ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
+ ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
+
+ for(j = 0; j < i; j++)
+ {
+ ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
+ u4_wd_y, u4_wd_uv);
+ }
+ }
+
+ /*handle the last mb in picture case*/
+ if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ ps_dec->u4_cur_slice_decode_done = 1;
+
+ if(i != u1_num_mbs)
+ {
+ u1_end_of_row = 0;
+ /*Number of MB's left in row*/
+ u1_num_mbs_next = u1_num_mbs_next + ((u1_num_mbs - i) >> u1_mbaff);
+ }
+
+ ih264d_decode_tfr_nmb(ps_dec, (i), u1_num_mbs_next, u1_end_of_row);
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_decode_slice_thread */
+/* */
+/* Description : */
+/* : */
+/* : */
+/* Inputs : */
+/* Processing : */
+/* */
+/* Outputs : */
+/* Returns : 0 on success */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* ITTIAM */
+/*****************************************************************************/
+WORD32 isvcd_decode_slice_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ UWORD8 u1_num_mbs_next, u1_num_mbsleft, u1_end_of_row = 0;
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
+ UWORD8 u1_mbaff, u1_num_mbs;
+
+ UWORD16 u2_first_mb_in_slice;
+ UWORD16 i16_mb_x, i16_mb_y;
+ UWORD8 u1_field_pic;
+ UWORD32 u4_frame_stride, x_offset, y_offset;
+ WORD32 ret;
+ tfr_ctxt_t *ps_trns_addr;
+
+ /*check for mb map of first mb in slice to ensure slice header is parsed*/
+ while(1)
+ {
+ UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num;
+ UWORD32 u4_cond = 0;
+ WORD32 nop_cnt = 8 * 128;
+ CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
+ if(u4_cond)
+ {
+ break;
+ }
+ else
+ {
+ if(nop_cnt > 0)
+ {
+ nop_cnt -= 128;
+ NOP(128);
+ }
+ else if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
+ (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
+ {
+ ps_dec->u4_fmt_conv_num_rows =
+ MIN(FMT_CONV_NUM_ROWS,
+ (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ }
+ else
+ {
+ nop_cnt = 8 * 128;
+ ithread_yield();
+ }
+ if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
+ {
+ return NOT_OK;
+ }
+ DEBUG_THREADS_PRINTF(
+ "waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr = "
+ "%d\n",
+ u2_cur_dec_mb_num, ps_dec->u2_cur_mb_addr);
+ }
+ }
+
+ u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
+ u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice;
+ i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs);
+ i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs);
+ i16_mb_y <<= u1_mbaff;
+ ps_dec->i2_dec_thread_mb_y = i16_mb_y;
+ ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u1_mbaff;
+
+ if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
+ {
+ ps_dec->pv_proc_tu_coeff_data =
+ (void *) ps_dec->ps_decode_cur_slice->pv_tu_coeff_data_start;
+ }
+
+ // recalculate recon pointers
+ u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag;
+ u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
+ x_offset = i16_mb_x << 4;
+ y_offset = (i16_mb_y * u4_frame_stride) << 4;
+
+ ps_trns_addr = &(ps_dec->s_tran_addrecon);
+
+ ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
+
+ u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
+ x_offset >>= 1;
+ y_offset = (i16_mb_y * u4_frame_stride) << 3;
+ x_offset *= YUV420SP_FACTOR;
+
+ ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
+ ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
+
+ ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
+ ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
+ ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
+
+ /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
+ {
+ ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp;
+ ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp;
+ }
+ {
+ UWORD8 uc_nofield_nombaff;
+ uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) &&
+ (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) &&
+ (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE) &&
+ (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
+
+ if(uc_nofield_nombaff == 0)
+ {
+ ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp;
+ ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp;
+ }
+ }
+
+ ps_dec->u4_cur_slice_decode_done = 0;
+
+ while(ps_dec->u4_cur_slice_decode_done != 1)
+ {
+ u1_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u1_mbaff);
+
+ if(u1_num_mbsleft <= ps_dec->u1_recon_mb_grp)
+ {
+ u1_num_mbs = u1_num_mbsleft;
+
+ /*Indicate number of mb's left in a row*/
+ u1_num_mbs_next = 0;
+ u1_end_of_row = 1;
+ i16_mb_x = 0;
+ }
+ else
+ {
+ u1_num_mbs = ps_dec->u1_recon_mb_grp;
+
+ /*Indicate number of mb's left in a row*/
+ u1_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x - (ps_dec->u1_recon_mb_grp >> u1_mbaff);
+ i16_mb_x += (u1_num_mbs >> u1_mbaff);
+ u1_end_of_row = 0;
+ }
+ if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
+ {
+ ret = isvcd_decode_recon_tfr_nmb_thread(ps_svc_lyr_dec, u1_num_mbs, u1_num_mbs_next,
+ u1_end_of_row);
+ }
+ if(ret != OK) return ret;
+ }
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_decode_picture_thread */
+/* */
+/* Description : */
+/* : */
+/* : */
+/* Inputs : */
+/* Processing : */
+/* */
+/* Outputs : */
+/* Returns : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* ITTIAM */
+/*****************************************************************************/
+void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD32 ret;
+ ithread_set_name("isvcd_decode_picture_thread");
+ while(1)
+ {
+#ifdef KEEP_THREADS_ACTIVE
+ ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
+ if(OK != ret) break;
+
+ while(ps_dec->ai4_process_start[0] != PROC_START)
+ {
+ ithread_cond_wait(ps_dec->apv_proc_start_condition[0], ps_dec->apv_proc_start_mutex[0]);
+ }
+ ps_dec->ai4_process_start[0] = PROC_IN_PROGRESS;
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
+ if(OK != ret || ps_dec->i4_break_threads == 1) break;
+#endif
+ while(1)
+ {
+ /*Complete all writes before processing next slice*/
+
+ DEBUG_THREADS_PRINTF(" Entering decode slice svc ext\n");
+
+ ret = isvcd_decode_slice_thread(ps_svc_lyr_dec);
+ if(OK != ret) break;
+ DEBUG_THREADS_PRINTF(" Exit isvcd_decode_slice_thread\n");
+
+ if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
+ {
+ /*Last slice in frame*/
+ break;
+ }
+ else
+ {
+ ps_dec->ps_decode_cur_slice++;
+ ps_dec->u2_cur_slice_num_dec_thread++;
+ }
+ }
+ if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
+ (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
+ {
+ ps_dec->u4_fmt_conv_num_rows =
+ (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row);
+ ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
+ ps_dec->u4_fmt_conv_num_rows);
+ ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
+ }
+#ifdef KEEP_THREADS_ACTIVE
+ ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]);
+ if(OK != ret) break;
+
+ ps_dec->ai4_process_done[0] = PROC_DONE;
+ ithread_cond_signal(ps_dec->apv_proc_done_condition[0]);
+
+ ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]);
+ if(OK != ret) break;
+#else
+ break;
+#endif
+ }
+}
diff --git a/decoder/svc/isvcd_thread_parse_decode.h b/decoder/svc/isvcd_thread_parse_decode.h
new file mode 100644
index 0000000..e533f8b
--- /dev/null
+++ b/decoder/svc/isvcd_thread_parse_decode.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_thread_parse_decode.h
+ *
+ * @brief
+ * Contains routines that for multi-thread decoder
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_THREAD_PARSE_DECPDE_H_
+#define _ISVCD_THREAD_PARSE_DECPDE_H_
+WORD32 isvcd_decode_recon_tfr_nmb_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD8 u1_num_mbs,
+ UWORD8 u1_num_mbs_next, UWORD8 u1_end_of_row);
+void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+WORD32 isvcd_decode_slice_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+void ih264d_compute_bs_non_mbaff_thread(dec_struct_t *ps_dec, dec_mb_info_t *ps_cur_mb_info,
+ UWORD32 u4_mb_num);
+
+#endif /* _ISVCD_THREAD_PARSE_DECPDE_H_ */
diff --git a/decoder/svc/isvcd_utils.c b/decoder/svc/isvcd_utils.c
new file mode 100644
index 0000000..3220685
--- /dev/null
+++ b/decoder/svc/isvcd_utils.c
@@ -0,0 +1,908 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_utils.c
+ *
+ * @brief
+ * Contains routines that handle of start and end of pic processing
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <string.h>
+#include "ih264_typedefs.h"
+#include "ithread.h"
+#include "ih264d_deblocking.h"
+#include "ih264d_parse_slice.h"
+#include "ih264d_parse_cavlc.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_defs.h"
+#include "isvcd_structs.h"
+#include "ih264d_mem_request.h"
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_tables.h"
+#include "ih264d_debug.h"
+#include "ih264d_mb_utils.h"
+#include "ih264d_error_handler.h"
+#include "ih264d_dpb_manager.h"
+#include "ih264d_utils.h"
+#include "ih264d_defs.h"
+#include "ih264d_tables.h"
+#include "ih264d_inter_pred.h"
+#include "ih264d_dpb_manager.h"
+#include "iv.h"
+#include "ivd.h"
+#include "ih264d_format_conv.h"
+#include "ih264_error.h"
+#include "ih264_disp_mgr.h"
+#include "ih264_buf_mgr.h"
+#include "ih264d_utils.h"
+
+WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec);
+/*!
+**************************************************************************
+* \if Function name : isvcd_free_dynamic_bufs \endif
+*
+* \brief
+* This function frees dynamic memory allocated by Decoder.
+*
+* \param ps_dec: Pointer to dec_struct_t.
+*
+* \return
+* Returns i4_status as returned by MemManager.
+*
+**************************************************************************
+*/
+WORD16 isvcd_free_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ /* Free any avc dynamic buffers that are allocated */
+ ih264d_free_dynamic_bufs(ps_dec);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_crop_wnd_flag);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pi2_il_residual_resample_luma_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_svc_frm_mb_info);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu2_frm_res_luma_csbp);
+ PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_svc_base_mode_flag);
+ return 0;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_allocate_dynamic_bufs \endif
+*
+* \brief
+* This function allocates memory required by Decoder.
+*
+* \param ps_dec: Pointer to dec_struct_t.
+*
+* \return
+* Returns i4_status as returned by MemManager.
+*
+**************************************************************************
+*/
+
+WORD16 isvcd_allocate_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ WORD16 i16_status = 0;
+ UWORD8 uc_frmOrFld = (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag);
+ dec_seq_params_t *ps_sps = ps_dec->ps_cur_sps;
+ UWORD32 u4_total_mbs = ps_sps->u2_total_num_of_mbs << uc_frmOrFld;
+ WORD32 size;
+ void *pv_buf;
+ void *pv_mem_ctxt = ps_dec->pv_mem_ctxt;
+ size = u4_total_mbs;
+
+ i16_status = ih264d_allocate_dynamic_bufs(ps_dec);
+
+ if(i16_status != OK)
+ {
+ /* Free any dynamic buffers that are allocated */
+ ih264d_free_dynamic_bufs(ps_dec);
+ ps_dec->i4_error_code = IVD_MEM_ALLOC_FAILED;
+ return IVD_MEM_ALLOC_FAILED;
+ }
+ if(u4_total_mbs == 0)
+ {
+ return IVD_MEM_ALLOC_FAILED;
+ }
+
+ /* Allocate frame level mb info */
+ size = sizeof(dec_svc_mb_info_t) * u4_total_mbs;
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_svc_lyr_dec->ps_svc_frm_mb_info = pv_buf;
+ memset(ps_svc_lyr_dec->ps_svc_frm_mb_info, 0, size);
+
+ /* Allocate frame level residual luma csbp info */
+ size = sizeof(UWORD16) * u4_total_mbs;
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_svc_lyr_dec->pu2_frm_res_luma_csbp = pv_buf;
+ memset(ps_svc_lyr_dec->pu2_frm_res_luma_csbp, 0, size);
+ ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride = ps_dec->u2_frm_wd_in_mbs;
+
+ /* Allocate frame level residual luma csbp info */
+ size = sizeof(UWORD8) * u4_total_mbs;
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_svc_lyr_dec->pu1_svc_base_mode_flag = pv_buf;
+ memset(ps_svc_lyr_dec->pu1_svc_base_mode_flag, 0, size);
+ ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_stride = ps_dec->u2_frm_wd_in_mbs;
+ ps_svc_lyr_dec->i4_frm_svc_base_mode_cabac_size = u4_total_mbs;
+
+ /* Allocate frame level crop windows flags */
+ size = sizeof(UWORD8) * u4_total_mbs;
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_svc_lyr_dec->pu1_crop_wnd_flag = pv_buf;
+ memset(ps_svc_lyr_dec->pu1_crop_wnd_flag, 0, size);
+
+ /**********************************/
+ /*Creation of Inter layer buffers */
+ /**********************************/
+
+ /* MB type buffer : one element per MB */
+ size = (ps_dec->u2_frm_wd_in_mbs + 2) * (ps_dec->u2_frm_ht_in_mbs + 2) *
+ sizeof(inter_lyr_mb_prms_t);
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, -1, size);
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base = pv_buf;
+ ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride = ps_dec->u2_frm_wd_in_mbs + 2;
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start =
+ ps_svc_lyr_dec->ps_inter_lyr_mb_prms_base + 1 + ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride;
+
+ ps_svc_lyr_dec->u4_inter_lyr_mb_prms_size = (ps_dec->u2_frm_wd_in_mbs + 2) *
+ (ps_dec->u2_frm_ht_in_mbs + 2) *
+ sizeof(inter_lyr_mb_prms_t);
+
+ /* Luma Residual data at each layer : dafault 0*/
+ size = ((ps_dec->u2_pic_wd + 4) * (ps_dec->u2_pic_ht + 4)) * sizeof(WORD16);
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svc_lyr_dec->pi2_il_residual_resample_luma_base = pv_buf;
+ ps_svc_lyr_dec->u2_residual_resample_luma_stride = (ps_dec->u2_pic_wd + 4);
+ ps_svc_lyr_dec->pi2_il_residual_resample_mb_luma_frm_start =
+ ps_svc_lyr_dec->pi2_il_residual_resample_luma_base + 2 +
+ (2 * ps_svc_lyr_dec->u2_residual_resample_luma_stride);
+ ps_svc_lyr_dec->u4_residual_resample_luma_size =
+ ((ps_dec->u2_pic_wd + 4) * (ps_dec->u2_pic_ht + 4)) * sizeof(WORD16);
+
+ /* Chroma Residual data at each layer : dafault 0*/
+ size = (((4 + ps_dec->u2_pic_wd) * ((4 + ps_dec->u2_pic_ht) >> 1)) * sizeof(WORD16));
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base = pv_buf;
+ ps_svc_lyr_dec->u2_residual_resample_chroma_stride = (ps_dec->u2_pic_wd + 4);
+ ps_svc_lyr_dec->pi2_il_residual_resample_mb_chroma_frm_start =
+ ps_svc_lyr_dec->pi2_il_residual_resample_chroma_base + 2 +
+ ps_svc_lyr_dec->u2_residual_resample_chroma_stride;
+ ps_svc_lyr_dec->u4_residual_resample_chroma_size =
+ (((4 + ps_dec->u2_pic_wd) * ((4 + ps_dec->u2_pic_ht) >> 1)) * sizeof(WORD16));
+
+ /* mv bank buffer : 16 elements per MB: each at 4x4 block level */
+ size = ((ps_dec->u2_pic_wd) * (ps_dec->u2_pic_ht >> 4)) * sizeof(mv_pred_t);
+ pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_svc_lyr_dec->ps_il_pred_mv_bank_buf_base = pv_buf;
+
+ /*syntax for SVC related bin ctxt tables*/
+ {
+ bin_ctxt_model_t *const p_cabac_ctxt_table_t = ps_dec->p_cabac_ctxt_table_t;
+
+ ps_svc_lyr_dec->ps_base_mode_flag = p_cabac_ctxt_table_t + CABAC_BASE_MODE_FLAG;
+ ps_svc_lyr_dec->ps_motion_prediction_flag_l0 = p_cabac_ctxt_table_t + CABAC_MOT_PRED_FLAG0;
+ ps_svc_lyr_dec->ps_motion_prediction_flag_l1 = p_cabac_ctxt_table_t + CABAC_MOT_PRED_FLAG1;
+ ps_svc_lyr_dec->ps_residual_prediction_flag = p_cabac_ctxt_table_t + CABAC_RES_PRED_FLAG;
+ }
+ return (i16_status);
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_decode_pic_order_cnt \endif
+*
+* \brief
+* Calculates picture order count of picture.
+*
+* \return
+* Returns the pic order count of the picture to which current
+* Slice belongs.
+*
+**************************************************************************
+*/
+WORD32 isvcd_decode_pic_order_cnt(
+ UWORD8 u1_is_idr_slice, UWORD32 u2_frame_num, pocstruct_t *ps_prev_poc, pocstruct_t *ps_cur_poc,
+ dec_slice_params_t *ps_cur_slice, /*!< Pointer to current slice Params*/
+ dec_pic_params_t *ps_pps, UWORD8 u1_nal_ref_idc, UWORD8 u1_bottom_field_flag,
+ UWORD8 u1_field_pic_flag, WORD32 *pi4_poc, dec_struct_t *ps_dec)
+{
+ WORD64 i8_pic_msb;
+ WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0;
+ dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps;
+ WORD32 i4_prev_frame_num_ofst;
+
+ switch(ps_seq->u1_pic_order_cnt_type)
+ {
+ case 0:
+ /* POC TYPE 0 */
+ if(u1_is_idr_slice)
+ {
+ ps_prev_poc->i4_pic_order_cnt_msb = 0;
+ ps_prev_poc->i4_pic_order_cnt_lsb = 0;
+ }
+ if(ps_prev_poc->u1_mmco_equalto5)
+ {
+ if(ps_prev_poc->u1_bot_field != 1)
+ {
+ ps_prev_poc->i4_pic_order_cnt_msb = 0;
+ ps_prev_poc->i4_pic_order_cnt_lsb = ps_prev_poc->i4_top_field_order_count;
+ }
+ else
+ {
+ ps_prev_poc->i4_pic_order_cnt_msb = 0;
+ ps_prev_poc->i4_pic_order_cnt_lsb = 0;
+ }
+ }
+
+ if((ps_cur_poc->i4_pic_order_cnt_lsb < ps_prev_poc->i4_pic_order_cnt_lsb) &&
+ ((ps_prev_poc->i4_pic_order_cnt_lsb - ps_cur_poc->i4_pic_order_cnt_lsb) >=
+ (ps_seq->i4_max_pic_order_cntLsb >> 1)))
+ {
+ i8_pic_msb =
+ (WORD64) ps_prev_poc->i4_pic_order_cnt_msb + ps_seq->i4_max_pic_order_cntLsb;
+ }
+ else if((ps_cur_poc->i4_pic_order_cnt_lsb > ps_prev_poc->i4_pic_order_cnt_lsb) &&
+ ((ps_cur_poc->i4_pic_order_cnt_lsb - ps_prev_poc->i4_pic_order_cnt_lsb) >=
+ (ps_seq->i4_max_pic_order_cntLsb >> 1)))
+ {
+ i8_pic_msb =
+ (WORD64) ps_prev_poc->i4_pic_order_cnt_msb - ps_seq->i4_max_pic_order_cntLsb;
+ }
+ else
+ {
+ i8_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb;
+ }
+
+ if(!u1_field_pic_flag || !u1_bottom_field_flag)
+ {
+ WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_top_field_order_cnt = (WORD32) i8_result;
+ }
+
+ if(!u1_field_pic_flag)
+ {
+ WORD64 i8_result =
+ (WORD64) i4_top_field_order_cnt + ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_bottom_field_order_cnt = (WORD32) i8_result;
+ }
+ else if(u1_bottom_field_flag)
+ {
+ WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_bottom_field_order_cnt = (WORD32) i8_result;
+ }
+
+ if(IS_OUT_OF_RANGE_S32(i8_pic_msb))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_cur_poc->i4_pic_order_cnt_msb = (WORD32) i8_pic_msb;
+ break;
+
+ case 1:
+ {
+ /* POC TYPE 1 */
+ UWORD8 i;
+ WORD32 prev_frame_num;
+ WORD32 frame_num_ofst;
+ WORD32 abs_frm_num;
+ WORD32 poc_cycle_cnt, frame_num_in_poc_cycle;
+ WORD64 i8_expected_delta_poc_cycle;
+ WORD32 expected_poc;
+ WORD64 i8_result;
+
+ prev_frame_num = (WORD32) ps_cur_slice->u2_frame_num;
+ if(!u1_is_idr_slice)
+ {
+ if(ps_cur_slice->u1_mmco_equalto5)
+ {
+ prev_frame_num = 0;
+ i4_prev_frame_num_ofst = 0;
+ }
+ else
+ {
+ i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst;
+ }
+ }
+ else
+ i4_prev_frame_num_ofst = 0;
+
+ /* 1. Derivation for FrameNumOffset */
+ if(u1_is_idr_slice)
+ {
+ frame_num_ofst = 0;
+ ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
+ ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
+ }
+ else if(prev_frame_num > ((WORD32) u2_frame_num))
+ {
+ WORD64 i8_result =
+ i4_prev_frame_num_ofst + (WORD64) ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ frame_num_ofst = (WORD32) i8_result;
+ }
+ else
+ frame_num_ofst = i4_prev_frame_num_ofst;
+
+ /* 2. Derivation for absFrameNum */
+ if(0 != ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle)
+ {
+ WORD64 i8_result = frame_num_ofst + (WORD64) u2_frame_num;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ abs_frm_num = (WORD32) i8_result;
+ }
+ else
+ abs_frm_num = 0;
+ if((u1_nal_ref_idc == 0) && (abs_frm_num > 0)) abs_frm_num = abs_frm_num - 1;
+
+ /* 4. expectedDeltaPerPicOrderCntCycle is derived as */
+ i8_expected_delta_poc_cycle = 0;
+ for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ i8_expected_delta_poc_cycle += ps_seq->i4_ofst_for_ref_frame[i];
+ }
+
+ /* 3. When absFrameNum > 0, picOrderCntCycleCnt and
+ frame_num_in_poc_cycle are derived as : */
+ /* 5. expectedPicOrderCnt is derived as : */
+ if(abs_frm_num > 0)
+ {
+ poc_cycle_cnt =
+ DIV((abs_frm_num - 1), ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
+ frame_num_in_poc_cycle =
+ MOD((abs_frm_num - 1), ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle);
+
+ i8_result = poc_cycle_cnt * i8_expected_delta_poc_cycle;
+
+ for(i = 0; i <= frame_num_in_poc_cycle; i++)
+ {
+ i8_result = i8_result + ps_seq->i4_ofst_for_ref_frame[i];
+ }
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+
+ expected_poc = (WORD32) i8_result;
+ }
+ else
+ expected_poc = 0;
+
+ if(u1_nal_ref_idc == 0)
+ {
+ i8_result = (WORD64) expected_poc + ps_seq->i4_ofst_for_non_ref_pic;
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+
+ expected_poc = (WORD32) i8_result;
+ }
+
+ /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */
+ if(!u1_field_pic_flag)
+ {
+ i8_result = (WORD64) expected_poc + ps_cur_poc->i4_delta_pic_order_cnt[0];
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+ i4_top_field_order_cnt = (WORD32) i8_result;
+
+ i8_result = (WORD64) i4_top_field_order_cnt +
+ ps_seq->i4_ofst_for_top_to_bottom_field +
+ ps_cur_poc->i4_delta_pic_order_cnt[1];
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+ i4_bottom_field_order_cnt = (WORD32) i8_result;
+ }
+ else if(!u1_bottom_field_flag)
+ {
+ i8_result = (WORD64) expected_poc + ps_cur_poc->i4_delta_pic_order_cnt[0];
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+ i4_top_field_order_cnt = (WORD32) i8_result;
+ }
+ else
+ {
+ i8_result = (WORD64) expected_poc + ps_seq->i4_ofst_for_top_to_bottom_field +
+ ps_cur_poc->i4_delta_pic_order_cnt[0];
+
+ if(IS_OUT_OF_RANGE_S32(i8_result)) return ERROR_INV_POC;
+ i4_bottom_field_order_cnt = (WORD32) i8_result;
+ }
+ /* Copy the current POC info into Previous POC structure */
+ ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst;
+ }
+
+ break;
+ case 2:
+ {
+ /* POC TYPE 2 */
+ WORD32 prev_frame_num;
+ WORD32 frame_num_ofst;
+ WORD32 tmp_poc;
+
+ prev_frame_num = (WORD32) ps_cur_slice->u2_frame_num;
+ if(!u1_is_idr_slice)
+ {
+ if(ps_cur_slice->u1_mmco_equalto5)
+ {
+ prev_frame_num = 0;
+ i4_prev_frame_num_ofst = 0;
+ }
+ else
+ i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst;
+ }
+ else
+ i4_prev_frame_num_ofst = 0;
+
+ /* 1. Derivation for FrameNumOffset */
+ if(u1_is_idr_slice)
+ {
+ frame_num_ofst = 0;
+ ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
+ ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
+ }
+ else if(prev_frame_num > ((WORD32) u2_frame_num))
+ {
+ WORD64 i8_result =
+ i4_prev_frame_num_ofst + (WORD64) ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ frame_num_ofst = (WORD32) i8_result;
+ }
+ else
+ frame_num_ofst = i4_prev_frame_num_ofst;
+
+ /* 2. Derivation for tempPicOrderCnt */
+ if(u1_is_idr_slice)
+ tmp_poc = 0;
+ else if(u1_nal_ref_idc == 0)
+ {
+ WORD64 i8_result = ((frame_num_ofst + (WORD64) u2_frame_num) << 1) - 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ tmp_poc = (WORD32) i8_result;
+ }
+ else
+ {
+ WORD64 i8_result = (frame_num_ofst + (WORD64) u2_frame_num) << 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ tmp_poc = (WORD32) i8_result;
+ }
+
+ /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */
+ if(!u1_field_pic_flag)
+ {
+ i4_top_field_order_cnt = tmp_poc;
+ i4_bottom_field_order_cnt = tmp_poc;
+ }
+ else if(!u1_bottom_field_flag)
+ i4_top_field_order_cnt = tmp_poc;
+ else
+ i4_bottom_field_order_cnt = tmp_poc;
+
+ /* Copy the current POC info into Previous POC structure */
+ ps_prev_poc->i4_prev_frame_num_ofst = frame_num_ofst;
+ ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst;
+ }
+ break;
+ default:
+ return ERROR_INV_POC_TYPE_T;
+ break;
+ }
+
+ if(!u1_field_pic_flag) // or a complementary field pair
+ {
+ *pi4_poc = MIN(i4_top_field_order_cnt, i4_bottom_field_order_cnt);
+ ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt;
+ ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt;
+ }
+ else if(!u1_bottom_field_flag)
+ {
+ *pi4_poc = i4_top_field_order_cnt;
+ ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt;
+ }
+ else
+ {
+ *pi4_poc = i4_bottom_field_order_cnt;
+ ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt;
+ }
+
+ ps_pps->i4_avg_poc = *pi4_poc;
+
+ return OK;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_decode_gaps_in_frame_num */
+/* */
+/* Description : This function decodes gaps in frame number */
+/* */
+/* Inputs : ps_dec Decoder parameters */
+/* u2_frame_num current frame number */
+/* */
+/* Globals : None */
+/* Processing : This functionality needs to be implemented */
+/* Outputs : None */
+/* Returns : None */
+/* */
+/* Issues : Not implemented */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 05 2002 NS Draft */
+/* */
+/*****************************************************************************/
+WORD32 isvcd_decode_gaps_in_frame_num(dec_struct_t *ps_dec, UWORD16 u2_frame_num)
+{
+ UWORD32 u4_next_frm_num, u4_start_frm_num;
+ UWORD32 u4_max_frm_num;
+ pocstruct_t s_tmp_poc;
+ WORD32 i4_poc;
+ dec_slice_params_t *ps_cur_slice;
+
+ dec_pic_params_t *ps_pic_params;
+ WORD8 i1_gap_idx;
+ WORD32 *i4_gaps_start_frm_num;
+ dpb_manager_t *ps_dpb_mgr;
+ WORD8 *pi1_gaps_per_seq;
+ WORD32 ret;
+
+ ps_cur_slice = ps_dec->ps_cur_slice;
+ if(ps_cur_slice->u1_field_pic_flag)
+ {
+ if(ps_dec->u2_prev_ref_frame_num == u2_frame_num) return 0;
+ }
+
+ u4_next_frm_num = ps_dec->u2_prev_ref_frame_num + 1;
+ u4_max_frm_num = ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1;
+
+ if(u4_next_frm_num >= u4_max_frm_num)
+ {
+ u4_next_frm_num -= u4_max_frm_num;
+ }
+
+ if(u4_next_frm_num == u2_frame_num)
+ {
+ return (0);
+ }
+
+ if((ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) && (u4_next_frm_num >= u2_frame_num))
+ {
+ return (0);
+ }
+ u4_start_frm_num = u4_next_frm_num;
+
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ s_tmp_poc.i4_pic_order_cnt_lsb = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[0] = 0;
+ s_tmp_poc.i4_delta_pic_order_cnt[1] = 0;
+
+ ps_cur_slice = ps_dec->ps_cur_slice;
+ ps_pic_params = ps_dec->ps_cur_pps;
+
+ ps_dpb_mgr = ps_dec->ps_dpb_mgr;
+
+ /* Find a empty slot to store gap seqn info */
+ i4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num;
+ for(i1_gap_idx = 0; i1_gap_idx < MAX_FRAMES; i1_gap_idx++)
+ {
+ if(INVALID_FRAME_NUM == i4_gaps_start_frm_num[i1_gap_idx]) break;
+ }
+ if(MAX_FRAMES == i1_gap_idx)
+ {
+ UWORD32 i4_error_code;
+ i4_error_code = ERROR_DBP_MANAGER_T;
+ return i4_error_code;
+ }
+
+ i4_poc = 0;
+ i4_gaps_start_frm_num[i1_gap_idx] = u4_start_frm_num;
+ ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = u2_frame_num - 1;
+ pi1_gaps_per_seq = ps_dpb_mgr->ai1_gaps_per_seq;
+ pi1_gaps_per_seq[i1_gap_idx] = 0;
+ while(u4_next_frm_num != u2_frame_num)
+ {
+ ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+ if(ps_pic_params->ps_sps->u1_pic_order_cnt_type)
+ {
+ /* allocate a picture buffer and insert it as ST node */
+ ret =
+ isvcd_decode_pic_order_cnt(0, u4_next_frm_num, &ps_dec->s_prev_pic_poc, &s_tmp_poc,
+ ps_cur_slice, ps_pic_params, 1, 0, 0, &i4_poc, ps_dec);
+ if(ret != OK) return ret;
+
+ /* Display seq no calculations */
+ if(i4_poc >= ps_dec->i4_max_poc) ps_dec->i4_max_poc = i4_poc;
+ /* IDR Picture or POC wrap around */
+ if(i4_poc == 0)
+ {
+ WORD64 i8_temp;
+ i8_temp = (WORD64) ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc +
+ ps_dec->u1_max_dec_frame_buffering + 1;
+ /*If i4_prev_max_display_seq overflows integer range, reset it */
+ ps_dec->i4_prev_max_display_seq =
+ IS_OUT_OF_RANGE_S32(i8_temp) ? 0 : (WORD32) i8_temp;
+ ps_dec->i4_max_poc = 0;
+ }
+
+ ps_cur_slice->u1_mmco_equalto5 = 0;
+ ps_cur_slice->u2_frame_num = u4_next_frm_num;
+ }
+
+ if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dec->u1_max_dec_frame_buffering)
+ {
+ ret = ih264d_assign_display_seq(ps_dec);
+ if(ret != OK) return ret;
+ }
+
+ {
+ WORD64 i8_display_poc;
+ i8_display_poc = (WORD64) ps_dec->i4_prev_max_display_seq + i4_poc;
+ if(IS_OUT_OF_RANGE_S32(i8_display_poc))
+ {
+ ps_dec->i4_prev_max_display_seq = 0;
+ }
+ }
+ ret = ih264d_insert_pic_in_display_list(ps_dec->ps_dpb_mgr, (WORD8) DO_NOT_DISP,
+ (WORD32) (ps_dec->i4_prev_max_display_seq + i4_poc),
+ u4_next_frm_num);
+ if(ret != OK) return ret;
+
+ pi1_gaps_per_seq[i1_gap_idx]++;
+ ret = ih264d_do_mmco_for_gaps(ps_dpb_mgr, ps_dec->ps_cur_sps->u1_num_ref_frames);
+ if(ret != OK) return ret;
+
+ ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr);
+
+ u4_next_frm_num++;
+ if(u4_next_frm_num >= u4_max_frm_num)
+ {
+ u4_next_frm_num -= u4_max_frm_num;
+ }
+ }
+
+ return OK;
+}
+
+/*!
+**************************************************************************
+* \if Function name : isvcd_init_pic \endif
+*
+* \brief
+* Initializes the picture.
+*
+* \return
+* 0 on Success and Error code otherwise
+*
+* \note
+* This function is called when first slice of the
+* NON -IDR picture is encountered.
+**************************************************************************
+*/
+WORD32 isvcd_init_pic(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_frame_num, WORD32 i4_poc,
+ dec_pic_params_t *ps_pps)
+{
+ dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
+ dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps;
+ prev_seq_params_t *ps_prev_seq_params = &ps_dec->s_prev_seq_params;
+ WORD32 ret;
+
+ ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num;
+ ps_dec->ps_cur_slice->i4_poc = i4_poc;
+ ps_dec->ps_cur_pps = ps_pps;
+ ps_dec->ps_cur_pps->pv_codec_handle = ps_dec;
+
+ ps_dec->ps_dpb_mgr->i4_max_frm_num = ps_seq->u2_u4_max_pic_num_minus1 + 1;
+
+ ps_dec->ps_dpb_mgr->u2_pic_ht = ps_dec->u2_pic_ht;
+ ps_dec->ps_dpb_mgr->u2_pic_wd = ps_dec->u2_pic_wd;
+ ps_dec->i4_pic_type = NA_SLICE;
+ ps_dec->i4_frametype = IV_NA_FRAME;
+ ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
+
+ /*--------------------------------------------------------------------*/
+ /* Get the value of MaxMbAddress and frmheight in Mbs */
+ /*--------------------------------------------------------------------*/
+ ps_seq->u2_max_mb_addr =
+ (ps_seq->u2_frm_wd_in_mbs *
+ (ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag))) -
+ 1;
+ ps_dec->u2_frm_ht_in_mbs = (ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag));
+
+ /***************************************************************************/
+ /* If change in Level or the required PicBuffers i4_size is more than the */
+ /* current one FREE the current PicBuffers and allocate affresh */
+ /***************************************************************************/
+ if(!ps_dec->u1_init_dec_flag)
+ {
+ ps_dec->u1_max_dec_frame_buffering = ih264d_get_dpb_size(ps_seq);
+
+ ps_dec->i4_display_delay = ps_dec->u1_max_dec_frame_buffering;
+ if((1 == ps_seq->u1_vui_parameters_present_flag) &&
+ (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+ {
+ if(ps_seq->u1_frame_mbs_only_flag == 1)
+ ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames + 1;
+ else
+ ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames * 2 + 2;
+ }
+
+ if(IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) ps_dec->i4_display_delay = 0;
+
+ if(ps_dec->u4_share_disp_buf == 0)
+ {
+ if(ps_seq->u1_frame_mbs_only_flag == 1)
+ ps_dec->u1_pic_bufs = ps_dec->i4_display_delay + ps_seq->u1_num_ref_frames + 1;
+ else
+ ps_dec->u1_pic_bufs = ps_dec->i4_display_delay + ps_seq->u1_num_ref_frames * 2 + 2;
+ }
+ else
+ {
+ ps_dec->u1_pic_bufs = (WORD32) ps_dec->u4_num_disp_bufs;
+ }
+
+ /* Ensure at least two buffers are allocated */
+ ps_dec->u1_pic_bufs = MAX(ps_dec->u1_pic_bufs, 2);
+
+ if(ps_dec->u4_share_disp_buf == 0)
+ ps_dec->u1_pic_bufs = MIN(ps_dec->u1_pic_bufs, (H264_MAX_REF_PICS * 2));
+
+ ps_dec->u1_max_dec_frame_buffering =
+ MIN(ps_dec->u1_max_dec_frame_buffering, ps_dec->u1_pic_bufs);
+
+ /* Temporary hack to run Tractor Cav/Cab/MbAff Profiler streams also for
+ * CAFI1_SVA_C.264 in conformance*/
+ if(ps_dec->u1_init_dec_flag)
+ {
+ ih264d_release_pics_in_dpb((void *) ps_dec, ps_dec->u1_pic_bufs);
+ ih264d_release_display_bufs(ps_dec);
+ ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr);
+ }
+
+ /*********************************************************************/
+ /* Configuring decoder parameters based on level and then */
+ /* fresh pointer initialisation in decoder scratch and state buffers */
+ /*********************************************************************/
+ if(!ps_dec->u1_init_dec_flag || ((ps_seq->u1_level_idc < H264_LEVEL_3_0) ^
+ (ps_prev_seq_params->u1_level_idc < H264_LEVEL_3_0)))
+ {
+ ret = ih264d_init_dec_mb_grp(ps_dec);
+ if(ret != OK) return ret;
+ }
+
+ ret = isvcd_allocate_dynamic_bufs(ps_svc_lyr_dec);
+
+ if(ret != OK)
+ {
+ /* Free any dynamic buffers that are allocated */
+ isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
+ ps_dec->i4_error_code = IVD_MEM_ALLOC_FAILED;
+ return IVD_MEM_ALLOC_FAILED;
+ }
+
+ ret = ih264d_create_pic_buffers(ps_dec->u1_pic_bufs, ps_dec);
+ if(ret != OK) return ret;
+
+ ret = ih264d_create_mv_bank(ps_dec, ps_dec->u2_pic_wd, ps_dec->u2_pic_ht);
+ if(ret != OK) return ret;
+
+ /* In shared mode, set all of them as used by display */
+ if(ps_dec->u4_share_disp_buf == 1)
+ {
+ WORD32 i;
+
+ for(i = 0; i < ps_dec->u1_pic_bufs; i++)
+ {
+ ih264_buf_mgr_set_status((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, i, BUF_MGR_IO);
+ }
+ }
+
+ ps_dec->u1_init_dec_flag = 1;
+ ps_prev_seq_params->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs;
+ ps_prev_seq_params->u1_level_idc = ps_seq->u1_level_idc;
+ ps_prev_seq_params->u1_profile_idc = ps_seq->u1_profile_idc;
+ ps_prev_seq_params->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs;
+ ps_prev_seq_params->u1_frame_mbs_only_flag = ps_seq->u1_frame_mbs_only_flag;
+ ps_prev_seq_params->u1_direct_8x8_inference_flag = ps_seq->u1_direct_8x8_inference_flag;
+
+ ps_dec->i4_cur_display_seq = 0;
+ ps_dec->i4_prev_max_display_seq = 0;
+ ps_dec->i4_max_poc = 0;
+
+ {
+ /* 0th entry of CtxtIncMbMap will be always be containing default values
+ for CABAC context representing MB not available */
+ ctxt_inc_mb_info_t *p_DefCtxt = ps_dec->p_ctxt_inc_mb_map - 1;
+ UWORD8 *pu1_temp;
+ WORD8 i;
+ p_DefCtxt->u1_mb_type = CAB_SKIP;
+
+ p_DefCtxt->u1_cbp = 0x0f;
+ p_DefCtxt->u1_intra_chroma_pred_mode = 0;
+
+ p_DefCtxt->u1_yuv_dc_csbp = 0x7;
+
+ p_DefCtxt->u1_transform8x8_ctxt = 0;
+
+ pu1_temp = (UWORD8 *) p_DefCtxt->i1_ref_idx;
+ for(i = 0; i < 4; i++, pu1_temp++) (*pu1_temp) = 0;
+ pu1_temp = (UWORD8 *) p_DefCtxt->u1_mv;
+ for(i = 0; i < 16; i++, pu1_temp++) (*pu1_temp) = 0;
+ ps_dec->ps_def_ctxt_mb_info = p_DefCtxt;
+ }
+ }
+ /* reset DBP commands read u4_flag */
+ ps_dec->ps_dpb_cmds->u1_dpb_commands_read = 0;
+
+ return OK;
+}
diff --git a/decoder/svc/isvcd_utils.h b/decoder/svc/isvcd_utils.h
new file mode 100644
index 0000000..56c0322
--- /dev/null
+++ b/decoder/svc/isvcd_utils.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_utils.h
+ *
+ * @brief
+ * Contains declaration of routines that handle of start and end of
+ * pic processing
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_UTILS_H_
+#define _ISVCD_UTILS_H_
+
+#include "ih264d_defs.h"
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvcd_structs.h"
+#include "ih264d_parse_cavlc.h"
+
+WORD16 isvcd_allocate_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD16 isvcd_free_dynamic_bufs(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
+
+WORD32 isvcd_init_pic(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD16 u2_frame_num, WORD32 i4_poc,
+ dec_pic_params_t *ps_pps);
+
+WORD32 isvcd_decode_gaps_in_frame_num(dec_struct_t *ps_dec, UWORD16 u2_frame_num);
+
+WORD32 isvcd_decode_pic_order_cnt(
+ UWORD8 u1_is_idr_slice, UWORD32 u2_frame_num, pocstruct_t *ps_prev_poc, pocstruct_t *ps_cur_poc,
+ dec_slice_params_t *ps_cur_slice, /*!< Pointer to current slice Params*/
+ dec_pic_params_t *ps_pps, UWORD8 u1_nal_ref_idc, UWORD8 u1_bottom_field_flag,
+ UWORD8 u1_field_pic_flag, WORD32 *pi4_poc, dec_struct_t *ps_dec);
+
+#endif /*_ISVCD_UTILS_H_*/ \ No newline at end of file
diff --git a/decoder/svc/isvcd_vui.c b/decoder/svc/isvcd_vui.c
new file mode 100644
index 0000000..e77eee7
--- /dev/null
+++ b/decoder/svc/isvcd_vui.c
@@ -0,0 +1,118 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_vui.c
+ *
+ * @brief
+ * This file contains routines to parse VUI NAL's
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_vui.h"
+#include "ih264d_bitstrm.h"
+#include "ih264d_parse_cavlc.h"
+#include "isvcd_structs.h"
+#include "ih264d_error_handler.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_parse_vui_ext_parametres */
+/* */
+/* Description : This function parses VUI NALs. */
+/* Inputs : ps_vu4 pointer to VUI params */
+/* ps_bitstrm Bitstream */
+/* Globals : None */
+/* Processing : Parses VUI NAL's units and stores the info */
+/* Outputs : None */
+/* Returns : None */
+/* */
+/* Issues : None */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 05 2002 Kishore Draft */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_parse_vui_ext_parametres(svc_vui_ext_t *ps_svc_vui_ext, dec_bit_stream_t *ps_bitstrm)
+{
+ UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
+ WORD32 ret;
+ UWORD32 u4_i;
+
+ ps_svc_vui_ext->u4_vui_ext_num_entries_minus1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(ps_svc_vui_ext->u4_vui_ext_num_entries_minus1 > 1023)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ for(u4_i = 0; u4_i <= ps_svc_vui_ext->u4_vui_ext_num_entries_minus1; u4_i++)
+ {
+ ps_svc_vui_ext->u1_vui_ext_dependency_id[u4_i] = ih264d_get_bits_h264(ps_bitstrm, 3);
+ ps_svc_vui_ext->u1_vui_ext_quality_id[u4_i] = ih264d_get_bits_h264(ps_bitstrm, 4);
+ ps_svc_vui_ext->u1_vui_ext_temporal_id[u4_i] = ih264d_get_bits_h264(ps_bitstrm, 3);
+ ps_svc_vui_ext->u1_vui_ext_timing_info_present_flag[u4_i] = ih264d_get_bit_h264(ps_bitstrm);
+
+ if(1 == ps_svc_vui_ext->u1_vui_ext_timing_info_present_flag[u4_i])
+ {
+ ps_svc_vui_ext->u4_vui_ext_num_units_in_tick[u4_i] =
+ ih264d_get_bits_h264(ps_bitstrm, 32);
+ ps_svc_vui_ext->u4_vui_ext_time_scale[u4_i] = ih264d_get_bits_h264(ps_bitstrm, 32);
+ ps_svc_vui_ext->u1_vui_ext_fixed_frame_rate_flag[u4_i] =
+ ih264d_get_bit_h264(ps_bitstrm);
+ }
+
+ ps_svc_vui_ext->u1_vui_ext_nal_hrd_params_present_flag[u4_i] =
+ ih264d_get_bit_h264(ps_bitstrm);
+ if(ps_svc_vui_ext->u1_vui_ext_nal_hrd_params_present_flag[u4_i])
+ {
+ ret = ih264d_parse_hrd_parametres(&ps_svc_vui_ext->s_nal_hrd[u4_i], ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ ps_svc_vui_ext->u1_vui_ext_vcl_hrd_params_present_flag[u4_i] =
+ ih264d_get_bit_h264(ps_bitstrm);
+ if(ps_svc_vui_ext->u1_vui_ext_vcl_hrd_params_present_flag[u4_i])
+ {
+ ret = ih264d_parse_hrd_parametres(&ps_svc_vui_ext->s_vcl_hrd[u4_i], ps_bitstrm);
+ if(ret != OK) return ret;
+ }
+ if(ps_svc_vui_ext->u1_vui_ext_nal_hrd_params_present_flag[u4_i] ||
+ ps_svc_vui_ext->u1_vui_ext_vcl_hrd_params_present_flag[u4_i])
+ {
+ ps_svc_vui_ext->u1_vui_ext_low_delay_hrd_flag[u4_i] = ih264d_get_bit_h264(ps_bitstrm);
+ }
+ ps_svc_vui_ext->u1_vui_ext_pic_struct_present_flag[u4_i] = ih264d_get_bit_h264(ps_bitstrm);
+ }
+ return OK;
+}
diff --git a/decoder/svc/isvcd_vui.h b/decoder/svc/isvcd_vui.h
new file mode 100644
index 0000000..a52ae25
--- /dev/null
+++ b/decoder/svc/isvcd_vui.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_vui.h
+ *
+ * @brief
+ * This file contains routines to parse SEI NAL's
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCD_VUI_H_
+#define _ISVCD_VUI_H_
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264d_bitstrm.h"
+
+#define MAX_VUI_EXT_NUM_ENTRIES 1024
+
+typedef struct
+{
+ UWORD32 u4_vui_ext_num_entries_minus1;
+ UWORD8 u1_vui_ext_dependency_id[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_quality_id[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_temporal_id[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_timing_info_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD32 u4_vui_ext_num_units_in_tick[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD32 u4_vui_ext_time_scale[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_fixed_frame_rate_flag[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_nal_hrd_params_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+ hrd_t s_nal_hrd[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_vcl_hrd_params_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+ hrd_t s_vcl_hrd[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_low_delay_hrd_flag[MAX_VUI_EXT_NUM_ENTRIES];
+ UWORD8 u1_vui_ext_pic_struct_present_flag[MAX_VUI_EXT_NUM_ENTRIES];
+} svc_vui_ext_t;
+
+WORD32 isvcd_parse_vui_ext_parametres(svc_vui_ext_t *ps_svc_vui_ext, dec_bit_stream_t *ps_bitstrm);
+
+#endif /*_ISVCD_VUI_H_ */
diff --git a/decoder/svc/libsvcdec.cmake b/decoder/svc/libsvcdec.cmake
new file mode 100644
index 0000000..d088426
--- /dev/null
+++ b/decoder/svc/libsvcdec.cmake
@@ -0,0 +1,102 @@
+# src files
+list(
+ APPEND
+ LIBSVCDEC_SRCS
+ "${AVC_ROOT}/decoder/ih264d_api.c"
+ "${AVC_ROOT}/decoder/ih264d_bitstrm.c"
+ "${AVC_ROOT}/decoder/ih264d_cabac.c"
+ "${AVC_ROOT}/decoder/ih264d_cabac_init_tables.c"
+ "${AVC_ROOT}/decoder/ih264d_compute_bs.c"
+ "${AVC_ROOT}/decoder/ih264d_deblocking.c"
+ "${AVC_ROOT}/decoder/ih264d_dpb_mgr.c"
+ "${AVC_ROOT}/decoder/ih264d_format_conv.c"
+ "${AVC_ROOT}/decoder/ih264d_function_selector_generic.c"
+ "${AVC_ROOT}/decoder/ih264d_inter_pred.c"
+ "${AVC_ROOT}/decoder/ih264d_mb_utils.c"
+ "${AVC_ROOT}/decoder/ih264d_mvpred.c"
+ "${AVC_ROOT}/decoder/ih264d_nal.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_bslice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_cabac.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_cavlc.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_headers.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_islice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_mb_header.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_pslice.c"
+ "${AVC_ROOT}/decoder/ih264d_parse_slice.c"
+ "${AVC_ROOT}/decoder/ih264d_process_bslice.c"
+ "${AVC_ROOT}/decoder/ih264d_process_intra_mb.c"
+ "${AVC_ROOT}/decoder/ih264d_process_pslice.c"
+ "${AVC_ROOT}/decoder/ih264d_quant_scaling.c"
+ "${AVC_ROOT}/decoder/ih264d_sei.c"
+ "${AVC_ROOT}/decoder/ih264d_tables.c"
+ "${AVC_ROOT}/decoder/ih264d_thread_compute_bs.c"
+ "${AVC_ROOT}/decoder/ih264d_thread_parse_decode.c"
+ "${AVC_ROOT}/decoder/ih264d_utils.c"
+ "${AVC_ROOT}/decoder/ih264d_vui.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_api.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_cabac.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_cabac_init_tables.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_compute_bs.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_function_selector_generic.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_mb_utils.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_nal.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_nal_parse.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_cavlc.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_ebslice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_eislice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_epslice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_headers.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_parse_slice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_process_ebslice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_process_epslice.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_thread_compute_bs.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_thread_parse_decode.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_utils.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_vui.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_ii_pred.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_intra_resamp.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_iquant_itrans.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_iquant_itrans_residual.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_iquant_itrans_residual_recon.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_mode_mv_resamp.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_pred_residual_recon.c"
+ "${AVC_ROOT}/decoder/svc/isvcd_residual_resamp.c")
+
+include_directories(${AVC_ROOT}/decoder)
+include_directories(${AVC_ROOT}/decoder/svc)
+
+if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${CMAKE_SYSTEM_PROCESSOR}"
+ STREQUAL "aarch32")
+ list(
+ APPEND
+ LIBSVCDEC_ASMS
+ "${AVC_ROOT}/decoder/arm/ih264d_function_selector.c"
+ "${AVC_ROOT}/decoder/arm/ih264d_function_selector_a9q.c"
+ "${AVC_ROOT}/decoder/arm/ih264d_function_selector_av8.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_function_selector.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_function_selector_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_intra_resamp_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_iquant_itrans_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_iquant_itrans_residual_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_iquant_itrans_residual_recon_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_pred_residual_recon_neon.c"
+ "${AVC_ROOT}/decoder/arm/svc/isvcd_residual_resamp_neon.c")
+else()
+ list(
+ APPEND
+ LIBSVCDEC_ASMS
+ "${AVC_ROOT}/decoder/x86/ih264d_function_selector.c"
+ "${AVC_ROOT}/decoder/x86/ih264d_function_selector_sse42.c"
+ "${AVC_ROOT}/decoder/x86/ih264d_function_selector_ssse3.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_function_selector.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_function_selector_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_intra_resamp_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_iquant_itrans_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_pred_residual_recon_sse42.c"
+ "${AVC_ROOT}/decoder/x86/svc/isvcd_residual_resamp_sse42.c")
+endif()
+
+add_library(libsvcdec STATIC ${LIBAVC_COMMON_SRCS} ${LIBAVC_COMMON_ASMS}
+ ${LIBSVCDEC_SRCS} ${LIBSVCDEC_ASMS})
diff --git a/decoder/x86/svc/isvcd_function_selector.c b/decoder/x86/svc/isvcd_function_selector.c
new file mode 100644
index 0000000..6a825c1
--- /dev/null
+++ b/decoder/x86/svc/isvcd_function_selector.c
@@ -0,0 +1,85 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in svc
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "isvcd_structs.h"
+#include "ih264d_function_selector.h"
+#include "isvcd_function_selector.h"
+
+/**
+ *******************************************************************************
+ *
+ * @brief Initialize the intra/inter/transform/deblk function pointers of
+ * codec context
+ *
+ * @par Description: the current routine initializes the function pointers of
+ * codec context basing on the architecture in use for svc
+ *
+ * @param[in] ps_svc_lyr_dec
+ * svc dec layer context pointer
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvcd_init_function_ptr(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ isvcd_init_function_ptr_generic(ps_svc_lyr_dec);
+ switch(ps_svc_lyr_dec->s_dec.e_processor_arch)
+ {
+ case ARCH_X86_GENERIC:
+ isvcd_init_function_ptr_generic(ps_svc_lyr_dec);
+ break;
+ case ARCH_X86_SSSE3:
+ ih264d_init_function_ptr_ssse3(&ps_svc_lyr_dec->s_dec);
+ break;
+ case ARCH_X86_SSE42:
+ default:
+ ih264d_init_function_ptr_ssse3(&ps_svc_lyr_dec->s_dec);
+ isvcd_init_function_ptr_sse42(ps_svc_lyr_dec);
+ break;
+ }
+}
diff --git a/decoder/x86/svc/isvcd_function_selector_sse42.c b/decoder/x86/svc/isvcd_function_selector_sse42.c
new file mode 100644
index 0000000..2f9527d
--- /dev/null
+++ b/decoder/x86/svc/isvcd_function_selector_sse42.c
@@ -0,0 +1,141 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_function_selector_sse42.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_init_function_ptr_sse42
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "isvcd_structs.h"
+#include "ih264d_function_selector.h"
+
+/**
+ *******************************************************************************
+ *
+ * @brief Initialize the intra/inter/transform/deblk function pointers of
+ * codec context
+ *
+ * @par Description: the current routine initializes the function pointers of
+ * codec context based on x86_sse42 arch in use for svc
+ *
+ * @param[in] ps_svc_lyr_dec
+ * svc dec layer context pointer
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvcd_init_function_ptr_sse42(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
+{
+ dec_struct_t *ps_codec = &ps_svc_lyr_dec->s_dec;
+ residual_sampling_ctxt_t *ps_resd_samp_ctx;
+ intra_sampling_ctxt_t *ps_intra_samp_ctxt;
+ /* call default init func prt sse42 */
+ ih264d_init_function_ptr_sse42(ps_codec);
+
+ ps_resd_samp_ctx = (residual_sampling_ctxt_t *) ps_svc_lyr_dec->pv_residual_sample_ctxt;
+ ps_intra_samp_ctxt = (intra_sampling_ctxt_t *) ps_svc_lyr_dec->pv_intra_sample_ctxt;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4 =
+ isvcd_iquant_itrans_residual_recon_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_4x4_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8 =
+ isvcd_iquant_itrans_residual_recon_8x8_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_luma_8x8_dc =
+ isvcd_iquant_itrans_residual_recon_8x8_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4 =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_recon_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_sse42;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4 = isvcd_iquant_itrans_residual_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_4x4_dc =
+ isvcd_iquant_itrans_residual_4x4_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8 = isvcd_iquant_itrans_residual_8x8_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_luma_8x8_dc =
+ isvcd_iquant_itrans_residual_8x8_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4 =
+ isvcd_iquant_itrans_residual_chroma_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_residual_chroma_4x4_dc =
+ isvcd_iquant_itrans_residual_chroma_4x4_dc_sse42;
+
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_4x4 = isvcd_pred_residual_recon_4x4_sse42;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_8x8 = isvcd_pred_residual_recon_8x8_sse42;
+ ps_svc_lyr_dec->pf_pred_residual_recon_luma_16x16 = isvcd_pred_residual_recon_16x16_sse42;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_4x4 = isvcd_pred_residual_recon_chroma_4x4_sse42;
+ ps_svc_lyr_dec->pf_pred_residual_recon_chroma_8x8 = isvcd_pred_residual_recon_chroma_8x8_sse42;
+
+ ps_svc_lyr_dec->pf_residual_luma_4x4 = isvcd_residual_luma_4x4_sse42;
+ ps_svc_lyr_dec->pf_residual_luma_8x8 = isvcd_residual_luma_8x8_sse42;
+ ps_svc_lyr_dec->pf_residual_luma_16x16 = isvcd_residual_luma_16x16_sse42;
+ ps_svc_lyr_dec->pf_residual_chroma_cb_cr_8x8 = isvcd_residual_chroma_cb_cr_8x8_sse42;
+
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4 = isvcd_iquant_itrans_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_4x4_dc = isvcd_iquant_itrans_4x4_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8 = isvcd_iquant_itrans_8x8_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_luma_8x8_dc = isvcd_iquant_itrans_8x8_dc_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4 = isvcd_iquant_itrans_chroma_4x4_sse42;
+ ps_svc_lyr_dec->pf_iquant_itrans_chroma_4x4_dc = isvcd_iquant_itrans_chroma_4x4_dc_sse42;
+
+ ps_intra_samp_ctxt->pf_interpolate_base_luma_dyadic = isvcd_interpolate_base_luma_dyadic_sse42;
+ ps_intra_samp_ctxt->pf_interpolate_intra_base = isvcd_interpolate_intra_base_sse42;
+
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[0] = isvcd_vert_interpol_chroma_dyadic_1_sse42;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[1] = isvcd_vert_interpol_chroma_dyadic_2_sse42;
+ ps_intra_samp_ctxt->pf_vert_chroma_interpol[2] = isvcd_vert_interpol_chroma_dyadic_3_sse42;
+
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[0] = isvcd_horz_interpol_chroma_dyadic_1_sse42;
+ ps_intra_samp_ctxt->pf_horz_chroma_interpol[1] = isvcd_horz_interpol_chroma_dyadic_2_sse42;
+
+ ps_resd_samp_ctx->pf_residual_luma_dyadic = isvcd_residual_luma_dyadic_sse42;
+ ps_resd_samp_ctx->pf_interpolate_residual = isvcd_interpolate_residual_sse42;
+ ps_resd_samp_ctx->pf_residual_reflayer_const_non_boundary_mb =
+ isvcd_residual_reflayer_const_non_boundary_mb_sse42;
+
+ return;
+}
diff --git a/decoder/x86/svc/isvcd_intra_resamp_sse42.c b/decoder/x86/svc/isvcd_intra_resamp_sse42.c
new file mode 100644
index 0000000..7e777fc
--- /dev/null
+++ b/decoder/x86/svc/isvcd_intra_resamp_sse42.c
@@ -0,0 +1,1925 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_intra_resamp_sse42.c
+ *
+ * @brief
+ * Contains function definitions for intra resampling functions
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_interpolate_base_luma_dyadic_sse42
+ * - isvcd_vert_interpol_chroma_dyadic_1_sse42
+ * - isvcd_vert_interpol_chroma_dyadic_2_sse42
+ * - isvcd_vert_interpol_chroma_dyadic_3_sse42
+ * - isvcd_horz_interpol_chroma_dyadic_1_sse42
+ * - isvcd_horz_interpol_chroma_dyadic_2_sse42
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+#include <smmintrin.h>
+#include <emmintrin.h>
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvcd_structs.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_base_luma_dyadic_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* intra resampling for dyadic scaling ratios */
+/* Inputs : pu1_inp_buf : ptr to the 12x12 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 12x16 buffer to hold the */
+/* vertically interpolated data */
+/* pu1_out_buf : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 05 21 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_interpolate_base_luma_dyadic_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ UWORD8 *pu1_out_buf, WORD32 i4_out_stride)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp, *pu1_out;
+ WORD16 *pi2_tmp;
+
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3;
+ __m128i i4_samp_8x16b_0, i4_samp_8x16b_1, i4_samp_8x16b_2, i4_samp_8x16b_3;
+ __m128i i4_res_8x16b_r1_1, i4_res_8x16b_r1_2, i4_res_8x16b_r1_3;
+ __m128i i4_res_8x16b_r2_1, i4_res_8x16b_r2_2, i4_res_8x16b_r2_3;
+
+ /* Filter coefficient values for phase 4 */
+ __m128i i4_coeff_8x16b_0 = _mm_set1_epi16(-3);
+ __m128i i4_coeff_8x16b_1 = _mm_set1_epi16(28);
+ i4_filt_stride = 12;
+ i4_src_stride = DYADIC_REF_W_Y;
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ pu1_out = pu1_out_buf;
+
+ /* Vertical interpolation */
+ /*First 64 bit */
+ for(i4_x = 0; i4_x < 1; i4_x++)
+ {
+ /* y = 0, y_phase = 12 */
+ i4_samp_16x8b_0 = _mm_loadl_epi64((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadl_epi64((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 =
+ _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ pu1_inp += (i4_src_stride << 2);
+ i4_samp_8x16b_0 = _mm_cvtepu8_epi16(i4_samp_16x8b_0);
+ i4_samp_8x16b_1 = _mm_cvtepu8_epi16(i4_samp_16x8b_1);
+ i4_samp_8x16b_2 = _mm_cvtepu8_epi16(i4_samp_16x8b_2);
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(i4_samp_16x8b_3);
+
+ /* since y_phase 12 for y = 0 */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_0);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ pi2_tmp += i4_filt_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ /* Store the output */
+ _mm_storeu_si128((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ } /* End of loop over x */
+
+ /*Remaining 32 bit */
+ pu1_inp += 8;
+ pi2_tmp += 8;
+ for(i4_x = 0; i4_x < 1; i4_x++)
+ {
+ /* y = 0, y_phase = 12 */
+ i4_samp_16x8b_0 = _mm_loadl_epi64((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadl_epi64((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 =
+ _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ pu1_inp += (i4_src_stride << 2);
+ i4_samp_8x16b_0 = _mm_cvtepu8_epi16(i4_samp_16x8b_0);
+ i4_samp_8x16b_1 = _mm_cvtepu8_epi16(i4_samp_16x8b_1);
+ i4_samp_8x16b_2 = _mm_cvtepu8_epi16(i4_samp_16x8b_2);
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(i4_samp_16x8b_3);
+
+ /* since y_phase 12 for y = 0 */
+ /*Multiply by 8 => left shift by 3*/
+ i4_res_8x16b_r1_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_0);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ pi2_tmp += i4_filt_stride;
+
+ for(i4_y = 1; i4_y < 15; i4_y += 2)
+ {
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+ /* y_phase is 4 for odd values of y */
+ /* and 12 for even values of y */
+ /*Multiply by 8 => left shift by 3*/
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+
+ i4_res_8x16b_r2_1 = _mm_slli_epi16(i4_samp_8x16b_1, 3);
+ i4_res_8x16b_r2_2 = _mm_mullo_epi16(i4_samp_8x16b_2, i4_coeff_8x16b_1);
+ i4_res_8x16b_r2_3 = _mm_mullo_epi16(i4_samp_8x16b_3, i4_coeff_8x16b_0);
+
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+ i4_res_8x16b_r2_3 = _mm_subs_epi16(i4_res_8x16b_r2_3, i4_samp_8x16b_0);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_2);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+ i4_res_8x16b_r2_1 = _mm_adds_epi16(i4_res_8x16b_r2_1, i4_res_8x16b_r2_3);
+
+ /* Storing the results */
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r2_1);
+ pi2_tmp += (i4_filt_stride << 1);
+ pu1_inp += i4_src_stride;
+ } /* End of loop over y */
+
+ /* y = 15, y_phase = 4 */
+ i4_samp_8x16b_0 = i4_samp_8x16b_1;
+ i4_samp_8x16b_1 = i4_samp_8x16b_2;
+ i4_samp_8x16b_2 = i4_samp_8x16b_3;
+ i4_samp_8x16b_3 = _mm_cvtepu8_epi16(_mm_loadl_epi64((__m128i *) (pu1_inp)));
+
+ i4_res_8x16b_r1_1 = _mm_mullo_epi16(i4_samp_8x16b_0, i4_coeff_8x16b_0);
+ i4_res_8x16b_r1_2 = _mm_mullo_epi16(i4_samp_8x16b_1, i4_coeff_8x16b_1);
+ i4_res_8x16b_r1_3 = _mm_slli_epi16(i4_samp_8x16b_2, 3);
+ i4_res_8x16b_r1_3 = _mm_subs_epi16(i4_res_8x16b_r1_3, i4_samp_8x16b_3);
+
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_2);
+ i4_res_8x16b_r1_1 = _mm_adds_epi16(i4_res_8x16b_r1_1, i4_res_8x16b_r1_3);
+
+ /* Store the output */
+ _mm_storel_epi64((__m128i *) pi2_tmp, i4_res_8x16b_r1_1);
+
+ /* Reinitializing the ptrs */
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ }
+
+ {
+ __m128i coeff_c0_c1_8x16b = _mm_set_epi16(28, -3, 28, -3, 28, -3, 28, -3);
+ __m128i coeff_c2_c3_8x16b = _mm_set_epi16(-1, 8, -1, 8, -1, 8, -1, 8);
+ __m128i coeff_c3_c2_8x16b = _mm_set_epi16(8, -1, 8, -1, 8, -1, 8, -1);
+ __m128i coeff_c1_c0_8x16b = _mm_set_epi16(-3, 28, -3, 28, -3, 28, -3, 28);
+
+ __m128i i4_samp_8x16b_rpart1_0, i4_samp_8x16b_rpart2_0;
+ __m128i i4_samp_8x16b_rpart1_1, i4_samp_8x16b_rpart2_1;
+ __m128i i4_samp_8x16b_rpart1_2, i4_samp_8x16b_rpart2_2;
+ __m128i i4_samp_8x16b_rpart1_3, i4_samp_8x16b_rpart2_3;
+ __m128i i4_samp_8x16b_rpart1_4, i4_samp_8x16b_rpart2_4;
+
+ __m128i i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart2_0;
+ __m128i i4_res_4x32b_rpart1_1, i4_res_4x32b_rpart2_1;
+ __m128i i4_res_4x32b_rpart1_2, i4_res_4x32b_rpart2_2;
+ __m128i i4_res_4x32b_rpart1_3, i4_res_4x32b_rpart2_3;
+
+ __m128i res_512 = _mm_set1_epi32(512);
+ /* Horizontal interpolation */
+ for(i4_y = 0; i4_y < 16; i4_y++)
+ {
+ // a0 a1 a2 a3 a4 a5 a6 a7
+ i4_samp_8x16b_rpart1_0 = _mm_loadu_si128((__m128i *) pi2_tmp);
+ // a4 a5 a6 a7 a8 a9 a10 a11
+ i4_samp_8x16b_rpart2_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 4));
+ // a1 a2 a3 a4 a5 a6 a7 0
+ i4_samp_8x16b_rpart1_1 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 2);
+ // a2 a3 a4 a5 a6 a7 0 0
+ i4_samp_8x16b_rpart1_2 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 4);
+ // a3 a4 a5 a6 a7 0 0 0
+ i4_samp_8x16b_rpart1_3 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 6);
+ // a4 a5 a6 a7 0 0 0 0
+ i4_samp_8x16b_rpart1_4 = _mm_srli_si128(i4_samp_8x16b_rpart1_0, 8);
+
+ // a5 a6 a7 a8 a9 a10 a11 0
+ i4_samp_8x16b_rpart2_1 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 2);
+ // a6 a7 a8 a9 a10 a11 0 0
+ i4_samp_8x16b_rpart2_2 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 4);
+ // a7 a8 a9 a10 a11 0 0 0
+ i4_samp_8x16b_rpart2_3 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 6);
+ // a8 a9 a10 a11 0 0 0 0
+ i4_samp_8x16b_rpart2_4 = _mm_srli_si128(i4_samp_8x16b_rpart2_0, 8);
+ // a0 a1 a1 a2 a2 a3 a3 a4
+ i4_samp_8x16b_rpart1_0 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_0, i4_samp_8x16b_rpart1_1);
+ // a1 a2 a2 a3 a3 a4 a4 a5
+ i4_samp_8x16b_rpart1_1 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_1, i4_samp_8x16b_rpart1_2);
+ // a2 a3 a3 a4 a4 a5 a5 a6
+ i4_samp_8x16b_rpart1_2 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_2, i4_samp_8x16b_rpart1_3);
+ // a3 a4 a4 a5 a5 a6 a6 a7
+ i4_samp_8x16b_rpart1_3 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart1_3, i4_samp_8x16b_rpart1_4);
+ // a4 a5 a5 a6 a6 a7 a7 a8
+ i4_samp_8x16b_rpart2_0 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_0, i4_samp_8x16b_rpart2_1);
+ // a5 a6 a6 a7 a7 a8 a8 a9
+ i4_samp_8x16b_rpart2_1 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_1, i4_samp_8x16b_rpart2_2);
+ // a6 a7 a7 a8 a8 a9 a9 a10
+ i4_samp_8x16b_rpart2_2 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_2, i4_samp_8x16b_rpart2_3);
+ // a7 a8 a8 a9 a9 a10 a10 a11
+ i4_samp_8x16b_rpart2_3 =
+ _mm_unpacklo_epi16(i4_samp_8x16b_rpart2_3, i4_samp_8x16b_rpart2_4);
+ // a0c3+a1c2 a1c3+a2c2 a2c3+a3c2 a3c3+a4c2
+ i4_res_4x32b_rpart1_0 = _mm_madd_epi16(i4_samp_8x16b_rpart1_0, coeff_c3_c2_8x16b);
+ // a2c1+a3c0 a3c1+a4c0 a4c1+a5c0 a5c1+a6c0
+ i4_res_4x32b_rpart1_2 = _mm_madd_epi16(i4_samp_8x16b_rpart1_2, coeff_c1_c0_8x16b);
+ // a1c0+a2c1 a2c0+a3c1 a3c0+a4c1 a4c0+a5c1
+ i4_res_4x32b_rpart1_1 = _mm_madd_epi16(i4_samp_8x16b_rpart1_1, coeff_c0_c1_8x16b);
+ // a3c2+a4c3 a5c2+a5c3 a5c2+a6c3 a6c2+a7c3
+ i4_res_4x32b_rpart1_3 = _mm_madd_epi16(i4_samp_8x16b_rpart1_3, coeff_c2_c3_8x16b);
+ // a4c3+a5c2 a5a3+a6c2 a6c3+a7c2 a7c3+a8c2
+ i4_res_4x32b_rpart2_0 = _mm_madd_epi16(i4_samp_8x16b_rpart2_0, coeff_c3_c2_8x16b);
+ // a6c1+a7c0 a7c1+a8c0 a8c1+a9c0 a9c1+a10c0
+ i4_res_4x32b_rpart2_2 = _mm_madd_epi16(i4_samp_8x16b_rpart2_2, coeff_c1_c0_8x16b);
+ // a5c0+a6c1 a6c0+a7c1 a7c0+a8c1 a8c0+a9c1
+ i4_res_4x32b_rpart2_1 = _mm_madd_epi16(i4_samp_8x16b_rpart2_1, coeff_c0_c1_8x16b);
+ // a7c2+a8c3 a8c2+a9c3 a9c2+a10c3 a10c2+a11c3
+ i4_res_4x32b_rpart2_3 = _mm_madd_epi16(i4_samp_8x16b_rpart2_3, coeff_c2_c3_8x16b);
+ // a0c3+a1c2 + a2c1+a3c0 a1c3+a2c2 + a3c1+a4c0 a2c3+a3c2 + a4c1+a5c0
+ // a3c3+a4c2 +a5c1+a6c0
+ i4_res_4x32b_rpart1_0 = _mm_add_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_2);
+ // a1c0+a2c1 + a3c2+a4c3 a2c0+a3c1 + a5c2+a5c3 a3c0+a4c1 + a5c2+a6c3
+ // a4c0+a5c1 + a6c2+a7c3
+ i4_res_4x32b_rpart1_1 = _mm_add_epi32(i4_res_4x32b_rpart1_1, i4_res_4x32b_rpart1_3);
+ // a4c3+a5c2 + a6c1+a7c0 a5a3+a6c2 + a7c1+a8c0 a6c3+a7c2 + a8c1+a9c0
+ // a7c3+a8c2+ a9c1+a10c0
+ i4_res_4x32b_rpart2_0 = _mm_add_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_2);
+ // a5c0+a6c1 + a7c2+a8c3 a6c0+a7c1 + a8c2+a9c3 a7c0+a8c1 + a9c2+a10c3
+ // a8c0+a9c1 + a10c2+a11c3
+ i4_res_4x32b_rpart2_1 = _mm_add_epi32(i4_res_4x32b_rpart2_1, i4_res_4x32b_rpart2_3);
+
+ i4_res_4x32b_rpart1_2 =
+ _mm_unpacklo_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1);
+ i4_res_4x32b_rpart1_3 =
+ _mm_unpackhi_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1);
+
+ i4_res_4x32b_rpart2_2 =
+ _mm_unpacklo_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1);
+ i4_res_4x32b_rpart2_3 =
+ _mm_unpackhi_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1);
+
+ i4_res_4x32b_rpart1_0 = _mm_add_epi32(i4_res_4x32b_rpart1_2, res_512);
+ i4_res_4x32b_rpart1_1 = _mm_add_epi32(i4_res_4x32b_rpart1_3, res_512);
+
+ i4_res_4x32b_rpart1_0 = _mm_srai_epi32(i4_res_4x32b_rpart1_0, 10);
+ i4_res_4x32b_rpart1_1 = _mm_srai_epi32(i4_res_4x32b_rpart1_1, 10);
+
+ i4_res_4x32b_rpart2_0 = _mm_add_epi32(i4_res_4x32b_rpart2_2, res_512);
+ i4_res_4x32b_rpart2_1 = _mm_add_epi32(i4_res_4x32b_rpart2_3, res_512);
+
+ i4_res_4x32b_rpart2_0 = _mm_srai_epi32(i4_res_4x32b_rpart2_0, 10);
+ i4_res_4x32b_rpart2_1 = _mm_srai_epi32(i4_res_4x32b_rpart2_1, 10);
+
+ _mm_storeu_si128(
+ (__m128i *) pu1_out,
+ _mm_packus_epi16(_mm_packus_epi32(i4_res_4x32b_rpart1_0, i4_res_4x32b_rpart1_1),
+ _mm_packus_epi32(i4_res_4x32b_rpart2_0, i4_res_4x32b_rpart2_1)));
+
+ pi2_tmp += i4_filt_stride;
+ pu1_out += i4_out_stride;
+ } /* End of loop over y */
+ }
+} /* isvcd_interpolate_base_luma_dyadic */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_intra_base_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* interpolation of a component to find the intra */
+/* resampled value */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* pu1_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction followed */
+/* by horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_interpolate_intra_base_sse42(void *pv_intra_samp_ctxt, UWORD8 *pu1_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd, WORD32 i4_mb_x,
+ WORD32 i4_mb_y, WORD32 i4_chroma_flag,
+ WORD32 i4_refarray_flag)
+{
+ /* --------------------------------------------------------------------- */
+ /* Index Parameters */
+ /* --------------------------------------------------------------------- */
+ intra_sampling_ctxt_t *ps_ctxt;
+ intra_samp_map_ctxt_t *ps_map_ctxt;
+ intra_samp_lyr_ctxt *ps_lyr_ctxt;
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ UWORD8 *pu1_refarray = NULL;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+ WORD32 i4_temp_array_ht;
+ WORD32 *pi4_interp_buff;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+
+ WORD32 i4_x_min;
+ ref_min_max_map_t *ps_x_min_max;
+ WORD8 arr_y_ref_pos_luma[16] = {0};
+ WORD8 arr_x_ref_pos_luma[16] = {0};
+ WORD8 arr_x_ref_pos_luma_low[16] = {0};
+ WORD8 arr_x_ref_pos_luma_high[16] = {0};
+ WORD8 arr_phase_luma[32] = {0};
+ WORD8 *pi4_y_ref_pos_luma;
+ WORD8 *pi4_x_ref_pos_luma_low;
+ WORD8 *pi4_x_ref_pos_luma_high;
+ WORD8 *pi4_phase_luma;
+ UWORD8 *pu1_refarray_temp;
+
+ /* --------------------------------------------------------------------- */
+ /* Extracting pointers from the context */
+ /* --------------------------------------------------------------------- */
+ ps_ctxt = (intra_sampling_ctxt_t *) pv_intra_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+
+ if(0 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_buffer;
+ }
+ else if(1 == i4_refarray_flag)
+ {
+ pu1_refarray = ps_ctxt->pu1_refarray_cb;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* LUMA or CHROMA */
+ /* --------------------------------------------------------------------- */
+
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &(ps_lyr_ctxt->s_chroma_map_ctxt);
+ else
+ ps_map_ctxt = &(ps_lyr_ctxt->s_luma_map_ctxt);
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ ps_x_min_max = ps_map_ctxt->ps_x_min_max;
+
+ i4_frm_mb_y = i4_mb_y * i4_mb_ht;
+ i4_frm_mb_x = i4_mb_x * i4_mb_wd;
+ /* get the min position */
+ i4_x_min = ps_x_min_max[i4_mb_x].i2_min_pos;
+
+ /* --------------------------------------------------------------------- */
+ /* Projected frame level pointers */
+ /* --------------------------------------------------------------------- */
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ /* --------------------------------------------------------------------- */
+ /* Pointers and Dimenstion of the temporary buffer */
+ /* --------------------------------------------------------------------- */
+ i4_temp_array_ht = i4_mb_ht;
+ pi4_interp_buff = ps_ctxt->pi4_temp_interpolation_buffer;
+
+ if(i4_chroma_flag == 0)
+ {
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation in vertical direction */
+ /* --------------------------------------------------------------------- */
+ WORD16 *pi2_interp_buff_temp;
+ pi2_interp_buff_temp = (WORD16 *) pi4_interp_buff;
+ {
+ __m128i out_res_8x16b_0, out_res_8x16b_1;
+
+ __m128i inp_8x16b_r0, inp_8x16b_r01_0, phs_mask_16x8b_r0, phs_mask_16x8b_r01_0,
+ out_res_8x16b_r01_0;
+ __m128i inp_8x16b_r1, inp_8x16b_r23_0, phs_mask_16x8b_r1, phs_mask_16x8b_r23_0,
+ out_res_8x16b_r01_1;
+ __m128i inp_8x16b_r2, inp_8x16b_r01_1, phs_mask_16x8b_r2, phs_mask_16x8b_r01_1,
+ out_res_8x16b_r23_0;
+ __m128i inp_8x16b_r3, inp_8x16b_r23_1, phs_mask_16x8b_r3, phs_mask_16x8b_r23_1,
+ out_res_8x16b_r23_1;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_phase_luma[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos_luma[i4_y] = (WORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi4_y_ref_pos_luma = arr_y_ref_pos_luma;
+ pi4_phase_luma = arr_phase_luma;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ pu1_refarray_temp =
+ pu1_refarray + (pi4_y_ref_pos_luma[i4_y] * i4_refarray_wd) + (i4_x_min - 1);
+ inp_8x16b_r0 = _mm_loadu_si128((__m128i *) (pu1_refarray_temp - i4_refarray_wd));
+ inp_8x16b_r1 = _mm_loadu_si128((__m128i *) (pu1_refarray_temp));
+ inp_8x16b_r2 = _mm_loadu_si128((__m128i *) (pu1_refarray_temp + i4_refarray_wd));
+ inp_8x16b_r3 =
+ _mm_loadu_si128((__m128i *) (pu1_refarray_temp + 2 * i4_refarray_wd));
+
+ inp_8x16b_r01_0 = _mm_unpacklo_epi8(inp_8x16b_r0, inp_8x16b_r1);
+ inp_8x16b_r23_0 = _mm_unpacklo_epi8(inp_8x16b_r2, inp_8x16b_r3);
+ inp_8x16b_r01_1 = _mm_unpackhi_epi8(inp_8x16b_r0, inp_8x16b_r1);
+ inp_8x16b_r23_1 = _mm_unpackhi_epi8(inp_8x16b_r2, inp_8x16b_r3);
+
+ phs_mask_16x8b_r0 = _mm_set1_epi8(g_ai1_interp_filter_luma[pi4_phase_luma[i4_y]]);
+ phs_mask_16x8b_r1 =
+ _mm_set1_epi8(g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 16]);
+ phs_mask_16x8b_r2 =
+ _mm_set1_epi8(g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 32]);
+ phs_mask_16x8b_r3 =
+ _mm_set1_epi8(g_ai1_interp_filter_luma[pi4_phase_luma[i4_y] + 48]);
+
+ phs_mask_16x8b_r01_0 = _mm_unpacklo_epi8(phs_mask_16x8b_r0, phs_mask_16x8b_r1);
+ phs_mask_16x8b_r23_0 = _mm_unpacklo_epi8(phs_mask_16x8b_r2, phs_mask_16x8b_r3);
+ phs_mask_16x8b_r01_1 = _mm_unpackhi_epi8(phs_mask_16x8b_r0, phs_mask_16x8b_r1);
+ phs_mask_16x8b_r23_1 = _mm_unpackhi_epi8(phs_mask_16x8b_r2, phs_mask_16x8b_r3);
+
+ out_res_8x16b_r01_0 = _mm_maddubs_epi16(inp_8x16b_r01_0, phs_mask_16x8b_r01_0);
+ out_res_8x16b_r01_1 = _mm_maddubs_epi16(inp_8x16b_r01_1, phs_mask_16x8b_r01_1);
+ out_res_8x16b_r23_0 = _mm_maddubs_epi16(inp_8x16b_r23_0, phs_mask_16x8b_r23_0);
+ out_res_8x16b_r23_1 = _mm_maddubs_epi16(inp_8x16b_r23_1, phs_mask_16x8b_r23_1);
+
+ out_res_8x16b_0 = _mm_add_epi16(out_res_8x16b_r01_0, out_res_8x16b_r23_0);
+ out_res_8x16b_1 = _mm_add_epi16(out_res_8x16b_r01_1, out_res_8x16b_r23_1);
+
+ _mm_storeu_si128(
+ (__m128i *) (pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1)),
+ out_res_8x16b_0);
+ _mm_storeu_si128((__m128i *) (pi2_interp_buff_temp + (i4_y * i4_refarray_wd) +
+ (i4_x_min - 1) + 8),
+ out_res_8x16b_1);
+ }
+ }
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation in horizontal direction */
+ /* --------------------------------------------------------------------- */
+ {
+ WORD32 strt_indx = 10, strt_indx_h = 0;
+
+ __m128i inp_8x16b_0;
+ __m128i inp_8x16b_1;
+
+ __m128i phs_mask_16x8b_0;
+ __m128i phs_mask_16x8b_1;
+ __m128i x_ref_pos_luma_mask_r0_0, x_ref_pos_luma_mask_r0_1, x_ref_pos_luma_mask_r1_0,
+ x_ref_pos_luma_mask_r1_1, x_ref_pos_luma_mask_r2_0, x_ref_pos_luma_mask_r2_1,
+ x_ref_pos_luma_mask_r3_0, x_ref_pos_luma_mask_r3_1;
+
+ __m128i inp_8x16b_2, inp_8x16b_3;
+
+ WORD32 i4_x2 = 0;
+ WORD32 i4_mb_wd_hlf = (i4_mb_wd >> 1);
+ __m128i twos = _mm_set1_epi8(2);
+
+ strt_indx = ps_x_pos_phase[0 + i4_frm_mb_x].i2_ref_pos - 1;
+ strt_indx_h = (ps_x_pos_phase[8 + i4_frm_mb_x].i2_ref_pos - strt_indx - 1);
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos_luma[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_phase_luma[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ arr_x_ref_pos_luma[i4_x] = arr_x_ref_pos_luma[i4_x] - strt_indx - 1;
+ }
+
+ for(i4_x = 0; i4_x < i4_mb_wd_hlf; i4_x++)
+ {
+ i4_x2 = i4_x << 1;
+ arr_x_ref_pos_luma_low[i4_x2] = (arr_x_ref_pos_luma[i4_x]) << 1;
+ arr_x_ref_pos_luma_low[i4_x2 + 1] = arr_x_ref_pos_luma_low[i4_x2] + 1;
+ }
+ for(i4_x = i4_mb_wd_hlf; i4_x < i4_mb_wd; i4_x++)
+ {
+ i4_x2 = (i4_x - i4_mb_wd_hlf) << 1;
+ arr_x_ref_pos_luma_high[i4_x2] = ((arr_x_ref_pos_luma[i4_x] - strt_indx_h) << 1);
+ arr_x_ref_pos_luma_high[i4_x2 + 1] = arr_x_ref_pos_luma_high[i4_x2] + 1;
+ }
+ pi4_x_ref_pos_luma_low = arr_x_ref_pos_luma_low;
+ pi4_x_ref_pos_luma_high = arr_x_ref_pos_luma_high;
+ pi4_phase_luma = arr_phase_luma;
+
+ phs_mask_16x8b_0 = _mm_loadu_si128((__m128i *) (pi4_phase_luma));
+ phs_mask_16x8b_1 = _mm_loadu_si128((__m128i *) (pi4_phase_luma + 8));
+
+ x_ref_pos_luma_mask_r0_0 = _mm_loadu_si128((__m128i *) (pi4_x_ref_pos_luma_low));
+ x_ref_pos_luma_mask_r0_1 = _mm_loadu_si128((__m128i *) (pi4_x_ref_pos_luma_high));
+ x_ref_pos_luma_mask_r1_0 = _mm_add_epi8(x_ref_pos_luma_mask_r0_0, twos);
+ x_ref_pos_luma_mask_r1_1 = _mm_add_epi8(x_ref_pos_luma_mask_r0_1, twos);
+ x_ref_pos_luma_mask_r2_0 = _mm_add_epi8(x_ref_pos_luma_mask_r1_0, twos);
+ x_ref_pos_luma_mask_r2_1 = _mm_add_epi8(x_ref_pos_luma_mask_r1_1, twos);
+ x_ref_pos_luma_mask_r3_0 = x_ref_pos_luma_mask_r0_0;
+ x_ref_pos_luma_mask_r3_1 = x_ref_pos_luma_mask_r0_1;
+
+ {
+ __m128i ip_filt_16x8b_r0, ip_filt_8x16b_r0_0, ip_filt_8x16b_r0_1,
+ ip_filt_8x16b_r01_l_0, ip_filt_8x16b_r01_h_0;
+ __m128i ip_filt_16x8b_r1, ip_filt_8x16b_r1_0, ip_filt_8x16b_r1_1,
+ ip_filt_8x16b_r23_l_0, ip_filt_8x16b_r23_h_0;
+ __m128i ip_filt_16x8b_r2, ip_filt_8x16b_r2_0, ip_filt_8x16b_r2_1,
+ ip_filt_8x16b_r01_l_1, ip_filt_8x16b_r01_h_1;
+ __m128i ip_filt_16x8b_r3, ip_filt_8x16b_r3_0, ip_filt_8x16b_r3_1,
+ ip_filt_8x16b_r23_l_1, ip_filt_8x16b_r23_h_1;
+
+ __m128i inp_8x16b_r0_0, inp_8x16b_r2_0, inp_8x16b_r01_l_0, inp_8x16b_r01_h_0,
+ out_res_4x32b_r01_l_0, out_res_4x32b_r01_h_0;
+ __m128i inp_8x16b_r0_1, inp_8x16b_r2_1, inp_8x16b_r23_l_0, inp_8x16b_r23_h_0,
+ out_res_4x32b_r01_l_1, out_res_4x32b_r01_h_1;
+ __m128i inp_8x16b_r1_0, inp_8x16b_r3_0, inp_8x16b_r01_l_1, inp_8x16b_r01_h_1,
+ out_res_4x32b_r23_l_0, out_res_4x32b_r23_h_0;
+ __m128i inp_8x16b_r1_1, inp_8x16b_r3_1, inp_8x16b_r23_l_1, inp_8x16b_r23_h_1,
+ out_res_4x32b_r23_l_1, out_res_4x32b_r23_h_1;
+
+ __m128i out_res_4x32b_l_0;
+ __m128i out_res_4x32b_l_1;
+ __m128i out_res_4x32b_h_0;
+ __m128i out_res_4x32b_h_1;
+
+ __m128i out_res_8x16b_l;
+ __m128i out_res_8x16b_h;
+
+ __m128i out_res_16x8b;
+ __m128i const_512 = _mm_set1_epi32(512);
+
+ ip_filt_16x8b_r0 = _mm_loadu_si128((__m128i *) (g_ai1_interp_filter_luma));
+ ip_filt_16x8b_r1 = _mm_loadu_si128((__m128i *) (g_ai1_interp_filter_luma + 16));
+ ip_filt_16x8b_r2 = _mm_loadu_si128((__m128i *) (g_ai1_interp_filter_luma + 32));
+ ip_filt_16x8b_r3 = _mm_loadu_si128((__m128i *) (g_ai1_interp_filter_luma + 48));
+
+ ip_filt_8x16b_r0_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r0, phs_mask_16x8b_0));
+ ip_filt_8x16b_r1_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r1, phs_mask_16x8b_0));
+ ip_filt_8x16b_r2_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r2, phs_mask_16x8b_0));
+ ip_filt_8x16b_r3_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r3, phs_mask_16x8b_0));
+
+ ip_filt_8x16b_r0_1 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r0, phs_mask_16x8b_1));
+ ip_filt_8x16b_r1_1 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r1, phs_mask_16x8b_1));
+ ip_filt_8x16b_r2_1 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r2, phs_mask_16x8b_1));
+ ip_filt_8x16b_r3_1 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r3, phs_mask_16x8b_1));
+
+ ip_filt_8x16b_r01_l_0 = _mm_unpacklo_epi16(ip_filt_8x16b_r0_0, ip_filt_8x16b_r1_0);
+ ip_filt_8x16b_r23_l_0 = _mm_unpacklo_epi16(ip_filt_8x16b_r2_0, ip_filt_8x16b_r3_0);
+ ip_filt_8x16b_r01_l_1 = _mm_unpackhi_epi16(ip_filt_8x16b_r0_0, ip_filt_8x16b_r1_0);
+ ip_filt_8x16b_r23_l_1 = _mm_unpackhi_epi16(ip_filt_8x16b_r2_0, ip_filt_8x16b_r3_0);
+
+ ip_filt_8x16b_r01_h_0 = _mm_unpacklo_epi16(ip_filt_8x16b_r0_1, ip_filt_8x16b_r1_1);
+ ip_filt_8x16b_r23_h_0 = _mm_unpacklo_epi16(ip_filt_8x16b_r2_1, ip_filt_8x16b_r3_1);
+ ip_filt_8x16b_r01_h_1 = _mm_unpackhi_epi16(ip_filt_8x16b_r0_1, ip_filt_8x16b_r1_1);
+ ip_filt_8x16b_r23_h_1 = _mm_unpackhi_epi16(ip_filt_8x16b_r2_1, ip_filt_8x16b_r3_1);
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ inp_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_interp_buff_temp + strt_indx));
+ inp_8x16b_1 = _mm_loadu_si128(
+ (__m128i *) (pi2_interp_buff_temp + strt_indx + strt_indx_h));
+ inp_8x16b_2 =
+ _mm_loadu_si128((__m128i *) (pi2_interp_buff_temp + strt_indx + 3));
+ inp_8x16b_3 = _mm_loadu_si128(
+ (__m128i *) (pi2_interp_buff_temp + strt_indx + strt_indx_h + 3));
+ pi2_interp_buff_temp += i4_refarray_wd;
+
+ inp_8x16b_r0_0 = _mm_shuffle_epi8(inp_8x16b_0, x_ref_pos_luma_mask_r0_0);
+ inp_8x16b_r0_1 = _mm_shuffle_epi8(inp_8x16b_1, x_ref_pos_luma_mask_r0_1);
+ inp_8x16b_r1_0 = _mm_shuffle_epi8(inp_8x16b_0, x_ref_pos_luma_mask_r1_0);
+ inp_8x16b_r1_1 = _mm_shuffle_epi8(inp_8x16b_1, x_ref_pos_luma_mask_r1_1);
+
+ inp_8x16b_r2_0 = _mm_shuffle_epi8(inp_8x16b_0, x_ref_pos_luma_mask_r2_0);
+ inp_8x16b_r2_1 = _mm_shuffle_epi8(inp_8x16b_1, x_ref_pos_luma_mask_r2_1);
+ inp_8x16b_r3_0 = _mm_shuffle_epi8(inp_8x16b_2, x_ref_pos_luma_mask_r3_0);
+ inp_8x16b_r3_1 = _mm_shuffle_epi8(inp_8x16b_3, x_ref_pos_luma_mask_r3_1);
+
+ inp_8x16b_r01_l_0 = _mm_unpacklo_epi16(inp_8x16b_r0_0, inp_8x16b_r1_0);
+ inp_8x16b_r23_l_0 = _mm_unpacklo_epi16(inp_8x16b_r2_0, inp_8x16b_r3_0);
+ inp_8x16b_r01_l_1 = _mm_unpackhi_epi16(inp_8x16b_r0_0, inp_8x16b_r1_0);
+ inp_8x16b_r23_l_1 = _mm_unpackhi_epi16(inp_8x16b_r2_0, inp_8x16b_r3_0);
+
+ inp_8x16b_r01_h_0 = _mm_unpacklo_epi16(inp_8x16b_r0_1, inp_8x16b_r1_1);
+ inp_8x16b_r23_h_0 = _mm_unpacklo_epi16(inp_8x16b_r2_1, inp_8x16b_r3_1);
+ inp_8x16b_r01_h_1 = _mm_unpackhi_epi16(inp_8x16b_r0_1, inp_8x16b_r1_1);
+ inp_8x16b_r23_h_1 = _mm_unpackhi_epi16(inp_8x16b_r2_1, inp_8x16b_r3_1);
+
+ out_res_4x32b_r01_l_0 =
+ _mm_madd_epi16(inp_8x16b_r01_l_0, ip_filt_8x16b_r01_l_0);
+ out_res_4x32b_r01_l_1 =
+ _mm_madd_epi16(inp_8x16b_r01_l_1, ip_filt_8x16b_r01_l_1);
+ out_res_4x32b_r23_l_0 =
+ _mm_madd_epi16(inp_8x16b_r23_l_0, ip_filt_8x16b_r23_l_0);
+ out_res_4x32b_r23_l_1 =
+ _mm_madd_epi16(inp_8x16b_r23_l_1, ip_filt_8x16b_r23_l_1);
+
+ out_res_4x32b_r01_h_0 =
+ _mm_madd_epi16(inp_8x16b_r01_h_0, ip_filt_8x16b_r01_h_0);
+ out_res_4x32b_r01_h_1 =
+ _mm_madd_epi16(inp_8x16b_r01_h_1, ip_filt_8x16b_r01_h_1);
+ out_res_4x32b_r23_h_0 =
+ _mm_madd_epi16(inp_8x16b_r23_h_0, ip_filt_8x16b_r23_h_0);
+ out_res_4x32b_r23_h_1 =
+ _mm_madd_epi16(inp_8x16b_r23_h_1, ip_filt_8x16b_r23_h_1);
+
+ out_res_4x32b_l_0 = _mm_add_epi32(out_res_4x32b_r01_l_0, out_res_4x32b_r23_l_0);
+ out_res_4x32b_l_1 = _mm_add_epi32(out_res_4x32b_r01_l_1, out_res_4x32b_r23_l_1);
+ out_res_4x32b_h_0 = _mm_add_epi32(out_res_4x32b_r01_h_0, out_res_4x32b_r23_h_0);
+ out_res_4x32b_h_1 = _mm_add_epi32(out_res_4x32b_r01_h_1, out_res_4x32b_r23_h_1);
+
+ out_res_4x32b_l_0 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_l_0, const_512), 10);
+ out_res_4x32b_l_1 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_l_1, const_512), 10);
+ out_res_4x32b_h_0 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_h_0, const_512), 10);
+ out_res_4x32b_h_1 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_h_1, const_512), 10);
+
+ out_res_8x16b_l = _mm_packs_epi32(out_res_4x32b_l_0, out_res_4x32b_l_1);
+ out_res_8x16b_h = _mm_packs_epi32(out_res_4x32b_h_0, out_res_4x32b_h_1);
+
+ out_res_16x8b = _mm_packus_epi16(out_res_8x16b_l, out_res_8x16b_h);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_y * i4_out_stride)), out_res_16x8b);
+ }
+ }
+ }
+ }
+ else
+ {
+ WORD16 *pi2_interp_buff_temp;
+ pi2_interp_buff_temp = (WORD16 *) pi4_interp_buff;
+
+ {
+ __m128i inp_8x16b_r0, inp_8x16b_r01_0, phs_mask_16x8b_r0, phs_mask_16x8b_r01_0,
+ out_res_8x16b_r01_0;
+ __m128i inp_8x16b_r1, phs_mask_16x8b_r1, out_res_8x16b_r01_1;
+ __m128i inp_8x16b_r01_1, phs_mask_16x8b_r01_1;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_ref_pos_luma[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos;
+ arr_phase_luma[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ }
+ pi4_y_ref_pos_luma = arr_y_ref_pos_luma;
+ pi4_phase_luma = arr_phase_luma;
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ pu1_refarray_temp =
+ pu1_refarray + (pi4_y_ref_pos_luma[i4_y] * i4_refarray_wd) + (i4_x_min - 1);
+ inp_8x16b_r0 = _mm_loadu_si128((__m128i *) (pu1_refarray_temp));
+ inp_8x16b_r1 = _mm_loadu_si128((__m128i *) (pu1_refarray_temp + i4_refarray_wd));
+
+ inp_8x16b_r01_0 = _mm_unpacklo_epi8(inp_8x16b_r0, inp_8x16b_r1);
+ inp_8x16b_r01_1 = _mm_unpackhi_epi8(inp_8x16b_r0, inp_8x16b_r1);
+
+ phs_mask_16x8b_r0 = _mm_set1_epi8(g_au1_interp_filter_chroma[pi4_phase_luma[i4_y]]);
+ phs_mask_16x8b_r1 =
+ _mm_set1_epi8(g_au1_interp_filter_chroma[pi4_phase_luma[i4_y] + 16]);
+
+ phs_mask_16x8b_r01_0 = _mm_unpacklo_epi8(phs_mask_16x8b_r0, phs_mask_16x8b_r1);
+ phs_mask_16x8b_r01_1 = _mm_unpackhi_epi8(phs_mask_16x8b_r0, phs_mask_16x8b_r1);
+
+ out_res_8x16b_r01_0 = _mm_maddubs_epi16(inp_8x16b_r01_0, phs_mask_16x8b_r01_0);
+ out_res_8x16b_r01_1 = _mm_maddubs_epi16(inp_8x16b_r01_1, phs_mask_16x8b_r01_1);
+
+ _mm_storeu_si128(
+ (__m128i *) (pi2_interp_buff_temp + (i4_y * i4_refarray_wd) + (i4_x_min - 1)),
+ out_res_8x16b_r01_0);
+ _mm_storeu_si128((__m128i *) (pi2_interp_buff_temp + (i4_y * i4_refarray_wd) +
+ (i4_x_min - 1) + 8),
+ out_res_8x16b_r01_1);
+ }
+ }
+
+ {
+ WORD32 strt_indx = 10;
+ __m128i inp_8x16b_0, inp_8x16b_r0_0;
+ __m128i phs_mask_16x8b_0;
+ __m128i x_ref_pos_luma_mask_r0_0, x_ref_pos_luma_mask_r1_0;
+ __m128i ip_filt_16x8b_r0, ip_filt_8x16b_r0_0, ip_filt_8x16b_r01_l_0;
+ __m128i ip_filt_16x8b_r1, ip_filt_8x16b_r1_0, ip_filt_8x16b_r01_l_1;
+ __m128i inp_8x16b_r1_0, inp_8x16b_r01_l_0, out_res_4x32b_r01_l_0;
+ __m128i inp_8x16b_r01_l_1, out_res_4x32b_r01_l_1;
+
+ __m128i out_res_4x32b_l_0;
+ __m128i out_res_4x32b_l_1;
+ __m128i out_res_8x16b_l;
+ __m128i out_16x8b_r1;
+ __m128i chroma_mask;
+ __m128i const_512 = _mm_set1_epi32(512);
+
+ WORD32 i4_x2 = 0;
+ __m128i twos = _mm_set1_epi8(2);
+ strt_indx = ps_x_pos_phase[0 + i4_frm_mb_x].i2_ref_pos;
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos_luma[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_phase_luma[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ arr_x_ref_pos_luma[i4_x] = arr_x_ref_pos_luma[i4_x] - strt_indx;
+ i4_x2 = i4_x << 1;
+ arr_x_ref_pos_luma_low[i4_x2] = (arr_x_ref_pos_luma[i4_x]) << 1;
+ arr_x_ref_pos_luma_low[i4_x2 + 1] = arr_x_ref_pos_luma_low[i4_x2] + 1;
+ }
+
+ pi4_x_ref_pos_luma_low = arr_x_ref_pos_luma_low;
+ pi4_phase_luma = arr_phase_luma;
+ phs_mask_16x8b_0 = _mm_loadu_si128((__m128i *) (pi4_phase_luma));
+ x_ref_pos_luma_mask_r0_0 = _mm_loadu_si128((__m128i *) (pi4_x_ref_pos_luma_low));
+ x_ref_pos_luma_mask_r1_0 = _mm_add_epi8(x_ref_pos_luma_mask_r0_0, twos);
+
+ ip_filt_16x8b_r0 = _mm_loadu_si128((__m128i *) (g_au1_interp_filter_chroma));
+ ip_filt_16x8b_r1 = _mm_loadu_si128((__m128i *) (g_au1_interp_filter_chroma + 16));
+
+ ip_filt_8x16b_r0_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r0, phs_mask_16x8b_0));
+ ip_filt_8x16b_r1_0 =
+ _mm_cvtepi8_epi16(_mm_shuffle_epi8(ip_filt_16x8b_r1, phs_mask_16x8b_0));
+
+ ip_filt_8x16b_r01_l_0 = _mm_unpacklo_epi16(ip_filt_8x16b_r0_0, ip_filt_8x16b_r1_0);
+ ip_filt_8x16b_r01_l_1 = _mm_unpackhi_epi16(ip_filt_8x16b_r0_0, ip_filt_8x16b_r1_0);
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ inp_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_interp_buff_temp + strt_indx));
+ pi2_interp_buff_temp += i4_refarray_wd;
+
+ inp_8x16b_r0_0 = _mm_shuffle_epi8(inp_8x16b_0, x_ref_pos_luma_mask_r0_0);
+ inp_8x16b_r1_0 = _mm_shuffle_epi8(inp_8x16b_0, x_ref_pos_luma_mask_r1_0);
+
+ inp_8x16b_r01_l_0 = _mm_unpacklo_epi16(inp_8x16b_r0_0, inp_8x16b_r1_0);
+ inp_8x16b_r01_l_1 = _mm_unpackhi_epi16(inp_8x16b_r0_0, inp_8x16b_r1_0);
+
+ out_res_4x32b_r01_l_0 = _mm_madd_epi16(inp_8x16b_r01_l_0, ip_filt_8x16b_r01_l_0);
+ out_res_4x32b_r01_l_1 = _mm_madd_epi16(inp_8x16b_r01_l_1, ip_filt_8x16b_r01_l_1);
+
+ out_res_4x32b_l_0 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_r01_l_0, const_512), 10);
+ out_res_4x32b_l_1 =
+ _mm_srai_epi32(_mm_add_epi32(out_res_4x32b_r01_l_1, const_512), 10);
+
+ out_res_8x16b_l = _mm_packs_epi32(out_res_4x32b_l_0, out_res_4x32b_l_1);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ out_16x8b_r1 = _mm_loadu_si128((__m128i *) (pu1_out + (i4_y * i4_out_stride)));
+ out_16x8b_r1 = _mm_and_si128(out_16x8b_r1, chroma_mask);
+ out_16x8b_r1 = _mm_add_epi8(out_res_8x16b_l, out_16x8b_r1);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_y * i4_out_stride)), out_16x8b_r1);
+ }
+ }
+ }
+ return;
+} /* End of Interpolation Function */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_1_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* interpolation of a component to find the intra */
+/* resampled value */
+/* Inputs : pv_intra_samp_ctxt : intra sampling context */
+/* pu1_out : output buffer pointer */
+/* i4_out_stride : output buffer stride */
+/* i4_refarray_wd : reference array width */
+/* i4_x_offset : offset in reference layer in horz direction*/
+/* ps_coord : current mb co-ordinate */
+/* i4_chroma_flag : chroma processing flag */
+/* Globals : none */
+/* Processing : it does the interpolation on horizontal direction */
+/* Outputs : resampled pixels */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_1_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD8 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3, i4_samp_16x8b_4,
+ i4_samp_16x8b_5;
+ __m128i i4_res_8x16b_r0, i4_res_8x16b_r1, i4_res_8x16b_r2, i4_res_8x16b_r3, i4_res_8x16b_r4,
+ i4_res_8x16b_r5, i4_res_8x16b_r6, i4_res_8x16b_r7;
+ __m128i i4_res_8x16b_r7_temp;
+ __m128i i4_c0_c1_16x8b, i4_c2_c3_16x8b;
+
+ i4_coeff_0 = (WORD8) (8 - i4_phase_0);
+ i4_coeff_1 = (WORD8) (i4_phase_0);
+ i4_coeff_2 = (WORD8) (8 - i4_phase_1);
+ i4_coeff_3 = (WORD8) (i4_phase_1);
+
+ i4_c0_c1_16x8b =
+ _mm_set_epi8(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ i4_c2_c3_16x8b =
+ _mm_set_epi8(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2);
+
+ pu1_inp = pu1_inp_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+
+ i4_samp_16x8b_0 = _mm_loadl_epi64((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadl_epi64((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ i4_samp_16x8b_4 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 2)));
+ i4_samp_16x8b_5 = _mm_loadl_epi64((__m128i *) (pu1_inp + (i4_src_stride << 2) + i4_src_stride));
+
+ i4_samp_16x8b_0 = _mm_unpacklo_epi8(i4_samp_16x8b_0, i4_samp_16x8b_1);
+ i4_res_8x16b_r0 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp), i4_res_8x16b_r0);
+
+ i4_samp_16x8b_1 = _mm_unpacklo_epi8(i4_samp_16x8b_1, i4_samp_16x8b_2);
+ i4_res_8x16b_r1 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r1);
+
+ i4_res_8x16b_r2 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1)), i4_res_8x16b_r2);
+
+ i4_samp_16x8b_2 = _mm_unpacklo_epi8(i4_samp_16x8b_2, i4_samp_16x8b_3);
+ i4_res_8x16b_r3 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1) + i4_filt_stride),
+ i4_res_8x16b_r3);
+
+ i4_res_8x16b_r4 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2)), i4_res_8x16b_r4);
+
+ i4_samp_16x8b_3 = _mm_unpacklo_epi8(i4_samp_16x8b_3, i4_samp_16x8b_4);
+ i4_res_8x16b_r5 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + i4_filt_stride),
+ i4_res_8x16b_r5);
+
+ i4_res_8x16b_r6 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c0_c1_16x8b);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1)),
+ i4_res_8x16b_r6);
+
+ i4_res_8x16b_r6 = _mm_shuffle_epi32(i4_res_8x16b_r6, 78);
+
+ i4_samp_16x8b_4 = _mm_unpacklo_epi8(i4_samp_16x8b_4, i4_samp_16x8b_5);
+
+ i4_res_8x16b_r7 = _mm_maddubs_epi16(i4_samp_16x8b_4, i4_c2_c3_16x8b);
+
+ i4_res_8x16b_r7 = _mm_shuffle_epi32(i4_res_8x16b_r7, 147);
+
+ i4_res_8x16b_r7_temp = _mm_blend_epi16(i4_res_8x16b_r6, i4_res_8x16b_r7, 252);
+
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1) + 4),
+ i4_res_8x16b_r7_temp);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_2_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 0 1 */
+/* 0 2 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_2_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD8 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3, i4_samp_16x8b_4;
+ __m128i i4_res_8x16b_r0, i4_res_8x16b_r1, i4_res_8x16b_r2, i4_res_8x16b_r3, i4_res_8x16b_r4,
+ i4_res_8x16b_r5, i4_res_8x16b_r6, i4_res_8x16b_r7;
+ __m128i i4_res_8x16b_r7_temp, i4_c0_c1_16x8b, i4_c2_c3_16x8b;
+ i4_coeff_0 = (WORD8) (8 - i4_phase_0);
+ i4_coeff_1 = (WORD8) (i4_phase_0);
+ i4_coeff_2 = (WORD8) (8 - i4_phase_1);
+ i4_coeff_3 = (WORD8) (i4_phase_1);
+
+ i4_c0_c1_16x8b =
+ _mm_set_epi8(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ i4_c2_c3_16x8b =
+ _mm_set_epi8(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2);
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf + i4_src_stride;
+
+ i4_samp_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ i4_samp_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 2)));
+
+ i4_samp_16x8b_0 = _mm_unpacklo_epi8(i4_samp_16x8b_0, i4_samp_16x8b_1);
+ i4_res_8x16b_r0 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp), i4_res_8x16b_r0);
+
+ i4_res_8x16b_r1 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r1);
+
+ i4_samp_16x8b_1 = _mm_unpacklo_epi8(i4_samp_16x8b_1, i4_samp_16x8b_2);
+ i4_res_8x16b_r2 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1)), i4_res_8x16b_r2);
+
+ i4_res_8x16b_r3 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1) + i4_filt_stride),
+ i4_res_8x16b_r3);
+
+ i4_samp_16x8b_2 = _mm_unpacklo_epi8(i4_samp_16x8b_2, i4_samp_16x8b_3);
+ i4_res_8x16b_r4 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2)), i4_res_8x16b_r4);
+
+ i4_res_8x16b_r5 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + i4_filt_stride),
+ i4_res_8x16b_r5);
+
+ i4_samp_16x8b_3 = _mm_unpacklo_epi8(i4_samp_16x8b_3, i4_samp_16x8b_4);
+ i4_res_8x16b_r6 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c0_c1_16x8b);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1)),
+ i4_res_8x16b_r6);
+
+ i4_res_8x16b_r7 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c2_c3_16x8b);
+ i4_res_8x16b_r6 = _mm_shuffle_epi32(i4_res_8x16b_r6, 78);
+ i4_res_8x16b_r7 = _mm_shuffle_epi32(i4_res_8x16b_r7, 147);
+ i4_res_8x16b_r7_temp = _mm_blend_epi16(i4_res_8x16b_r6, i4_res_8x16b_r7, 252);
+
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1) + 4),
+ i4_res_8x16b_r7_temp);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_vert_interpol_chroma_dyadic_3_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_vert_interpol_chroma_dyadic_3_sse42(UWORD8 *pu1_inp_buf, WORD16 *pi2_tmp_filt_buf,
+ WORD32 i4_phase_0, WORD32 i4_phase_1)
+{
+ WORD8 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_filt_stride, i4_src_stride;
+ UWORD8 *pu1_inp;
+ WORD16 *pi2_tmp;
+ __m128i i4_samp_16x8b_0, i4_samp_16x8b_1, i4_samp_16x8b_2, i4_samp_16x8b_3, i4_samp_16x8b_4;
+ __m128i i4_res_8x16b_r0, i4_res_8x16b_r1, i4_res_8x16b_r2, i4_res_8x16b_r3, i4_res_8x16b_r4,
+ i4_res_8x16b_r5, i4_res_8x16b_r6, i4_res_8x16b_r7;
+ __m128i i4_res_8x16b_r7_temp, i4_c0_c1_16x8b, i4_c2_c3_16x8b;
+ i4_coeff_0 = (WORD8) (8 - i4_phase_0);
+ i4_coeff_1 = (WORD8) (i4_phase_0);
+ i4_coeff_2 = (WORD8) (8 - i4_phase_1);
+ i4_coeff_3 = (WORD8) (i4_phase_1);
+
+ i4_c0_c1_16x8b =
+ _mm_set_epi8(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0,
+ i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ i4_c2_c3_16x8b =
+ _mm_set_epi8(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2,
+ i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2);
+
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_filt_stride = 6;
+ i4_src_stride = DYADIC_REF_W_C;
+ pu1_inp = pu1_inp_buf;
+
+ i4_samp_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_inp));
+ i4_samp_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_inp + i4_src_stride));
+ i4_samp_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1)));
+ i4_samp_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 1) + i4_src_stride));
+ i4_samp_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_inp + (i4_src_stride << 2)));
+
+ i4_samp_16x8b_0 = _mm_unpacklo_epi8(i4_samp_16x8b_0, i4_samp_16x8b_1);
+ i4_res_8x16b_r0 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp), i4_res_8x16b_r0);
+
+ i4_res_8x16b_r1 = _mm_maddubs_epi16(i4_samp_16x8b_0, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + i4_filt_stride), i4_res_8x16b_r1);
+
+ i4_samp_16x8b_1 = _mm_unpacklo_epi8(i4_samp_16x8b_1, i4_samp_16x8b_2);
+ i4_res_8x16b_r2 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1)), i4_res_8x16b_r2);
+
+ i4_res_8x16b_r3 = _mm_maddubs_epi16(i4_samp_16x8b_1, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 1) + i4_filt_stride),
+ i4_res_8x16b_r3);
+
+ i4_samp_16x8b_2 = _mm_unpacklo_epi8(i4_samp_16x8b_2, i4_samp_16x8b_3);
+ i4_res_8x16b_r4 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c0_c1_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2)), i4_res_8x16b_r4);
+
+ i4_res_8x16b_r5 = _mm_maddubs_epi16(i4_samp_16x8b_2, i4_c2_c3_16x8b);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + i4_filt_stride),
+ i4_res_8x16b_r5);
+
+ i4_samp_16x8b_3 = _mm_unpacklo_epi8(i4_samp_16x8b_3, i4_samp_16x8b_4);
+ i4_res_8x16b_r6 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c0_c1_16x8b);
+ _mm_storel_epi64((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1)),
+ i4_res_8x16b_r6);
+
+ i4_res_8x16b_r7 = _mm_maddubs_epi16(i4_samp_16x8b_3, i4_c2_c3_16x8b);
+ i4_res_8x16b_r6 = _mm_shuffle_epi32(i4_res_8x16b_r6, 78);
+ i4_res_8x16b_r7 = _mm_shuffle_epi32(i4_res_8x16b_r7, 147);
+ i4_res_8x16b_r7_temp = _mm_blend_epi16(i4_res_8x16b_r6, i4_res_8x16b_r7, 252);
+ _mm_storeu_si128((__m128i *) (pi2_tmp + (i4_filt_stride << 2) + (i4_filt_stride << 1) + 4),
+ i4_res_8x16b_r7_temp);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_1_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_horz_interpol_chroma_dyadic_1_sse42(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_dst_stride, i4_dst_stride2, i4_dst_stride4;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ __m128i i4_samp_8x16b_r1_0, i4_samp_8x16b_r1_1, i4_samp_8x16b_r1_2;
+ __m128i i4_samp_8x16b_r2_0, i4_samp_8x16b_r2_1, i4_samp_8x16b_r2_2;
+ __m128i i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1, i4_samp_8x16b_r3_2;
+ __m128i i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1, i4_samp_8x16b_r4_2;
+ __m128i i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1, i4_samp_8x16b_r5_2;
+ __m128i i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1, i4_samp_8x16b_r6_2;
+ __m128i i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1, i4_samp_8x16b_r7_2;
+ __m128i i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1, i4_samp_8x16b_r8_2;
+
+ __m128i i4_res_4x32b_r1_0, i4_res_4x32b_r1_1;
+ __m128i i4_res_4x32b_r2_0, i4_res_4x32b_r2_1;
+ __m128i i4_res_4x32b_r3_0, i4_res_4x32b_r3_1;
+ __m128i i4_res_4x32b_r4_0, i4_res_4x32b_r4_1;
+ __m128i i4_res_4x32b_r5_0, i4_res_4x32b_r5_1;
+ __m128i i4_res_4x32b_r6_0, i4_res_4x32b_r6_1;
+ __m128i i4_res_4x32b_r7_0, i4_res_4x32b_r7_1;
+ __m128i i4_res_4x32b_r8_0, i4_res_4x32b_r8_1;
+
+ __m128i i4_res_final_8x16b_r1;
+ __m128i i4_res_final_8x16b_r2;
+ __m128i i4_res_final_8x16b_r3;
+ __m128i i4_res_final_8x16b_r4;
+ __m128i i4_res_final_8x16b_r5;
+ __m128i i4_res_final_8x16b_r6;
+ __m128i i4_res_final_8x16b_r7;
+ __m128i i4_res_final_8x16b_r8;
+
+ __m128i out_16x8b_r1;
+ __m128i out_16x8b_r2;
+ __m128i out_16x8b_r3;
+ __m128i out_16x8b_r4;
+ __m128i out_16x8b_r5;
+ __m128i out_16x8b_r6;
+ __m128i out_16x8b_r7;
+ __m128i out_16x8b_r8;
+ __m128i i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1;
+ __m128i i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1;
+ __m128i i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1;
+ __m128i i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1;
+ __m128i chroma_mask, chroma_mask2;
+ __m128i coeff_c0_c1_8x16b, coeff_c2_c3_8x16b, res_32;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+ coeff_c0_c1_8x16b = _mm_set_epi16(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1,
+ i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ coeff_c2_c3_8x16b = _mm_set_epi16(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3,
+ i4_coeff_2, i4_coeff_3, i4_coeff_2);
+ res_32 = _mm_set1_epi32(32);
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf;
+ i4_dst_stride = i4_out_stride;
+
+ i4_dst_stride2 = i4_dst_stride << 1;
+ i4_dst_stride4 = i4_dst_stride << 2;
+
+ /* Horizontal interpolation */
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_8x16b_r1_0 = _mm_loadu_si128((__m128i *) pi2_tmp); // a0 a1 a2 a3 a4 a5 a6 a7
+ i4_samp_8x16b_r2_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 6)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r3_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 12)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r4_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 18)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r5_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 24)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r6_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 30)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r7_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 36)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r8_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 42)); // b0 b1 b2 b3 b4 b5 b6 b7
+
+ i4_samp_8x16b_r1_1 = _mm_srli_si128(i4_samp_8x16b_r1_0, 2); // a1 a2 a3 a4 a5 a6 a7 0
+ i4_samp_8x16b_r1_2 = _mm_srli_si128(i4_samp_8x16b_r1_0, 4); // a2 a3 a4 a5 a6 a7 0 0
+
+ i4_samp_8x16b_r2_1 = _mm_srli_si128(i4_samp_8x16b_r2_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r2_2 = _mm_srli_si128(i4_samp_8x16b_r2_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r3_1 = _mm_srli_si128(i4_samp_8x16b_r3_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r3_2 = _mm_srli_si128(i4_samp_8x16b_r3_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r4_1 = _mm_srli_si128(i4_samp_8x16b_r4_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r4_2 = _mm_srli_si128(i4_samp_8x16b_r4_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r5_1 = _mm_srli_si128(i4_samp_8x16b_r5_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r5_2 = _mm_srli_si128(i4_samp_8x16b_r5_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r6_1 = _mm_srli_si128(i4_samp_8x16b_r6_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r6_2 = _mm_srli_si128(i4_samp_8x16b_r6_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r7_1 = _mm_srli_si128(i4_samp_8x16b_r7_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r7_2 = _mm_srli_si128(i4_samp_8x16b_r7_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r8_1 = _mm_srli_si128(i4_samp_8x16b_r8_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r8_2 = _mm_srli_si128(i4_samp_8x16b_r8_0, 4); // b2 b3 b4 b5 b6 b7 0 0
+
+ i4_samp_8x16b_r1_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r1_0,
+ i4_samp_8x16b_r1_1); // a0 a1 a1 a2 a2 a3 a3 a4
+ i4_samp_8x16b_r2_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r2_0,
+ i4_samp_8x16b_r2_1); // b0 b1 b1 b2 b2 b3 b3 b4
+ i4_samp_8x16b_r3_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1);
+ i4_samp_8x16b_r4_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1);
+ i4_samp_8x16b_r5_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1);
+ i4_samp_8x16b_r6_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1);
+ i4_samp_8x16b_r7_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1);
+ i4_samp_8x16b_r8_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1);
+
+ i4_samp_8x16b_r1_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r1_1,
+ i4_samp_8x16b_r1_2); // a1 a2 a2 a3 a3 a4 a4 a5
+ i4_samp_8x16b_r2_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r2_1,
+ i4_samp_8x16b_r2_2); // b1 b2 b2 b3 b3 b4 b4 b5
+ i4_samp_8x16b_r3_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r3_1, i4_samp_8x16b_r3_2);
+ i4_samp_8x16b_r4_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r4_1, i4_samp_8x16b_r4_2);
+ i4_samp_8x16b_r5_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r5_1, i4_samp_8x16b_r5_2);
+ i4_samp_8x16b_r6_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r6_1, i4_samp_8x16b_r6_2);
+ i4_samp_8x16b_r7_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r7_1, i4_samp_8x16b_r7_2);
+ i4_samp_8x16b_r8_1 = _mm_unpacklo_epi16(i4_samp_8x16b_r8_1, i4_samp_8x16b_r8_2);
+
+ // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_res_4x32b_r1_0 = _mm_madd_epi16(i4_samp_8x16b_r1_0, coeff_c0_c1_8x16b);
+ // b0c0+b1c1 b1c0+b2c1 b2c0+b3c1 b3c0+b4c1
+ i4_res_4x32b_r2_0 = _mm_madd_epi16(i4_samp_8x16b_r2_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r3_0 = _mm_madd_epi16(i4_samp_8x16b_r3_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r4_0 = _mm_madd_epi16(i4_samp_8x16b_r4_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r5_0 = _mm_madd_epi16(i4_samp_8x16b_r5_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r6_0 = _mm_madd_epi16(i4_samp_8x16b_r6_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r7_0 = _mm_madd_epi16(i4_samp_8x16b_r7_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r8_0 = _mm_madd_epi16(i4_samp_8x16b_r8_0, coeff_c0_c1_8x16b);
+
+ // a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3
+ i4_res_4x32b_r1_1 = _mm_madd_epi16(i4_samp_8x16b_r1_1, coeff_c2_c3_8x16b);
+ // b1c2+b2c3 b2c2+b3c3 b3c2+b4c3 b4c2+b5c3
+ i4_res_4x32b_r2_1 = _mm_madd_epi16(i4_samp_8x16b_r2_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r3_1 = _mm_madd_epi16(i4_samp_8x16b_r3_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r4_1 = _mm_madd_epi16(i4_samp_8x16b_r4_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r5_1 = _mm_madd_epi16(i4_samp_8x16b_r5_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r6_1 = _mm_madd_epi16(i4_samp_8x16b_r6_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r7_1 = _mm_madd_epi16(i4_samp_8x16b_r7_1, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r8_1 = _mm_madd_epi16(i4_samp_8x16b_r8_1, coeff_c2_c3_8x16b);
+
+ i4_res_4x32b_r1_0 = _mm_add_epi32(i4_res_4x32b_r1_0, res_32);
+ i4_res_4x32b_r2_0 = _mm_add_epi32(i4_res_4x32b_r2_0, res_32);
+ i4_res_4x32b_r3_0 = _mm_add_epi32(i4_res_4x32b_r3_0, res_32);
+ i4_res_4x32b_r4_0 = _mm_add_epi32(i4_res_4x32b_r4_0, res_32);
+ i4_res_4x32b_r5_0 = _mm_add_epi32(i4_res_4x32b_r5_0, res_32);
+ i4_res_4x32b_r6_0 = _mm_add_epi32(i4_res_4x32b_r6_0, res_32);
+ i4_res_4x32b_r7_0 = _mm_add_epi32(i4_res_4x32b_r7_0, res_32);
+ i4_res_4x32b_r8_0 = _mm_add_epi32(i4_res_4x32b_r8_0, res_32);
+
+ i4_res_4x32b_r1_1 = _mm_add_epi32(i4_res_4x32b_r1_1, res_32);
+ i4_res_4x32b_r2_1 = _mm_add_epi32(i4_res_4x32b_r2_1, res_32);
+ i4_res_4x32b_r3_1 = _mm_add_epi32(i4_res_4x32b_r3_1, res_32);
+ i4_res_4x32b_r4_1 = _mm_add_epi32(i4_res_4x32b_r4_1, res_32);
+ i4_res_4x32b_r5_1 = _mm_add_epi32(i4_res_4x32b_r5_1, res_32);
+ i4_res_4x32b_r6_1 = _mm_add_epi32(i4_res_4x32b_r6_1, res_32);
+ i4_res_4x32b_r7_1 = _mm_add_epi32(i4_res_4x32b_r7_1, res_32);
+ i4_res_4x32b_r8_1 = _mm_add_epi32(i4_res_4x32b_r8_1, res_32);
+
+ i4_res_4x32b_r1_0 = _mm_srai_epi32(i4_res_4x32b_r1_0, 6);
+ i4_res_4x32b_r2_0 = _mm_srai_epi32(i4_res_4x32b_r2_0, 6);
+ i4_res_4x32b_r3_0 = _mm_srai_epi32(i4_res_4x32b_r3_0, 6);
+ i4_res_4x32b_r4_0 = _mm_srai_epi32(i4_res_4x32b_r4_0, 6);
+ i4_res_4x32b_r5_0 = _mm_srai_epi32(i4_res_4x32b_r5_0, 6);
+ i4_res_4x32b_r6_0 = _mm_srai_epi32(i4_res_4x32b_r6_0, 6);
+ i4_res_4x32b_r7_0 = _mm_srai_epi32(i4_res_4x32b_r7_0, 6);
+ i4_res_4x32b_r8_0 = _mm_srai_epi32(i4_res_4x32b_r8_0, 6);
+
+ i4_res_4x32b_r1_1 = _mm_srai_epi32(i4_res_4x32b_r1_1, 6);
+ i4_res_4x32b_r2_1 = _mm_srai_epi32(i4_res_4x32b_r2_1, 6);
+ i4_res_4x32b_r3_1 = _mm_srai_epi32(i4_res_4x32b_r3_1, 6);
+ i4_res_4x32b_r4_1 = _mm_srai_epi32(i4_res_4x32b_r4_1, 6);
+ i4_res_4x32b_r5_1 = _mm_srai_epi32(i4_res_4x32b_r5_1, 6);
+ i4_res_4x32b_r6_1 = _mm_srai_epi32(i4_res_4x32b_r6_1, 6);
+ i4_res_4x32b_r7_1 = _mm_srai_epi32(i4_res_4x32b_r7_1, 6);
+ i4_res_4x32b_r8_1 = _mm_srai_epi32(i4_res_4x32b_r8_1, 6);
+
+ i4_res_final_8x16b_r12_0 = _mm_packs_epi32(i4_res_4x32b_r1_0, i4_res_4x32b_r2_0);
+ i4_res_final_8x16b_r34_0 = _mm_packs_epi32(i4_res_4x32b_r3_0, i4_res_4x32b_r4_0);
+ i4_res_final_8x16b_r56_0 = _mm_packs_epi32(i4_res_4x32b_r5_0, i4_res_4x32b_r6_0);
+ i4_res_final_8x16b_r67_0 = _mm_packs_epi32(i4_res_4x32b_r7_0, i4_res_4x32b_r8_0);
+
+ i4_res_final_8x16b_r12_1 = _mm_packs_epi32(i4_res_4x32b_r1_1, i4_res_4x32b_r2_1);
+ i4_res_final_8x16b_r34_1 = _mm_packs_epi32(i4_res_4x32b_r3_1, i4_res_4x32b_r4_1);
+ i4_res_final_8x16b_r56_1 = _mm_packs_epi32(i4_res_4x32b_r5_1, i4_res_4x32b_r6_1);
+ i4_res_final_8x16b_r67_1 = _mm_packs_epi32(i4_res_4x32b_r7_1, i4_res_4x32b_r8_1);
+
+ i4_res_final_8x16b_r1 = _mm_unpacklo_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r2 = _mm_unpackhi_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r3 = _mm_unpacklo_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r4 = _mm_unpackhi_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r5 = _mm_unpacklo_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r6 = _mm_unpackhi_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r7 = _mm_unpacklo_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+ i4_res_final_8x16b_r8 = _mm_unpackhi_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ chroma_mask2 = _mm_set1_epi16(0x00FF);
+ out_16x8b_r1 = _mm_loadu_si128((__m128i *) (&pu1_out[0]));
+ out_16x8b_r2 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride]));
+ out_16x8b_r3 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2]));
+ out_16x8b_r4 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2 + i4_dst_stride]));
+ out_16x8b_r5 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4]));
+ out_16x8b_r6 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride]));
+ out_16x8b_r7 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2]));
+ out_16x8b_r8 =
+ _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2 + i4_dst_stride]));
+
+ out_16x8b_r1 = _mm_and_si128(out_16x8b_r1, chroma_mask);
+ out_16x8b_r2 = _mm_and_si128(out_16x8b_r2, chroma_mask);
+ out_16x8b_r3 = _mm_and_si128(out_16x8b_r3, chroma_mask);
+ out_16x8b_r4 = _mm_and_si128(out_16x8b_r4, chroma_mask);
+ out_16x8b_r5 = _mm_and_si128(out_16x8b_r5, chroma_mask);
+ out_16x8b_r6 = _mm_and_si128(out_16x8b_r6, chroma_mask);
+ out_16x8b_r7 = _mm_and_si128(out_16x8b_r7, chroma_mask);
+ out_16x8b_r8 = _mm_and_si128(out_16x8b_r8, chroma_mask);
+
+ i4_res_final_8x16b_r1 = _mm_and_si128(i4_res_final_8x16b_r1, chroma_mask2);
+ i4_res_final_8x16b_r2 = _mm_and_si128(i4_res_final_8x16b_r2, chroma_mask2);
+ i4_res_final_8x16b_r3 = _mm_and_si128(i4_res_final_8x16b_r3, chroma_mask2);
+ i4_res_final_8x16b_r4 = _mm_and_si128(i4_res_final_8x16b_r4, chroma_mask2);
+ i4_res_final_8x16b_r5 = _mm_and_si128(i4_res_final_8x16b_r5, chroma_mask2);
+ i4_res_final_8x16b_r6 = _mm_and_si128(i4_res_final_8x16b_r6, chroma_mask2);
+ i4_res_final_8x16b_r7 = _mm_and_si128(i4_res_final_8x16b_r7, chroma_mask2);
+ i4_res_final_8x16b_r8 = _mm_and_si128(i4_res_final_8x16b_r8, chroma_mask2);
+
+ out_16x8b_r1 = _mm_add_epi8(i4_res_final_8x16b_r1, out_16x8b_r1);
+ out_16x8b_r2 = _mm_add_epi8(i4_res_final_8x16b_r2, out_16x8b_r2);
+ out_16x8b_r3 = _mm_add_epi8(i4_res_final_8x16b_r3, out_16x8b_r3);
+ out_16x8b_r4 = _mm_add_epi8(i4_res_final_8x16b_r4, out_16x8b_r4);
+ out_16x8b_r5 = _mm_add_epi8(i4_res_final_8x16b_r5, out_16x8b_r5);
+ out_16x8b_r6 = _mm_add_epi8(i4_res_final_8x16b_r6, out_16x8b_r6);
+ out_16x8b_r7 = _mm_add_epi8(i4_res_final_8x16b_r7, out_16x8b_r7);
+ out_16x8b_r8 = _mm_add_epi8(i4_res_final_8x16b_r8, out_16x8b_r8);
+
+ _mm_storeu_si128((__m128i *) pu1_out, out_16x8b_r1);
+ _mm_storeu_si128((__m128i *) (pu1_out + i4_dst_stride), out_16x8b_r2);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride << 1)), out_16x8b_r3);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 3)), out_16x8b_r4);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride << 2)), out_16x8b_r5);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 5)), out_16x8b_r6);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 6)), out_16x8b_r7);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 7)), out_16x8b_r8);
+ /* End of loop over x */
+} /* isvcd_horz_interpol_chroma_dyadic_1_sse42 */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_horz_interpol_chroma_dyadic_2_sse42 */
+/* */
+/* Description : This function takes the reference array buffer & performs*/
+/* vertical intra resampling for dyadic scaling ratios for */
+/* chroma for the following ref_lyr_chroma_phase_y_plus1 and*/
+/* chroma_phase_y_plus1: */
+/* ref_lyr cur_lyr */
+/* 2 0 */
+/* Inputs : pu1_inp_buf : ptr to the 6x6 reference sample buffer */
+/* pi2_tmp_filt_buf : ptr to the 6x8 buffer to hold the */
+/* vertically interpolated data */
+/* i4_phase_0 : y phase for even values of y */
+/* i4_phase_1 : y phase for odd values of y */
+/* Globals : none */
+/* Processing : it does the interpolation in vertical direction */
+/* Outputs : vertically resampled samples */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 21 05 2021 Dolan creation */
+/* */
+/*****************************************************************************/
+void isvcd_horz_interpol_chroma_dyadic_2_sse42(WORD16 *pi2_tmp_filt_buf, UWORD8 *pu1_out_buf,
+ WORD32 i4_out_stride, WORD32 i4_phase_0,
+ WORD32 i4_phase_1)
+{
+ WORD32 i4_coeff_0, i4_coeff_1, i4_coeff_2, i4_coeff_3;
+ WORD32 i4_dst_stride, i4_dst_stride2, i4_dst_stride4;
+ UWORD8 *pu1_out;
+ WORD16 *pi2_tmp;
+
+ __m128i i4_samp_8x16b_r1_0, i4_samp_8x16b_r1_1;
+ __m128i i4_samp_8x16b_r2_0, i4_samp_8x16b_r2_1;
+ __m128i i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1;
+ __m128i i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1;
+ __m128i i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1;
+ __m128i i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1;
+ __m128i i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1;
+ __m128i i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1;
+
+ __m128i i4_res_4x32b_r1_0, i4_res_4x32b_r1_1;
+ __m128i i4_res_4x32b_r2_0, i4_res_4x32b_r2_1;
+ __m128i i4_res_4x32b_r3_0, i4_res_4x32b_r3_1;
+ __m128i i4_res_4x32b_r4_0, i4_res_4x32b_r4_1;
+ __m128i i4_res_4x32b_r5_0, i4_res_4x32b_r5_1;
+ __m128i i4_res_4x32b_r6_0, i4_res_4x32b_r6_1;
+ __m128i i4_res_4x32b_r7_0, i4_res_4x32b_r7_1;
+ __m128i i4_res_4x32b_r8_0, i4_res_4x32b_r8_1;
+
+ __m128i i4_res_final_8x16b_r1;
+ __m128i i4_res_final_8x16b_r2;
+ __m128i i4_res_final_8x16b_r3;
+ __m128i i4_res_final_8x16b_r4;
+ __m128i i4_res_final_8x16b_r5;
+ __m128i i4_res_final_8x16b_r6;
+ __m128i i4_res_final_8x16b_r7;
+ __m128i i4_res_final_8x16b_r8;
+
+ __m128i out_16x8b_r1;
+ __m128i out_16x8b_r2;
+ __m128i out_16x8b_r3;
+ __m128i out_16x8b_r4;
+ __m128i out_16x8b_r5;
+ __m128i out_16x8b_r6;
+ __m128i out_16x8b_r7;
+ __m128i out_16x8b_r8;
+ __m128i i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1;
+ __m128i i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1;
+ __m128i i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1;
+ __m128i i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1;
+ __m128i chroma_mask, chroma_mask2;
+ __m128i coeff_c0_c1_8x16b, coeff_c2_c3_8x16b, res_32;
+
+ i4_coeff_0 = 8 - i4_phase_0;
+ i4_coeff_1 = i4_phase_0;
+ i4_coeff_2 = 8 - i4_phase_1;
+ i4_coeff_3 = i4_phase_1;
+ coeff_c0_c1_8x16b = _mm_set_epi16(i4_coeff_1, i4_coeff_0, i4_coeff_1, i4_coeff_0, i4_coeff_1,
+ i4_coeff_0, i4_coeff_1, i4_coeff_0);
+ coeff_c2_c3_8x16b = _mm_set_epi16(i4_coeff_3, i4_coeff_2, i4_coeff_3, i4_coeff_2, i4_coeff_3,
+ i4_coeff_2, i4_coeff_3, i4_coeff_2);
+ res_32 = _mm_set1_epi32(32);
+ pu1_out = pu1_out_buf;
+ pi2_tmp = pi2_tmp_filt_buf + 1;
+ i4_dst_stride = i4_out_stride;
+
+ i4_dst_stride2 = i4_dst_stride << 1;
+ i4_dst_stride4 = i4_dst_stride << 2;
+
+ /* Horizontal interpolation */
+ /* x = 0, x_phase = phase_0 */
+ i4_samp_8x16b_r1_0 = _mm_loadu_si128((__m128i *) pi2_tmp); // a0 a1 a2 a3 a4 a5 a6 a7
+ i4_samp_8x16b_r2_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 6)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r3_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 12)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r4_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 18)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r5_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 24)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r6_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 30)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r7_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 36)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i4_samp_8x16b_r8_0 = _mm_loadu_si128((__m128i *) (pi2_tmp + 42)); // b0 b1 b2 b3 b4 b5 b6 b7
+
+ i4_samp_8x16b_r1_1 = _mm_srli_si128(i4_samp_8x16b_r1_0, 2); // a1 a2 a3 a4 a5 a6 a7 0
+ i4_samp_8x16b_r2_1 = _mm_srli_si128(i4_samp_8x16b_r2_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r3_1 = _mm_srli_si128(i4_samp_8x16b_r3_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r4_1 = _mm_srli_si128(i4_samp_8x16b_r4_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r5_1 = _mm_srli_si128(i4_samp_8x16b_r5_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r6_1 = _mm_srli_si128(i4_samp_8x16b_r6_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r7_1 = _mm_srli_si128(i4_samp_8x16b_r7_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i4_samp_8x16b_r8_1 = _mm_srli_si128(i4_samp_8x16b_r8_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+
+ i4_samp_8x16b_r1_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r1_0,
+ i4_samp_8x16b_r1_1); // a0 a1 a1 a2 a2 a3 a3 a4
+ i4_samp_8x16b_r2_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r2_0,
+ i4_samp_8x16b_r2_1); // b0 b1 b1 b2 b2 b3 b3 b4
+ i4_samp_8x16b_r3_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r3_0, i4_samp_8x16b_r3_1);
+ i4_samp_8x16b_r4_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r4_0, i4_samp_8x16b_r4_1);
+ i4_samp_8x16b_r5_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r5_0, i4_samp_8x16b_r5_1);
+ i4_samp_8x16b_r6_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r6_0, i4_samp_8x16b_r6_1);
+ i4_samp_8x16b_r7_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r7_0, i4_samp_8x16b_r7_1);
+ i4_samp_8x16b_r8_0 = _mm_unpacklo_epi16(i4_samp_8x16b_r8_0, i4_samp_8x16b_r8_1);
+
+ // a0c0+a1c1 a1c0+a2c1 a2c0+a3c1 a3c0+a4c1
+ i4_res_4x32b_r1_0 = _mm_madd_epi16(i4_samp_8x16b_r1_0, coeff_c0_c1_8x16b);
+ // b0c0+b1c1 b1c0+b2c1 b2c0+b3c1 b3c0+b4c1
+ i4_res_4x32b_r2_0 = _mm_madd_epi16(i4_samp_8x16b_r2_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r3_0 = _mm_madd_epi16(i4_samp_8x16b_r3_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r4_0 = _mm_madd_epi16(i4_samp_8x16b_r4_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r5_0 = _mm_madd_epi16(i4_samp_8x16b_r5_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r6_0 = _mm_madd_epi16(i4_samp_8x16b_r6_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r7_0 = _mm_madd_epi16(i4_samp_8x16b_r7_0, coeff_c0_c1_8x16b);
+ i4_res_4x32b_r8_0 = _mm_madd_epi16(i4_samp_8x16b_r8_0, coeff_c0_c1_8x16b);
+
+ // a1c2+a2c3 a2c2+a3c3 a3c2+a4c3 a4c2+a5c3
+ i4_res_4x32b_r1_1 = _mm_madd_epi16(i4_samp_8x16b_r1_0, coeff_c2_c3_8x16b);
+ // b1c2+b2c3 b2c2+b3c3 b3c2+b4c3 b4c2+b5c3
+ i4_res_4x32b_r2_1 = _mm_madd_epi16(i4_samp_8x16b_r2_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r3_1 = _mm_madd_epi16(i4_samp_8x16b_r3_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r4_1 = _mm_madd_epi16(i4_samp_8x16b_r4_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r5_1 = _mm_madd_epi16(i4_samp_8x16b_r5_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r6_1 = _mm_madd_epi16(i4_samp_8x16b_r6_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r7_1 = _mm_madd_epi16(i4_samp_8x16b_r7_0, coeff_c2_c3_8x16b);
+ i4_res_4x32b_r8_1 = _mm_madd_epi16(i4_samp_8x16b_r8_0, coeff_c2_c3_8x16b);
+
+ i4_res_4x32b_r1_0 = _mm_add_epi32(i4_res_4x32b_r1_0, res_32);
+ i4_res_4x32b_r2_0 = _mm_add_epi32(i4_res_4x32b_r2_0, res_32);
+ i4_res_4x32b_r3_0 = _mm_add_epi32(i4_res_4x32b_r3_0, res_32);
+ i4_res_4x32b_r4_0 = _mm_add_epi32(i4_res_4x32b_r4_0, res_32);
+ i4_res_4x32b_r5_0 = _mm_add_epi32(i4_res_4x32b_r5_0, res_32);
+ i4_res_4x32b_r6_0 = _mm_add_epi32(i4_res_4x32b_r6_0, res_32);
+ i4_res_4x32b_r7_0 = _mm_add_epi32(i4_res_4x32b_r7_0, res_32);
+ i4_res_4x32b_r8_0 = _mm_add_epi32(i4_res_4x32b_r8_0, res_32);
+
+ i4_res_4x32b_r1_1 = _mm_add_epi32(i4_res_4x32b_r1_1, res_32);
+ i4_res_4x32b_r2_1 = _mm_add_epi32(i4_res_4x32b_r2_1, res_32);
+ i4_res_4x32b_r3_1 = _mm_add_epi32(i4_res_4x32b_r3_1, res_32);
+ i4_res_4x32b_r4_1 = _mm_add_epi32(i4_res_4x32b_r4_1, res_32);
+ i4_res_4x32b_r5_1 = _mm_add_epi32(i4_res_4x32b_r5_1, res_32);
+ i4_res_4x32b_r6_1 = _mm_add_epi32(i4_res_4x32b_r6_1, res_32);
+ i4_res_4x32b_r7_1 = _mm_add_epi32(i4_res_4x32b_r7_1, res_32);
+ i4_res_4x32b_r8_1 = _mm_add_epi32(i4_res_4x32b_r8_1, res_32);
+
+ i4_res_4x32b_r1_0 = _mm_srai_epi32(i4_res_4x32b_r1_0, 6);
+ i4_res_4x32b_r2_0 = _mm_srai_epi32(i4_res_4x32b_r2_0, 6);
+ i4_res_4x32b_r3_0 = _mm_srai_epi32(i4_res_4x32b_r3_0, 6);
+ i4_res_4x32b_r4_0 = _mm_srai_epi32(i4_res_4x32b_r4_0, 6);
+ i4_res_4x32b_r5_0 = _mm_srai_epi32(i4_res_4x32b_r5_0, 6);
+ i4_res_4x32b_r6_0 = _mm_srai_epi32(i4_res_4x32b_r6_0, 6);
+ i4_res_4x32b_r7_0 = _mm_srai_epi32(i4_res_4x32b_r7_0, 6);
+ i4_res_4x32b_r8_0 = _mm_srai_epi32(i4_res_4x32b_r8_0, 6);
+
+ i4_res_4x32b_r1_1 = _mm_srai_epi32(i4_res_4x32b_r1_1, 6);
+ i4_res_4x32b_r2_1 = _mm_srai_epi32(i4_res_4x32b_r2_1, 6);
+ i4_res_4x32b_r3_1 = _mm_srai_epi32(i4_res_4x32b_r3_1, 6);
+ i4_res_4x32b_r4_1 = _mm_srai_epi32(i4_res_4x32b_r4_1, 6);
+ i4_res_4x32b_r5_1 = _mm_srai_epi32(i4_res_4x32b_r5_1, 6);
+ i4_res_4x32b_r6_1 = _mm_srai_epi32(i4_res_4x32b_r6_1, 6);
+ i4_res_4x32b_r7_1 = _mm_srai_epi32(i4_res_4x32b_r7_1, 6);
+ i4_res_4x32b_r8_1 = _mm_srai_epi32(i4_res_4x32b_r8_1, 6);
+
+ i4_res_final_8x16b_r12_0 = _mm_packs_epi32(i4_res_4x32b_r1_0, i4_res_4x32b_r2_0);
+ i4_res_final_8x16b_r34_0 = _mm_packs_epi32(i4_res_4x32b_r3_0, i4_res_4x32b_r4_0);
+ i4_res_final_8x16b_r56_0 = _mm_packs_epi32(i4_res_4x32b_r5_0, i4_res_4x32b_r6_0);
+ i4_res_final_8x16b_r67_0 = _mm_packs_epi32(i4_res_4x32b_r7_0, i4_res_4x32b_r8_0);
+
+ i4_res_final_8x16b_r12_1 = _mm_packs_epi32(i4_res_4x32b_r1_1, i4_res_4x32b_r2_1);
+ i4_res_final_8x16b_r34_1 = _mm_packs_epi32(i4_res_4x32b_r3_1, i4_res_4x32b_r4_1);
+ i4_res_final_8x16b_r56_1 = _mm_packs_epi32(i4_res_4x32b_r5_1, i4_res_4x32b_r6_1);
+ i4_res_final_8x16b_r67_1 = _mm_packs_epi32(i4_res_4x32b_r7_1, i4_res_4x32b_r8_1);
+
+ i4_res_final_8x16b_r1 = _mm_unpacklo_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r2 = _mm_unpackhi_epi16(i4_res_final_8x16b_r12_0, i4_res_final_8x16b_r12_1);
+ i4_res_final_8x16b_r3 = _mm_unpacklo_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r4 = _mm_unpackhi_epi16(i4_res_final_8x16b_r34_0, i4_res_final_8x16b_r34_1);
+ i4_res_final_8x16b_r5 = _mm_unpacklo_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r6 = _mm_unpackhi_epi16(i4_res_final_8x16b_r56_0, i4_res_final_8x16b_r56_1);
+ i4_res_final_8x16b_r7 = _mm_unpacklo_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+ i4_res_final_8x16b_r8 = _mm_unpackhi_epi16(i4_res_final_8x16b_r67_0, i4_res_final_8x16b_r67_1);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ chroma_mask2 = _mm_set1_epi16(0x00FF);
+ out_16x8b_r1 = _mm_loadu_si128((__m128i *) (&pu1_out[0]));
+ out_16x8b_r2 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride]));
+ out_16x8b_r3 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2]));
+ out_16x8b_r4 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride2 + i4_dst_stride]));
+ out_16x8b_r5 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4]));
+ out_16x8b_r6 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride]));
+ out_16x8b_r7 = _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2]));
+ out_16x8b_r8 =
+ _mm_loadu_si128((__m128i *) (&pu1_out[i4_dst_stride4 + i4_dst_stride2 + i4_dst_stride]));
+
+ out_16x8b_r1 = _mm_and_si128(out_16x8b_r1, chroma_mask);
+ out_16x8b_r2 = _mm_and_si128(out_16x8b_r2, chroma_mask);
+ out_16x8b_r3 = _mm_and_si128(out_16x8b_r3, chroma_mask);
+ out_16x8b_r4 = _mm_and_si128(out_16x8b_r4, chroma_mask);
+ out_16x8b_r5 = _mm_and_si128(out_16x8b_r5, chroma_mask);
+ out_16x8b_r6 = _mm_and_si128(out_16x8b_r6, chroma_mask);
+ out_16x8b_r7 = _mm_and_si128(out_16x8b_r7, chroma_mask);
+ out_16x8b_r8 = _mm_and_si128(out_16x8b_r8, chroma_mask);
+
+ i4_res_final_8x16b_r1 = _mm_and_si128(i4_res_final_8x16b_r1, chroma_mask2);
+ i4_res_final_8x16b_r2 = _mm_and_si128(i4_res_final_8x16b_r2, chroma_mask2);
+ i4_res_final_8x16b_r3 = _mm_and_si128(i4_res_final_8x16b_r3, chroma_mask2);
+ i4_res_final_8x16b_r4 = _mm_and_si128(i4_res_final_8x16b_r4, chroma_mask2);
+ i4_res_final_8x16b_r5 = _mm_and_si128(i4_res_final_8x16b_r5, chroma_mask2);
+ i4_res_final_8x16b_r6 = _mm_and_si128(i4_res_final_8x16b_r6, chroma_mask2);
+ i4_res_final_8x16b_r7 = _mm_and_si128(i4_res_final_8x16b_r7, chroma_mask2);
+ i4_res_final_8x16b_r8 = _mm_and_si128(i4_res_final_8x16b_r8, chroma_mask2);
+
+ out_16x8b_r1 = _mm_add_epi8(i4_res_final_8x16b_r1, out_16x8b_r1);
+ out_16x8b_r2 = _mm_add_epi8(i4_res_final_8x16b_r2, out_16x8b_r2);
+ out_16x8b_r3 = _mm_add_epi8(i4_res_final_8x16b_r3, out_16x8b_r3);
+ out_16x8b_r4 = _mm_add_epi8(i4_res_final_8x16b_r4, out_16x8b_r4);
+ out_16x8b_r5 = _mm_add_epi8(i4_res_final_8x16b_r5, out_16x8b_r5);
+ out_16x8b_r6 = _mm_add_epi8(i4_res_final_8x16b_r6, out_16x8b_r6);
+ out_16x8b_r7 = _mm_add_epi8(i4_res_final_8x16b_r7, out_16x8b_r7);
+ out_16x8b_r8 = _mm_add_epi8(i4_res_final_8x16b_r8, out_16x8b_r8);
+
+ _mm_storeu_si128((__m128i *) pu1_out, out_16x8b_r1);
+ _mm_storeu_si128((__m128i *) (pu1_out + i4_dst_stride), out_16x8b_r2);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride << 1)), out_16x8b_r3);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 3)), out_16x8b_r4);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride << 2)), out_16x8b_r5);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 5)), out_16x8b_r6);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 6)), out_16x8b_r7);
+ _mm_storeu_si128((__m128i *) (pu1_out + (i4_dst_stride * 7)), out_16x8b_r8);
+
+ /* End of loop over x */
+}
diff --git a/decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c b/decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c
new file mode 100644
index 0000000..6573190
--- /dev/null
+++ b/decoder/x86/svc/isvcd_iquant_itrans_residual_recon_sse42.c
@@ -0,0 +1,1879 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_recon_sse42.c
+ *
+ * @brief
+ * Contains function definitions for iquant_itrans_residual_recon
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_residual_recon_4x4_sse42()
+ * - isvcd_iquant_itrans_residual_recon_8x8_sse42()
+ * - isvcd_iquant_itrans_residual_recon_4x4_dc_sse42()
+ * - isvcd_iquant_itrans_residual_recon_8x8_dc_sse42()
+ * - isvcd_iquant_itrans_residual_recon_chroma_4x4_sse42()
+ * - isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_sse42()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+/* User include files */
+#include <immintrin.h>
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0;
+ WORD32 row_0, row_1, row_2, row_3;
+ UWORD32 *pu4_out = (UWORD32 *) pu1_out;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i rsd_r0, rsd_r1, rsd_r2, rsd_r3;
+ __m128i sign_reg, dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 --the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_ld_addr[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ // Load pred buffer
+ // p00 p01 p02 p03 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ // p10 p11 p12 p13 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[pred_strd]));
+ // p20 p21 p22 p23 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * pred_strd]));
+ // p30 p31 p32 p33 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * pred_strd]));
+
+ pred_r0 = _mm_cvtepu8_epi32(pred_r0); // p00 p01 p02 p03 -- all 32 bits
+ pred_r1 = _mm_cvtepu8_epi32(pred_r1); // p10 p11 p12 p13 -- all 32 bits
+ pred_r2 = _mm_cvtepu8_epi32(pred_r2); // p20 p21 p22 p23 -- all 32 bits
+ pred_r3 = _mm_cvtepu8_epi32(pred_r3); // p30 p31 p32 p33 -- all 32 bits
+
+ // Load resd buffer
+ rsd_r0 = _mm_loadl_epi64((__m128i *) (&pi2_rsd[0]));
+ rsd_r1 = _mm_loadl_epi64((__m128i *) (&pi2_rsd[rsd_strd]));
+ rsd_r2 = _mm_loadl_epi64((__m128i *) (&pi2_rsd[2 * rsd_strd]));
+ rsd_r3 = _mm_loadl_epi64((__m128i *) (&pi2_rsd[3 * rsd_strd]));
+
+ rsd_r0 = _mm_cvtepi16_epi32(rsd_r0);
+ rsd_r1 = _mm_cvtepi16_epi32(rsd_r1);
+ rsd_r2 = _mm_cvtepi16_epi32(rsd_r2);
+ rsd_r3 = _mm_cvtepi16_epi32(rsd_r3);
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+
+ row_0 = _mm_test_all_ones(_mm_cmpeq_epi32(temp4, zero_8x16b)); // return 1 if all zeros, else 0
+ temp4 = _mm_add_epi32(temp4, rsd_r0);
+ temp4 = _mm_min_epi16(dupmax_8x16b, temp4);
+ temp4 = _mm_max_epi16(dupmin_8x16b, temp4);
+ temp4 = _mm_add_epi32(temp4, pred_r0);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+
+ row_1 = _mm_test_all_ones(_mm_cmpeq_epi32(temp5, zero_8x16b)); // return 1 if all zeros, else 0
+ temp5 = _mm_add_epi32(temp5, rsd_r1);
+ temp5 = _mm_min_epi16(dupmax_8x16b, temp5);
+ temp5 = _mm_max_epi16(dupmin_8x16b, temp5);
+ temp5 = _mm_add_epi32(temp5, pred_r1);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+
+ row_2 = _mm_test_all_ones(_mm_cmpeq_epi32(temp6, zero_8x16b)); // return 1 if all zeros, else 0
+ temp6 = _mm_add_epi32(temp6, rsd_r2);
+ temp6 = _mm_min_epi16(dupmax_8x16b, temp6);
+ temp6 = _mm_max_epi16(dupmin_8x16b, temp6);
+ temp6 = _mm_add_epi32(temp6, pred_r2);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+
+ row_3 = _mm_test_all_ones(_mm_cmpeq_epi32(temp7, zero_8x16b)); // return 1 if all zeros, else 0
+ temp7 = _mm_add_epi32(temp7, rsd_r3);
+ temp7 = _mm_min_epi16(dupmax_8x16b, temp7);
+ temp7 = _mm_max_epi16(dupmin_8x16b, temp7);
+ temp7 = _mm_add_epi32(temp7, pred_r3);
+
+ // 32-bit to 16-bit conversion
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp0, zero_8x16b); // sign check
+ temp0 = _mm_and_si128(temp0, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b);
+ temp1 = _mm_and_si128(temp1, sign_reg);
+
+ resq_r0 = _mm_packus_epi16(temp0, temp1);
+ resq_r1 = _mm_srli_si128(resq_r0, 4);
+ resq_r2 = _mm_srli_si128(resq_r1, 4);
+ resq_r3 = _mm_srli_si128(resq_r2, 4);
+
+ *pu4_out = _mm_cvtsi128_si32(resq_r0);
+ pu1_out += out_strd;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r1);
+ pu1_out += out_strd;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r2);
+ pu1_out += out_strd;
+ pu4_out = (UWORD32 *) (pu1_out);
+ *(pu4_out) = _mm_cvtsi128_si32(resq_r3);
+
+ i4_nnz = !(row_0 && row_1 && row_2 && row_3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ __m128i rsd_r01_b0, rsd_r23_b0, rsd_r45_b2, rsd_r67_b2;
+ __m128i rsd_r01_b1, rsd_r23_b1, rsd_r45_b3, rsd_r67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+ __m128i src_r0;
+ __m128i scalemat_r0;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i add_rshift = _mm_set1_epi32((qp_div < 6) ? (1 << (5 - qp_div)) : 0);
+ __m128i dequant_r0;
+ __m128i predload_r;
+ __m128i pred_r0_1, pred_r1_1, pred_r2_1, pred_r3_1, pred_r4_1, pred_r5_1, pred_r6_1, pred_r7_1;
+
+ __m128i rsd_r0, rsd_r1, rsd_r2, rsd_r3, rsd_r4, rsd_r5, rsd_r6, rsd_r7;
+ __m128i sign_reg;
+ __m128i src_r0_1, src_r0_2;
+ __m128i scalemat_r0_1, scalemat_r0_2;
+ __m128i temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+ __m128i temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp20;
+ // To store dequantization results
+ __m128i resq_r0_1, resq_r0_2, resq_r1_1, resq_r1_2, resq_r2_1, resq_r2_2, resq_r3_1, resq_r3_2,
+ resq_r4_1, resq_r4_2, resq_r5_1, resq_r5_2, resq_r6_1, resq_r6_2, resq_r7_1, resq_r7_2;
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+
+ // Row 0 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 -- the source matrix 0th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // b00 b01 b02 b03 b04 b05 b06 b07 -- the scaling matrix 0th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[0]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+
+ if(qp_div >= 6)
+ {
+ resq_r0_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r0_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r0_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16
+ // bit long
+ resq_r0_1 = _mm_packs_epi32(resq_r0_1, resq_r0_2);
+ // Row 1 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 1st row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 1st row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 8));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[8]));
+ // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b);
+ // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b);
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r1_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r1_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r1_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r1_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16
+ // bit long
+ resq_r1_1 = _mm_packs_epi32(resq_r1_1, resq_r1_2);
+ // Row 2 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 2nd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 16));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 2nd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 16));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[16]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r2_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r2_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r2_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r2_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 -- 16 bit long
+ resq_r2_1 = _mm_packs_epi32(resq_r2_1, resq_r2_2);
+ // Row 3 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 3rd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 24));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 3rd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 24));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[24]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 - 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r3_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r3_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r3_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r3_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 .... -- 16 bit long
+ resq_r3_1 = _mm_packs_epi32(resq_r3_1, resq_r3_2);
+ // Row 4 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 4th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 32));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 4th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 32));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[32]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r4_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r4_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r4_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r4_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 -- 16 bit long
+ resq_r4_1 = _mm_packs_epi32(resq_r4_1, resq_r4_2);
+ // Row 5 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 5th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 40));
+ //
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 5th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 40));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[40]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r5_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r5_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r5_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r5_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 -- 16 bit long
+ resq_r5_1 = _mm_packs_epi32(resq_r5_1, resq_r5_2);
+ // Row 6 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 6th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 48));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 6th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 48));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[48]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r6_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r6_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r6_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r6_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 -- 16 bit long
+ resq_r6_1 = _mm_packs_epi32(resq_r6_1, resq_r6_2);
+ // Row 7 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 7th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 56));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 7th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 56));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[56]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r7_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r7_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r7_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r7_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 -- 16 bit long
+ resq_r7_1 = _mm_packs_epi32(resq_r7_1, resq_r7_2);
+
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3 a4 a5 a6 a7
+ * b0 b1 b2 b3 b4 b5 b6 b7
+ * c0 c1 c2 c3 c4 c5 c6 c7
+ * d0 d1 d2 d3 d4 d5 d6 d7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r0_1, resq_r1_1); // a0 b0 a1 b1 a2 b2 a3 b3
+ temp3 = _mm_unpacklo_epi16(resq_r2_1, resq_r3_1); // c0 d0 c1 d1 c2 d2 c3 d3
+ temp2 = _mm_unpackhi_epi16(resq_r0_1, resq_r1_1); // a4 b4 a5 b5 a6 b6 a7 b7
+ temp4 = _mm_unpackhi_epi16(resq_r2_1, resq_r3_1); // c4 d4 c5 d5 c6 d6 c7 d7
+ resq_r0_1 = _mm_unpacklo_epi32(temp1, temp3); // a0 b0 c0 d0 a1 b1 c1 d1
+ resq_r1_1 = _mm_unpackhi_epi32(temp1, temp3); // a2 b2 c2 d2 a3 b3 c3 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp2, temp4); // a4 b4 c4 d4 a5 b5 c5 d5
+ resq_r3_1 = _mm_unpackhi_epi32(temp2, temp4); // a6 b6 c6 d6 a7 b7 c7 d7
+ /*
+ * e0 e1 e2 e3 e4 e5 e6 e7
+ * f0 f1 f2 f3 f4 f5 f6 f7
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * h0 h1 h2 h3 h4 h5 h6 h7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r4_1, resq_r5_1); // e0 f0 e1 f1 e2 f2 e2 f3
+ temp3 = _mm_unpacklo_epi16(resq_r6_1, resq_r7_1); // g0 h0 g1 h1 g2 h2 g3 h3
+ temp2 = _mm_unpackhi_epi16(resq_r4_1, resq_r5_1); // e4 f4 e5 f5 e6 f6 e7 f7
+ temp4 = _mm_unpackhi_epi16(resq_r6_1, resq_r7_1); // g4 h4 g5 h5 g6 h6 g7 h7
+ resq_r4_1 = _mm_unpacklo_epi32(temp1, temp3); // e0 f0 g0 h0 e1 f1 g1 h1
+ resq_r5_1 = _mm_unpackhi_epi32(temp1, temp3); // e2 f2 g2 h2 e3 f3 g3 h3
+ resq_r6_1 = _mm_unpacklo_epi32(temp2, temp4); // e4 f4 g4 h4 e5 f5 g5 h5
+ resq_r7_1 = _mm_unpackhi_epi32(temp2, temp4); // e6 f6 g6 h6 e7 f7 g7 h7
+ /*
+ * a0 b0 c0 d0 a1 b1 c1 d1
+ * a2 b2 c2 d2 a3 b3 c3 d3
+ * a4 b4 c4 d4 a5 b5 c5 d5
+ * a6 b6 c6 d6 a7 b7 c7 d7
+ * e0 f0 g0 h0 e1 f1 g1 h1
+ * e2 f2 g2 h2 e3 f3 g3 h3
+ * e4 f4 g4 h4 e5 f5 g5 h5
+ * e6 f6 g6 h6 e7 f7 g7 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 b0 c0 d0 e0 f0 g0 h0
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // a1 b1 c1 d1 e1 f1 g1 h1
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // a2 b2 c2 d2 e2 f2 g2 h2
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // a3 b3 c3 d3 e3 f3 g3 h3
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // a4 b4 c4 d4 e4 f4 g4 h4
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // a5 b5 c5 d5 e5 f5 g5 h5
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // a6 b6 c6 d6 e6 f6 g6 h6
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // a7 b7 c7 d7 e7 f7 g7 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2 = w0 - w4 */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4 = (w2 >> 1) - w6 */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6 = w2 + (w6 >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1 = y1 + (y7 >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2 = y2 + y4 */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3 = y3 + (y5 >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4 = y2 - y4 */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5 = (y3 >> 2) - y5 */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6 = y0 - y6 */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7 = y7 - (y1 >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ /* x1 = z2 + z5 */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ /* x2 = z4 + z3 */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ /* x3 = z6 + z1 */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ /* x4 = z6 - z1 */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ /* x5 = z4 - z3 */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ /* x6 = z2 - z5 */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ /* x7 = z0 - z7 */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0 e0 f0 g0 h0
+ * a1 b1 c1 d1 e1 f1 g1 h1
+ * a2 b2 c2 d2 e2 f2 g2 h2
+ * a3 b3 c3 d3 e3 f3 g3 h3
+ */
+ temp17 = _mm_unpacklo_epi16(temp1, temp2); // a0 a1 b0 b1 c0 c1 d0 d1
+ temp19 = _mm_unpacklo_epi16(temp3, temp4); // a2 a3 b2 b3 c2 c3 d2 d3
+ temp18 = _mm_unpackhi_epi16(temp1, temp2); // e0 e1 f0 f1 g0 g1 h0 h1
+ temp20 = _mm_unpackhi_epi16(temp3, temp4); // e2 e3 f2 f3 g2 g3 h2 h3
+
+ resq_r0_1 = _mm_unpacklo_epi32(temp17, temp19); // a0 a1 a2 a3 b0 b1 b2 b3
+ resq_r1_1 = _mm_unpackhi_epi32(temp17, temp19); // c0 c1 c2 c3 d0 d1 d2 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp18, temp20); // e0 e1 e2 e3 f0 f1 f2 f3
+ resq_r3_1 = _mm_unpackhi_epi32(temp18, temp20); // g0 g2 g2 g3 h0 h1 h2 h3
+ /*
+ * a4 b4 c4 d4 e4 f4 g4 h4
+ * a5 b5 c5 d5 e5 f5 g5 h5
+ * a6 b6 c6 d6 e6 f6 g6 h6
+ * a7 b7 c7 d7 e7 f7 g7 h7
+ */
+ temp17 = _mm_unpacklo_epi16(temp5, temp6); // a4 a5 b4 b5 c4 c5 d4 d5
+ temp19 = _mm_unpacklo_epi16(temp7, temp8); // a6 a7 b6 b7 c6 c7 d6 d7
+ temp18 = _mm_unpackhi_epi16(temp5, temp6); // e4 e5 f4 f5 g4 g5 h4 h5
+ temp20 = _mm_unpackhi_epi16(temp7, temp8); // e6 e7 f6 f7 g6 g7 h6 h7
+
+ resq_r4_1 = _mm_unpacklo_epi32(temp17, temp19); // a4 a5 a6 a7 b4 b5 b6 b7
+ resq_r5_1 = _mm_unpackhi_epi32(temp17, temp19); // c4 c5 c6 c7 d4 d5 d6 d7
+ resq_r6_1 = _mm_unpacklo_epi32(temp18, temp20); // e4 e5 e6 e7 f4 f5 f6 f7
+ resq_r7_1 = _mm_unpackhi_epi32(temp18, temp20); // g4 g5 g6 g7 h4 h5 h6 h7
+ /* a0 a1 a2 a3 b0 b1 b2 b3
+ * c0 c1 c2 c3 d0 d1 d2 d3
+ * e0 e1 e2 e3 f0 f1 f2 f3
+ * g0 g2 g2 g3 h0 h1 h2 h3
+ * a4 a5 a6 a7 b4 b5 b6 b7
+ * c4 c5 c6 c7 d4 d5 d6 d7
+ * e4 e5 e6 e7 f4 f5 f6 f7
+ * g4 g5 g6 g7 h4 h5 h6 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 a1 a2 a3 a4 a5 a6 a7
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // b0 b1 b2 b3 b4 b5 b6 b7
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // c0 c1 c2 c3 c4 c5 c6 c7
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // d0 d1 d2 d3 d4 d5 d6 d7
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // e0 e1 e2 e3 e4 e5 e6 e7
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // f0 f1 f2 f3 f4 f5 f6 f7
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // g0 g1 g2 g3 g4 g5 g6 g7
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // h0 h1 h2 h3 h4 h5 h6 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+
+ zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // Load pred buffer row 0
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r0_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 1
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r1_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 2
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r2_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 3
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r3_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 4
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[4 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r4_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 5
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bit
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[5 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r5_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 6
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[6 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r6_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+ // Load pred buffer row 7
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ predload_r = _mm_loadl_epi64((__m128i *) (&pu1_pred[7 * pred_strd]));
+ // p0 p1 p2 p3 p4 p5 p6 p7 -- all 16 bits
+ pred_r7_1 = _mm_unpacklo_epi8(predload_r, zero_8x16b);
+
+ rsd_r0 = _mm_loadu_si128((__m128i *) (&pi2_rsd[0]));
+ rsd_r1 = _mm_loadu_si128((__m128i *) (&pi2_rsd[1 * rsd_strd]));
+ rsd_r2 = _mm_loadu_si128((__m128i *) (&pi2_rsd[2 * rsd_strd]));
+ rsd_r3 = _mm_loadu_si128((__m128i *) (&pi2_rsd[3 * rsd_strd]));
+ rsd_r4 = _mm_loadu_si128((__m128i *) (&pi2_rsd[4 * rsd_strd]));
+ rsd_r5 = _mm_loadu_si128((__m128i *) (&pi2_rsd[5 * rsd_strd]));
+ rsd_r6 = _mm_loadu_si128((__m128i *) (&pi2_rsd[6 * rsd_strd]));
+ rsd_r7 = _mm_loadu_si128((__m128i *) (&pi2_rsd[7 * rsd_strd]));
+
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ /* y0j = w0j + w4j */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2j = w0j - w4j */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1j = -w3j + w5j - w7j - (w7j >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3j = w1j + w7j - w3j - (w3j >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4j = (w2j >> 1) - w6j */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6j = w2j + (w6j >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1j = y1j + (y7j >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2j = y2j + y4j */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3j = y3j + (y5j >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4j = y2j - y4j */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5j = (y3j >> 2) - y5j */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6j = y0j - y6j */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7j = y7j - (y1j >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp1);
+ temp10 = _mm_unpacklo_epi16(temp1, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp1, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r0 = _mm_add_epi16(temp10, rsd_r0);
+ rsd_r0 = _mm_min_epi16(dupmax_8x16b, rsd_r0);
+ rsd_r0 = _mm_max_epi16(dupmin_8x16b, rsd_r0);
+ temp1 = _mm_add_epi16(rsd_r0, pred_r0_1);
+ /* x1j = z2j + z5j */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp2);
+ temp10 = _mm_unpacklo_epi16(temp2, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp2, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r1 = _mm_add_epi16(temp10, rsd_r1);
+ rsd_r1 = _mm_min_epi16(dupmax_8x16b, rsd_r1);
+ rsd_r1 = _mm_max_epi16(dupmin_8x16b, rsd_r1);
+ temp2 = _mm_add_epi16(rsd_r1, pred_r1_1);
+ /* x2j = z4j + z3j */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp3);
+ temp10 = _mm_unpacklo_epi16(temp3, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp3, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r2 = _mm_add_epi16(temp10, rsd_r2);
+ rsd_r2 = _mm_min_epi16(dupmax_8x16b, rsd_r2);
+ rsd_r2 = _mm_max_epi16(dupmin_8x16b, rsd_r2);
+ temp3 = _mm_add_epi16(rsd_r2, pred_r2_1);
+ /* x3j = z6j + z1j */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp4);
+ temp10 = _mm_unpacklo_epi16(temp4, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp4, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r3 = _mm_add_epi16(temp10, rsd_r3);
+ rsd_r3 = _mm_min_epi16(dupmax_8x16b, rsd_r3);
+ rsd_r3 = _mm_max_epi16(dupmin_8x16b, rsd_r3);
+ temp4 = _mm_add_epi16(rsd_r3, pred_r3_1);
+ /* x4j = z6j - z1j */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp5);
+ temp10 = _mm_unpacklo_epi16(temp5, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp5, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r4 = _mm_add_epi16(temp10, rsd_r4);
+ rsd_r4 = _mm_min_epi16(dupmax_8x16b, rsd_r4);
+ rsd_r4 = _mm_max_epi16(dupmin_8x16b, rsd_r4);
+ temp5 = _mm_add_epi16(rsd_r4, pred_r4_1);
+ /* x5j = z4j - z3j */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp6);
+ temp10 = _mm_unpacklo_epi16(temp6, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp6, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r5 = _mm_add_epi16(temp10, rsd_r5);
+ rsd_r5 = _mm_min_epi16(dupmax_8x16b, rsd_r5);
+ rsd_r5 = _mm_max_epi16(dupmin_8x16b, rsd_r5);
+ temp6 = _mm_add_epi16(rsd_r5, pred_r5_1);
+ /* x6j = z2j - z5j */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp7);
+ temp10 = _mm_unpacklo_epi16(temp7, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp7, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r6 = _mm_add_epi16(temp10, rsd_r6);
+ rsd_r6 = _mm_min_epi16(dupmax_8x16b, rsd_r6);
+ rsd_r6 = _mm_max_epi16(dupmin_8x16b, rsd_r6);
+ temp7 = _mm_add_epi16(rsd_r6, pred_r6_1);
+ /* x7j = z0j - z7j */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp8);
+ temp10 = _mm_unpacklo_epi16(temp8, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp8, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ rsd_r7 = _mm_add_epi16(temp10, rsd_r7);
+ rsd_r7 = _mm_min_epi16(dupmax_8x16b, rsd_r7);
+ rsd_r7 = _mm_max_epi16(dupmin_8x16b, rsd_r7);
+ temp8 = _mm_add_epi16(rsd_r7, pred_r7_1);
+
+ rsd_r01_b0 = _mm_unpacklo_epi64(rsd_r0, rsd_r1);
+ rsd_r23_b0 = _mm_unpacklo_epi64(rsd_r2, rsd_r3);
+ rsd_r45_b2 = _mm_unpacklo_epi64(rsd_r4, rsd_r5);
+ rsd_r67_b2 = _mm_unpacklo_epi64(rsd_r6, rsd_r7);
+
+ rsd_r01_b1 = _mm_unpackhi_epi64(rsd_r0, rsd_r1);
+ rsd_r23_b1 = _mm_unpackhi_epi64(rsd_r2, rsd_r3);
+ rsd_r45_b3 = _mm_unpackhi_epi64(rsd_r4, rsd_r5);
+ rsd_r67_b3 = _mm_unpackhi_epi64(rsd_r6, rsd_r7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r23_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_45_b2 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r45_b2, zero_8x16b)); // return 1 if all zeros, else 0
+ row_67_b2 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r67_b2, zero_8x16b)); // return 1 if all zeros, else 0
+
+ row_01_b1 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r01_b1, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b1 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r23_b1, zero_8x16b)); // return 1 if all zeros, else 0
+ row_45_b3 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r45_b3, zero_8x16b)); // return 1 if all zeros, else 0
+ row_67_b3 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_r67_b3, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /*------------------------------------------------------------------*/
+ // Clipping the results to 8 bits
+ sign_reg = _mm_cmpgt_epi16(temp1, zero_8x16b); // sign check
+ temp1 = _mm_and_si128(temp1, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp2, zero_8x16b); // sign check
+ temp2 = _mm_and_si128(temp2, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp3, zero_8x16b); // sign check
+ temp3 = _mm_and_si128(temp3, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp4, zero_8x16b); // sign check
+ temp4 = _mm_and_si128(temp4, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp5, zero_8x16b); // sign check
+ temp5 = _mm_and_si128(temp5, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp6, zero_8x16b); // sign check
+ temp6 = _mm_and_si128(temp6, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp7, zero_8x16b); // sign check
+ temp7 = _mm_and_si128(temp7, sign_reg);
+ sign_reg = _mm_cmpgt_epi16(temp8, zero_8x16b); // sign check
+ temp8 = _mm_and_si128(temp8, sign_reg);
+
+ resq_r0_2 = _mm_packus_epi16(temp1, zero_8x16b);
+ resq_r1_2 = _mm_packus_epi16(temp2, zero_8x16b);
+ resq_r2_2 = _mm_packus_epi16(temp3, zero_8x16b);
+ resq_r3_2 = _mm_packus_epi16(temp4, zero_8x16b);
+ resq_r4_2 = _mm_packus_epi16(temp5, zero_8x16b);
+ resq_r5_2 = _mm_packus_epi16(temp6, zero_8x16b);
+ resq_r6_2 = _mm_packus_epi16(temp7, zero_8x16b);
+ resq_r7_2 = _mm_packus_epi16(temp8, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), resq_r0_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[out_strd]), resq_r1_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * out_strd]), resq_r2_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * out_strd]), resq_r3_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[4 * out_strd]), resq_r4_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[5 * out_strd]), resq_r5_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[6 * out_strd]), resq_r6_2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[7 * out_strd]), resq_r7_2);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_4x4_dc_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, out_8x16b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, out_8x16b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, out_8x16b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, out_8x16b_3, out_16x8b_3;
+ __m128i rsd_8x16b_01, rsd_8x16b_23;
+
+ __m128i i_macro_8x16b, dupmax_8x16b, dupmin_8x16b;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ WORD32 i4_nnz, row_01, row_23;
+ WORD32 q0;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+ i_macro = ((q0 + 32) >> 6);
+
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+ dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1)));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1) + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1)));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1) + rsd_strd));
+
+ rsd_8x16b_0 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_3);
+
+ rsd_8x16b_0 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_0);
+ rsd_8x16b_0 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_1);
+ rsd_8x16b_1 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_2);
+ rsd_8x16b_2 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_3);
+ rsd_8x16b_3 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_3);
+
+ rsd_8x16b_01 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ row_01 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+
+ *((WORD32 *) (pu1_out)) = _mm_cvtsi128_si32(out_16x8b_0);
+ *((WORD32 *) (pu1_out + out_strd)) = _mm_cvtsi128_si32(out_16x8b_1);
+ *((WORD32 *) (pu1_out + (out_strd << 1))) = _mm_cvtsi128_si32(out_16x8b_2);
+ *((WORD32 *) (pu1_out + (out_strd * 3))) = _mm_cvtsi128_si32(out_16x8b_3);
+
+ i4_nnz = !(row_01 && row_23);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_8x8_dc_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_recon_8x8_dc_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx, WORD16 *pi2_dc_ld_addr)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, out_8x16b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, out_8x16b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, out_8x16b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, out_8x16b_3, out_16x8b_3;
+ __m128i pred_16x8b_4, pred_8x16b_4, rsd_8x16b_4, out_8x16b_4, out_16x8b_4;
+ __m128i pred_16x8b_5, pred_8x16b_5, rsd_8x16b_5, out_8x16b_5, out_16x8b_5;
+ __m128i pred_16x8b_6, pred_8x16b_6, rsd_8x16b_6, out_8x16b_6, out_16x8b_6;
+ __m128i pred_16x8b_7, pred_8x16b_7, rsd_8x16b_7, out_8x16b_7, out_16x8b_7;
+ __m128i rsd_8x16b_01_b0, rsd_8x16b_23_b0, rsd_8x16b_45_b2, rsd_8x16b_67_b2;
+ __m128i rsd_8x16b_01_b1, rsd_8x16b_23_b1, rsd_8x16b_45_b3, rsd_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 pred_strd2 = (pred_strd << 1);
+ WORD32 pred_strd4 = (pred_strd << 2);
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+ WORD32 out_strd2 = (out_strd << 1);
+ WORD32 out_strd4 = (out_strd << 2);
+
+ __m128i i_macro_8x16b, dupmax_8x16b, dupmin_8x16b;
+ WORD32 q;
+ WORD16 i_macro;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+ i_macro = (q + 32) >> 6;
+
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+ dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_0 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_3);
+ rsd_8x16b_4 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_4);
+ rsd_8x16b_5 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_5);
+ rsd_8x16b_6 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_6);
+ rsd_8x16b_7 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_7);
+
+ rsd_8x16b_0 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_0);
+ rsd_8x16b_0 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_1);
+ rsd_8x16b_1 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_2);
+ rsd_8x16b_2 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_3);
+ rsd_8x16b_3 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_3);
+ rsd_8x16b_4 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_4);
+ rsd_8x16b_4 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_4);
+ rsd_8x16b_5 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_5);
+ rsd_8x16b_5 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_5);
+ rsd_8x16b_6 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_6);
+ rsd_8x16b_6 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_6);
+ rsd_8x16b_7 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_7);
+ rsd_8x16b_7 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_7);
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(rsd_8x16b_01_b0); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(rsd_8x16b_23_b0);
+ row_01_b1 = _mm_test_all_ones(rsd_8x16b_01_b1);
+ row_23_b1 = _mm_test_all_ones(rsd_8x16b_23_b1);
+
+ row_45_b2 = _mm_test_all_ones(rsd_8x16b_45_b2);
+ row_67_b2 = _mm_test_all_ones(rsd_8x16b_67_b2);
+ row_45_b3 = _mm_test_all_ones(rsd_8x16b_45_b3);
+ row_67_b3 = _mm_test_all_ones(rsd_8x16b_67_b3);
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4_dc_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, rsd_16x8b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, rsd_16x8b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, rsd_16x8b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, rsd_16x8b_3, out_16x8b_3;
+
+ __m128i i_macro_8x16b, dupmax_8x16b, dupmin_8x16b;
+ __m128i chroma_mask, chroma_mask2;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ WORD32 q0;
+ WORD16 i_macro;
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(u4_qp_div_6);
+ UNUSED(pi2_tmp);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = ((q0 + 32) >> 6);
+
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+ dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1)));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1) + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1)));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1) + rsd_strd));
+
+ rsd_8x16b_0 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_add_epi16(i_macro_8x16b, rsd_8x16b_3);
+
+ rsd_8x16b_0 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_0);
+ rsd_8x16b_0 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_1);
+ rsd_8x16b_1 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_2);
+ rsd_8x16b_2 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_min_epi16(dupmax_8x16b, rsd_8x16b_3);
+ rsd_8x16b_3 = _mm_max_epi16(dupmin_8x16b, rsd_8x16b_3);
+
+ rsd_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ rsd_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ rsd_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ rsd_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+
+ chroma_mask = _mm_set1_epi16(0xFF00);
+ chroma_mask2 = _mm_set1_epi16(0x00FF);
+ out_16x8b_0 = _mm_loadu_si128((__m128i *) (&pu1_out[0]));
+ out_16x8b_1 = _mm_loadu_si128((__m128i *) (&pu1_out[out_strd]));
+ out_16x8b_2 = _mm_loadu_si128((__m128i *) (&pu1_out[(out_strd << 1)]));
+ out_16x8b_3 = _mm_loadu_si128((__m128i *) (&pu1_out[(out_strd << 1) + out_strd]));
+
+ out_16x8b_0 = _mm_and_si128(out_16x8b_0, chroma_mask);
+ out_16x8b_1 = _mm_and_si128(out_16x8b_1, chroma_mask);
+ out_16x8b_2 = _mm_and_si128(out_16x8b_2, chroma_mask);
+ out_16x8b_3 = _mm_and_si128(out_16x8b_3, chroma_mask);
+
+ rsd_16x8b_0 = _mm_packus_epi16(rsd_8x16b_0, zero_8x16b);
+ rsd_16x8b_1 = _mm_packus_epi16(rsd_8x16b_1, zero_8x16b);
+ rsd_16x8b_2 = _mm_packus_epi16(rsd_8x16b_2, zero_8x16b);
+ rsd_16x8b_3 = _mm_packus_epi16(rsd_8x16b_3, zero_8x16b);
+
+ rsd_8x16b_0 = _mm_and_si128(rsd_16x8b_0, chroma_mask2);
+ rsd_8x16b_1 = _mm_and_si128(rsd_16x8b_1, chroma_mask2);
+ rsd_8x16b_2 = _mm_and_si128(rsd_16x8b_2, chroma_mask2);
+ rsd_8x16b_3 = _mm_and_si128(rsd_16x8b_3, chroma_mask2);
+
+ out_16x8b_0 = _mm_add_epi8(rsd_8x16b_0, out_16x8b_0);
+ out_16x8b_1 = _mm_add_epi8(rsd_8x16b_1, out_16x8b_1);
+ out_16x8b_2 = _mm_add_epi8(rsd_8x16b_2, out_16x8b_2);
+ out_16x8b_3 = _mm_add_epi8(rsd_8x16b_3, out_16x8b_3);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + (out_strd << 1)), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + (out_strd * 3)), out_16x8b_3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_recon_chroma_4x4_sse42 */
+/* */
+/* Description : this function computes the recon output from the */
+/* IQ+IT+RESD */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_residual_recon_chroma_4x4_sse42(
+ WORD16 *pi2_src, UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out, WORD32 pred_strd,
+ WORD32 rsd_strd, WORD32 out_strd, const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i rsd_r0, rsd_r1, rsd_r2, rsd_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i chroma_mask = _mm_set1_epi16(0xFF00);
+ __m128i chroma_mask2 = _mm_set1_epi16(0x00FF);
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ __m128i out_16x8b_0, out_16x8b_1, out_16x8b_2, out_16x8b_3;
+
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ // Load pred buffer
+ // p00 p01 p02 p03 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pu1_pred[0]));
+ // p10 p11 p12 p13 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pu1_pred[pred_strd]));
+ // p20 p21 p22 p23 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pu1_pred[2 * pred_strd]));
+ // p30 p31 p32 p33 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pu1_pred[3 * pred_strd]));
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0); // p00 p01 p02 p03 -- all 16 bits
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1); // p10 p11 p12 p13 -- all 16 bits
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2); // p20 p21 p22 p23 -- all 16 bits
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3); // p30 p31 p32 p33 -- all 16 bits
+
+ // Load resd buffer
+ rsd_r0 = _mm_loadu_si128((__m128i *) (&pi2_rsd[0]));
+ rsd_r1 = _mm_loadu_si128((__m128i *) (&pi2_rsd[rsd_strd]));
+ rsd_r2 = _mm_loadu_si128((__m128i *) (&pi2_rsd[2 * rsd_strd]));
+ rsd_r3 = _mm_loadu_si128((__m128i *) (&pi2_rsd[3 * rsd_strd]));
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_add_epi16(temp4, rsd_r0);
+ temp4 = _mm_min_epi16(dupmax_8x16b, temp4);
+ temp4 = _mm_max_epi16(dupmin_8x16b, temp4);
+ temp4 = _mm_add_epi16(temp4, pred_r0);
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_add_epi16(temp5, rsd_r1);
+ temp5 = _mm_min_epi16(dupmax_8x16b, temp5);
+ temp5 = _mm_max_epi16(dupmin_8x16b, temp5);
+ temp5 = _mm_add_epi16(temp5, pred_r1);
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_add_epi16(temp6, rsd_r2);
+ temp6 = _mm_min_epi16(dupmax_8x16b, temp6);
+ temp6 = _mm_max_epi16(dupmin_8x16b, temp6);
+ temp6 = _mm_add_epi16(temp6, pred_r2);
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_add_epi16(temp7, rsd_r3);
+ temp7 = _mm_min_epi16(dupmax_8x16b, temp7);
+ temp7 = _mm_max_epi16(dupmin_8x16b, temp7);
+ temp7 = _mm_add_epi16(temp7, pred_r3);
+
+ out_16x8b_0 = _mm_loadu_si128((__m128i *) (&pu1_out[0]));
+ out_16x8b_1 = _mm_loadu_si128((__m128i *) (&pu1_out[out_strd]));
+ out_16x8b_2 = _mm_loadu_si128((__m128i *) (&pu1_out[(out_strd << 1)]));
+ out_16x8b_3 = _mm_loadu_si128((__m128i *) (&pu1_out[(out_strd << 1) + out_strd]));
+
+ out_16x8b_0 = _mm_and_si128(out_16x8b_0, chroma_mask);
+ out_16x8b_1 = _mm_and_si128(out_16x8b_1, chroma_mask);
+ out_16x8b_2 = _mm_and_si128(out_16x8b_2, chroma_mask);
+ out_16x8b_3 = _mm_and_si128(out_16x8b_3, chroma_mask);
+
+ temp4 = _mm_packus_epi16(temp4, zero_8x16b);
+ temp5 = _mm_packus_epi16(temp5, zero_8x16b);
+ temp6 = _mm_packus_epi16(temp6, zero_8x16b);
+ temp7 = _mm_packus_epi16(temp7, zero_8x16b);
+
+ temp4 = _mm_and_si128(temp4, chroma_mask2);
+ temp5 = _mm_and_si128(temp5, chroma_mask2);
+ temp6 = _mm_and_si128(temp6, chroma_mask2);
+ temp7 = _mm_and_si128(temp7, chroma_mask2);
+
+ out_16x8b_0 = _mm_add_epi8(temp4, out_16x8b_0);
+ out_16x8b_1 = _mm_add_epi8(temp5, out_16x8b_1);
+ out_16x8b_2 = _mm_add_epi8(temp6, out_16x8b_2);
+ out_16x8b_3 = _mm_add_epi8(temp7, out_16x8b_3);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + (out_strd << 1)), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + (out_strd * 3)), out_16x8b_3);
+}
diff --git a/decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c b/decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c
new file mode 100644
index 0000000..507a60e
--- /dev/null
+++ b/decoder/x86/svc/isvcd_iquant_itrans_residual_sse42.c
@@ -0,0 +1,1678 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_iquant_itrans_residual_sse42.c
+ *
+ * @brief
+ * Contains function definitions for iquant_itrans_residual_recon
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_iquant_itrans_residual_4x4_sse42()
+ * - isvcd_iquant_itrans_residual_8x8_sse42()
+ * - isvcd_iquant_itrans_residual_4x4_dc_sse42()
+ * - isvcd_iquant_itrans_residual_8x8_dc_sse42()
+ * - isvcd_iquant_itrans_residual_chroma_4x4_sse42()
+ * - isvcd_iquant_itrans_residual_chroma_4x4_dc_sse42()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_4x4_sse42(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 i4_nnz = 0;
+ WORD32 row_0, row_1, row_2, row_3;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i dupmax_4x32b = _mm_set1_epi32(RSD_MAX);
+ __m128i dupmin_4x32b = _mm_set1_epi32(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_ld_addr[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ // Load pred buffer
+ // p00 p01 p02 p03 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r0 = _mm_loadl_epi64((__m128i *) (&pi2_pred[0]));
+ // p10 p11 p12 p13 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r1 = _mm_loadl_epi64((__m128i *) (&pi2_pred[pred_strd]));
+ // p20 p21 p22 p23 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_loadl_epi64((__m128i *) (&pi2_pred[2 * pred_strd]));
+ // p30 p31 p32 p33 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_loadl_epi64((__m128i *) (&pi2_pred[3 * pred_strd]));
+
+ pred_r0 = _mm_cvtepi16_epi32(pred_r0); // p00 p01 p02 p03 -- all 32 bits
+ pred_r1 = _mm_cvtepi16_epi32(pred_r1); // p10 p11 p12 p13 -- all 32 bits
+ pred_r2 = _mm_cvtepi16_epi32(pred_r2); // p20 p21 p22 p23 -- all 32 bits
+ pred_r3 = _mm_cvtepi16_epi32(pred_r3); // p30 p31 p32 p33 -- all 32 bits
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_add_epi32(temp4, pred_r0);
+ temp4 = _mm_min_epi32(dupmax_4x32b, temp4);
+ temp4 = _mm_max_epi32(dupmin_4x32b, temp4);
+
+ row_0 = _mm_test_all_ones(_mm_cmpeq_epi32(temp4, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_add_epi32(temp5, pred_r1);
+ temp5 = _mm_min_epi32(dupmax_4x32b, temp5);
+ temp5 = _mm_max_epi32(dupmin_4x32b, temp5);
+
+ row_1 = _mm_test_all_ones(_mm_cmpeq_epi32(temp5, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_add_epi32(temp6, pred_r2);
+ temp6 = _mm_min_epi32(dupmax_4x32b, temp6);
+ temp6 = _mm_max_epi32(dupmin_4x32b, temp6);
+ row_2 = _mm_test_all_ones(_mm_cmpeq_epi32(temp6, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_add_epi32(temp7, pred_r3);
+ temp7 = _mm_min_epi32(dupmax_4x32b, temp7);
+ temp7 = _mm_max_epi32(dupmin_4x32b, temp7);
+ row_3 = _mm_test_all_ones(_mm_cmpeq_epi32(temp7, zero_8x16b)); // return 1 if all zeros, else 0
+
+ // 32-bit to 16-bit conversion
+ temp0 = _mm_packs_epi32(temp4, zero_8x16b);
+ temp1 = _mm_packs_epi32(temp5, zero_8x16b);
+ temp2 = _mm_packs_epi32(temp6, zero_8x16b);
+ temp3 = _mm_packs_epi32(temp7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pi2_out), temp0);
+ _mm_storel_epi64((__m128i *) (pi2_out + out_strd), temp1);
+ _mm_storel_epi64((__m128i *) (pi2_out + 2 * out_strd), temp2);
+ _mm_storel_epi64((__m128i *) (pi2_out + 3 * out_strd), temp3);
+
+ i4_nnz = !(row_0 && row_1 && row_2 && row_3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8_sse42(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ __m128i pred_r01_b0, pred_r23_b0, pred_r45_b2, pred_r67_b2;
+ __m128i pred_r01_b1, pred_r23_b1, pred_r45_b3, pred_r67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+ __m128i src_r0;
+ __m128i scalemat_r0;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // 0 1 0 1 0 --- 16 bits size
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i add_rshift = _mm_set1_epi32((qp_div < 6) ? (1 << (5 - qp_div)) : 0);
+ __m128i dequant_r0;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3, pred_r4, pred_r5, pred_r6, pred_r7;
+ __m128i sign_reg;
+ __m128i src_r0_1, src_r0_2;
+ __m128i scalemat_r0_1, scalemat_r0_2;
+ __m128i temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+ __m128i temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp20;
+ // To store dequantization results
+ __m128i resq_r0_1, resq_r0_2, resq_r1_1, resq_r1_2, resq_r2_1, resq_r2_2, resq_r3_1, resq_r3_2,
+ resq_r4_1, resq_r4_2, resq_r5_1, resq_r5_2, resq_r6_1, resq_r6_2, resq_r7_1, resq_r7_2;
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+
+ // Row 0 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 -- the source matrix 0th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // b00 b01 b02 b03 b04 b05 b06 b07 - the scaling matrix 0th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[0]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+
+ if(qp_div >= 6)
+ {
+ resq_r0_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r0_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r0_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16
+ // bit long
+ resq_r0_1 = _mm_packs_epi32(resq_r0_1, resq_r0_2);
+ // Row 1 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 1st row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 1st row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 8));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[8]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ if(qp_div >= 6)
+ {
+ resq_r1_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r1_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r1_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r1_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r1_1 = _mm_packs_epi32(resq_r1_1, resq_r1_2);
+ // Row 2 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 --the source matrix 2nd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 16));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 2nd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 16));
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[16])); // q0 q1 q2 q3 q4 q5 q6 q7
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ if(qp_div >= 6)
+ {
+ resq_r2_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r2_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r2_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r2_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r2_1 = _mm_packs_epi32(resq_r2_1, resq_r2_2);
+ // Row 3 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 3rd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 24));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 3rd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 24));
+ dequant_r0 = _mm_loadu_si128(
+ (__m128i *) (&pu2_weigh_mat[24])); // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ if(qp_div >= 6)
+ {
+ resq_r3_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r3_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r3_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r3_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r3_1 = _mm_packs_epi32(resq_r3_1, resq_r3_2);
+ // Row 4 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 4th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 32));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 4th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 32));
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[32])); // q0 q1 q2 q3 q4 q5 q6 q7
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ if(qp_div >= 6)
+ {
+ resq_r4_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r4_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r4_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r4_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r4_1 = _mm_packs_epi32(resq_r4_1, resq_r4_2);
+ // Row 5 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 5th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 40));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 5th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 40));
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[40])); // q0 q1 q2 q3 q4 q5 q6 q7
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b); // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b); // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1); // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2); // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ if(qp_div >= 6)
+ {
+ resq_r5_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r5_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r5_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r5_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r5_1 = _mm_packs_epi32(resq_r5_1, resq_r5_2);
+
+ // Row 6 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 6th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 48));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 6th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 48));
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[48])); // q0 q1 q2 q3 q4 q5 q6 q7
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r6_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r6_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r6_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r6_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r6_1 = _mm_packs_epi32(resq_r6_1, resq_r6_2);
+ // Row 7 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 7th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 56));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 7th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 56));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[56]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r7_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r7_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r7_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r7_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r7_1 = _mm_packs_epi32(resq_r7_1, resq_r7_2);
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3 a4 a5 a6 a7
+ * b0 b1 b2 b3 b4 b5 b6 b7
+ * c0 c1 c2 c3 c4 c5 c6 c7
+ * d0 d1 d2 d3 d4 d5 d6 d7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r0_1, resq_r1_1); // a0 b0 a1 b1 a2 b2 a3 b3
+ temp3 = _mm_unpacklo_epi16(resq_r2_1, resq_r3_1); // c0 d0 c1 d1 c2 d2 c3 d3
+ temp2 = _mm_unpackhi_epi16(resq_r0_1, resq_r1_1); // a4 b4 a5 b5 a6 b6 a7 b7
+ temp4 = _mm_unpackhi_epi16(resq_r2_1, resq_r3_1); // c4 d4 c5 d5 c6 d6 c7 d7
+ resq_r0_1 = _mm_unpacklo_epi32(temp1, temp3); // a0 b0 c0 d0 a1 b1 c1 d1
+ resq_r1_1 = _mm_unpackhi_epi32(temp1, temp3); // a2 b2 c2 d2 a3 b3 c3 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp2, temp4); // a4 b4 c4 d4 a5 b5 c5 d5
+ resq_r3_1 = _mm_unpackhi_epi32(temp2, temp4); // a6 b6 c6 d6 a7 b7 c7 d7
+ /*
+ * e0 e1 e2 e3 e4 e5 e6 e7
+ * f0 f1 f2 f3 f4 f5 f6 f7
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * h0 h1 h2 h3 h4 h5 h6 h7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r4_1, resq_r5_1); // e0 f0 e1 f1 e2 f2 e2 f3
+ temp3 = _mm_unpacklo_epi16(resq_r6_1, resq_r7_1); // g0 h0 g1 h1 g2 h2 g3 h3
+ temp2 = _mm_unpackhi_epi16(resq_r4_1, resq_r5_1); // e4 f4 e5 f5 e6 f6 e7 f7
+ temp4 = _mm_unpackhi_epi16(resq_r6_1, resq_r7_1); // g4 h4 g5 h5 g6 h6 g7 h7
+ resq_r4_1 = _mm_unpacklo_epi32(temp1, temp3); // e0 f0 g0 h0 e1 f1 g1 h1
+ resq_r5_1 = _mm_unpackhi_epi32(temp1, temp3); // e2 f2 g2 h2 e3 f3 g3 h3
+ resq_r6_1 = _mm_unpacklo_epi32(temp2, temp4); // e4 f4 g4 h4 e5 f5 g5 h5
+ resq_r7_1 = _mm_unpackhi_epi32(temp2, temp4); // e6 f6 g6 h6 e7 f7 g7 h7
+ /*
+ * a0 b0 c0 d0 a1 b1 c1 d1
+ * a2 b2 c2 d2 a3 b3 c3 d3
+ * a4 b4 c4 d4 a5 b5 c5 d5
+ * a6 b6 c6 d6 a7 b7 c7 d7
+ * e0 f0 g0 h0 e1 f1 g1 h1
+ * e2 f2 g2 h2 e3 f3 g3 h3
+ * e4 f4 g4 h4 e5 f5 g5 h5
+ * e6 f6 g6 h6 e7 f7 g7 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 b0 c0 d0 e0 f0 g0 h0
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // a1 b1 c1 d1 e1 f1 g1 h1
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // a2 b2 c2 d2 e2 f2 g2 h2
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // a3 b3 c3 d3 e3 f3 g3 h3
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // a4 b4 c4 d4 e4 f4 g4 h4
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // a5 b5 c5 d5 e5 f5 g5 h5
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // a6 b6 c6 d6 e6 f6 g6 h6
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // a7 b7 c7 d7 e7 f7 g7 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2 = w0 - w4 */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4 = (w2 >> 1) - w6 */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6 = w2 + (w6 >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1 = y1 + (y7 >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2 = y2 + y4 */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3 = y3 + (y5 >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4 = y2 - y4 */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5 = (y3 >> 2) - y5 */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6 = y0 - y6 */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7 = y7 - (y1 >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ /* x1 = z2 + z5 */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ /* x2 = z4 + z3 */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ /* x3 = z6 + z1 */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ /* x4 = z6 - z1 */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ /* x5 = z4 - z3 */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ /* x6 = z2 - z5 */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ /* x7 = z0 - z7 */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0 e0 f0 g0 h0
+ * a1 b1 c1 d1 e1 f1 g1 h1
+ * a2 b2 c2 d2 e2 f2 g2 h2
+ * a3 b3 c3 d3 e3 f3 g3 h3
+ */
+ temp17 = _mm_unpacklo_epi16(temp1, temp2); // a0 a1 b0 b1 c0 c1 d0 d1
+ temp19 = _mm_unpacklo_epi16(temp3, temp4); // a2 a3 b2 b3 c2 c3 d2 d3
+ temp18 = _mm_unpackhi_epi16(temp1, temp2); // e0 e1 f0 f1 g0 g1 h0 h1
+ temp20 = _mm_unpackhi_epi16(temp3, temp4); // e2 e3 f2 f3 g2 g3 h2 h3
+
+ resq_r0_1 = _mm_unpacklo_epi32(temp17, temp19); // a0 a1 a2 a3 b0 b1 b2 b3
+ resq_r1_1 = _mm_unpackhi_epi32(temp17, temp19); // c0 c1 c2 c3 d0 d1 d2 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp18, temp20); // e0 e1 e2 e3 f0 f1 f2 f3
+ resq_r3_1 = _mm_unpackhi_epi32(temp18, temp20); // g0 g2 g2 g3 h0 h1 h2 h3
+ /*
+ * a4 b4 c4 d4 e4 f4 g4 h4
+ * a5 b5 c5 d5 e5 f5 g5 h5
+ * a6 b6 c6 d6 e6 f6 g6 h6
+ * a7 b7 c7 d7 e7 f7 g7 h7
+ */
+ temp17 = _mm_unpacklo_epi16(temp5, temp6); // a4 a5 b4 b5 c4 c5 d4 d5
+ temp19 = _mm_unpacklo_epi16(temp7, temp8); // a6 a7 b6 b7 c6 c7 d6 d7
+ temp18 = _mm_unpackhi_epi16(temp5, temp6); // e4 e5 f4 f5 g4 g5 h4 h5
+ temp20 = _mm_unpackhi_epi16(temp7, temp8); // e6 e7 f6 f7 g6 g7 h6 h7
+
+ resq_r4_1 = _mm_unpacklo_epi32(temp17, temp19); // a4 a5 a6 a7 b4 b5 b6 b7
+ resq_r5_1 = _mm_unpackhi_epi32(temp17, temp19); // c4 c5 c6 c7 d4 d5 d6 d7
+ resq_r6_1 = _mm_unpacklo_epi32(temp18, temp20); // e4 e5 e6 e7 f4 f5 f6 f7
+ resq_r7_1 = _mm_unpackhi_epi32(temp18, temp20); // g4 g5 g6 g7 h4 h5 h6 h7
+ /* a0 a1 a2 a3 b0 b1 b2 b3
+ * c0 c1 c2 c3 d0 d1 d2 d3
+ * e0 e1 e2 e3 f0 f1 f2 f3
+ * g0 g2 g2 g3 h0 h1 h2 h3
+ * a4 a5 a6 a7 b4 b5 b6 b7
+ * c4 c5 c6 c7 d4 d5 d6 d7
+ * e4 e5 e6 e7 f4 f5 f6 f7
+ * g4 g5 g6 g7 h4 h5 h6 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 a1 a2 a3 a4 a5 a6 a7
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // b0 b1 b2 b3 b4 b5 b6 b7
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // c0 c1 c2 c3 c4 c5 c6 c7
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // d0 d1 d2 d3 d4 d5 d6 d7
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // e0 e1 e2 e3 e4 e5 e6 e7
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // f0 f1 f2 f3 f4 f5 f6 f7
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // g0 g1 g2 g3 g4 g5 g6 g7
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // h0 h1 h2 h3 h4 h5 h6 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+
+ zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ // p0 p1 p2 p3 p4 p5 p6 p7 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r0 = _mm_loadu_si128((__m128i *) (&pi2_pred[0]));
+ pred_r1 = _mm_loadu_si128((__m128i *) (&pi2_pred[pred_strd]));
+ pred_r2 = _mm_loadu_si128((__m128i *) (&pi2_pred[2 * pred_strd]));
+ pred_r3 = _mm_loadu_si128((__m128i *) (&pi2_pred[3 * pred_strd]));
+ pred_r4 = _mm_loadu_si128((__m128i *) (&pi2_pred[4 * pred_strd]));
+ pred_r5 = _mm_loadu_si128((__m128i *) (&pi2_pred[5 * pred_strd]));
+ pred_r6 = _mm_loadu_si128((__m128i *) (&pi2_pred[6 * pred_strd]));
+ pred_r7 = _mm_loadu_si128((__m128i *) (&pi2_pred[7 * pred_strd]));
+
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* Add the prediction and store it back to reconstructed frame buffer */
+ /* [Prediction buffer itself in this case] */
+ /*--------------------------------------------------------------------*/
+
+ /* y0j = w0j + w4j */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2j = w0j - w4j */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1j = -w3j + w5j - w7j - (w7j >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3j = w1j + w7j - w3j - (w3j >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4j = (w2j >> 1) - w6j */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6j = w2j + (w6j >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1j = y1j + (y7j >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2j = y2j + y4j */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3j = y3j + (y5j >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4j = y2j - y4j */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5j = (y3j >> 2) - y5j */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6j = y0j - y6j */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7j = y7j - (y1j >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp1);
+ temp10 = _mm_unpacklo_epi16(temp1, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp1, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r0 = _mm_add_epi16(temp10, pred_r0);
+ pred_r0 = _mm_min_epi16(dupmax_8x16b, pred_r0);
+ pred_r0 = _mm_max_epi16(dupmin_8x16b, pred_r0);
+
+ /* x1j = z2j + z5j */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp2);
+ temp10 = _mm_unpacklo_epi16(temp2, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp2, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r1 = _mm_add_epi16(temp10, pred_r1);
+ pred_r1 = _mm_min_epi16(dupmax_8x16b, pred_r1);
+ pred_r1 = _mm_max_epi16(dupmin_8x16b, pred_r1);
+ /* x2j = z4j + z3j */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp3);
+ temp10 = _mm_unpacklo_epi16(temp3, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp3, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r2 = _mm_add_epi16(temp10, pred_r2);
+ pred_r2 = _mm_min_epi16(dupmax_8x16b, pred_r2);
+ pred_r2 = _mm_max_epi16(dupmin_8x16b, pred_r2);
+ /* x3j = z6j + z1j */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp4);
+ temp10 = _mm_unpacklo_epi16(temp4, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp4, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r3 = _mm_add_epi16(temp10, pred_r3);
+ pred_r3 = _mm_min_epi16(dupmax_8x16b, pred_r3);
+ pred_r3 = _mm_max_epi16(dupmin_8x16b, pred_r3);
+ /* x4j = z6j - z1j */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp5);
+ temp10 = _mm_unpacklo_epi16(temp5, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp5, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r4 = _mm_add_epi16(temp10, pred_r4);
+ pred_r4 = _mm_min_epi16(dupmax_8x16b, pred_r4);
+ pred_r4 = _mm_max_epi16(dupmin_8x16b, pred_r4);
+ /* x5j = z4j - z3j */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp6);
+ temp10 = _mm_unpacklo_epi16(temp6, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp6, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r5 = _mm_add_epi16(temp10, pred_r5);
+ pred_r5 = _mm_min_epi16(dupmax_8x16b, pred_r5);
+ pred_r5 = _mm_max_epi16(dupmin_8x16b, pred_r5);
+ /* x6j = z2j - z5j */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp7);
+ temp10 = _mm_unpacklo_epi16(temp7, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp7, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r6 = _mm_add_epi16(temp10, pred_r6);
+ pred_r6 = _mm_min_epi16(dupmax_8x16b, pred_r6);
+ pred_r6 = _mm_max_epi16(dupmin_8x16b, pred_r6);
+ /* x7j = z0j - z7j */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp8);
+ temp10 = _mm_unpacklo_epi16(temp8, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp8, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ pred_r7 = _mm_add_epi16(temp10, pred_r7);
+ pred_r7 = _mm_min_epi16(dupmax_8x16b, pred_r7);
+ pred_r7 = _mm_max_epi16(dupmin_8x16b, pred_r7);
+
+ pred_r01_b0 = _mm_unpacklo_epi64(pred_r0, pred_r1);
+ pred_r23_b0 = _mm_unpacklo_epi64(pred_r2, pred_r3);
+ pred_r45_b2 = _mm_unpacklo_epi64(pred_r4, pred_r5);
+ pred_r67_b2 = _mm_unpacklo_epi64(pred_r6, pred_r7);
+
+ pred_r01_b1 = _mm_unpackhi_epi64(pred_r0, pred_r1);
+ pred_r23_b1 = _mm_unpackhi_epi64(pred_r2, pred_r3);
+ pred_r45_b3 = _mm_unpackhi_epi64(pred_r4, pred_r5);
+ pred_r67_b3 = _mm_unpackhi_epi64(pred_r6, pred_r7);
+
+ // return 1 if all zeros, else 0
+ row_01_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r01_b0, zero_8x16b));
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r23_b0, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r67_b2, zero_8x16b));
+
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r23_b1, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_r67_b3, zero_8x16b));
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), pred_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[out_strd]), pred_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_out[2 * out_strd]), pred_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_out[3 * out_strd]), pred_r3);
+ _mm_storeu_si128((__m128i *) (&pi2_out[4 * out_strd]), pred_r4);
+ _mm_storeu_si128((__m128i *) (&pi2_out[5 * out_strd]), pred_r5);
+ _mm_storeu_si128((__m128i *) (&pi2_out[6 * out_strd]), pred_r6);
+ _mm_storeu_si128((__m128i *) (&pi2_out[7 * out_strd]), pred_r7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_4x4_dc_sse42(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ __m128i pred_8x16b_0;
+ __m128i pred_8x16b_1;
+ __m128i pred_8x16b_2;
+ __m128i pred_8x16b_3;
+ __m128i pred_8x16b_01, pred_8x16b_23;
+ __m128i i_macro_8x16b;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ WORD32 i4_nnz, row_01, row_23;
+ WORD32 q0;
+ WORD16 i_macro;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+ i_macro = ((q0 + 32) >> 6);
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+
+ pred_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_pred));
+ pred_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd));
+ pred_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_pred + (pred_strd << 1)));
+ pred_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_pred + (pred_strd << 1) + pred_strd));
+
+ pred_8x16b_0 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_3);
+
+ pred_8x16b_0 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_0);
+ pred_8x16b_0 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_1);
+ pred_8x16b_1 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_2);
+ pred_8x16b_2 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_3);
+ pred_8x16b_3 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_3);
+
+ pred_8x16b_01 = _mm_unpacklo_epi64(pred_8x16b_0, pred_8x16b_1);
+ pred_8x16b_23 = _mm_unpacklo_epi64(pred_8x16b_2, pred_8x16b_3);
+
+ row_01 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(pred_8x16b_01, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_23, zero_8x16b));
+
+ _mm_storel_epi64((__m128i *) (pi2_out), pred_8x16b_0);
+ _mm_storel_epi64((__m128i *) (pi2_out + out_strd), pred_8x16b_1);
+ _mm_storel_epi64((__m128i *) (pi2_out + 2 * out_strd), pred_8x16b_2);
+ _mm_storel_epi64((__m128i *) (pi2_out + 3 * out_strd), pred_8x16b_3);
+
+ i4_nnz = !(row_01 && row_23);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_8x8_dc_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_8x8_dc_sse42(WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out,
+ WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 qp_div,
+ WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ __m128i pred_8x16b_0;
+ __m128i pred_8x16b_1;
+ __m128i pred_8x16b_2;
+ __m128i pred_8x16b_3;
+ __m128i pred_8x16b_4;
+ __m128i pred_8x16b_5;
+ __m128i pred_8x16b_6;
+ __m128i pred_8x16b_7;
+ __m128i pred_8x16b_01_b0, pred_8x16b_23_b0, pred_8x16b_45_b2, pred_8x16b_67_b2;
+ __m128i pred_8x16b_01_b1, pred_8x16b_23_b1, pred_8x16b_45_b3, pred_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 pred_strd2 = (pred_strd << 1);
+ WORD32 pred_strd4 = (pred_strd << 2);
+ WORD32 out_strd2 = (out_strd << 1);
+ WORD32 out_strd4 = (out_strd << 2);
+
+ __m128i i_macro_8x16b;
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ WORD32 q;
+ WORD16 i_macro;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+ i_macro = (q + 32) >> 6;
+
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+
+ pred_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_pred));
+ pred_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd));
+ pred_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd2));
+ pred_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd2 + pred_strd));
+ pred_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd4));
+ pred_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd4 + pred_strd));
+ pred_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd4 + pred_strd2));
+ pred_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_3);
+ pred_8x16b_4 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_4);
+ pred_8x16b_5 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_5);
+ pred_8x16b_6 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_6);
+ pred_8x16b_7 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_7);
+
+ pred_8x16b_0 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_0);
+ pred_8x16b_0 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_1);
+ pred_8x16b_1 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_2);
+ pred_8x16b_2 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_3);
+ pred_8x16b_3 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_3);
+ pred_8x16b_4 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_4);
+ pred_8x16b_4 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_4);
+ pred_8x16b_5 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_5);
+ pred_8x16b_5 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_5);
+ pred_8x16b_6 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_6);
+ pred_8x16b_6 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_6);
+ pred_8x16b_7 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_7);
+ pred_8x16b_7 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_7);
+
+ pred_8x16b_01_b0 = _mm_unpacklo_epi64(pred_8x16b_0, pred_8x16b_1);
+ pred_8x16b_23_b0 = _mm_unpacklo_epi64(pred_8x16b_2, pred_8x16b_3);
+ pred_8x16b_01_b1 = _mm_unpackhi_epi64(pred_8x16b_0, pred_8x16b_1);
+ pred_8x16b_23_b1 = _mm_unpackhi_epi64(pred_8x16b_2, pred_8x16b_3);
+
+ pred_8x16b_45_b2 = _mm_unpacklo_epi64(pred_8x16b_4, pred_8x16b_5);
+ pred_8x16b_67_b2 = _mm_unpacklo_epi64(pred_8x16b_6, pred_8x16b_7);
+ pred_8x16b_45_b3 = _mm_unpackhi_epi64(pred_8x16b_4, pred_8x16b_5);
+ pred_8x16b_67_b3 = _mm_unpackhi_epi64(pred_8x16b_6, pred_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(pred_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_67_b3, zero_8x16b));
+
+ _mm_storeu_si128((__m128i *) (pi2_out), pred_8x16b_0);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd), pred_8x16b_1);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd2), pred_8x16b_2);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd2 + out_strd), pred_8x16b_3);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd4), pred_8x16b_4);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd4 + out_strd), pred_8x16b_5);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd4 + out_strd2), pred_8x16b_6);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd4 + out_strd2 + out_strd), pred_8x16b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4_sse42(WORD16 *pi2_src, WORD16 *pi2_pred,
+ WORD16 *pi2_out, WORD32 pred_strd,
+ WORD32 out_strd, const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp,
+ WORD16 *pi2_dc_src)
+{
+ WORD32 i4_nnz = 0;
+ WORD32 row_0, row_1, row_2, row_3;
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+
+ __m128i out_8x16b_0, out_8x16b_1, out_8x16b_2, out_8x16b_3;
+ __m128i chroma_mask = _mm_set1_epi32(0xFFFF0000);
+ __m128i chroma_mask2 = _mm_set1_epi32(0x0000FFFF);
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ // Load pred buffer
+ // p00 p01 p02 p03 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r0 = _mm_loadu_si128((__m128i *) (&pi2_pred[0]));
+ // p10 p11 p12 p13 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r1 = _mm_loadu_si128((__m128i *) (&pi2_pred[pred_strd]));
+ // p20 p21 p22 p23 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r2 = _mm_loadu_si128((__m128i *) (&pi2_pred[2 * pred_strd]));
+ // p30 p31 p32 p33 0 0 0 0 0 0 0 0 -- all 8 bits
+ pred_r3 = _mm_loadu_si128((__m128i *) (&pi2_pred[3 * pred_strd]));
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_add_epi16(temp4, pred_r0);
+ temp4 = _mm_min_epi16(dupmax_8x16b, temp4);
+ temp4 = _mm_max_epi16(dupmin_8x16b, temp4);
+
+ temp4 = _mm_and_si128(temp4, chroma_mask2);
+ row_0 = _mm_test_all_ones(_mm_cmpeq_epi16(temp4, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_add_epi16(temp5, pred_r1);
+ temp5 = _mm_min_epi16(dupmax_8x16b, temp5);
+ temp5 = _mm_max_epi16(dupmin_8x16b, temp5);
+ temp5 = _mm_and_si128(temp5, chroma_mask2);
+ row_1 = _mm_test_all_ones(_mm_cmpeq_epi16(temp5, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_add_epi16(temp6, pred_r2);
+ temp6 = _mm_min_epi16(dupmax_8x16b, temp6);
+ temp6 = _mm_max_epi16(dupmin_8x16b, temp6);
+ temp6 = _mm_and_si128(temp6, chroma_mask2);
+ row_2 = _mm_test_all_ones(_mm_cmpeq_epi16(temp6, zero_8x16b)); // return 1 if all zeros, else 0
+
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_add_epi16(temp7, pred_r3);
+ temp7 = _mm_min_epi16(dupmax_8x16b, temp7);
+ temp7 = _mm_max_epi16(dupmin_8x16b, temp7);
+ temp7 = _mm_and_si128(temp7, chroma_mask2);
+ row_3 = _mm_test_all_ones(_mm_cmpeq_epi32(temp7, zero_8x16b)); // return 1 if all zeros, else 0
+
+ out_8x16b_0 = _mm_loadu_si128((__m128i *) (&pi2_out[0]));
+ out_8x16b_1 = _mm_loadu_si128((__m128i *) (&pi2_out[out_strd]));
+ out_8x16b_2 = _mm_loadu_si128((__m128i *) (&pi2_out[(out_strd << 1)]));
+ out_8x16b_3 = _mm_loadu_si128((__m128i *) (&pi2_out[(out_strd << 1) + out_strd]));
+
+ out_8x16b_0 = _mm_and_si128(out_8x16b_0, chroma_mask);
+ out_8x16b_1 = _mm_and_si128(out_8x16b_1, chroma_mask);
+ out_8x16b_2 = _mm_and_si128(out_8x16b_2, chroma_mask);
+ out_8x16b_3 = _mm_and_si128(out_8x16b_3, chroma_mask);
+
+ out_8x16b_0 = _mm_add_epi16(temp4, out_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(temp5, out_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(temp6, out_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(temp7, out_8x16b_3);
+
+ _mm_storeu_si128((__m128i *) (pi2_out), out_8x16b_0);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd), out_8x16b_1);
+ _mm_storeu_si128((__m128i *) (pi2_out + (out_strd << 1)), out_8x16b_2);
+ _mm_storeu_si128((__m128i *) (pi2_out + (out_strd * 3)), out_8x16b_3);
+
+ i4_nnz = !(row_0 && row_1 && row_2 && row_3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_residual_chroma_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the resd output from the */
+/* IQ+IT */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : i4_nnz */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_iquant_itrans_residual_chroma_4x4_dc_sse42(
+ WORD16 *pi2_src, WORD16 *pi2_pred, WORD16 *pi2_out, WORD32 pred_strd, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ __m128i pred_8x16b_0, out_8x16b_0;
+ __m128i pred_8x16b_1, out_8x16b_1;
+ __m128i pred_8x16b_2, out_8x16b_2;
+ __m128i pred_8x16b_3, out_8x16b_3;
+
+ __m128i i_macro_8x16b, chroma_mask, chroma_mask2;
+ __m128i zero_8x16b = _mm_setzero_si128();
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ WORD32 i4_nnz, row_0, row_1, row_2, row_3;
+ WORD32 q0;
+ WORD16 i_macro;
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(pi2_tmp);
+ UNUSED(u4_qp_div_6);
+
+ q0 = pi2_dc_src[0]; // Restoring dc value for intra case3
+ i_macro = ((q0 + 32) >> 6);
+
+ i_macro_8x16b = _mm_set1_epi16(i_macro);
+
+ pred_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_pred));
+ pred_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_pred + pred_strd));
+ pred_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_pred + (pred_strd << 1)));
+ pred_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_pred + (pred_strd << 1) + pred_strd));
+
+ pred_8x16b_0 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_add_epi16(i_macro_8x16b, pred_8x16b_3);
+
+ pred_8x16b_0 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_0);
+ pred_8x16b_0 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_0);
+ pred_8x16b_1 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_1);
+ pred_8x16b_1 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_1);
+ pred_8x16b_2 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_2);
+ pred_8x16b_2 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_2);
+ pred_8x16b_3 = _mm_min_epi16(dupmax_8x16b, pred_8x16b_3);
+ pred_8x16b_3 = _mm_max_epi16(dupmin_8x16b, pred_8x16b_3);
+
+ chroma_mask = _mm_set1_epi32(0xFFFF0000);
+ chroma_mask2 = _mm_set1_epi32(0x0000FFFF);
+ out_8x16b_0 = _mm_loadu_si128((__m128i *) (&pi2_out[0]));
+ out_8x16b_1 = _mm_loadu_si128((__m128i *) (&pi2_out[out_strd]));
+ out_8x16b_2 = _mm_loadu_si128((__m128i *) (&pi2_out[(out_strd << 1)]));
+ out_8x16b_3 = _mm_loadu_si128((__m128i *) (&pi2_out[(out_strd << 1) + out_strd]));
+
+ out_8x16b_0 = _mm_and_si128(out_8x16b_0, chroma_mask);
+ out_8x16b_1 = _mm_and_si128(out_8x16b_1, chroma_mask);
+ out_8x16b_2 = _mm_and_si128(out_8x16b_2, chroma_mask);
+ out_8x16b_3 = _mm_and_si128(out_8x16b_3, chroma_mask);
+
+ pred_8x16b_0 = _mm_and_si128(pred_8x16b_0, chroma_mask2);
+ pred_8x16b_1 = _mm_and_si128(pred_8x16b_1, chroma_mask2);
+ pred_8x16b_2 = _mm_and_si128(pred_8x16b_2, chroma_mask2);
+ pred_8x16b_3 = _mm_and_si128(pred_8x16b_3, chroma_mask2);
+
+ // return 1 if all zeros, else 0
+ row_0 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_0, zero_8x16b));
+ // return 1 if all zeros, else 0
+ row_1 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_1, zero_8x16b));
+ row_2 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_2, zero_8x16b));
+ row_3 = _mm_test_all_ones(_mm_cmpeq_epi16(pred_8x16b_3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, out_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, out_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, out_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, out_8x16b_3);
+
+ _mm_storeu_si128((__m128i *) (pi2_out), out_8x16b_0);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_strd), out_8x16b_1);
+ _mm_storeu_si128((__m128i *) (pi2_out + (out_strd << 1)), out_8x16b_2);
+ _mm_storeu_si128((__m128i *) (pi2_out + (out_strd * 3)), out_8x16b_3);
+
+ i4_nnz = !(row_0 && row_1 && row_2 && row_3);
+ return i4_nnz;
+}
diff --git a/decoder/x86/svc/isvcd_iquant_itrans_sse42.c b/decoder/x86/svc/isvcd_iquant_itrans_sse42.c
new file mode 100644
index 0000000..784bfcd
--- /dev/null
+++ b/decoder/x86/svc/isvcd_iquant_itrans_sse42.c
@@ -0,0 +1,1465 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvcd_iquant_itrans_sse42.c
+*
+* @brief
+* Contains function definitions for inverse quantization, inverse
+* transform
+*
+* @author
+* Kishore
+*
+* @par List of Functions:
+* - isvcd_iquant_itrans_4x4_sse42()
+* - isvcd_iquant_itrans_chroma_4x4_sse42()
+* - isvcd_iquant_itrans_8x8_dc_sse42()
+* - isvcd_iquant_itrans_4x4_dc_sse42()
+* - isvcd_iquant_itrans_chroma_4x4_dc_sse42()
+* - isvcd_iquant_itrans_8x8_sse42()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+/* User include files */
+#include <immintrin.h>
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_iquant_itrans.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_4x4_dc_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 q0;
+ WORD16 rnd_fact = (u4_qp_div_6 < 4) ? 1 << (3 - u4_qp_div_6) : 0;
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+ __m128i i_macro;
+ UNUSED(pi2_tmp);
+
+ if(iq_start_idx == 0)
+ {
+ q0 = pi2_src[0];
+ INV_QUANT(q0, pu2_iscal_mat[0], pu2_weigh_mat[0], u4_qp_div_6, rnd_fact, 4);
+ }
+ else
+ {
+ q0 = pi2_dc_ld_addr[0]; // Restoring dc value for intra case3
+ }
+
+ i_macro = _mm_set1_epi16((q0 + 32) >> 6);
+ i_macro = _mm_min_epi16(dupmax_8x16b, i_macro);
+ i_macro = _mm_max_epi16(dupmin_8x16b, i_macro);
+
+ _mm_storel_epi64((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, i_macro);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_8x8_dc_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_8x8_dc_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ WORD32 q;
+ WORD32 rnd_fact = (qp_div < 6) ? (1 << (5 - qp_div)) : 0;
+ __m128i dupmin_8x16b, dupmax_8x16b, i_macro;
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ q = pi2_src[0];
+ INV_QUANT(q, pu2_iscale_mat[0], pu2_weigh_mat[0], qp_div, rnd_fact, 6);
+
+ i_macro = _mm_set1_epi16((q + 32) >> 6);
+ dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ i_macro = _mm_min_epi16(dupmax_8x16b, i_macro);
+ i_macro = _mm_max_epi16(dupmin_8x16b, i_macro);
+
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+ pi2_out += out_strd;
+ _mm_storeu_si128((__m128i *) pi2_out, i_macro);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4_dc_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_chroma_4x4_dc_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i i_macro = _mm_set1_epi16((pi2_dc_src[0] + 32) >> 6);
+ __m128i chroma_mask_even, chroma_mask_odd;
+ __m128i dupmax_8x16b = _mm_set1_epi16(RSD_MAX);
+ __m128i dupmin_8x16b = _mm_set1_epi16(RSD_MIN);
+
+ UNUSED(pi2_src);
+ UNUSED(pu2_iscal_mat);
+ UNUSED(pu2_weigh_mat);
+ UNUSED(pi2_tmp);
+ UNUSED(u4_qp_div_6);
+
+ i_macro = _mm_min_epi16(dupmax_8x16b, i_macro);
+ i_macro = _mm_max_epi16(dupmin_8x16b, i_macro);
+
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_out));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r1 = _mm_loadu_si128((__m128i *) (pi2_out + (1 * out_strd)));
+ src_r2 = _mm_loadu_si128((__m128i *) (pi2_out + (2 * out_strd)));
+ src_r3 = _mm_loadu_si128((__m128i *) (pi2_out + (3 * out_strd)));
+
+ chroma_mask_even =
+ _mm_set_epi16(0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff);
+ chroma_mask_odd = _mm_set_epi16(0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000);
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask_odd); // 0 src1 0 src2 0 ...
+ src_r1 = _mm_and_si128(src_r1, chroma_mask_odd);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask_odd);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask_odd);
+
+ i_macro = _mm_and_si128(i_macro, chroma_mask_even); // macro 0 macro 0 ..
+
+ src_r0 = _mm_add_epi16(src_r0, i_macro); // macro src1 macro src2 macro ...
+ src_r1 = _mm_add_epi16(src_r1, i_macro);
+ src_r2 = _mm_add_epi16(src_r2, i_macro);
+ src_r3 = _mm_add_epi16(src_r3, i_macro);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), src_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[out_strd]), src_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_out[2 * out_strd]), src_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_out[3 * out_strd]), src_r3);
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_4x4_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_4x4_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 u4_qp_div_6, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i dupmax_4x32b = _mm_set1_epi32(RSD_MAX);
+ __m128i dupmin_4x32b = _mm_set1_epi32(RSD_MIN);
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ if(iq_start_idx == 1) resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_ld_addr[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_min_epi32(dupmax_4x32b, temp4);
+ temp4 = _mm_max_epi32(dupmin_4x32b, temp4);
+
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_min_epi32(dupmax_4x32b, temp5);
+ temp5 = _mm_max_epi32(dupmin_4x32b, temp5);
+
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_min_epi32(dupmax_4x32b, temp6);
+ temp6 = _mm_max_epi32(dupmin_4x32b, temp6);
+
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_min_epi32(dupmax_4x32b, temp7);
+ temp7 = _mm_max_epi32(dupmin_4x32b, temp7);
+
+ // 32-bit to 16-bit conversion
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ resq_r0 = temp0;
+ resq_r1 = _mm_srli_si128(temp0, 8);
+ resq_r2 = temp1;
+ resq_r3 = _mm_srli_si128(temp1, 8);
+
+ _mm_storel_epi64((__m128i *) pi2_out, resq_r0);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, resq_r1);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, resq_r2);
+ pi2_out += out_strd;
+ _mm_storel_epi64((__m128i *) pi2_out, resq_r3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_8x8_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_8x8_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscale_mat, const UWORD16 *pu2_weigh_mat,
+ UWORD32 qp_div, WORD16 *pi2_tmp, WORD32 iq_start_idx,
+ WORD16 *pi2_dc_ld_addr)
+{
+ __m128i src_r0;
+ __m128i scalemat_r0;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i add_rshift = _mm_set1_epi32((qp_div < 6) ? (1 << (5 - qp_div)) : 0);
+ __m128i dequant_r0;
+ __m128i sign_reg;
+ __m128i src_r0_1, src_r0_2;
+ __m128i scalemat_r0_1, scalemat_r0_2;
+ __m128i temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
+ __m128i temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp20;
+ // To store dequantization results
+ __m128i resq_r0_1, resq_r0_2, resq_r1_1, resq_r1_2, resq_r2_1, resq_r2_2, resq_r3_1, resq_r3_2,
+ resq_r4_1, resq_r4_2, resq_r5_1, resq_r5_2, resq_r6_1, resq_r6_2, resq_r7_1, resq_r7_2;
+ __m128i dupmax_4x32b = _mm_set1_epi32(RSD_MAX);
+ __m128i dupmin_4x32b = _mm_set1_epi32(RSD_MIN);
+
+ UNUSED(pi2_tmp);
+ UNUSED(iq_start_idx);
+ UNUSED(pi2_dc_ld_addr);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform. Note : DC coeff is not scaled */
+ /*************************************************************/
+
+ // Row 0 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 -- the source matrix 0th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // b00 b01 b02 b03 b04 b05 b06 b07 -- the scaling matrix 0th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat));
+ dequant_r0 =
+ _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[0])); // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+
+ if(qp_div >= 6)
+ {
+ resq_r0_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r0_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r0_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 16
+ // bit long
+ resq_r0_1 = _mm_packs_epi32(resq_r0_1, resq_r0_2);
+ // Row 1 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 1st row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 1st row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 8));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[8]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r1_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r1_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r1_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r1_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r1_1 = _mm_packs_epi32(resq_r1_1, resq_r1_2);
+ // Row 2 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 2nd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 16));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08-- the scaling matrix 2nd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 16));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[16]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r2_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r2_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r2_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r2_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r2_1 = _mm_packs_epi32(resq_r2_1, resq_r2_2);
+ // Row 3 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 3rd row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 24));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 3rd row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 24));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[24]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b);
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 - 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r3_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r3_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r3_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r3_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r3_1 = _mm_packs_epi32(resq_r3_1, resq_r3_2);
+ // Row 4 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 4th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 32));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 4th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 32));
+ dequant_r0 = _mm_loadu_si128(
+ (__m128i *) (&pu2_weigh_mat[32])); // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r4_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r4_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r4_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r4_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7
+ resq_r4_1 = _mm_packs_epi32(resq_r4_1, resq_r4_2);
+ // Row 5 processing
+ // a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 5th row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 40));
+ // b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 5th row
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 40));
+ // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ dequant_r0 = _mm_loadu_si128((__m128i *) (&pu2_weigh_mat[40]));
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ // b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ // a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ // a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r5_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r5_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r5_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r5_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ /* a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 */
+ resq_r5_1 = _mm_packs_epi32(resq_r5_1, resq_r5_2);
+ // Row 6 processing
+ /* a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 6th row */
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 48));
+ /* b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 6th row */
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 48));
+ dequant_r0 = _mm_loadu_si128(
+ (__m128i *) (&pu2_weigh_mat[48])); // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+ /* b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result */
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ // b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ // b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ /* a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long */
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ /* a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long */
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r6_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r6_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r6_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r6_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ /* a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 */
+ resq_r6_1 = _mm_packs_epi32(resq_r6_1, resq_r6_2);
+ // Row 7 processing
+ /* a00 a01 a02 a03 a04 a05 a06 a07 a08 -- the source matrix 7th row */
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_src + 56));
+ /* b00 b01 b02 b03 b04 b05 b06 b07 b08 -- the scaling matrix 7th row */
+ scalemat_r0 = _mm_loadu_si128((__m128i *) (pu2_iscale_mat + 56));
+ dequant_r0 = _mm_loadu_si128(
+ (__m128i *) (&pu2_weigh_mat[56])); // q0 q1 q2 q3 q4 q5 q6 q7 -- all 16 bits
+ src_r0_1 = _mm_unpacklo_epi16(src_r0, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r0_2 = _mm_unpackhi_epi16(src_r0, zero_8x16b); // a04 0 a05 0 a06 0 a07 0 -- 16 bit long
+
+ /* b00*q0 b01*q1 b02*q2 b03*q3 b04*q4 b05*q5 b06*q6 b07*q7 -- 16 bit result */
+ temp10 = _mm_mullo_epi16(scalemat_r0, dequant_r0);
+ /* b00*q0 0 b01*q1 0 b02*q2 0 b03*q3 0 -- 16 bit long */
+ scalemat_r0_1 = _mm_unpacklo_epi16(temp10, zero_8x16b);
+ /* b04*q4 0 b05*q5 0 b06*q6 0 b07*q7 0 -- 16 bit long */
+ scalemat_r0_2 = _mm_unpackhi_epi16(temp10, zero_8x16b);
+ /* a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 -- 32 bits long */
+ temp5 = _mm_madd_epi16(src_r0_1, scalemat_r0_1);
+ /* a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 -- 32 bits long */
+ temp7 = _mm_madd_epi16(src_r0_2, scalemat_r0_2);
+ if(qp_div >= 6)
+ {
+ resq_r7_1 = _mm_slli_epi32(temp5, qp_div - 6);
+ resq_r7_2 = _mm_slli_epi32(temp7, qp_div - 6);
+ }
+ else
+ {
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r7_1 = _mm_srai_epi32(temp5, 6 - qp_div);
+ resq_r7_2 = _mm_srai_epi32(temp7, 6 - qp_div);
+ }
+ /* a00*b00*q0 a01*b01*q1 a02*b02*q2 a03*b03*q3 a04*b04*q4 a05*b05*q5 a06*b06*q6 a07*b07*q7 */
+ resq_r7_1 = _mm_packs_epi32(resq_r7_1, resq_r7_2);
+ /* Perform Inverse transform */
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*--------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3 a4 a5 a6 a7
+ * b0 b1 b2 b3 b4 b5 b6 b7
+ * c0 c1 c2 c3 c4 c5 c6 c7
+ * d0 d1 d2 d3 d4 d5 d6 d7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r0_1, resq_r1_1); // a0 b0 a1 b1 a2 b2 a3 b3
+ temp3 = _mm_unpacklo_epi16(resq_r2_1, resq_r3_1); // c0 d0 c1 d1 c2 d2 c3 d3
+ temp2 = _mm_unpackhi_epi16(resq_r0_1, resq_r1_1); // a4 b4 a5 b5 a6 b6 a7 b7
+ temp4 = _mm_unpackhi_epi16(resq_r2_1, resq_r3_1); // c4 d4 c5 d5 c6 d6 c7 d7
+ resq_r0_1 = _mm_unpacklo_epi32(temp1, temp3); // a0 b0 c0 d0 a1 b1 c1 d1
+ resq_r1_1 = _mm_unpackhi_epi32(temp1, temp3); // a2 b2 c2 d2 a3 b3 c3 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp2, temp4); // a4 b4 c4 d4 a5 b5 c5 d5
+ resq_r3_1 = _mm_unpackhi_epi32(temp2, temp4); // a6 b6 c6 d6 a7 b7 c7 d7
+ /*
+ * e0 e1 e2 e3 e4 e5 e6 e7
+ * f0 f1 f2 f3 f4 f5 f6 f7
+ * g0 g1 g2 g3 g4 g5 g6 g7
+ * h0 h1 h2 h3 h4 h5 h6 h7
+ */
+ temp1 = _mm_unpacklo_epi16(resq_r4_1, resq_r5_1); // e0 f0 e1 f1 e2 f2 e2 f3
+ temp3 = _mm_unpacklo_epi16(resq_r6_1, resq_r7_1); // g0 h0 g1 h1 g2 h2 g3 h3
+ temp2 = _mm_unpackhi_epi16(resq_r4_1, resq_r5_1); // e4 f4 e5 f5 e6 f6 e7 f7
+ temp4 = _mm_unpackhi_epi16(resq_r6_1, resq_r7_1); // g4 h4 g5 h5 g6 h6 g7 h7
+ resq_r4_1 = _mm_unpacklo_epi32(temp1, temp3); // e0 f0 g0 h0 e1 f1 g1 h1
+ resq_r5_1 = _mm_unpackhi_epi32(temp1, temp3); // e2 f2 g2 h2 e3 f3 g3 h3
+ resq_r6_1 = _mm_unpacklo_epi32(temp2, temp4); // e4 f4 g4 h4 e5 f5 g5 h5
+ resq_r7_1 = _mm_unpackhi_epi32(temp2, temp4); // e6 f6 g6 h6 e7 f7 g7 h7
+ /*
+ * a0 b0 c0 d0 a1 b1 c1 d1
+ * a2 b2 c2 d2 a3 b3 c3 d3
+ * a4 b4 c4 d4 a5 b5 c5 d5
+ * a6 b6 c6 d6 a7 b7 c7 d7
+ * e0 f0 g0 h0 e1 f1 g1 h1
+ * e2 f2 g2 h2 e3 f3 g3 h3
+ * e4 f4 g4 h4 e5 f5 g5 h5
+ * e6 f6 g6 h6 e7 f7 g7 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 b0 c0 d0 e0 f0 g0 h0
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // a1 b1 c1 d1 e1 f1 g1 h1
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // a2 b2 c2 d2 e2 f2 g2 h2
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // a3 b3 c3 d3 e3 f3 g3 h3
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // a4 b4 c4 d4 e4 f4 g4 h4
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // a5 b5 c5 d5 e5 f5 g5 h5
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // a6 b6 c6 d6 e6 f6 g6 h6
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // a7 b7 c7 d7 e7 f7 g7 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* y0 = w0 + w4 */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2 = w0 - w4 */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1 = -w3 + w5 - w7 - (w7 >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3 = w1 + w7 - w3 - (w3 >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4 = (w2 >> 1) - w6 */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5 = -w1 + w7 + w5 + (w5 >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6 = w2 + (w6 >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7 = w3 + w5 + w1 + (w1 >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0 = y0 + y6 */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1 = y1 + (y7 >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2 = y2 + y4 */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3 = y3 + (y5 >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4 = y2 - y4 */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5 = (y3 >> 2) - y5 */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6 = y0 - y6 */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7 = y7 - (y1 >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* x0 = z0 + z7 */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ /* x1 = z2 + z5 */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ /* x2 = z4 + z3 */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ /* x3 = z6 + z1 */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ /* x4 = z6 - z1 */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ /* x5 = z4 - z3 */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ /* x6 = z2 - z5 */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ /* x7 = z0 - z7 */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ /*------------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0 e0 f0 g0 h0
+ * a1 b1 c1 d1 e1 f1 g1 h1
+ * a2 b2 c2 d2 e2 f2 g2 h2
+ * a3 b3 c3 d3 e3 f3 g3 h3
+ */
+ temp17 = _mm_unpacklo_epi16(temp1, temp2); // a0 a1 b0 b1 c0 c1 d0 d1
+ temp19 = _mm_unpacklo_epi16(temp3, temp4); // a2 a3 b2 b3 c2 c3 d2 d3
+ temp18 = _mm_unpackhi_epi16(temp1, temp2); // e0 e1 f0 f1 g0 g1 h0 h1
+ temp20 = _mm_unpackhi_epi16(temp3, temp4); // e2 e3 f2 f3 g2 g3 h2 h3
+
+ resq_r0_1 = _mm_unpacklo_epi32(temp17, temp19); // a0 a1 a2 a3 b0 b1 b2 b3
+ resq_r1_1 = _mm_unpackhi_epi32(temp17, temp19); // c0 c1 c2 c3 d0 d1 d2 d3
+ resq_r2_1 = _mm_unpacklo_epi32(temp18, temp20); // e0 e1 e2 e3 f0 f1 f2 f3
+ resq_r3_1 = _mm_unpackhi_epi32(temp18, temp20); // g0 g2 g2 g3 h0 h1 h2 h3
+ /*
+ * a4 b4 c4 d4 e4 f4 g4 h4
+ * a5 b5 c5 d5 e5 f5 g5 h5
+ * a6 b6 c6 d6 e6 f6 g6 h6
+ * a7 b7 c7 d7 e7 f7 g7 h7
+ */
+ temp17 = _mm_unpacklo_epi16(temp5, temp6); // a4 a5 b4 b5 c4 c5 d4 d5
+ temp19 = _mm_unpacklo_epi16(temp7, temp8); // a6 a7 b6 b7 c6 c7 d6 d7
+ temp18 = _mm_unpackhi_epi16(temp5, temp6); // e4 e5 f4 f5 g4 g5 h4 h5
+ temp20 = _mm_unpackhi_epi16(temp7, temp8); // e6 e7 f6 f7 g6 g7 h6 h7
+
+ resq_r4_1 = _mm_unpacklo_epi32(temp17, temp19); // a4 a5 a6 a7 b4 b5 b6 b7
+ resq_r5_1 = _mm_unpackhi_epi32(temp17, temp19); // c4 c5 c6 c7 d4 d5 d6 d7
+ resq_r6_1 = _mm_unpacklo_epi32(temp18, temp20); // e4 e5 e6 e7 f4 f5 f6 f7
+ resq_r7_1 = _mm_unpackhi_epi32(temp18, temp20); // g4 g5 g6 g7 h4 h5 h6 h7
+ /* a0 a1 a2 a3 b0 b1 b2 b3
+ * c0 c1 c2 c3 d0 d1 d2 d3
+ * e0 e1 e2 e3 f0 f1 f2 f3
+ * g0 g2 g2 g3 h0 h1 h2 h3
+ * a4 a5 a6 a7 b4 b5 b6 b7
+ * c4 c5 c6 c7 d4 d5 d6 d7
+ * e4 e5 e6 e7 f4 f5 f6 f7
+ * g4 g5 g6 g7 h4 h5 h6 h7
+ */
+ resq_r0_2 = _mm_unpacklo_epi64(resq_r0_1, resq_r4_1); // a0 a1 a2 a3 a4 a5 a6 a7
+ resq_r1_2 = _mm_unpackhi_epi64(resq_r0_1, resq_r4_1); // b0 b1 b2 b3 b4 b5 b6 b7
+ resq_r2_2 = _mm_unpacklo_epi64(resq_r1_1, resq_r5_1); // c0 c1 c2 c3 c4 c5 c6 c7
+ resq_r3_2 = _mm_unpackhi_epi64(resq_r1_1, resq_r5_1); // d0 d1 d2 d3 d4 d5 d6 d7
+ resq_r4_2 = _mm_unpacklo_epi64(resq_r2_1, resq_r6_1); // e0 e1 e2 e3 e4 e5 e6 e7
+ resq_r5_2 = _mm_unpackhi_epi64(resq_r2_1, resq_r6_1); // f0 f1 f2 f3 f4 f5 f6 f7
+ resq_r6_2 = _mm_unpacklo_epi64(resq_r3_1, resq_r7_1); // g0 g1 g2 g3 g4 g5 g6 g7
+ resq_r7_2 = _mm_unpackhi_epi64(resq_r3_1, resq_r7_1); // h0 h1 h2 h3 h4 h5 h6 h7
+
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r1_2);
+ resq_r1_1 = _mm_unpacklo_epi16(resq_r1_2, sign_reg); // a1 b1 c1 d1 -- 32 bit
+ resq_r1_2 = _mm_unpackhi_epi16(resq_r1_2, sign_reg); // e1 f1 g1 h1 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r3_2);
+ resq_r3_1 = _mm_unpacklo_epi16(resq_r3_2, sign_reg); // a3 b3 c3 d3 -- 32 bit
+ resq_r3_2 = _mm_unpackhi_epi16(resq_r3_2, sign_reg); // e3 f3 g3 h3 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r5_2);
+ resq_r5_1 = _mm_unpacklo_epi16(resq_r5_2, sign_reg); // a5 b5 c5 d5 -- 32 bit
+ resq_r5_2 = _mm_unpackhi_epi16(resq_r5_2, sign_reg); // e5 f5 g5 h5 -- 32 bit
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, resq_r7_2);
+ resq_r7_1 = _mm_unpacklo_epi16(resq_r7_2, sign_reg); // a7 b7 c7 d7 -- 32 bit
+ resq_r7_2 = _mm_unpackhi_epi16(resq_r7_2, sign_reg); // e7 f7 g7 h7 -- 32 bit
+
+ /*--------------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* */
+
+ /* y0j = w0j + w4j */
+ temp1 = _mm_add_epi16(resq_r0_2, resq_r4_2);
+ /* y2j = w0j - w4j */
+ temp3 = _mm_sub_epi16(resq_r0_2, resq_r4_2);
+ /* y1j = -w3j + w5j - w7j - (w7j >> 1) */
+ temp2 = _mm_sub_epi32(resq_r5_1, resq_r3_1); //-w3+w5
+ temp10 = _mm_sub_epi32(resq_r5_2, resq_r3_2);
+ temp4 = _mm_sub_epi32(temp2, resq_r7_1); //-w3+w5-w7
+ temp12 = _mm_sub_epi32(temp10, resq_r7_2);
+ temp5 = _mm_srai_epi32(resq_r7_1, 1); // w7>>1
+ temp13 = _mm_srai_epi32(resq_r7_2, 1);
+ temp2 = _mm_sub_epi32(temp4, temp5); //-w3+w5-w7 -(w7>>1)
+ temp10 = _mm_sub_epi32(temp12, temp13);
+ temp2 = _mm_packs_epi32(temp2, temp10);
+ /* y3j = w1j + w7j - w3j - (w3j >> 1) */
+ temp4 = _mm_add_epi32(resq_r1_1, resq_r7_1); // w1+w7
+ temp12 = _mm_add_epi32(resq_r1_2, resq_r7_2);
+ temp4 = _mm_sub_epi32(temp4, resq_r3_1); // w1+w7-w3
+ temp12 = _mm_sub_epi32(temp12, resq_r3_2);
+ temp5 = _mm_srai_epi32(resq_r3_1, 1); // w3>>1
+ temp13 = _mm_srai_epi32(resq_r3_2, 1);
+ temp4 = _mm_sub_epi32(temp4, temp5); // w1+w7-w3-(w3>>1)
+ temp12 = _mm_sub_epi32(temp12, temp13);
+ temp4 = _mm_packs_epi32(temp4, temp12);
+ /* y4j = (w2j >> 1) - w6j */
+ temp5 = _mm_srai_epi16(resq_r2_2, 1); // w2>>1
+ temp5 = _mm_sub_epi16(temp5, resq_r6_2); //(w2>>1)-w6
+ /* y5j = -w1j + w7j + w5j + (w5j >> 1) */
+ temp6 = _mm_sub_epi32(resq_r7_1, resq_r1_1); // w7-w1
+ temp14 = _mm_sub_epi32(resq_r7_2, resq_r1_2);
+ temp6 = _mm_add_epi32(temp6, resq_r5_1); // w7-w1+w5
+ temp14 = _mm_add_epi32(temp14, resq_r5_2);
+ temp7 = _mm_srai_epi32(resq_r5_1, 1); // w5>>1
+ temp15 = _mm_srai_epi32(resq_r5_2, 1);
+ temp6 = _mm_add_epi32(temp6, temp7); // w7-w1_w5+(w5>>1)
+ temp14 = _mm_add_epi32(temp14, temp15);
+ temp6 = _mm_packs_epi32(temp6, temp14);
+ /* y6j = w2j + (w6j >> 1) */
+ temp7 = _mm_srai_epi16(resq_r6_2, 1); // w6>>1
+ temp7 = _mm_add_epi16(temp7, resq_r2_2); //(w6>>1)+w2
+ /* y7j = w3j + w5j + w1j + (w1j >> 1) */
+ temp8 = _mm_add_epi32(resq_r3_1, resq_r5_1); // w3+w5
+ temp16 = _mm_add_epi32(resq_r3_2, resq_r5_2);
+ temp8 = _mm_add_epi32(temp8, resq_r1_1); // w3+w5+w1
+ temp16 = _mm_add_epi32(temp16, resq_r1_2);
+ temp17 = _mm_srai_epi32(resq_r1_1, 1); // w1>>1
+ temp18 = _mm_srai_epi32(resq_r1_2, 1);
+ temp8 = _mm_add_epi32(temp8, temp17); // w3+w5+w1+(w1>>1)
+ temp16 = _mm_add_epi32(temp16, temp18);
+ temp8 = _mm_packs_epi32(temp8, temp16);
+ /*------------------------------------------------------------------*/
+ /*------------------------------------------------------------------*/
+ /* z0j = y0j + y6j */
+ resq_r0_1 = _mm_add_epi16(temp1, temp7);
+ /* z1j = y1j + (y7j >> 2) */
+ resq_r1_1 = _mm_srai_epi16(temp8, 2);
+ resq_r1_1 = _mm_add_epi16(resq_r1_1, temp2);
+ /* z2j = y2j + y4j */
+ resq_r2_1 = _mm_add_epi16(temp3, temp5);
+ /* z3j = y3j + (y5j >> 2) */
+ resq_r3_1 = _mm_srai_epi16(temp6, 2);
+ resq_r3_1 = _mm_add_epi16(resq_r3_1, temp4);
+ /* z4j = y2j - y4j */
+ resq_r4_1 = _mm_sub_epi16(temp3, temp5);
+ /* z5j = (y3j >> 2) - y5j */
+ resq_r5_1 = _mm_srai_epi16(temp4, 2);
+ resq_r5_1 = _mm_sub_epi16(resq_r5_1, temp6);
+ /* z6j = y0j - y6j */
+ resq_r6_1 = _mm_sub_epi16(temp1, temp7);
+ /* z7j = y7j - (y1j >> 2) */
+ resq_r7_1 = _mm_srai_epi16(temp2, 2);
+ resq_r7_1 = _mm_sub_epi16(temp8, resq_r7_1);
+ /*------------------------------------------------------------------*/
+
+ /*------------------------------------------------------------------*/
+ /* x0j = z0j + z7j */
+ temp1 = _mm_add_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp1);
+ temp10 = _mm_unpacklo_epi16(temp1, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp1, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp1 = temp10; //_mm_add_epi16(temp10, pred_r0_1);
+ /* x1j = z2j + z5j */
+ temp2 = _mm_add_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp2);
+ temp10 = _mm_unpacklo_epi16(temp2, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp2, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp2 = temp10; //_mm_add_epi16(temp10, pred_r1_1);
+ /* x2j = z4j + z3j */
+ temp3 = _mm_add_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp3);
+ temp10 = _mm_unpacklo_epi16(temp3, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp3, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp3 = temp10; //_mm_add_epi16(temp10, pred_r2_1);
+ /* x3j = z6j + z1j */
+ temp4 = _mm_add_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp4);
+ temp10 = _mm_unpacklo_epi16(temp4, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp4, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp4 = temp10; //_mm_add_epi16(temp10, pred_r3_1);
+ /* x4j = z6j - z1j */
+ temp5 = _mm_sub_epi16(resq_r6_1, resq_r1_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp5);
+ temp10 = _mm_unpacklo_epi16(temp5, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp5, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp5 = temp10; //_mm_add_epi16(temp10, pred_r4_1);
+ /* x5j = z4j - z3j */
+ temp6 = _mm_sub_epi16(resq_r4_1, resq_r3_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp6);
+ temp10 = _mm_unpacklo_epi16(temp6, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp6, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp6 = temp10; //_mm_add_epi16(temp10, pred_r5_1);
+ /* x6j = z2j - z5j */
+ temp7 = _mm_sub_epi16(resq_r2_1, resq_r5_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp7);
+ temp10 = _mm_unpacklo_epi16(temp7, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp7, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp7 = temp10; //_mm_add_epi16(temp10, pred_r6_1);
+ /* x7j = z0j - z7j */
+ temp8 = _mm_sub_epi16(resq_r0_1, resq_r7_1);
+ sign_reg = _mm_cmpgt_epi16(zero_8x16b, temp8);
+ temp10 = _mm_unpacklo_epi16(temp8, sign_reg);
+ temp11 = _mm_unpackhi_epi16(temp8, sign_reg);
+ temp10 = _mm_add_epi32(temp10, value_32);
+ temp11 = _mm_add_epi32(temp11, value_32);
+ temp10 = _mm_srai_epi32(temp10, 6);
+ temp10 = _mm_min_epi32(dupmax_4x32b, temp10);
+ temp10 = _mm_max_epi32(dupmin_4x32b, temp10);
+ temp11 = _mm_srai_epi32(temp11, 6);
+ temp11 = _mm_min_epi32(dupmax_4x32b, temp11);
+ temp11 = _mm_max_epi32(dupmin_4x32b, temp11);
+ temp10 = _mm_packs_epi32(temp10, temp11);
+ temp8 = temp10; //_mm_add_epi16(temp10, pred_r7_1);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), temp1);
+ _mm_storeu_si128((__m128i *) (&pi2_out[out_strd]), temp2);
+ _mm_storeu_si128((__m128i *) (&pi2_out[2 * out_strd]), temp3);
+ _mm_storeu_si128((__m128i *) (&pi2_out[3 * out_strd]), temp4);
+ _mm_storeu_si128((__m128i *) (&pi2_out[4 * out_strd]), temp5);
+ _mm_storeu_si128((__m128i *) (&pi2_out[5 * out_strd]), temp6);
+ _mm_storeu_si128((__m128i *) (&pi2_out[6 * out_strd]), temp7);
+ _mm_storeu_si128((__m128i *) (&pi2_out[7 * out_strd]), temp8);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_iquant_itrans_chroma_4x4_sse42 */
+/* */
+/* Description : this function computes the inverse quantized and */
+/* inverse transformed output */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_iquant_itrans_chroma_4x4_sse42(WORD16 *pi2_src, WORD16 *pi2_out, WORD32 out_strd,
+ const UWORD16 *pu2_iscal_mat,
+ const UWORD16 *pu2_weigh_mat, UWORD32 u4_qp_div_6,
+ WORD16 *pi2_tmp, WORD16 *pi2_dc_src)
+{
+ __m128i src_r0_r1, src_r2_r3;
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i scalemat_r0_r1, scalemat_r2_r3;
+ __m128i dequant_r0_r1, dequant_r2_r3;
+ __m128i zero_8x16b = _mm_setzero_si128(); // all bits reset to zero
+ __m128i temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+ __m128i resq_r0, resq_r1, resq_r2, resq_r3;
+ __m128i add_rshift = _mm_set1_epi32((u4_qp_div_6 < 4) ? (1 << (3 - u4_qp_div_6)) : 0);
+ __m128i value_32 = _mm_set1_epi32(32);
+ __m128i dupmax_4x32b = _mm_set1_epi32(RSD_MAX);
+ __m128i dupmin_4x32b = _mm_set1_epi32(RSD_MIN);
+
+ __m128i chroma_mask_even =
+ _mm_set_epi16(0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff);
+ __m128i chroma_mask_odd =
+ _mm_set_epi16(0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000);
+
+ UNUSED(pi2_tmp);
+
+ /*************************************************************/
+ /* Dequantization of coefficients. Will be replaced by SIMD */
+ /* operations on platform */
+ /*************************************************************/
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0_r1 = _mm_loadu_si128((__m128i *) (pi2_src));
+ // a20 a21 a22 a23 a30 a31 a32 a33 --the source matrix 2nd,3rd row
+ src_r2_r3 = _mm_loadu_si128((__m128i *) (pi2_src + 8));
+ // b00 b01 b02 b03 b10 b11 b12 b13 -- the scaling matrix 0th,1st row
+ scalemat_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat));
+ // b20 b21 b22 b23 b30 b31 b32 b33 -- the scaling matrix 2nd,3rd row
+ scalemat_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_iscal_mat + 8));
+ // q00 q01 q02 q03 q10 q11 q12 q13 -- all 16 bits
+ dequant_r0_r1 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat));
+ // q20 q21 q22 q23 q30 q31 q32 q33 -- all 16 bits
+ dequant_r2_r3 = _mm_loadu_si128((__m128i *) (pu2_weigh_mat + 8));
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp0 = _mm_mullo_epi16(scalemat_r0_r1, dequant_r0_r1);
+ // b00*q00 b01*q01 b02*q02 b03*q03 b10*q10 b11*q11 b12*q12 b13*q13 -- 16 bit result
+ temp1 = _mm_mullo_epi16(scalemat_r2_r3, dequant_r2_r3);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp4 = _mm_unpacklo_epi16(temp0, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp5 = _mm_unpackhi_epi16(temp0, zero_8x16b);
+ // b00*q00 0 b01*q01 0 b02*q02 0 b03*q03 0 -- 16 bit long
+ temp6 = _mm_unpacklo_epi16(temp1, zero_8x16b);
+ // b10*q10 0 b11*q11 0 b12*q12 0 b13*q13 0 -- 16 bit long
+ temp7 = _mm_unpackhi_epi16(temp1, zero_8x16b);
+
+ src_r0 = _mm_unpacklo_epi16(src_r0_r1, zero_8x16b); // a00 0 a01 0 a02 0 a03 0 -- 16 bit long
+ src_r1 = _mm_unpackhi_epi16(src_r0_r1, zero_8x16b); // a10 0 a11 0 a12 0 a13 0 -- 16 bit long
+ src_r2 = _mm_unpacklo_epi16(src_r2_r3, zero_8x16b); // a20 0 a21 0 a22 0 a23 0 -- 16 bit long
+ src_r3 = _mm_unpackhi_epi16(src_r2_r3, zero_8x16b); // a30 0 a31 0 a32 0 a33 0 -- 16 bit long
+
+ // a00*b00*q00 a10*b10*q10 a20*b20*q20 a30*b30 q30 -- 32 bits long
+ temp4 = _mm_madd_epi16(src_r0, temp4);
+ temp5 = _mm_madd_epi16(src_r1, temp5);
+ temp6 = _mm_madd_epi16(src_r2, temp6);
+ temp7 = _mm_madd_epi16(src_r3, temp7);
+
+ if(u4_qp_div_6 >= 4)
+ {
+ resq_r0 = _mm_slli_epi32(temp4, u4_qp_div_6 - 4);
+ resq_r1 = _mm_slli_epi32(temp5, u4_qp_div_6 - 4);
+ resq_r2 = _mm_slli_epi32(temp6, u4_qp_div_6 - 4);
+ resq_r3 = _mm_slli_epi32(temp7, u4_qp_div_6 - 4);
+ }
+ else
+ {
+ temp4 = _mm_add_epi32(temp4, add_rshift);
+ temp5 = _mm_add_epi32(temp5, add_rshift);
+ temp6 = _mm_add_epi32(temp6, add_rshift);
+ temp7 = _mm_add_epi32(temp7, add_rshift);
+ resq_r0 = _mm_srai_epi32(temp4, 4 - u4_qp_div_6);
+ resq_r1 = _mm_srai_epi32(temp5, 4 - u4_qp_div_6);
+ resq_r2 = _mm_srai_epi32(temp6, 4 - u4_qp_div_6);
+ resq_r3 = _mm_srai_epi32(temp7, 4 - u4_qp_div_6);
+ }
+
+ resq_r0 = _mm_insert_epi32(resq_r0, (WORD32) pi2_dc_src[0], 0);
+ /* Perform Inverse transform */
+ /*-------------------------------------------------------------*/
+ /* IDCT [ Horizontal transformation ] */
+ /*-------------------------------------------------------------*/
+ // Matrix transpose
+ /*
+ * a0 a1 a2 a3
+ * b0 b1 b2 b3
+ * c0 c1 c2 c3
+ * d0 d1 d2 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 b0 a1 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // c0 d0 c1 d1
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // a2 b2 a3 b3
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 d2 c3 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 b0 c0 d0
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // a1 b1 c1 d1
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // a2 b2 c2 d2
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // a3 b3 c3 d3
+ // Transform starts -- horizontal transform
+ /*------------------------------------------------------------------*/
+ /* z0 = w0 + w2 */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1 = w0 - w2 */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2 = (w1 >> 1) - w3 */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(w1>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3); //(w1>>1) - w3
+ /* z3 = w1 + (w3 >> 1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(w3>>1) + w1
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+ /*----------------------------------------------------------*/
+ /* x0 = z0 + z3 */
+ resq_r0 = _mm_add_epi32(temp0, temp3);
+ /* x1 = z1 + z2 */
+ resq_r1 = _mm_add_epi32(temp1, temp2);
+ /* x2 = z1 - z2 */
+ resq_r2 = _mm_sub_epi32(temp1, temp2);
+ /* x3 = z0 - z3 */
+ resq_r3 = _mm_sub_epi32(temp0, temp3);
+ // Matrix transpose
+ /*
+ * a0 b0 c0 d0
+ * a1 b1 c1 d1
+ * a2 b2 c2 d2
+ * a3 b3 c3 d3
+ */
+ temp1 = _mm_unpacklo_epi32(resq_r0, resq_r1); // a0 a1 b0 b1
+ temp3 = _mm_unpacklo_epi32(resq_r2, resq_r3); // a2 a3 b2 b3
+ temp2 = _mm_unpackhi_epi32(resq_r0, resq_r1); // c0 c1 d0 d1
+ temp4 = _mm_unpackhi_epi32(resq_r2, resq_r3); // c2 c3 d2 d3
+ resq_r0 = _mm_unpacklo_epi64(temp1, temp3); // a0 a1 a2 a3
+ resq_r1 = _mm_unpackhi_epi64(temp1, temp3); // b0 b1 b2 b3
+ resq_r2 = _mm_unpacklo_epi64(temp2, temp4); // c0 c1 c2 c3
+ resq_r3 = _mm_unpackhi_epi64(temp2, temp4); // d0 d1 d2 d3
+ // Transform ends -- horizontal transform
+
+ /*--------------------------------------------------------------*/
+ /* IDCT [ Vertical transformation] and Xij = (xij + 32)>>6 */
+ /* Add the prediction and store it back to same buffer */
+ /*--------------------------------------------------------------*/
+ /* z0j = y0j + y2j */
+ temp0 = _mm_add_epi32(resq_r0, resq_r2);
+ /* z1j = y0j - y2j */
+ temp1 = _mm_sub_epi32(resq_r0, resq_r2);
+ /* z2j = (y1j>>1) - y3j */
+ temp2 = _mm_srai_epi32(resq_r1, 1); //(y1j>>1)
+ temp2 = _mm_sub_epi32(temp2, resq_r3);
+ /* z3j = y1j + (y3j>>1) */
+ temp3 = _mm_srai_epi32(resq_r3, 1); //(y3j>>1)
+ temp3 = _mm_add_epi32(temp3, resq_r1);
+
+ /* x0j = z0j + z3j */
+ temp4 = _mm_add_epi32(temp0, temp3);
+ temp4 = _mm_add_epi32(temp4, value_32);
+ temp4 = _mm_srai_epi32(temp4, 6);
+ temp4 = _mm_min_epi32(dupmax_4x32b, temp4);
+ temp4 = _mm_max_epi32(dupmin_4x32b, temp4);
+
+ /* x1j = z1j + z2j */
+ temp5 = _mm_add_epi32(temp1, temp2);
+ temp5 = _mm_add_epi32(temp5, value_32);
+ temp5 = _mm_srai_epi32(temp5, 6);
+ temp5 = _mm_min_epi32(dupmax_4x32b, temp5);
+ temp5 = _mm_max_epi32(dupmin_4x32b, temp5);
+
+ /* x2j = z1j - z2j */
+ temp6 = _mm_sub_epi32(temp1, temp2);
+ temp6 = _mm_add_epi32(temp6, value_32);
+ temp6 = _mm_srai_epi32(temp6, 6);
+ temp6 = _mm_min_epi32(dupmax_4x32b, temp6);
+ temp6 = _mm_max_epi32(dupmin_4x32b, temp6);
+
+ /* x3j = z0j - z3j */
+ temp7 = _mm_sub_epi32(temp0, temp3);
+ temp7 = _mm_add_epi32(temp7, value_32);
+ temp7 = _mm_srai_epi32(temp7, 6);
+ temp7 = _mm_min_epi32(dupmax_4x32b, temp7);
+ temp7 = _mm_max_epi32(dupmin_4x32b, temp7);
+
+ // 32-bit to 16-bit conversion
+ temp0 = _mm_packs_epi32(temp4, temp5);
+ temp1 = _mm_packs_epi32(temp6, temp7);
+
+ resq_r0 = temp0;
+ resq_r1 = _mm_srli_si128(temp0, 8);
+ resq_r2 = temp1;
+ resq_r3 = _mm_srli_si128(temp1, 8);
+
+ // a00 a01 a02 a03 a10 a11 a12 a13 -- the source matrix 0th,1st row
+ src_r0 = _mm_loadu_si128((__m128i *) (pi2_out));
+ // a20 a21 a22 a23 a30 a31 a32 a33 -- the source matrix 2nd,3rd row
+ src_r1 = _mm_loadu_si128((__m128i *) (pi2_out + (1 * out_strd)));
+
+ src_r2 = _mm_loadu_si128((__m128i *) (pi2_out + (2 * out_strd)));
+ src_r3 = _mm_loadu_si128((__m128i *) (pi2_out + (3 * out_strd)));
+
+ resq_r0 = _mm_and_si128(temp4, chroma_mask_even); // macro 0 macro 0 ..
+ resq_r1 = _mm_and_si128(temp5, chroma_mask_even);
+ resq_r2 = _mm_and_si128(temp6, chroma_mask_even);
+ resq_r3 = _mm_and_si128(temp7, chroma_mask_even);
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask_odd); // 0 src1 0 src2 0 ...
+ src_r1 = _mm_and_si128(src_r1, chroma_mask_odd);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask_odd);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask_odd);
+
+ src_r0 = _mm_add_epi16(src_r0, resq_r0); // macro src1 macro src2 macro ...
+ src_r1 = _mm_add_epi16(src_r1, resq_r1);
+ src_r2 = _mm_add_epi16(src_r2, resq_r2);
+ src_r3 = _mm_add_epi16(src_r3, resq_r3);
+
+ _mm_storeu_si128((__m128i *) (&pi2_out[0]), src_r0);
+ _mm_storeu_si128((__m128i *) (&pi2_out[out_strd]), src_r1);
+ _mm_storeu_si128((__m128i *) (&pi2_out[2 * out_strd]), src_r2);
+ _mm_storeu_si128((__m128i *) (&pi2_out[3 * out_strd]), src_r3);
+}
diff --git a/decoder/x86/svc/isvcd_pred_residual_recon_sse42.c b/decoder/x86/svc/isvcd_pred_residual_recon_sse42.c
new file mode 100644
index 0000000..d55c8d7
--- /dev/null
+++ b/decoder/x86/svc/isvcd_pred_residual_recon_sse42.c
@@ -0,0 +1,1466 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_pred_residual_recon_sse42.c
+ *
+ * @brief
+ * Contains function definitions for pred_residual and recon transform
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_pred_residual_recon_4x4_sse42()
+ * - isvcd_pred_residual_recon_8x8_sse42()
+ * - isvcd_pred_residual_recon_16x16_sse42()
+ * - isvcd_pred_residual_recon_chroma_4x4_sse42()
+ * - isvcd_pred_residual_recon_chroma_8x8_sse42()
+ * - isvcd_residual_luma_4x4_sse42()
+ * - isvcd_residual_luma_8x8_sse42()
+ * - isvcd_residual_luma_16x16_sse42()
+ * - isvcd_residual_chroma_cb_cr_8x8_sse42()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+/* User include files */
+#include <immintrin.h>
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+#include "ih264_trans_macros.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+#include "ih264_structs.h"
+#include "isvcd_pred_residual_recon.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_4x4_sse42 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_4x4_sse42(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, out_8x16b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, out_8x16b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, out_8x16b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, out_8x16b_3, out_16x8b_3;
+ __m128i rsd_8x16b_01, rsd_8x16b_23;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+ WORD32 i4_nnz, row_01, row_23;
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1)));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + (pred_strd << 1) + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1)));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1) + rsd_strd));
+
+ rsd_8x16b_01 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ row_01 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+
+ *((WORD32 *) (pu1_out)) = _mm_cvtsi128_si32(out_16x8b_0);
+ *((WORD32 *) (pu1_out + out_strd)) = _mm_cvtsi128_si32(out_16x8b_1);
+ *((WORD32 *) (pu1_out + (out_strd << 1))) = _mm_cvtsi128_si32(out_16x8b_2);
+ *((WORD32 *) (pu1_out + (out_strd * 3))) = _mm_cvtsi128_si32(out_16x8b_3);
+ i4_nnz = !(row_01 && row_23);
+
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_8x8_sse42 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_8x8_sse42(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, out_8x16b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, out_8x16b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, out_8x16b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, out_8x16b_3, out_16x8b_3;
+ __m128i pred_16x8b_4, pred_8x16b_4, rsd_8x16b_4, out_8x16b_4, out_16x8b_4;
+ __m128i pred_16x8b_5, pred_8x16b_5, rsd_8x16b_5, out_8x16b_5, out_16x8b_5;
+ __m128i pred_16x8b_6, pred_8x16b_6, rsd_8x16b_6, out_8x16b_6, out_16x8b_6;
+ __m128i pred_16x8b_7, pred_8x16b_7, rsd_8x16b_7, out_8x16b_7, out_16x8b_7;
+ __m128i rsd_8x16b_01_b0, rsd_8x16b_23_b0, rsd_8x16b_45_b2, rsd_8x16b_67_b2;
+ __m128i rsd_8x16b_01_b1, rsd_8x16b_23_b1, rsd_8x16b_45_b3, rsd_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 pred_strd2 = (pred_strd << 1);
+ WORD32 pred_strd4 = (pred_strd << 2);
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+ WORD32 out_strd2 = (out_strd << 1);
+ WORD32 out_strd4 = (out_strd << 2);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_16x16_sse42 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_pred_residual_recon_16x16_sse42(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ __m128i pred_16x8b_0, pred_8x16b_0, rsd_8x16b_0, out_8x16b_0, out_16x8b_0;
+ __m128i pred_16x8b_1, pred_8x16b_1, rsd_8x16b_1, out_8x16b_1, out_16x8b_1;
+ __m128i pred_16x8b_2, pred_8x16b_2, rsd_8x16b_2, out_8x16b_2, out_16x8b_2;
+ __m128i pred_16x8b_3, pred_8x16b_3, rsd_8x16b_3, out_8x16b_3, out_16x8b_3;
+ __m128i pred_16x8b_4, pred_8x16b_4, rsd_8x16b_4, out_8x16b_4, out_16x8b_4;
+ __m128i pred_16x8b_5, pred_8x16b_5, rsd_8x16b_5, out_8x16b_5, out_16x8b_5;
+ __m128i pred_16x8b_6, pred_8x16b_6, rsd_8x16b_6, out_8x16b_6, out_16x8b_6;
+ __m128i pred_16x8b_7, pred_8x16b_7, rsd_8x16b_7, out_8x16b_7, out_16x8b_7;
+ __m128i rsd_8x16b_01_b0, rsd_8x16b_23_b0, rsd_8x16b_45_b2, rsd_8x16b_67_b2;
+ __m128i rsd_8x16b_01_b1, rsd_8x16b_23_b1, rsd_8x16b_45_b3, rsd_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 pred_strd2 = (pred_strd << 1);
+ WORD32 pred_strd4 = (pred_strd << 2);
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+ WORD32 out_strd2 = (out_strd << 1);
+ WORD32 out_strd4 = (out_strd << 2);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pu1_pred += 8;
+ pi2_rsd += 8;
+ pu1_out += 8;
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 2;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 3;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 6;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 7;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pu1_pred -= 8;
+ pi2_rsd -= 8;
+ pu1_out -= 8;
+
+ pu1_pred += (pred_strd << 3);
+ pi2_rsd += (rsd_strd << 3);
+ pu1_out += (out_strd << 3);
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 8;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 9;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 12;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 13;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pu1_pred += 8;
+ pi2_rsd += 8;
+ pu1_out += 8;
+
+ pred_16x8b_0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_16x8b_1 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd));
+ pred_16x8b_2 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2));
+ pred_16x8b_3 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd2 + pred_strd));
+ pred_16x8b_4 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4));
+ pred_16x8b_5 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd));
+ pred_16x8b_6 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2));
+ pred_16x8b_7 = _mm_loadu_si128((__m128i *) (pu1_pred + pred_strd4 + pred_strd2 + pred_strd));
+
+ pred_8x16b_0 = _mm_cvtepu8_epi16(pred_16x8b_0);
+ pred_8x16b_1 = _mm_cvtepu8_epi16(pred_16x8b_1);
+ pred_8x16b_2 = _mm_cvtepu8_epi16(pred_16x8b_2);
+ pred_8x16b_3 = _mm_cvtepu8_epi16(pred_16x8b_3);
+ pred_8x16b_4 = _mm_cvtepu8_epi16(pred_16x8b_4);
+ pred_8x16b_5 = _mm_cvtepu8_epi16(pred_16x8b_5);
+ pred_8x16b_6 = _mm_cvtepu8_epi16(pred_16x8b_6);
+ pred_8x16b_7 = _mm_cvtepu8_epi16(pred_16x8b_7);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ out_8x16b_0 = _mm_add_epi16(pred_8x16b_0, rsd_8x16b_0);
+ out_8x16b_1 = _mm_add_epi16(pred_8x16b_1, rsd_8x16b_1);
+ out_8x16b_2 = _mm_add_epi16(pred_8x16b_2, rsd_8x16b_2);
+ out_8x16b_3 = _mm_add_epi16(pred_8x16b_3, rsd_8x16b_3);
+ out_8x16b_4 = _mm_add_epi16(pred_8x16b_4, rsd_8x16b_4);
+ out_8x16b_5 = _mm_add_epi16(pred_8x16b_5, rsd_8x16b_5);
+ out_8x16b_6 = _mm_add_epi16(pred_8x16b_6, rsd_8x16b_6);
+ out_8x16b_7 = _mm_add_epi16(pred_8x16b_7, rsd_8x16b_7);
+
+ out_16x8b_0 = _mm_packus_epi16(out_8x16b_0, zero_8x16b);
+ out_16x8b_1 = _mm_packus_epi16(out_8x16b_1, zero_8x16b);
+ out_16x8b_2 = _mm_packus_epi16(out_8x16b_2, zero_8x16b);
+ out_16x8b_3 = _mm_packus_epi16(out_8x16b_3, zero_8x16b);
+ out_16x8b_4 = _mm_packus_epi16(out_8x16b_4, zero_8x16b);
+ out_16x8b_5 = _mm_packus_epi16(out_8x16b_5, zero_8x16b);
+ out_16x8b_6 = _mm_packus_epi16(out_8x16b_6, zero_8x16b);
+ out_16x8b_7 = _mm_packus_epi16(out_8x16b_7, zero_8x16b);
+
+ _mm_storel_epi64((__m128i *) (pu1_out), out_16x8b_0);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd), out_16x8b_1);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2), out_16x8b_2);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd2 + out_strd), out_16x8b_3);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4), out_16x8b_4);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd), out_16x8b_5);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2), out_16x8b_6);
+ _mm_storel_epi64((__m128i *) (pu1_out + out_strd4 + out_strd2 + out_strd), out_16x8b_7);
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 10;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 11;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 14;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 15;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_4x4_sse42 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_pred_residual_recon_chroma_4x4_sse42(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i pred0, pred1, pred2, pred3;
+ __m128i rsd_r0, rsd_r1, rsd_r2, rsd_r3;
+ __m128i zero_16x8b; // all bits reset to zero
+ __m128i chroma_mask_even;
+ __m128i chroma_mask_odd;
+
+ zero_16x8b = _mm_setzero_si128();
+
+ rsd_r0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_r1 = _mm_loadu_si128((__m128i *) (pi2_rsd + (1 * rsd_strd)));
+ rsd_r2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (2 * rsd_strd)));
+ rsd_r3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (3 * rsd_strd)));
+
+ pred_r0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred_r1 = _mm_loadu_si128((__m128i *) (pu1_pred + (1 * pred_strd)));
+ pred_r2 = _mm_loadu_si128((__m128i *) (pu1_pred + (2 * pred_strd)));
+ pred_r3 = _mm_loadu_si128((__m128i *) (pu1_pred + (3 * pred_strd)));
+
+ src_r0 = _mm_loadu_si128((__m128i *) (pu1_out));
+ src_r1 = _mm_loadu_si128((__m128i *) (pu1_out + (1 * out_strd)));
+ src_r2 = _mm_loadu_si128((__m128i *) (pu1_out + (2 * out_strd)));
+ src_r3 = _mm_loadu_si128((__m128i *) (pu1_out + (3 * out_strd)));
+
+ pred0 = _mm_cvtepu8_epi16(pred_r0);
+ pred1 = _mm_cvtepu8_epi16(pred_r1);
+ pred2 = _mm_cvtepu8_epi16(pred_r2);
+ pred3 = _mm_cvtepu8_epi16(pred_r3);
+
+ pred0 = _mm_add_epi16(pred0, rsd_r0);
+ pred1 = _mm_add_epi16(pred1, rsd_r1);
+ pred2 = _mm_add_epi16(pred2, rsd_r2);
+ pred3 = _mm_add_epi16(pred3, rsd_r3);
+
+ pred0 = _mm_packus_epi16(pred0, zero_16x8b);
+ pred1 = _mm_packus_epi16(pred1, zero_16x8b);
+ pred2 = _mm_packus_epi16(pred2, zero_16x8b);
+ pred3 = _mm_packus_epi16(pred3, zero_16x8b);
+
+ chroma_mask_even = _mm_set_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff);
+ chroma_mask_odd = _mm_set_epi8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xff, 0x00);
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask_odd); // 0 src1 0 src2 0 ...
+ src_r1 = _mm_and_si128(src_r1, chroma_mask_odd);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask_odd);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask_odd);
+
+ pred0 = _mm_and_si128(pred0, chroma_mask_even); // val 0 val 0 ..
+ pred1 = _mm_and_si128(pred1, chroma_mask_even);
+ pred2 = _mm_and_si128(pred2, chroma_mask_even);
+ pred3 = _mm_and_si128(pred3, chroma_mask_even);
+
+ src_r0 = _mm_add_epi8(src_r0, pred0); // macro src1 macro src2 macro ...
+ src_r1 = _mm_add_epi8(src_r1, pred1);
+ src_r2 = _mm_add_epi8(src_r2, pred2);
+ src_r3 = _mm_add_epi8(src_r3, pred3);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), src_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[out_strd]), src_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * out_strd]), src_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * out_strd]), src_r3);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_pred_residual_recon_chroma_8x8_sse42 */
+/* */
+/* Description : this function computes the recon from */
+/* the residual and pred buffer */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_pred_residual_recon_chroma_8x8_sse42(UWORD8 *pu1_pred, WORD16 *pi2_rsd, UWORD8 *pu1_out,
+ WORD32 pred_strd, WORD32 rsd_strd, WORD32 out_strd)
+{
+ __m128i src_r0, src_r1, src_r2, src_r3, src_r4, src_r5, src_r6, src_r7;
+ __m128i pred0, pred1, pred2, pred3, pred4, pred5, pred6, pred7;
+ __m128i rsd_r0, rsd_r1, rsd_r2, rsd_r3, rsd_r4, rsd_r5, rsd_r6, rsd_r7;
+ __m128i zero_16x8b; // all bits reset to zero
+ __m128i chroma_mask_even;
+ __m128i chroma_mask_odd;
+
+ zero_16x8b = _mm_setzero_si128();
+
+ rsd_r0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_r1 = _mm_loadu_si128((__m128i *) (pi2_rsd + (1 * rsd_strd)));
+ rsd_r2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (2 * rsd_strd)));
+ rsd_r3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (3 * rsd_strd)));
+ rsd_r4 = _mm_loadu_si128((__m128i *) (pi2_rsd + (4 * rsd_strd)));
+ rsd_r5 = _mm_loadu_si128((__m128i *) (pi2_rsd + (5 * rsd_strd)));
+ rsd_r6 = _mm_loadu_si128((__m128i *) (pi2_rsd + (6 * rsd_strd)));
+ rsd_r7 = _mm_loadu_si128((__m128i *) (pi2_rsd + (7 * rsd_strd)));
+
+ pred0 = _mm_loadu_si128((__m128i *) (pu1_pred));
+ pred1 = _mm_loadu_si128((__m128i *) (pu1_pred + (1 * pred_strd)));
+ pred2 = _mm_loadu_si128((__m128i *) (pu1_pred + (2 * pred_strd)));
+ pred3 = _mm_loadu_si128((__m128i *) (pu1_pred + (3 * pred_strd)));
+ pred4 = _mm_loadu_si128((__m128i *) (pu1_pred + (4 * pred_strd)));
+ pred5 = _mm_loadu_si128((__m128i *) (pu1_pred + (5 * pred_strd)));
+ pred6 = _mm_loadu_si128((__m128i *) (pu1_pred + (6 * pred_strd)));
+ pred7 = _mm_loadu_si128((__m128i *) (pu1_pred + (7 * pred_strd)));
+
+ src_r0 = _mm_loadu_si128((__m128i *) (pu1_out));
+ src_r1 = _mm_loadu_si128((__m128i *) (pu1_out + (1 * out_strd)));
+ src_r2 = _mm_loadu_si128((__m128i *) (pu1_out + (2 * out_strd)));
+ src_r3 = _mm_loadu_si128((__m128i *) (pu1_out + (3 * out_strd)));
+ src_r4 = _mm_loadu_si128((__m128i *) (pu1_out + (4 * out_strd)));
+ src_r5 = _mm_loadu_si128((__m128i *) (pu1_out + (5 * out_strd)));
+ src_r6 = _mm_loadu_si128((__m128i *) (pu1_out + (6 * out_strd)));
+ src_r7 = _mm_loadu_si128((__m128i *) (pu1_out + (7 * out_strd)));
+
+ pred0 = _mm_cvtepu8_epi16(pred0);
+ pred1 = _mm_cvtepu8_epi16(pred1);
+ pred2 = _mm_cvtepu8_epi16(pred2);
+ pred3 = _mm_cvtepu8_epi16(pred3);
+ pred4 = _mm_cvtepu8_epi16(pred4);
+ pred5 = _mm_cvtepu8_epi16(pred5);
+ pred6 = _mm_cvtepu8_epi16(pred6);
+ pred7 = _mm_cvtepu8_epi16(pred7);
+
+ pred0 = _mm_add_epi16(pred0, rsd_r0);
+ pred1 = _mm_add_epi16(pred1, rsd_r1);
+ pred2 = _mm_add_epi16(pred2, rsd_r2);
+ pred3 = _mm_add_epi16(pred3, rsd_r3);
+ pred4 = _mm_add_epi16(pred4, rsd_r4);
+ pred5 = _mm_add_epi16(pred5, rsd_r5);
+ pred6 = _mm_add_epi16(pred6, rsd_r6);
+ pred7 = _mm_add_epi16(pred7, rsd_r7);
+
+ pred0 = _mm_packus_epi16(pred0, zero_16x8b);
+ pred1 = _mm_packus_epi16(pred1, zero_16x8b);
+ pred2 = _mm_packus_epi16(pred2, zero_16x8b);
+ pred3 = _mm_packus_epi16(pred3, zero_16x8b);
+ pred4 = _mm_packus_epi16(pred4, zero_16x8b);
+ pred5 = _mm_packus_epi16(pred5, zero_16x8b);
+ pred6 = _mm_packus_epi16(pred6, zero_16x8b);
+ pred7 = _mm_packus_epi16(pred7, zero_16x8b);
+
+ chroma_mask_even = _mm_set_epi8(0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff);
+ chroma_mask_odd = _mm_set_epi8(0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xff, 0x00);
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask_odd); // 0 src1 0 src2 0 ...
+ src_r1 = _mm_and_si128(src_r1, chroma_mask_odd);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask_odd);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask_odd);
+ src_r4 = _mm_and_si128(src_r4, chroma_mask_odd);
+ src_r5 = _mm_and_si128(src_r5, chroma_mask_odd);
+ src_r6 = _mm_and_si128(src_r6, chroma_mask_odd);
+ src_r7 = _mm_and_si128(src_r7, chroma_mask_odd);
+
+ pred0 = _mm_and_si128(pred0, chroma_mask_even); // val 0 val 0 ..
+ pred1 = _mm_and_si128(pred1, chroma_mask_even);
+ pred2 = _mm_and_si128(pred2, chroma_mask_even);
+ pred3 = _mm_and_si128(pred3, chroma_mask_even);
+ pred4 = _mm_and_si128(pred4, chroma_mask_even);
+ pred5 = _mm_and_si128(pred5, chroma_mask_even);
+ pred6 = _mm_and_si128(pred6, chroma_mask_even);
+ pred7 = _mm_and_si128(pred7, chroma_mask_even);
+
+ src_r0 = _mm_add_epi8(src_r0, pred0); // macro src1 macro src2 macro ...
+ src_r1 = _mm_add_epi8(src_r1, pred1);
+ src_r2 = _mm_add_epi8(src_r2, pred2);
+ src_r3 = _mm_add_epi8(src_r3, pred3);
+ src_r4 = _mm_add_epi8(src_r4, pred4);
+ src_r5 = _mm_add_epi8(src_r5, pred5);
+ src_r6 = _mm_add_epi8(src_r6, pred6);
+ src_r7 = _mm_add_epi8(src_r7, pred7);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0]), src_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[out_strd]), src_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[2 * out_strd]), src_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[3 * out_strd]), src_r3);
+ _mm_storel_epi64((__m128i *) (&pu1_out[4 * out_strd]), src_r4);
+ _mm_storel_epi64((__m128i *) (&pu1_out[5 * out_strd]), src_r5);
+ _mm_storel_epi64((__m128i *) (&pu1_out[6 * out_strd]), src_r6);
+ _mm_storel_epi64((__m128i *) (&pu1_out[7 * out_strd]), src_r7);
+
+ /* load and repeat for the last 4 elements interleaved in the row */
+
+ rsd_r0 = _mm_loadu_si128((__m128i *) (pi2_rsd + 8));
+ rsd_r1 = _mm_loadu_si128((__m128i *) (pi2_rsd + (1 * rsd_strd) + 8));
+ rsd_r2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (2 * rsd_strd) + 8));
+ rsd_r3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (3 * rsd_strd) + 8));
+ rsd_r4 = _mm_loadu_si128((__m128i *) (pi2_rsd + (4 * rsd_strd) + 8));
+ rsd_r5 = _mm_loadu_si128((__m128i *) (pi2_rsd + (5 * rsd_strd) + 8));
+ rsd_r6 = _mm_loadu_si128((__m128i *) (pi2_rsd + (6 * rsd_strd) + 8));
+ rsd_r7 = _mm_loadu_si128((__m128i *) (pi2_rsd + (7 * rsd_strd) + 8));
+
+ pred0 = _mm_loadu_si128((__m128i *) (pu1_pred + 8));
+ pred1 = _mm_loadu_si128((__m128i *) (pu1_pred + (1 * pred_strd) + 8));
+ pred2 = _mm_loadu_si128((__m128i *) (pu1_pred + (2 * pred_strd) + 8));
+ pred3 = _mm_loadu_si128((__m128i *) (pu1_pred + (3 * pred_strd) + 8));
+ pred4 = _mm_loadu_si128((__m128i *) (pu1_pred + (4 * pred_strd) + 8));
+ pred5 = _mm_loadu_si128((__m128i *) (pu1_pred + (5 * pred_strd) + 8));
+ pred6 = _mm_loadu_si128((__m128i *) (pu1_pred + (6 * pred_strd) + 8));
+ pred7 = _mm_loadu_si128((__m128i *) (pu1_pred + (7 * pred_strd) + 8));
+
+ src_r0 = _mm_loadu_si128((__m128i *) (pu1_out + 8));
+ src_r1 = _mm_loadu_si128((__m128i *) (pu1_out + (1 * out_strd) + 8));
+ src_r2 = _mm_loadu_si128((__m128i *) (pu1_out + (2 * out_strd) + 8));
+ src_r3 = _mm_loadu_si128((__m128i *) (pu1_out + (3 * out_strd) + 8));
+ src_r4 = _mm_loadu_si128((__m128i *) (pu1_out + (4 * out_strd) + 8));
+ src_r5 = _mm_loadu_si128((__m128i *) (pu1_out + (5 * out_strd) + 8));
+ src_r6 = _mm_loadu_si128((__m128i *) (pu1_out + (6 * out_strd) + 8));
+ src_r7 = _mm_loadu_si128((__m128i *) (pu1_out + (7 * out_strd) + 8));
+
+ pred0 = _mm_cvtepu8_epi16(pred0);
+ pred1 = _mm_cvtepu8_epi16(pred1);
+ pred2 = _mm_cvtepu8_epi16(pred2);
+ pred3 = _mm_cvtepu8_epi16(pred3);
+ pred4 = _mm_cvtepu8_epi16(pred4);
+ pred5 = _mm_cvtepu8_epi16(pred5);
+ pred6 = _mm_cvtepu8_epi16(pred6);
+ pred7 = _mm_cvtepu8_epi16(pred7);
+
+ pred0 = _mm_add_epi16(pred0, rsd_r0);
+ pred1 = _mm_add_epi16(pred1, rsd_r1);
+ pred2 = _mm_add_epi16(pred2, rsd_r2);
+ pred3 = _mm_add_epi16(pred3, rsd_r3);
+ pred4 = _mm_add_epi16(pred4, rsd_r4);
+ pred5 = _mm_add_epi16(pred5, rsd_r5);
+ pred6 = _mm_add_epi16(pred6, rsd_r6);
+ pred7 = _mm_add_epi16(pred7, rsd_r7);
+
+ pred0 = _mm_packus_epi16(pred0, zero_16x8b);
+ pred1 = _mm_packus_epi16(pred1, zero_16x8b);
+ pred2 = _mm_packus_epi16(pred2, zero_16x8b);
+ pred3 = _mm_packus_epi16(pred3, zero_16x8b);
+ pred4 = _mm_packus_epi16(pred4, zero_16x8b);
+ pred5 = _mm_packus_epi16(pred5, zero_16x8b);
+ pred6 = _mm_packus_epi16(pred6, zero_16x8b);
+ pred7 = _mm_packus_epi16(pred7, zero_16x8b);
+
+ src_r0 = _mm_and_si128(src_r0, chroma_mask_odd); // 0 src1 0 src2 0 ...
+ src_r1 = _mm_and_si128(src_r1, chroma_mask_odd);
+ src_r2 = _mm_and_si128(src_r2, chroma_mask_odd);
+ src_r3 = _mm_and_si128(src_r3, chroma_mask_odd);
+ src_r4 = _mm_and_si128(src_r4, chroma_mask_odd);
+ src_r5 = _mm_and_si128(src_r5, chroma_mask_odd);
+ src_r6 = _mm_and_si128(src_r6, chroma_mask_odd);
+ src_r7 = _mm_and_si128(src_r7, chroma_mask_odd);
+
+ pred0 = _mm_and_si128(pred0, chroma_mask_even); // val 0 val 0 ..
+ pred1 = _mm_and_si128(pred1, chroma_mask_even);
+ pred2 = _mm_and_si128(pred2, chroma_mask_even);
+ pred3 = _mm_and_si128(pred3, chroma_mask_even);
+ pred4 = _mm_and_si128(pred4, chroma_mask_even);
+ pred5 = _mm_and_si128(pred5, chroma_mask_even);
+ pred6 = _mm_and_si128(pred6, chroma_mask_even);
+ pred7 = _mm_and_si128(pred7, chroma_mask_even);
+
+ src_r0 = _mm_add_epi8(src_r0, pred0); // macro src1 macro src2 macro ...
+ src_r1 = _mm_add_epi8(src_r1, pred1);
+ src_r2 = _mm_add_epi8(src_r2, pred2);
+ src_r3 = _mm_add_epi8(src_r3, pred3);
+ src_r4 = _mm_add_epi8(src_r4, pred4);
+ src_r5 = _mm_add_epi8(src_r5, pred5);
+ src_r6 = _mm_add_epi8(src_r6, pred6);
+ src_r7 = _mm_add_epi8(src_r7, pred7);
+
+ _mm_storel_epi64((__m128i *) (&pu1_out[0] + 8), src_r0);
+ _mm_storel_epi64((__m128i *) (&pu1_out[out_strd] + 8), src_r1);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(2 * out_strd)] + 8), src_r2);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(3 * out_strd)] + 8), src_r3);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(4 * out_strd)] + 8), src_r4);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(5 * out_strd)] + 8), src_r5);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(6 * out_strd)] + 8), src_r6);
+ _mm_storel_epi64((__m128i *) (&pu1_out[(7 * out_strd)] + 8), src_r7);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_4x4_sse42 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_4x4_sse42(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ __m128i rsd_8x16b_0;
+ __m128i rsd_8x16b_1;
+ __m128i rsd_8x16b_2;
+ __m128i rsd_8x16b_3;
+ __m128i rsd_8x16b_01, rsd_8x16b_23;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+ WORD32 i4_nnz, row_01, row_23;
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1)));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + (rsd_strd << 1) + rsd_strd));
+
+ rsd_8x16b_01 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ row_01 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23, zero_8x16b));
+
+ i4_nnz = !(row_01 && row_23);
+ return i4_nnz;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_8x8_sse42 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_8x8_sse42(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ __m128i rsd_8x16b_0;
+ __m128i rsd_8x16b_1;
+ __m128i rsd_8x16b_2;
+ __m128i rsd_8x16b_3;
+ __m128i rsd_8x16b_4;
+ __m128i rsd_8x16b_5;
+ __m128i rsd_8x16b_6;
+ __m128i rsd_8x16b_7;
+ __m128i rsd_8x16b_01_b0, rsd_8x16b_23_b0, rsd_8x16b_45_b2, rsd_8x16b_67_b2;
+ __m128i rsd_8x16b_01_b1, rsd_8x16b_23_b1, rsd_8x16b_45_b3, rsd_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_16x16_sse42 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_luma_16x16_sse42(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ __m128i rsd_8x16b_0;
+ __m128i rsd_8x16b_1;
+ __m128i rsd_8x16b_2;
+ __m128i rsd_8x16b_3;
+ __m128i rsd_8x16b_4;
+ __m128i rsd_8x16b_5;
+ __m128i rsd_8x16b_6;
+ __m128i rsd_8x16b_7;
+ __m128i rsd_8x16b_01_b0, rsd_8x16b_23_b0, rsd_8x16b_45_b2, rsd_8x16b_67_b2;
+ __m128i rsd_8x16b_01_b1, rsd_8x16b_23_b1, rsd_8x16b_45_b3, rsd_8x16b_67_b3;
+
+ WORD32 row_01_b0, row_23_b0, row_45_b2, row_67_b2;
+ WORD32 row_01_b1, row_23_b1, row_45_b3, row_67_b3;
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0));
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 1;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 4;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 5;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pi2_rsd += 8;
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 2;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 3;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 6;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 7;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pi2_rsd -= 8;
+ pi2_rsd += (rsd_strd << 3);
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 8;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 9;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 12;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 13;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+
+ pi2_rsd += 8;
+
+ rsd_8x16b_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_2 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_3 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_4 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_5 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_6 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_7 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_01_b0 = _mm_unpacklo_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b0 = _mm_unpacklo_epi64(rsd_8x16b_2, rsd_8x16b_3);
+ rsd_8x16b_01_b1 = _mm_unpackhi_epi64(rsd_8x16b_0, rsd_8x16b_1);
+ rsd_8x16b_23_b1 = _mm_unpackhi_epi64(rsd_8x16b_2, rsd_8x16b_3);
+
+ rsd_8x16b_45_b2 = _mm_unpacklo_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b2 = _mm_unpacklo_epi64(rsd_8x16b_6, rsd_8x16b_7);
+ rsd_8x16b_45_b3 = _mm_unpackhi_epi64(rsd_8x16b_4, rsd_8x16b_5);
+ rsd_8x16b_67_b3 = _mm_unpackhi_epi64(rsd_8x16b_6, rsd_8x16b_7);
+
+ row_01_b0 = _mm_test_all_ones(
+ _mm_cmpeq_epi16(rsd_8x16b_01_b0, zero_8x16b)); // return 1 if all zeros, else 0
+ row_23_b0 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b0, zero_8x16b));
+ row_01_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_01_b1, zero_8x16b));
+ row_23_b1 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_23_b1, zero_8x16b));
+ row_45_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b2, zero_8x16b));
+ row_67_b2 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b2, zero_8x16b));
+ row_45_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_45_b3, zero_8x16b));
+ row_67_b3 = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_67_b3, zero_8x16b));
+
+ i4_nnz_b0 = (!(row_01_b0 && row_23_b0)) << 10;
+ i4_nnz_b1 = (!(row_01_b1 && row_23_b1)) << 11;
+ i4_nnz_b2 = (!(row_45_b2 && row_67_b2)) << 14;
+ i4_nnz_b3 = (!(row_45_b3 && row_67_b3)) << 15;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_chroma_cb_cr_8x8_sse42 */
+/* */
+/* Description : this function computes the nnz from resd */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : nnz */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+WORD32 isvcd_residual_chroma_cb_cr_8x8_sse42(WORD16 *pi2_rsd, WORD32 rsd_strd)
+{
+ __m128i rsd_8x16b_r0_0, rsd_8x16b_r0_1, mix_8x16b_r01_0_l, mix_8x16b_r01_1_l,
+ rsd_8x16b_r01_b0_cb, rsd_8x16b_r01_b1_cb;
+ __m128i rsd_8x16b_r1_0, rsd_8x16b_r1_1, mix_8x16b_r23_0_l, mix_8x16b_r23_1_l,
+ rsd_8x16b_r01_b0_cr, rsd_8x16b_r01_b1_cr;
+ __m128i rsd_8x16b_r2_0, rsd_8x16b_r2_1, mix_8x16b_r45_0_l, mix_8x16b_r45_1_l,
+ rsd_8x16b_r23_b0_cb, rsd_8x16b_r23_b1_cb;
+ __m128i rsd_8x16b_r3_0, rsd_8x16b_r3_1, mix_8x16b_r67_0_l, mix_8x16b_r67_1_l,
+ rsd_8x16b_r23_b0_cr, rsd_8x16b_r23_b1_cr;
+ __m128i rsd_8x16b_r4_0, rsd_8x16b_r4_1, mix_8x16b_r01_0_h, mix_8x16b_r01_1_h,
+ rsd_8x16b_r45_b2_cb, rsd_8x16b_r45_b3_cb;
+ __m128i rsd_8x16b_r5_0, rsd_8x16b_r5_1, mix_8x16b_r23_0_h, mix_8x16b_r23_1_h,
+ rsd_8x16b_r45_b2_cr, rsd_8x16b_r45_b3_cr;
+ __m128i rsd_8x16b_r6_0, rsd_8x16b_r6_1, mix_8x16b_r45_0_h, mix_8x16b_r45_1_h,
+ rsd_8x16b_r67_b2_cb, rsd_8x16b_r67_b3_cb;
+ __m128i rsd_8x16b_r7_0, rsd_8x16b_r7_1, mix_8x16b_r67_0_h, mix_8x16b_r67_1_h,
+ rsd_8x16b_r67_b2_cr, rsd_8x16b_r67_b3_cr;
+
+ WORD32 r01_b0_cb, r01_b0_cr;
+ WORD32 r23_b0_cb, r23_b0_cr;
+ WORD32 r01_b1_cb, r01_b1_cr;
+ WORD32 r23_b1_cb, r23_b1_cr;
+ WORD32 r45_b2_cb, r45_b2_cr;
+ WORD32 r67_b2_cb, r67_b2_cr;
+ WORD32 r45_b3_cb, r45_b3_cr;
+ WORD32 r67_b3_cb, r67_b3_cr;
+
+ WORD32 i4_nnz, i4_nnz_b0, i4_nnz_b1, i4_nnz_b2, i4_nnz_b3;
+
+ __m128i zero_8x16b = _mm_setzero_si128();
+
+ WORD32 rsd_strd2 = (rsd_strd << 1);
+ WORD32 rsd_strd4 = (rsd_strd << 2);
+
+ rsd_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pi2_rsd));
+ rsd_8x16b_r1_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd));
+ rsd_8x16b_r2_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2));
+ rsd_8x16b_r3_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd));
+ rsd_8x16b_r4_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4));
+ rsd_8x16b_r5_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd));
+ rsd_8x16b_r6_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2));
+ rsd_8x16b_r7_0 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd));
+
+ rsd_8x16b_r0_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + 8));
+ rsd_8x16b_r1_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd + 8));
+ rsd_8x16b_r2_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + 8));
+ rsd_8x16b_r3_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd2 + rsd_strd + 8));
+ rsd_8x16b_r4_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + 8));
+ rsd_8x16b_r5_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd + 8));
+ rsd_8x16b_r6_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + 8));
+ rsd_8x16b_r7_1 = _mm_loadu_si128((__m128i *) (pi2_rsd + rsd_strd4 + rsd_strd2 + rsd_strd + 8));
+
+ mix_8x16b_r01_0_l =
+ _mm_unpacklo_epi16(rsd_8x16b_r0_0, rsd_8x16b_r1_0); // a0, b0 a1 b1 a2 b2 a3 b3
+ mix_8x16b_r23_0_l = _mm_unpacklo_epi16(rsd_8x16b_r2_0, rsd_8x16b_r3_0);
+ mix_8x16b_r45_0_l = _mm_unpacklo_epi16(rsd_8x16b_r4_0, rsd_8x16b_r5_0);
+ mix_8x16b_r67_0_l = _mm_unpacklo_epi16(rsd_8x16b_r6_0, rsd_8x16b_r7_0);
+ mix_8x16b_r01_0_h =
+ _mm_unpackhi_epi16(rsd_8x16b_r0_0, rsd_8x16b_r1_0); // a4 b4 a5 b5 a6 b6 a7 b7
+ mix_8x16b_r23_0_h = _mm_unpackhi_epi16(rsd_8x16b_r2_0, rsd_8x16b_r3_0);
+ mix_8x16b_r45_0_h = _mm_unpackhi_epi16(rsd_8x16b_r4_0, rsd_8x16b_r5_0);
+ mix_8x16b_r67_0_h = _mm_unpackhi_epi16(rsd_8x16b_r6_0, rsd_8x16b_r7_0);
+
+ mix_8x16b_r01_1_l =
+ _mm_unpacklo_epi16(rsd_8x16b_r0_1, rsd_8x16b_r1_1); // a8, b8 a9 b9 a10 b10 a11 b11
+ mix_8x16b_r23_1_l = _mm_unpacklo_epi16(rsd_8x16b_r2_1, rsd_8x16b_r3_1);
+ mix_8x16b_r45_1_l = _mm_unpacklo_epi16(rsd_8x16b_r4_1, rsd_8x16b_r5_1);
+ mix_8x16b_r67_1_l = _mm_unpacklo_epi16(rsd_8x16b_r6_1, rsd_8x16b_r7_1);
+ mix_8x16b_r01_1_h =
+ _mm_unpackhi_epi16(rsd_8x16b_r0_1, rsd_8x16b_r1_1); // a12 b12 a13 b13 a14 b14 a15 b15
+ mix_8x16b_r23_1_h = _mm_unpackhi_epi16(rsd_8x16b_r2_1, rsd_8x16b_r3_1);
+ mix_8x16b_r45_1_h = _mm_unpackhi_epi16(rsd_8x16b_r4_1, rsd_8x16b_r5_1);
+ mix_8x16b_r67_1_h = _mm_unpackhi_epi16(rsd_8x16b_r6_1, rsd_8x16b_r7_1);
+
+ mix_8x16b_r01_0_l = _mm_shuffle_epi32(mix_8x16b_r01_0_l, 0b11011000); // a0b0 a2b2 a1b1 a3b3
+ mix_8x16b_r23_0_l = _mm_shuffle_epi32(mix_8x16b_r23_0_l, 0b11011000); // c0d0
+ mix_8x16b_r45_0_l = _mm_shuffle_epi32(mix_8x16b_r45_0_l, 0b11011000); // e0f0
+ mix_8x16b_r67_0_l = _mm_shuffle_epi32(mix_8x16b_r67_0_l, 0b11011000); // g0h0
+ mix_8x16b_r01_0_h = _mm_shuffle_epi32(mix_8x16b_r01_0_h, 0b11011000); // a4b4 a6b6 a5b5 a7b7
+ mix_8x16b_r23_0_h = _mm_shuffle_epi32(mix_8x16b_r23_0_h, 0b11011000); // c4d4
+ mix_8x16b_r45_0_h = _mm_shuffle_epi32(mix_8x16b_r45_0_h, 0b11011000); // e4f4
+ mix_8x16b_r67_0_h = _mm_shuffle_epi32(mix_8x16b_r67_0_h, 0b11011000); // g4h4
+
+ mix_8x16b_r01_1_l = _mm_shuffle_epi32(mix_8x16b_r01_1_l, 0b11011000);
+ mix_8x16b_r23_1_l = _mm_shuffle_epi32(mix_8x16b_r23_1_l, 0b11011000);
+ mix_8x16b_r45_1_l = _mm_shuffle_epi32(mix_8x16b_r45_1_l, 0b11011000);
+ mix_8x16b_r67_1_l = _mm_shuffle_epi32(mix_8x16b_r67_1_l, 0b11011000);
+ mix_8x16b_r01_1_h = _mm_shuffle_epi32(mix_8x16b_r01_1_h, 0b11011000);
+ mix_8x16b_r23_1_h = _mm_shuffle_epi32(mix_8x16b_r23_1_h, 0b11011000);
+ mix_8x16b_r45_1_h = _mm_shuffle_epi32(mix_8x16b_r45_1_h, 0b11011000);
+ mix_8x16b_r67_1_h = _mm_shuffle_epi32(mix_8x16b_r67_1_h, 0b11011000);
+
+ rsd_8x16b_r01_b0_cb =
+ _mm_unpacklo_epi64(mix_8x16b_r01_0_l, mix_8x16b_r01_0_h); // a0b0 a2b2 a4b4 a6b6
+ rsd_8x16b_r01_b0_cr =
+ _mm_unpackhi_epi64(mix_8x16b_r01_0_l, mix_8x16b_r01_0_h); // a1b1 a3b3 a5b5 a7b7
+ rsd_8x16b_r23_b0_cb = _mm_unpacklo_epi64(mix_8x16b_r23_0_l, mix_8x16b_r23_0_h); //
+ rsd_8x16b_r23_b0_cr = _mm_unpackhi_epi64(mix_8x16b_r23_0_l, mix_8x16b_r23_0_h);
+ rsd_8x16b_r45_b2_cb = _mm_unpacklo_epi64(mix_8x16b_r45_0_l, mix_8x16b_r45_0_h);
+ rsd_8x16b_r45_b2_cr = _mm_unpackhi_epi64(mix_8x16b_r45_0_l, mix_8x16b_r45_0_h);
+ rsd_8x16b_r67_b2_cb = _mm_unpacklo_epi64(mix_8x16b_r67_0_l, mix_8x16b_r67_0_h);
+ rsd_8x16b_r67_b2_cr = _mm_unpackhi_epi64(mix_8x16b_r67_0_l, mix_8x16b_r67_0_h);
+
+ rsd_8x16b_r01_b1_cb =
+ _mm_unpacklo_epi64(mix_8x16b_r01_1_l, mix_8x16b_r01_1_h); // a8b8 a10b10 a12b12 a14b14
+ rsd_8x16b_r01_b1_cr =
+ _mm_unpackhi_epi64(mix_8x16b_r01_1_l, mix_8x16b_r01_1_h); // a9b9 a11b11 a13b13 a15b15
+ rsd_8x16b_r23_b1_cb = _mm_unpacklo_epi64(mix_8x16b_r23_1_l, mix_8x16b_r23_1_h);
+ rsd_8x16b_r23_b1_cr = _mm_unpackhi_epi64(mix_8x16b_r23_1_l, mix_8x16b_r23_1_h);
+ rsd_8x16b_r45_b3_cb = _mm_unpacklo_epi64(mix_8x16b_r45_1_l, mix_8x16b_r45_1_h);
+ rsd_8x16b_r45_b3_cr = _mm_unpackhi_epi64(mix_8x16b_r45_1_l, mix_8x16b_r45_1_h);
+ rsd_8x16b_r67_b3_cb = _mm_unpacklo_epi64(mix_8x16b_r67_1_l, mix_8x16b_r67_1_h);
+ rsd_8x16b_r67_b3_cr = _mm_unpackhi_epi64(mix_8x16b_r67_1_l, mix_8x16b_r67_1_h);
+
+ r01_b0_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r01_b0_cb, zero_8x16b));
+ r23_b0_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r23_b0_cb, zero_8x16b));
+ r01_b1_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r01_b1_cb, zero_8x16b));
+ r23_b1_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r23_b1_cb, zero_8x16b));
+ r45_b2_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r45_b2_cb, zero_8x16b));
+ r67_b2_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r67_b2_cb, zero_8x16b));
+ r45_b3_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r45_b3_cb, zero_8x16b));
+ r67_b3_cb = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r67_b3_cb, zero_8x16b));
+
+ r01_b0_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r01_b0_cr, zero_8x16b));
+ r23_b0_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r23_b0_cr, zero_8x16b));
+ r01_b1_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r01_b1_cr, zero_8x16b));
+ r23_b1_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r23_b1_cr, zero_8x16b));
+ r45_b2_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r45_b2_cr, zero_8x16b));
+ r67_b2_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r67_b2_cr, zero_8x16b));
+ r45_b3_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r45_b3_cr, zero_8x16b));
+ r67_b3_cr = _mm_test_all_ones(_mm_cmpeq_epi16(rsd_8x16b_r67_b3_cr, zero_8x16b));
+
+ i4_nnz_b0 = (!(r01_b0_cr && r23_b0_cr));
+ i4_nnz_b1 = (!(r01_b1_cr && r23_b1_cr)) << 1;
+ i4_nnz_b2 = (!(r45_b2_cr && r67_b2_cr)) << 2;
+ i4_nnz_b3 = (!(r45_b3_cr && r67_b3_cr)) << 3;
+
+ i4_nnz = (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ i4_nnz = i4_nnz << 4;
+
+ i4_nnz_b0 = (!(r01_b0_cb && r23_b0_cb));
+ i4_nnz_b1 = (!(r01_b1_cb && r23_b1_cb)) << 1;
+ i4_nnz_b2 = (!(r45_b2_cb && r67_b2_cb)) << 2;
+ i4_nnz_b3 = (!(r45_b3_cb && r67_b3_cb)) << 3;
+
+ i4_nnz |= (i4_nnz_b0 | i4_nnz_b1 | i4_nnz_b2 | i4_nnz_b3);
+ return i4_nnz;
+}
diff --git a/decoder/x86/svc/isvcd_residual_resamp_sse42.c b/decoder/x86/svc/isvcd_residual_resamp_sse42.c
new file mode 100644
index 0000000..19a6469
--- /dev/null
+++ b/decoder/x86/svc/isvcd_residual_resamp_sse42.c
@@ -0,0 +1,1546 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvcd_residual_resamp_sse42.c
+ *
+ * @brief
+ * Contains function definitions for intra resampling functions
+ *
+ * @author
+ * Kishore
+ *
+ * @par List of Functions:
+ * - isvcd_interpolate_residual_sse42
+ * - isvcd_residual_luma_dyadic_sse42
+ * - isvcd_residual_reflayer_const_non_boundary_mb_sse42
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <immintrin.h>
+#include <smmintrin.h>
+#include <emmintrin.h>
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvcd_structs.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_luma_dyadic_sse42 */
+/* */
+/* Description : */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+void isvcd_residual_luma_dyadic_sse42(void *pv_residual_samp_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD16 *pi2_out_res,
+ WORD32 i4_out_res_stride, mem_element_t *ps_ref_mb_mode,
+ UWORD16 u2_mb_x, UWORD16 u2_mb_y, WORD32 i4_ref_nnz,
+ WORD32 i4_ref_tx_size)
+
+{
+ WORD16 *pi2_refarray_buffer;
+ WORD32 i4_blk_ctr;
+ residual_sampling_ctxt_t *ps_ctxt;
+
+ UNUSED(ps_ref_mb_mode);
+ UNUSED(u2_mb_x);
+ UNUSED(u2_mb_y);
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ pi2_refarray_buffer = ps_ctxt->pi2_refarray_buffer;
+
+ /* based on transform size the counter and interpolation width and */
+ /* height are intialised as follows */
+
+ if((i4_ref_tx_size) && (0 != i4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 i4_i, i4_j;
+ WORD16 *pi2_refarray_buffer_tmp = pi2_refarray_buffer;
+
+ __m128i i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1;
+ __m128i res_8x16b_r1_0, res_8x16b_r1_1;
+ __m128i final_res_8x16b_r1_0, final_res_8x16b_r1_1;
+
+ __m128i coeff_add_8x16b_r1;
+
+ __m128i coeff_add_8x16b_r2;
+ __m128i i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1;
+ __m128i res_8x16b_r2_0, res_8x16b_r2_1;
+ __m128i final_res_8x16b_r2_0, final_res_8x16b_r2_1;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ for(i4_i = 0; i4_i < BLOCK_HEIGHT; i4_i += 2)
+ {
+ i2_coeff_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) pi2_ref_data_byte); // a0 a1 a2 a3 a4 a5 a6 a7
+ i2_coeff_8x16b_r2_0 = _mm_loadu_si128(
+ (__m128i *) (pi2_ref_data_byte + i4_inp_data_stride)); // b0 b1 b2 b3 b4 b5 b6 b7
+
+ i2_coeff_8x16b_r1_1 = _mm_srli_si128(i2_coeff_8x16b_r1_0, 2); // a1 a2 a3 a4 a5 a6 a7 0
+ i2_coeff_8x16b_r2_1 = _mm_srli_si128(i2_coeff_8x16b_r2_0, 2); // b1 b2 b3 b4 b5 b6 b7 0
+
+ coeff_add_8x16b_r1 = _mm_add_epi16(i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1);
+ coeff_add_8x16b_r2 = _mm_add_epi16(i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1);
+
+ i2_coeff_8x16b_r1_0 = _mm_slli_epi16(i2_coeff_8x16b_r1_0, 1);
+ i2_coeff_8x16b_r2_0 = _mm_slli_epi16(i2_coeff_8x16b_r2_0, 1);
+
+ i2_coeff_8x16b_r1_1 = _mm_slli_epi16(i2_coeff_8x16b_r1_1, 1);
+ i2_coeff_8x16b_r2_1 = _mm_slli_epi16(i2_coeff_8x16b_r2_1, 1);
+
+ res_8x16b_r1_0 = _mm_add_epi16(i2_coeff_8x16b_r1_0, coeff_add_8x16b_r1);
+ res_8x16b_r2_0 = _mm_add_epi16(i2_coeff_8x16b_r2_0, coeff_add_8x16b_r2);
+
+ res_8x16b_r1_1 = _mm_add_epi16(i2_coeff_8x16b_r1_1, coeff_add_8x16b_r1);
+ res_8x16b_r2_1 = _mm_add_epi16(i2_coeff_8x16b_r2_1, coeff_add_8x16b_r2);
+
+ final_res_8x16b_r1_0 = _mm_unpacklo_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_0 = _mm_unpacklo_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+
+ final_res_8x16b_r1_1 = _mm_unpackhi_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_1 = _mm_unpackhi_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 1), final_res_8x16b_r1_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 9), final_res_8x16b_r1_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 17), final_res_8x16b_r2_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 25), final_res_8x16b_r2_1);
+
+ pi2_refarray_buffer[0] = (pi2_ref_data_byte[0] << 2);
+ pi2_refarray_buffer[15] = (pi2_ref_data_byte[7] << 2);
+ pi2_ref_data_byte += i4_inp_data_stride;
+ pi2_refarray_buffer[16] = (pi2_ref_data_byte[0] << 2);
+ pi2_refarray_buffer[31] = (pi2_ref_data_byte[7] << 2);
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 2) * i4_inp_data_stride);
+ pi2_refarray_buffer += 32;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi2_refarray_buffer = pi2_refarray_buffer_tmp;
+
+ {
+ __m128i i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r1_3,
+ i4_horz_samp_4x32b_r1_4;
+ __m128i i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r2_2, i4_horz_samp_4x32b_r2_3,
+ i4_horz_samp_4x32b_r2_4;
+ __m128i i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2, i4_res_samp_4x32b_r1_3,
+ i4_res_samp_4x32b_r1_4;
+ __m128i i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2, i4_res_samp_4x32b_r2_3,
+ i4_res_samp_4x32b_r2_4;
+ __m128i horz_add_4x32b_r2_1, horz_add_4x32b_r2_2, horz_add_4x32b_r2_3,
+ horz_add_4x32b_r2_4;
+
+ __m128i i4_horz_samp_8x16b_r1_1, i4_horz_samp_8x16b_r2_1;
+ __m128i i4_horz_samp_8x16b_r1_2, i4_horz_samp_8x16b_r2_2;
+ __m128i i4_horz_samp_8x16b_r1_3, i4_horz_samp_8x16b_r2_3;
+ __m128i i4_horz_samp_8x16b_r1_4, i4_horz_samp_8x16b_r2_4;
+
+ __m128i twos = _mm_set1_epi32(2);
+ __m128i eights = _mm_set1_epi32(8);
+
+ WORD16 *pi2_out;
+
+ pi2_out = pi2_out_res;
+
+ i4_horz_samp_8x16b_r1_1 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r1_2 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r1_3 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 8));
+ i4_horz_samp_8x16b_r1_4 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 12));
+
+ i4_horz_samp_4x32b_r1_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_1);
+ i4_horz_samp_4x32b_r1_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_2);
+ i4_horz_samp_4x32b_r1_3 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_3);
+ i4_horz_samp_4x32b_r1_4 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_4);
+
+ /* populate the first inter sample */
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_1, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_2, twos), 2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_3, twos), 2);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_4, twos), 2);
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi2_refarray_buffer += MB_WIDTH;
+
+ i4_horz_samp_8x16b_r2_1 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r2_2 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r2_3 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 8));
+ i4_horz_samp_8x16b_r2_4 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 12));
+
+ i4_horz_samp_4x32b_r2_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_1);
+ i4_horz_samp_4x32b_r2_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_2);
+ i4_horz_samp_4x32b_r2_3 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_3);
+ i4_horz_samp_4x32b_r2_4 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_4);
+
+ horz_add_4x32b_r2_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r2_1);
+ horz_add_4x32b_r2_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r2_2);
+ horz_add_4x32b_r2_3 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_3, i4_horz_samp_4x32b_r2_3);
+ horz_add_4x32b_r2_4 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_4, i4_horz_samp_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_3, 1), horz_add_4x32b_r2_3);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_4, 1), horz_add_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r2_1 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r2_3 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_3, 1), horz_add_4x32b_r2_3);
+ i4_res_samp_4x32b_r2_4 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_4, 1), horz_add_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_1, eights), 4);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_2, eights), 4);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_3, eights), 4);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_4, eights), 4);
+
+ i4_res_samp_4x32b_r2_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_1, eights), 4);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_2, eights), 4);
+ i4_res_samp_4x32b_r2_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_3, eights), 4);
+ i4_res_samp_4x32b_r2_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_4, eights), 4);
+
+ /* populate 2 samples based on current coeffs */
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ pi2_out += i4_out_res_stride;
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_3, i4_res_samp_4x32b_r2_4));
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_4x32b_r1_1 = i4_horz_samp_4x32b_r2_1;
+ i4_horz_samp_4x32b_r1_2 = i4_horz_samp_4x32b_r2_2;
+ i4_horz_samp_4x32b_r1_3 = i4_horz_samp_4x32b_r2_3;
+ i4_horz_samp_4x32b_r1_4 = i4_horz_samp_4x32b_r2_4;
+ }
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_1, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_2, twos), 2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_3, twos), 2);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_4, twos), 2);
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ /* if reference layer is not coded then no processing */
+ if(0 != (i4_ref_nnz & 0x1))
+ {
+ __m128i i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1;
+ __m128i i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1;
+ __m128i i2_coeff_8x16b_r3_0, i2_coeff_8x16b_r3_1;
+ __m128i i2_coeff_8x16b_r4_0, i2_coeff_8x16b_r4_1;
+
+ __m128i res_8x16b_r1_0, res_8x16b_r1_1;
+ __m128i res_8x16b_r2_0, res_8x16b_r2_1;
+ __m128i res_8x16b_r3_0, res_8x16b_r3_1;
+ __m128i res_8x16b_r4_0, res_8x16b_r4_1;
+ __m128i final_res_8x16b_r1_0;
+ __m128i final_res_8x16b_r2_0;
+ __m128i final_res_8x16b_r3_0;
+ __m128i final_res_8x16b_r4_0;
+
+ __m128i coeff_add_8x16b_r1;
+ __m128i coeff_add_8x16b_r2;
+ __m128i coeff_add_8x16b_r3;
+ __m128i coeff_add_8x16b_r4;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+
+ i2_coeff_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) pi2_inp_data); // a0 a1 a2 a3 a4 a5 a6 a7
+ i2_coeff_8x16b_r2_0 = _mm_loadu_si128(
+ (__m128i *) (pi2_inp_data + i4_inp_data_stride)); // b0 b1 b2 b3 b4 b5 b6 b7
+ i2_coeff_8x16b_r3_0 =
+ _mm_loadu_si128((__m128i *) (pi2_inp_data + (i4_inp_data_stride << 1)));
+ i2_coeff_8x16b_r4_0 =
+ _mm_loadu_si128((__m128i *) (pi2_inp_data + (i4_inp_data_stride * 3)));
+
+ i2_coeff_8x16b_r1_1 = _mm_srli_si128(i2_coeff_8x16b_r1_0,
+ 2); // a1 a2 a3 a4 a5 a6 a7 0
+ i2_coeff_8x16b_r2_1 = _mm_srli_si128(i2_coeff_8x16b_r2_0,
+ 2); // b1 b2 b3 b4 b5 b6 b7 0
+ i2_coeff_8x16b_r3_1 = _mm_srli_si128(i2_coeff_8x16b_r3_0, 2);
+ i2_coeff_8x16b_r4_1 = _mm_srli_si128(i2_coeff_8x16b_r4_0, 2);
+
+ coeff_add_8x16b_r1 = _mm_add_epi16(i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1);
+ coeff_add_8x16b_r2 = _mm_add_epi16(i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1);
+ coeff_add_8x16b_r3 = _mm_add_epi16(i2_coeff_8x16b_r3_0, i2_coeff_8x16b_r3_1);
+ coeff_add_8x16b_r4 = _mm_add_epi16(i2_coeff_8x16b_r4_0, i2_coeff_8x16b_r4_1);
+
+ i2_coeff_8x16b_r1_0 = _mm_slli_epi16(i2_coeff_8x16b_r1_0, 1);
+ i2_coeff_8x16b_r2_0 = _mm_slli_epi16(i2_coeff_8x16b_r2_0, 1);
+ i2_coeff_8x16b_r3_0 = _mm_slli_epi16(i2_coeff_8x16b_r3_0, 1);
+ i2_coeff_8x16b_r4_0 = _mm_slli_epi16(i2_coeff_8x16b_r4_0, 1);
+
+ i2_coeff_8x16b_r1_1 = _mm_slli_epi16(i2_coeff_8x16b_r1_1, 1);
+ i2_coeff_8x16b_r2_1 = _mm_slli_epi16(i2_coeff_8x16b_r2_1, 1);
+ i2_coeff_8x16b_r3_1 = _mm_slli_epi16(i2_coeff_8x16b_r3_1, 1);
+ i2_coeff_8x16b_r4_1 = _mm_slli_epi16(i2_coeff_8x16b_r4_1, 1);
+
+ res_8x16b_r1_0 = _mm_add_epi16(i2_coeff_8x16b_r1_0, coeff_add_8x16b_r1);
+ res_8x16b_r2_0 = _mm_add_epi16(i2_coeff_8x16b_r2_0, coeff_add_8x16b_r2);
+ res_8x16b_r3_0 = _mm_add_epi16(i2_coeff_8x16b_r3_0, coeff_add_8x16b_r3);
+ res_8x16b_r4_0 = _mm_add_epi16(i2_coeff_8x16b_r4_0, coeff_add_8x16b_r4);
+
+ res_8x16b_r1_1 = _mm_add_epi16(i2_coeff_8x16b_r1_1, coeff_add_8x16b_r1);
+ res_8x16b_r2_1 = _mm_add_epi16(i2_coeff_8x16b_r2_1, coeff_add_8x16b_r2);
+ res_8x16b_r3_1 = _mm_add_epi16(i2_coeff_8x16b_r3_1, coeff_add_8x16b_r3);
+ res_8x16b_r4_1 = _mm_add_epi16(i2_coeff_8x16b_r4_1, coeff_add_8x16b_r4);
+
+ final_res_8x16b_r1_0 = _mm_unpacklo_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_0 = _mm_unpacklo_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+ final_res_8x16b_r3_0 = _mm_unpacklo_epi16(res_8x16b_r3_0, res_8x16b_r3_1);
+ final_res_8x16b_r4_0 = _mm_unpacklo_epi16(res_8x16b_r4_0, res_8x16b_r4_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 1), final_res_8x16b_r1_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 9), final_res_8x16b_r2_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 17), final_res_8x16b_r3_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 25), final_res_8x16b_r4_0);
+
+ pi2_refarray_buffer[0] = (pi2_inp_data[0] << 2);
+ pi2_refarray_buffer[7] = (pi2_inp_data[3] << 2);
+ pi2_refarray_buffer[8] = (pi2_inp_data[i4_inp_data_stride] << 2);
+ pi2_refarray_buffer[15] = (pi2_inp_data[i4_inp_data_stride + 3] << 2);
+ pi2_refarray_buffer[16] = (pi2_inp_data[(i4_inp_data_stride << 1)] << 2);
+ pi2_refarray_buffer[23] = (pi2_inp_data[(i4_inp_data_stride << 1) + 3] << 2);
+ pi2_refarray_buffer[24] = (pi2_inp_data[(i4_inp_data_stride * 3)] << 2);
+ pi2_refarray_buffer[31] = (pi2_inp_data[(i4_inp_data_stride * 3) + 3] << 2);
+
+ /* ----------- Vertical Interpolation ---------------- */
+ {
+ __m128i i4_horz_samp_8x16b_r0_1, i4_horz_samp_8x16b_r0_2;
+ __m128i i4_horz_samp_8x16b_r1_1, i4_horz_samp_8x16b_r1_2;
+ __m128i i4_horz_samp_8x16b_r2_1, i4_horz_samp_8x16b_r2_2;
+ __m128i i4_horz_samp_8x16b_r3_1, i4_horz_samp_8x16b_r3_2;
+
+ __m128i i4_horz_samp_4x32b_r0_1, i4_horz_samp_4x32b_r0_2;
+ __m128i i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r1_2;
+ __m128i i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r2_2;
+ __m128i i4_horz_samp_4x32b_r3_1, i4_horz_samp_4x32b_r3_2;
+
+ __m128i i4_res_samp_4x32b_r0_1, i4_res_samp_4x32b_r0_2;
+ __m128i i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2;
+ __m128i i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2;
+ __m128i i4_res_samp_4x32b_r3_1, i4_res_samp_4x32b_r3_2;
+ __m128i i4_res_samp_4x32b_r4_1, i4_res_samp_4x32b_r4_2;
+ __m128i i4_res_samp_4x32b_r5_1, i4_res_samp_4x32b_r5_2;
+ __m128i i4_res_samp_4x32b_r6_1, i4_res_samp_4x32b_r6_2;
+ __m128i i4_res_samp_4x32b_r7_1, i4_res_samp_4x32b_r7_2;
+
+ __m128i horz_add_4x32b_r1_1, horz_add_4x32b_r1_2;
+ __m128i horz_add_4x32b_r2_1, horz_add_4x32b_r2_2;
+ __m128i horz_add_4x32b_r3_1, horz_add_4x32b_r3_2;
+
+ __m128i twos = _mm_set1_epi32(2);
+ __m128i eights = _mm_set1_epi32(8);
+
+ i4_horz_samp_8x16b_r0_1 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r0_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r1_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + BLOCK_WIDTH));
+ i4_horz_samp_8x16b_r1_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + BLOCK_WIDTH + 4));
+ i4_horz_samp_8x16b_r2_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLOCK_WIDTH << 1)));
+ i4_horz_samp_8x16b_r2_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLOCK_WIDTH << 1) + 4));
+ i4_horz_samp_8x16b_r3_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLOCK_WIDTH * 3)));
+ i4_horz_samp_8x16b_r3_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLOCK_WIDTH * 3) + 4));
+
+ i4_horz_samp_4x32b_r0_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r0_1);
+ i4_horz_samp_4x32b_r0_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r0_2);
+ i4_horz_samp_4x32b_r1_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_1);
+ i4_horz_samp_4x32b_r1_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_2);
+ i4_horz_samp_4x32b_r2_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_1);
+ i4_horz_samp_4x32b_r2_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_2);
+ i4_horz_samp_4x32b_r3_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r3_1);
+ i4_horz_samp_4x32b_r3_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r3_2);
+
+ horz_add_4x32b_r1_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r0_1, i4_horz_samp_4x32b_r1_1);
+ horz_add_4x32b_r2_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r2_1);
+ horz_add_4x32b_r3_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r3_1);
+
+ horz_add_4x32b_r1_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r0_2, i4_horz_samp_4x32b_r1_2);
+ horz_add_4x32b_r2_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r2_2);
+ horz_add_4x32b_r3_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r2_2, i4_horz_samp_4x32b_r3_2);
+
+ i4_res_samp_4x32b_r1_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r0_1, 1), horz_add_4x32b_r1_1);
+ i4_res_samp_4x32b_r2_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r1_1);
+ i4_res_samp_4x32b_r3_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r4_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r5_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r3_1);
+ i4_res_samp_4x32b_r6_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r3_1, 1), horz_add_4x32b_r3_1);
+
+ i4_res_samp_4x32b_r1_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r0_2, 1), horz_add_4x32b_r1_2);
+ i4_res_samp_4x32b_r2_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r1_2);
+ i4_res_samp_4x32b_r3_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r4_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r5_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r3_2);
+ i4_res_samp_4x32b_r6_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r3_2, 1), horz_add_4x32b_r3_2);
+
+ i4_res_samp_4x32b_r0_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r0_1, twos), 2);
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_1, eights), 4);
+ i4_res_samp_4x32b_r2_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_1, eights), 4);
+ i4_res_samp_4x32b_r3_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r3_1, eights), 4);
+ i4_res_samp_4x32b_r4_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r4_1, eights), 4);
+ i4_res_samp_4x32b_r5_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r5_1, eights), 4);
+ i4_res_samp_4x32b_r6_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r6_1, eights), 4);
+ i4_res_samp_4x32b_r7_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r3_1, twos), 2);
+
+ i4_res_samp_4x32b_r0_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r0_2, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_2, eights), 4);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_2, eights), 4);
+ i4_res_samp_4x32b_r3_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r3_2, eights), 4);
+ i4_res_samp_4x32b_r4_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r4_2, eights), 4);
+ i4_res_samp_4x32b_r5_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r5_2, eights), 4);
+ i4_res_samp_4x32b_r6_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r6_2, eights), 4);
+ i4_res_samp_4x32b_r7_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r3_2, twos), 2);
+
+ /* populate 2 samples based on current coeffs */
+ _mm_storeu_si128(
+ (__m128i *) pi2_out_res,
+ _mm_packs_epi32(i4_res_samp_4x32b_r0_1, i4_res_samp_4x32b_r0_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + i4_out_res_stride),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride << 1)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 3)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r3_1, i4_res_samp_4x32b_r3_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride << 2)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r4_1, i4_res_samp_4x32b_r4_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 5)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r5_1, i4_res_samp_4x32b_r5_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 6)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r6_1, i4_res_samp_4x32b_r6_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 7)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r7_1, i4_res_samp_4x32b_r7_2));
+
+ pi2_out_res += BLOCK_WIDTH;
+ }
+ }
+ else
+ {
+ pi2_out_res += BLOCK_WIDTH;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= SUB_BLOCK_WIDTH;
+ pi2_inp_data += (i4_inp_data_stride * SUB_BLOCK_HEIGHT);
+ pi2_out_res -= MB_WIDTH;
+ pi2_out_res += (i4_out_res_stride * BLOCK_HEIGHT);
+ i4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += SUB_BLOCK_WIDTH;
+ }
+
+ i4_ref_nnz >>= 1;
+ } /* end of loop over all the blocks */
+ }
+ return;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_interpolate_residual_sse42 */
+/* */
+/* Description : */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_interpolate_residual_sse42(void *pv_residual_samp_ctxt, WORD16 *pi2_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd, UWORD16 u2_mb_x,
+ UWORD16 u2_mb_y, WORD32 i4_chroma_flag)
+{
+ residual_sampling_ctxt_t *ps_ctxt;
+ residual_samp_map_ctxt_t *ps_map_ctxt;
+ res_lyr_ctxt *ps_lyr_ctxt;
+ ref_pixel_map_t *ps_x_pos_phase;
+ ref_pixel_map_t *ps_y_pos_phase;
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_frm_mb_x, i4_frm_mb_y;
+ WORD32 i4_temp_array_ht;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD16 *pi2_ref_array;
+ UWORD8 *pu1_ref_x_ptr_incr, *pu1_ref_y_ptr_incr;
+
+ WORD8 arr_y_ref_pos[16] = {0};
+ WORD8 arr_x_ref_pos[16] = {0};
+ WORD8 arr_x_phase[32] = {0};
+ WORD8 arr_y_phase[32] = {0};
+ WORD8 *pi1_y_ref_pos;
+ WORD8 *pi1_x_ref_pos;
+ WORD8 *pi1_y_phase;
+ WORD8 *pi1_x_phase;
+
+ ps_ctxt = (residual_sampling_ctxt_t *) pv_residual_samp_ctxt;
+ ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id];
+ pi2_ref_array = ps_ctxt->pi2_refarray_buffer;
+ pu1_ref_x_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr;
+ pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_y_ptr_incr;
+
+ /* --------------------------------------------------------------------- */
+ /* Extracting information from the mapping context */
+ /* --------------------------------------------------------------------- */
+ if(1 == i4_chroma_flag)
+ ps_map_ctxt = &ps_lyr_ctxt->s_chroma_map_ctxt;
+ else
+ ps_map_ctxt = &ps_lyr_ctxt->s_luma_map_ctxt;
+
+ i4_mb_wd = MB_WIDTH >> i4_chroma_flag;
+ i4_mb_ht = MB_HEIGHT >> i4_chroma_flag;
+
+ ps_x_pos_phase = ps_map_ctxt->ps_x_pos_phase;
+ ps_y_pos_phase = ps_map_ctxt->ps_y_pos_phase;
+
+ i4_temp_array_ht = i4_mb_ht;
+ i4_frm_mb_y = u2_mb_y * i4_mb_ht;
+ i4_frm_mb_x = u2_mb_x * i4_mb_wd;
+
+ /* --------------------------------------------------------------------- */
+ /* Loop for interpolation */
+ /* --------------------------------------------------------------------- */
+
+ if(i4_chroma_flag == 0)
+ {
+ __m128i const_16_8x16b, const_128, const_ones, const_ones_8x16b, mid_indx_16x8b;
+ __m128i ref_arr_8x16b_r0_0;
+ __m128i ref_arr_8x16b_r1_0;
+ __m128i phs_mask_8x16b_0, phs_mask_16min_8x16b_0, phs_mask_16x8b_0;
+ __m128i x_ref_pos_mask_r0, x_ref_rnd_mask_r0_0;
+ __m128i x_ref_pos_mask_temp_r0_0;
+ __m128i x_ref_pos_mask_temp_r1_0;
+ __m128i phs_mask_div8_8x16b_0;
+ __m128i u1_incr_8x16b_r0_0, ref_arr_temp0_8x16b_r0_0, res0_8x16b_r0_0,
+ u1_incr_not_8x16b_r0_0;
+ __m128i u1_incr_8x16b_r1_0, ref_arr_temp1_8x16b_r0_0, res1_8x16b_r0_0;
+
+ __m128i u1_incr_not_8x16b_r0_even, u1_incr_not_8x16b_r1_even, x_ref_pos_mask_temp_r0_even,
+ x_ref_pos_mask_temp_r1_even;
+ __m128i u1_incr_not_8x16b_r0_odd, u1_incr_not_8x16b_r1_odd, x_ref_pos_mask_temp_r0_odd,
+ x_ref_pos_mask_temp_r1_odd;
+
+ __m128i ref_arr_temp0_8x16b_r1_0, res_8x16b_r0_0, res0_8x16b_r1_0, u1_incr_not_8x16b_r1_0;
+ __m128i ref_arr_temp1_8x16b_r1_0, res_8x16b_r1_0, res1_8x16b_r1_0;
+ __m128i u1_y_incr_8x16b_r0_0, u1_y_incr_8x16b_r0_1, u1_y_incr_8x16b_r0_low,
+ u1_y_incr_8x16b_r0_high;
+
+ __m128i prev_res_8x16b_r0_0;
+ __m128i prev_res_8x16b_r1_0;
+ __m128i prev_res_8x16b_r0_1;
+ __m128i prev_res_8x16b_r1_1;
+
+ __m128i u1_prev_y_incr_8x16b_r0_0;
+ __m128i u1_prev_y_incr_8x16b_r0_1;
+
+ __m128i ref_arr_8x16b_r0_1;
+ __m128i ref_arr_8x16b_r1_1;
+ __m128i phs_mask_8x16b_1, phs_mask_div8_8x16b_1, phs_mask_16min_8x16b_1;
+ __m128i x_ref_pos_mask_temp_r0_1;
+ __m128i x_ref_pos_mask_temp_r1_1;
+ __m128i ref_arr_temp0_8x16b_r0_1, res0_8x16b_r0_1, u1_incr_not_8x16b_r0_1;
+ __m128i ref_arr_temp1_8x16b_r0_1, res1_8x16b_r0_1;
+
+ __m128i ref_arr_temp0_8x16b_r1_1, res_8x16b_r0_1, res0_8x16b_r1_1, u1_incr_not_8x16b_r1_1;
+ __m128i ref_arr_temp1_8x16b_r1_1, res_8x16b_r1_1, res1_8x16b_r1_1;
+
+ __m128i vert_res0_8x16b_r0_0, vert_res0_8x16b_r0_1, res_4x32b_l_0, res_4x32b_h_0;
+ __m128i vert_res1_8x16b_r0_0, vert_res1_8x16b_r0_1, res_4x32b_l_1, res_4x32b_h_1;
+ __m128i res_8x16b_l, res_8x16b_h;
+ __m128i phs_y_mask_16min_8x16b, phs_y_mask_8x16b, phs_y_mask_mix_8x16b;
+ __m128i zero_8x16b;
+ WORD32 zero_r0_0, zero_r1_0, zero_r0_1, zero_r1_1, zero_r0_r1 = 0;
+ WORD32 strt_indx_h;
+ WORD16 *pi2_ref_array_temp;
+ UWORD8 *pu1_ref_x_ptr_incr_temp, *pu1_ref_y_ptr_incr_temp;
+ WORD32 i4_y_phase;
+ WORD32 out_stride_temp;
+ const_128 = _mm_set1_epi32(128);
+ zero_8x16b = _mm_set1_epi16(0);
+ const_ones = _mm_set1_epi8(1);
+ const_ones_8x16b = _mm_set1_epi16(1);
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_phase[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos[i4_y] = (WORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi1_y_ref_pos = arr_y_ref_pos;
+ pi1_y_phase = arr_y_phase;
+
+ strt_indx_h = 0;
+ strt_indx_h = (ps_x_pos_phase[8 + i4_frm_mb_x].i2_ref_pos);
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_x_phase[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ }
+
+ pi1_x_ref_pos = arr_x_ref_pos;
+ pi1_x_phase = arr_x_phase;
+
+ x_ref_pos_mask_r0 = _mm_loadu_si128((__m128i *) (pi1_x_ref_pos));
+ phs_mask_16x8b_0 = _mm_loadu_si128((__m128i *) (pi1_x_phase));
+ phs_mask_8x16b_0 = _mm_cvtepi8_epi16(phs_mask_16x8b_0);
+ phs_mask_8x16b_1 = _mm_cvtepi8_epi16(_mm_loadu_si128((__m128i *) (pi1_x_phase + 8)));
+
+ phs_mask_div8_8x16b_0 = _mm_srli_epi16(phs_mask_8x16b_0, 3);
+ phs_mask_div8_8x16b_1 = _mm_srli_epi16(phs_mask_8x16b_1, 3);
+ phs_mask_div8_8x16b_0 = _mm_packs_epi16(phs_mask_div8_8x16b_0, phs_mask_div8_8x16b_1);
+ const_16_8x16b = _mm_set1_epi16(16);
+
+ phs_mask_16min_8x16b_0 = _mm_sub_epi16(const_16_8x16b, phs_mask_8x16b_0);
+ phs_mask_16min_8x16b_1 = _mm_sub_epi16(const_16_8x16b, phs_mask_8x16b_1);
+
+ x_ref_rnd_mask_r0_0 = _mm_add_epi8(x_ref_pos_mask_r0, phs_mask_div8_8x16b_0);
+ mid_indx_16x8b = _mm_set1_epi8((strt_indx_h << 1));
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ if((i4_y > 0) && (pi1_y_ref_pos[i4_y] == pi1_y_ref_pos[i4_y - 1]))
+ {
+ if(zero_r0_r1)
+ {
+ res_8x16b_l = _mm_set1_epi16(0);
+ res_8x16b_h = _mm_set1_epi16(0);
+ out_stride_temp = (i4_y * i4_out_stride);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp), res_8x16b_l);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp + 8), res_8x16b_h);
+ continue;
+ }
+
+ res_8x16b_r0_0 = prev_res_8x16b_r0_0;
+ res_8x16b_r1_0 = prev_res_8x16b_r1_0;
+ res_8x16b_r0_1 = prev_res_8x16b_r0_1;
+ res_8x16b_r1_1 = prev_res_8x16b_r1_1;
+
+ u1_y_incr_8x16b_r0_0 = u1_prev_y_incr_8x16b_r0_0;
+ u1_y_incr_8x16b_r0_1 = u1_prev_y_incr_8x16b_r0_1;
+ }
+ else
+ {
+ pi2_ref_array_temp = pi2_ref_array + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ pu1_ref_x_ptr_incr_temp =
+ pu1_ref_x_ptr_incr + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ ref_arr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pi2_ref_array_temp));
+ ref_arr_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) (pi2_ref_array_temp + i4_refarray_wd));
+ ref_arr_8x16b_r0_1 =
+ _mm_loadu_si128((__m128i *) (pi2_ref_array_temp + strt_indx_h));
+ ref_arr_8x16b_r1_1 = _mm_loadu_si128(
+ (__m128i *) (pi2_ref_array_temp + i4_refarray_wd + strt_indx_h));
+
+ zero_r0_0 = _mm_test_all_ones(_mm_cmpeq_epi16(
+ ref_arr_8x16b_r0_0, zero_8x16b)); // return 1 if all zeros, else 0
+ zero_r1_0 = _mm_test_all_ones(_mm_cmpeq_epi16(ref_arr_8x16b_r1_0, zero_8x16b));
+ zero_r0_1 = _mm_test_all_ones(_mm_cmpeq_epi16(ref_arr_8x16b_r0_1, zero_8x16b));
+ zero_r1_1 = _mm_test_all_ones(_mm_cmpeq_epi16(ref_arr_8x16b_r1_1, zero_8x16b));
+
+ zero_r0_r1 = zero_r0_0 && zero_r1_0 && zero_r0_1 && zero_r1_1;
+
+ if(!zero_r0_r1)
+ {
+ u1_incr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pu1_ref_x_ptr_incr_temp));
+ u1_incr_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) (pu1_ref_x_ptr_incr_temp + i4_refarray_wd));
+
+ u1_incr_8x16b_r0_0 = _mm_shuffle_epi8(u1_incr_8x16b_r0_0, x_ref_pos_mask_r0);
+ u1_incr_8x16b_r1_0 = _mm_shuffle_epi8(u1_incr_8x16b_r1_0, x_ref_pos_mask_r0);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_andnot_si128(u1_incr_8x16b_r0_0, phs_mask_div8_8x16b_0);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_andnot_si128(u1_incr_8x16b_r1_0, phs_mask_div8_8x16b_0);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, x_ref_pos_mask_r0);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, x_ref_pos_mask_r0);
+
+ x_ref_pos_mask_temp_r0_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, u1_incr_8x16b_r0_0);
+ x_ref_pos_mask_temp_r1_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, u1_incr_8x16b_r1_0);
+
+ /* _mm_slli_epi8(u1_incr_not_8x16b_r0_0, 1)*/
+ u1_incr_not_8x16b_r0_even =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, u1_incr_not_8x16b_r0_0);
+ u1_incr_not_8x16b_r1_even =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, u1_incr_not_8x16b_r1_0);
+ x_ref_pos_mask_temp_r0_even =
+ _mm_add_epi8(x_ref_pos_mask_temp_r0_0, x_ref_pos_mask_temp_r0_0);
+ x_ref_pos_mask_temp_r1_even =
+ _mm_add_epi8(x_ref_pos_mask_temp_r1_0, x_ref_pos_mask_temp_r1_0);
+
+ u1_incr_not_8x16b_r0_odd = _mm_add_epi8(u1_incr_not_8x16b_r0_even, const_ones);
+ u1_incr_not_8x16b_r1_odd = _mm_add_epi8(u1_incr_not_8x16b_r1_even, const_ones);
+ x_ref_pos_mask_temp_r0_odd =
+ _mm_add_epi8(x_ref_pos_mask_temp_r0_even, const_ones);
+ x_ref_pos_mask_temp_r1_odd =
+ _mm_add_epi8(x_ref_pos_mask_temp_r1_even, const_ones);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_unpacklo_epi8(u1_incr_not_8x16b_r0_even, u1_incr_not_8x16b_r0_odd);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_unpacklo_epi8(u1_incr_not_8x16b_r1_even, u1_incr_not_8x16b_r1_odd);
+ x_ref_pos_mask_temp_r0_0 =
+ _mm_unpacklo_epi8(x_ref_pos_mask_temp_r0_even, x_ref_pos_mask_temp_r0_odd);
+ x_ref_pos_mask_temp_r1_0 =
+ _mm_unpacklo_epi8(x_ref_pos_mask_temp_r1_even, x_ref_pos_mask_temp_r1_odd);
+
+ u1_incr_not_8x16b_r0_1 =
+ _mm_unpackhi_epi8(u1_incr_not_8x16b_r0_even, u1_incr_not_8x16b_r0_odd);
+ u1_incr_not_8x16b_r1_1 =
+ _mm_unpackhi_epi8(u1_incr_not_8x16b_r1_even, u1_incr_not_8x16b_r1_odd);
+ x_ref_pos_mask_temp_r0_1 =
+ _mm_unpackhi_epi8(x_ref_pos_mask_temp_r0_even, x_ref_pos_mask_temp_r0_odd);
+ x_ref_pos_mask_temp_r1_1 =
+ _mm_unpackhi_epi8(x_ref_pos_mask_temp_r1_even, x_ref_pos_mask_temp_r1_odd);
+
+ u1_incr_not_8x16b_r0_1 = _mm_sub_epi8(u1_incr_not_8x16b_r0_1, mid_indx_16x8b);
+ u1_incr_not_8x16b_r1_1 = _mm_sub_epi8(u1_incr_not_8x16b_r1_1, mid_indx_16x8b);
+ x_ref_pos_mask_temp_r0_1 =
+ _mm_sub_epi8(x_ref_pos_mask_temp_r0_1, mid_indx_16x8b);
+ x_ref_pos_mask_temp_r1_1 =
+ _mm_sub_epi8(x_ref_pos_mask_temp_r1_1, mid_indx_16x8b);
+
+ ref_arr_temp0_8x16b_r0_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_0, u1_incr_not_8x16b_r0_0);
+ ref_arr_temp0_8x16b_r1_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_0, u1_incr_not_8x16b_r1_0);
+ ref_arr_temp1_8x16b_r0_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_0, x_ref_pos_mask_temp_r0_0);
+ ref_arr_temp1_8x16b_r1_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_0, x_ref_pos_mask_temp_r1_0);
+ ref_arr_temp0_8x16b_r0_1 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_1, u1_incr_not_8x16b_r0_1);
+ ref_arr_temp0_8x16b_r1_1 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_1, u1_incr_not_8x16b_r1_1);
+ ref_arr_temp1_8x16b_r0_1 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_1, x_ref_pos_mask_temp_r0_1);
+ ref_arr_temp1_8x16b_r1_1 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_1, x_ref_pos_mask_temp_r1_1);
+
+ res0_8x16b_r0_0 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r0_0, phs_mask_16min_8x16b_0);
+ res0_8x16b_r1_0 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r1_0, phs_mask_16min_8x16b_0);
+ res1_8x16b_r0_0 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r0_0, phs_mask_8x16b_0);
+ res1_8x16b_r1_0 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r1_0, phs_mask_8x16b_0);
+ res0_8x16b_r0_1 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r0_1, phs_mask_16min_8x16b_1);
+ res0_8x16b_r1_1 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r1_1, phs_mask_16min_8x16b_1);
+ res1_8x16b_r0_1 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r0_1, phs_mask_8x16b_1);
+ res1_8x16b_r1_1 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r1_1, phs_mask_8x16b_1);
+
+ res_8x16b_r0_0 = _mm_add_epi16(res0_8x16b_r0_0, res1_8x16b_r0_0);
+ res_8x16b_r1_0 = _mm_add_epi16(res0_8x16b_r1_0, res1_8x16b_r1_0);
+ res_8x16b_r0_1 = _mm_add_epi16(res0_8x16b_r0_1, res1_8x16b_r0_1);
+ res_8x16b_r1_1 = _mm_add_epi16(res0_8x16b_r1_1, res1_8x16b_r1_1);
+
+ prev_res_8x16b_r0_0 = res_8x16b_r0_0;
+ prev_res_8x16b_r1_0 = res_8x16b_r1_0;
+ prev_res_8x16b_r0_1 = res_8x16b_r0_1;
+ prev_res_8x16b_r1_1 = res_8x16b_r1_1;
+
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + (pi1_y_ref_pos[i4_y] * i4_refarray_wd);
+ u1_y_incr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pu1_ref_y_ptr_incr_temp));
+
+ u1_y_incr_8x16b_r0_0 =
+ _mm_shuffle_epi8(u1_y_incr_8x16b_r0_0, x_ref_rnd_mask_r0_0);
+
+ u1_y_incr_8x16b_r0_low = _mm_cvtepi8_epi16(u1_y_incr_8x16b_r0_0);
+ u1_y_incr_8x16b_r0_high =
+ _mm_cvtepi8_epi16(_mm_unpackhi_epi64(u1_y_incr_8x16b_r0_0, const_ones));
+
+ u1_y_incr_8x16b_r0_0 =
+ _mm_cmpeq_epi16(u1_y_incr_8x16b_r0_low, const_ones_8x16b);
+ u1_y_incr_8x16b_r0_1 =
+ _mm_cmpeq_epi16(u1_y_incr_8x16b_r0_high, const_ones_8x16b);
+
+ u1_prev_y_incr_8x16b_r0_0 = u1_y_incr_8x16b_r0_0;
+ u1_prev_y_incr_8x16b_r0_1 = u1_y_incr_8x16b_r0_1;
+ }
+ }
+
+ if(zero_r0_r1)
+ {
+ res_8x16b_l = _mm_set1_epi16(0);
+ res_8x16b_h = _mm_set1_epi16(0);
+ }
+ else
+ {
+ i4_y_phase = pi1_y_phase[i4_y];
+
+ if((i4_y_phase) >> 3)
+ {
+ vert_res0_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r1_0, res_8x16b_r0_0, u1_y_incr_8x16b_r0_0);
+ vert_res1_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r1_0, res_8x16b_r1_0, u1_y_incr_8x16b_r0_0);
+ vert_res0_8x16b_r0_1 =
+ _mm_blendv_epi8(res_8x16b_r1_1, res_8x16b_r0_1, u1_y_incr_8x16b_r0_1);
+ vert_res1_8x16b_r0_1 =
+ _mm_blendv_epi8(res_8x16b_r1_1, res_8x16b_r1_1, u1_y_incr_8x16b_r0_1);
+ }
+ else
+ {
+ vert_res0_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r0_0, res_8x16b_r0_0, u1_y_incr_8x16b_r0_0);
+ vert_res1_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r0_0, res_8x16b_r1_0, u1_y_incr_8x16b_r0_0);
+ vert_res0_8x16b_r0_1 =
+ _mm_blendv_epi8(res_8x16b_r0_1, res_8x16b_r0_1, u1_y_incr_8x16b_r0_1);
+ vert_res1_8x16b_r0_1 =
+ _mm_blendv_epi8(res_8x16b_r0_1, res_8x16b_r1_1, u1_y_incr_8x16b_r0_1);
+ }
+ res0_8x16b_r0_0 = _mm_unpacklo_epi16(vert_res0_8x16b_r0_0, vert_res1_8x16b_r0_0);
+ res1_8x16b_r0_0 = _mm_unpackhi_epi16(vert_res0_8x16b_r0_0, vert_res1_8x16b_r0_0);
+ res0_8x16b_r0_1 = _mm_unpacklo_epi16(vert_res0_8x16b_r0_1, vert_res1_8x16b_r0_1);
+ res1_8x16b_r0_1 = _mm_unpackhi_epi16(vert_res0_8x16b_r0_1, vert_res1_8x16b_r0_1);
+
+ phs_y_mask_16min_8x16b = _mm_set1_epi16(16 - i4_y_phase);
+ phs_y_mask_8x16b = _mm_set1_epi16(i4_y_phase);
+ phs_y_mask_mix_8x16b = _mm_unpacklo_epi16(phs_y_mask_16min_8x16b, phs_y_mask_8x16b);
+
+ res_4x32b_l_0 = _mm_madd_epi16(res0_8x16b_r0_0, phs_y_mask_mix_8x16b);
+ res_4x32b_l_1 = _mm_madd_epi16(res1_8x16b_r0_0, phs_y_mask_mix_8x16b);
+ res_4x32b_h_0 = _mm_madd_epi16(res0_8x16b_r0_1, phs_y_mask_mix_8x16b);
+ res_4x32b_h_1 = _mm_madd_epi16(res1_8x16b_r0_1, phs_y_mask_mix_8x16b);
+
+ res_4x32b_l_0 = _mm_add_epi32(res_4x32b_l_0, const_128);
+ res_4x32b_l_1 = _mm_add_epi32(res_4x32b_l_1, const_128);
+ res_4x32b_h_0 = _mm_add_epi32(res_4x32b_h_0, const_128);
+ res_4x32b_h_1 = _mm_add_epi32(res_4x32b_h_1, const_128);
+
+ res_4x32b_l_0 = _mm_srai_epi32(res_4x32b_l_0, 8);
+ res_4x32b_l_1 = _mm_srai_epi32(res_4x32b_l_1, 8);
+ res_4x32b_h_0 = _mm_srai_epi32(res_4x32b_h_0, 8);
+ res_4x32b_h_1 = _mm_srai_epi32(res_4x32b_h_1, 8);
+ res_8x16b_l = _mm_packs_epi32(res_4x32b_l_0, res_4x32b_l_1);
+ res_8x16b_h = _mm_packs_epi32(res_4x32b_h_0, res_4x32b_h_1);
+ }
+
+ out_stride_temp = (i4_y * i4_out_stride);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp), res_8x16b_l);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp + 8), res_8x16b_h);
+ }
+ }
+ else
+ {
+ __m128i const_16_8x16b, const_128, const_ones, const_ones_8x16b;
+ __m128i ref_arr_8x16b_r0_0;
+ __m128i ref_arr_8x16b_r1_0;
+ __m128i phs_mask_8x16b_0, phs_mask_div8_8x16b_0, phs_mask_16min_8x16b_0;
+ __m128i x_ref_pos_mask_r0, x_ref_rnd_mask_r0_0;
+ __m128i x_ref_pos_mask_temp_r0_0;
+ __m128i x_ref_pos_mask_temp_r1_0;
+
+ __m128i u1_incr_8x16b_r0_0, ref_arr_temp0_8x16b_r0_0, res0_8x16b_r0_0,
+ u1_incr_not_8x16b_r0_0;
+ __m128i u1_incr_8x16b_r1_0, ref_arr_temp1_8x16b_r0_0, res1_8x16b_r0_0;
+ __m128i u1_y_incr_8x16b_r0_0;
+
+ __m128i u1_incr_not_8x16b_r0_odd, u1_incr_not_8x16b_r1_odd, x_ref_pos_mask_temp_r0_odd,
+ x_ref_pos_mask_temp_r1_odd;
+ __m128i u1_incr_not_8x16b_r0_even, u1_incr_not_8x16b_r1_even, x_ref_pos_mask_temp_r0_even,
+ x_ref_pos_mask_temp_r1_even;
+
+ __m128i ref_arr_temp0_8x16b_r1_0, res_8x16b_r0_0, res0_8x16b_r1_0, u1_incr_not_8x16b_r1_0;
+ __m128i ref_arr_temp1_8x16b_r1_0, res_8x16b_r1_0, res1_8x16b_r1_0;
+ __m128i u1_prev_y_incr_8x16b_r0_0;
+ __m128i prev_res_8x16b_r0_0;
+ __m128i prev_res_8x16b_r1_0;
+
+ __m128i vert_res0_8x16b_r0_0, res_4x32b_l_0, out_4x32b_l;
+ __m128i vert_res1_8x16b_r0_0, res_4x32b_l_1, out_4x32b_h;
+ __m128i phs_y_mask_16min_8x16b, phs_y_mask_8x16b, phs_y_mask_mix_8x16b;
+ __m128i chroma_mask, chroma_mask2;
+ __m128i zero_8x16b = _mm_set1_epi16(0);
+ WORD32 zero_r0_0, zero_r1_0, zero_r0_r1 = 0;
+ WORD16 *pi2_ref_array_temp;
+ UWORD8 *pu1_ref_x_ptr_incr_temp, *pu1_ref_y_ptr_incr_temp;
+ WORD32 i4_y_phase;
+ WORD32 out_stride_temp;
+ const_ones = _mm_set1_epi8(1);
+ const_ones_8x16b = _mm_set1_epi16(1);
+ const_128 = _mm_set1_epi32(128);
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ arr_y_phase[i4_y] = (WORD8) ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_phase;
+ arr_y_ref_pos[i4_y] = (WORD8) (ps_y_pos_phase[i4_y + i4_frm_mb_y].i2_ref_pos);
+ }
+ pi1_y_ref_pos = arr_y_ref_pos;
+ pi1_y_phase = arr_y_phase;
+
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ arr_x_ref_pos[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_ref_pos;
+ arr_x_phase[i4_x] = (WORD8) ps_x_pos_phase[i4_x + i4_frm_mb_x].i2_phase;
+ }
+
+ pi1_x_ref_pos = arr_x_ref_pos;
+ pi1_x_phase = arr_x_phase;
+
+ phs_mask_8x16b_0 = _mm_cvtepi8_epi16(_mm_loadu_si128((__m128i *) (pi1_x_phase)));
+ x_ref_pos_mask_r0 = _mm_loadu_si128((__m128i *) (pi1_x_ref_pos));
+
+ const_16_8x16b = _mm_set1_epi16(16);
+ chroma_mask = _mm_set1_epi32(0xFFFF0000);
+ chroma_mask2 = _mm_set1_epi32(0x0000FFFF);
+ phs_mask_div8_8x16b_0 = _mm_srli_epi16(phs_mask_8x16b_0, 3);
+ phs_mask_div8_8x16b_0 = _mm_packs_epi16(phs_mask_div8_8x16b_0, const_ones);
+
+ phs_mask_16min_8x16b_0 = _mm_sub_epi16(const_16_8x16b, phs_mask_8x16b_0);
+ x_ref_rnd_mask_r0_0 = _mm_add_epi8(x_ref_pos_mask_r0, phs_mask_div8_8x16b_0);
+
+ for(i4_y = 0; i4_y < (i4_temp_array_ht); i4_y++)
+ {
+ if((i4_y > 0) && (pi1_y_ref_pos[i4_y] == pi1_y_ref_pos[i4_y - 1]))
+ {
+ if(zero_r0_r1)
+ {
+ res_4x32b_l_0 = _mm_set1_epi32(0);
+ res_4x32b_l_1 = _mm_set1_epi32(0);
+ out_stride_temp = (i4_y * i4_out_stride);
+
+ out_4x32b_l = _mm_loadu_si128((__m128i *) (pi2_out + out_stride_temp));
+ out_4x32b_h = _mm_loadu_si128((__m128i *) (pi2_out + out_stride_temp + 8));
+
+ out_4x32b_l = _mm_and_si128(out_4x32b_l, chroma_mask);
+ out_4x32b_h = _mm_and_si128(out_4x32b_h, chroma_mask);
+
+ res_4x32b_l_0 = _mm_and_si128(res_4x32b_l_0, chroma_mask2);
+ res_4x32b_l_1 = _mm_and_si128(res_4x32b_l_1, chroma_mask2);
+
+ out_4x32b_l = _mm_add_epi8(res_4x32b_l_0, out_4x32b_l);
+ out_4x32b_h = _mm_add_epi8(res_4x32b_l_1, out_4x32b_h);
+
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp), out_4x32b_l);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp + 8), out_4x32b_h);
+ continue;
+ }
+
+ res_8x16b_r0_0 = prev_res_8x16b_r0_0;
+ res_8x16b_r1_0 = prev_res_8x16b_r1_0;
+
+ u1_y_incr_8x16b_r0_0 = u1_prev_y_incr_8x16b_r0_0;
+ }
+ else
+ {
+ pi2_ref_array_temp = pi2_ref_array + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ pu1_ref_x_ptr_incr_temp =
+ pu1_ref_x_ptr_incr + ((pi1_y_ref_pos[i4_y]) * i4_refarray_wd);
+ ref_arr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pi2_ref_array_temp));
+ ref_arr_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) (pi2_ref_array_temp + i4_refarray_wd));
+
+ zero_r0_0 = _mm_test_all_ones(_mm_cmpeq_epi16(
+ ref_arr_8x16b_r0_0, zero_8x16b)); // return 1 if all zeros, else 0
+ zero_r1_0 = _mm_test_all_ones(_mm_cmpeq_epi16(ref_arr_8x16b_r1_0, zero_8x16b));
+
+ zero_r0_r1 = zero_r0_0 && zero_r1_0;
+
+ if(!zero_r0_r1)
+ {
+ u1_incr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pu1_ref_x_ptr_incr_temp));
+ u1_incr_8x16b_r1_0 =
+ _mm_loadu_si128((__m128i *) (pu1_ref_x_ptr_incr_temp + i4_refarray_wd));
+
+ u1_incr_8x16b_r0_0 = _mm_shuffle_epi8(u1_incr_8x16b_r0_0, x_ref_pos_mask_r0);
+ u1_incr_8x16b_r1_0 = _mm_shuffle_epi8(u1_incr_8x16b_r1_0, x_ref_pos_mask_r0);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_andnot_si128(u1_incr_8x16b_r0_0, phs_mask_div8_8x16b_0);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_andnot_si128(u1_incr_8x16b_r1_0, phs_mask_div8_8x16b_0);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, x_ref_pos_mask_r0);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, x_ref_pos_mask_r0);
+
+ x_ref_pos_mask_temp_r0_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, u1_incr_8x16b_r0_0);
+ x_ref_pos_mask_temp_r1_0 =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, u1_incr_8x16b_r1_0);
+
+ u1_incr_not_8x16b_r0_even =
+ _mm_add_epi8(u1_incr_not_8x16b_r0_0, u1_incr_not_8x16b_r0_0);
+ u1_incr_not_8x16b_r1_even =
+ _mm_add_epi8(u1_incr_not_8x16b_r1_0, u1_incr_not_8x16b_r1_0);
+ x_ref_pos_mask_temp_r0_even =
+ _mm_add_epi8(x_ref_pos_mask_temp_r0_0, x_ref_pos_mask_temp_r0_0);
+ x_ref_pos_mask_temp_r1_even =
+ _mm_add_epi8(x_ref_pos_mask_temp_r1_0, x_ref_pos_mask_temp_r1_0);
+
+ u1_incr_not_8x16b_r0_odd = _mm_add_epi8(u1_incr_not_8x16b_r0_even, const_ones);
+ u1_incr_not_8x16b_r1_odd = _mm_add_epi8(u1_incr_not_8x16b_r1_even, const_ones);
+ x_ref_pos_mask_temp_r0_odd =
+ _mm_add_epi8(x_ref_pos_mask_temp_r0_even, const_ones);
+ x_ref_pos_mask_temp_r1_odd =
+ _mm_add_epi8(x_ref_pos_mask_temp_r1_even, const_ones);
+
+ u1_incr_not_8x16b_r0_0 =
+ _mm_unpacklo_epi8(u1_incr_not_8x16b_r0_even, u1_incr_not_8x16b_r0_odd);
+ u1_incr_not_8x16b_r1_0 =
+ _mm_unpacklo_epi8(u1_incr_not_8x16b_r1_even, u1_incr_not_8x16b_r1_odd);
+ x_ref_pos_mask_temp_r0_0 =
+ _mm_unpacklo_epi8(x_ref_pos_mask_temp_r0_even, x_ref_pos_mask_temp_r0_odd);
+ x_ref_pos_mask_temp_r1_0 =
+ _mm_unpacklo_epi8(x_ref_pos_mask_temp_r1_even, x_ref_pos_mask_temp_r1_odd);
+
+ ref_arr_temp0_8x16b_r0_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_0, u1_incr_not_8x16b_r0_0);
+ ref_arr_temp0_8x16b_r1_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_0, u1_incr_not_8x16b_r1_0);
+ ref_arr_temp1_8x16b_r0_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r0_0, x_ref_pos_mask_temp_r0_0);
+ ref_arr_temp1_8x16b_r1_0 =
+ _mm_shuffle_epi8(ref_arr_8x16b_r1_0, x_ref_pos_mask_temp_r1_0);
+
+ res0_8x16b_r0_0 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r0_0, phs_mask_16min_8x16b_0);
+ res0_8x16b_r1_0 =
+ _mm_mullo_epi16(ref_arr_temp0_8x16b_r1_0, phs_mask_16min_8x16b_0);
+ res1_8x16b_r0_0 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r0_0, phs_mask_8x16b_0);
+ res1_8x16b_r1_0 = _mm_mullo_epi16(ref_arr_temp1_8x16b_r1_0, phs_mask_8x16b_0);
+
+ res_8x16b_r0_0 = _mm_add_epi16(res0_8x16b_r0_0, res1_8x16b_r0_0);
+ res_8x16b_r1_0 = _mm_add_epi16(res0_8x16b_r1_0, res1_8x16b_r1_0);
+
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + (pi1_y_ref_pos[i4_y] * i4_refarray_wd);
+ u1_y_incr_8x16b_r0_0 = _mm_loadu_si128((__m128i *) (pu1_ref_y_ptr_incr_temp));
+
+ u1_y_incr_8x16b_r0_0 =
+ _mm_shuffle_epi8(u1_y_incr_8x16b_r0_0, x_ref_rnd_mask_r0_0);
+
+ u1_y_incr_8x16b_r0_0 = _mm_cvtepi8_epi16(u1_y_incr_8x16b_r0_0);
+ u1_y_incr_8x16b_r0_0 = _mm_cmpeq_epi16(u1_y_incr_8x16b_r0_0, const_ones_8x16b);
+ u1_prev_y_incr_8x16b_r0_0 = u1_y_incr_8x16b_r0_0;
+
+ prev_res_8x16b_r0_0 = res_8x16b_r0_0;
+ prev_res_8x16b_r1_0 = res_8x16b_r1_0;
+ }
+ }
+
+ if(zero_r0_r1)
+ {
+ res_4x32b_l_0 = _mm_set1_epi32(0);
+ res_4x32b_l_1 = _mm_set1_epi32(0);
+ }
+ else
+ {
+ i4_y_phase = pi1_y_phase[i4_y];
+
+ if((i4_y_phase) >> 3)
+ {
+ vert_res0_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r1_0, res_8x16b_r0_0, u1_y_incr_8x16b_r0_0);
+ vert_res1_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r1_0, res_8x16b_r1_0, u1_y_incr_8x16b_r0_0);
+ }
+ else
+ {
+ vert_res0_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r0_0, res_8x16b_r0_0, u1_y_incr_8x16b_r0_0);
+ vert_res1_8x16b_r0_0 =
+ _mm_blendv_epi8(res_8x16b_r0_0, res_8x16b_r1_0, u1_y_incr_8x16b_r0_0);
+ }
+
+ res0_8x16b_r0_0 = _mm_unpacklo_epi16(vert_res0_8x16b_r0_0, vert_res1_8x16b_r0_0);
+ res1_8x16b_r0_0 = _mm_unpackhi_epi16(vert_res0_8x16b_r0_0, vert_res1_8x16b_r0_0);
+
+ phs_y_mask_16min_8x16b = _mm_set1_epi16(16 - i4_y_phase);
+ phs_y_mask_8x16b = _mm_set1_epi16(i4_y_phase);
+ phs_y_mask_mix_8x16b = _mm_unpacklo_epi16(phs_y_mask_16min_8x16b, phs_y_mask_8x16b);
+
+ res_4x32b_l_0 = _mm_madd_epi16(res0_8x16b_r0_0, phs_y_mask_mix_8x16b);
+ res_4x32b_l_1 = _mm_madd_epi16(res1_8x16b_r0_0, phs_y_mask_mix_8x16b);
+ res_4x32b_l_0 = _mm_add_epi32(res_4x32b_l_0, const_128);
+ res_4x32b_l_1 = _mm_add_epi32(res_4x32b_l_1, const_128);
+
+ res_4x32b_l_0 = _mm_srai_epi32(res_4x32b_l_0, 8);
+ res_4x32b_l_1 = _mm_srai_epi32(res_4x32b_l_1, 8);
+ }
+ out_stride_temp = (i4_y * i4_out_stride);
+
+ out_4x32b_l = _mm_loadu_si128((__m128i *) (pi2_out + out_stride_temp));
+ out_4x32b_h = _mm_loadu_si128((__m128i *) (pi2_out + out_stride_temp + 8));
+
+ out_4x32b_l = _mm_and_si128(out_4x32b_l, chroma_mask);
+ out_4x32b_h = _mm_and_si128(out_4x32b_h, chroma_mask);
+
+ res_4x32b_l_0 = _mm_and_si128(res_4x32b_l_0, chroma_mask2);
+ res_4x32b_l_1 = _mm_and_si128(res_4x32b_l_1, chroma_mask2);
+
+ out_4x32b_l = _mm_add_epi8(res_4x32b_l_0, out_4x32b_l);
+ out_4x32b_h = _mm_add_epi8(res_4x32b_l_1, out_4x32b_h);
+
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp), out_4x32b_l);
+ _mm_storeu_si128((__m128i *) (pi2_out + out_stride_temp + 8), out_4x32b_h);
+ }
+ }
+ return;
+} /* End of Interpolation Function */
+
+/*****************************************************************************/
+/* */
+/* Function Name : isvcd_residual_reflayer_const_non_boundary_mb_sse42 */
+/* */
+/* Description : */
+/* */
+/* Inputs : */
+/* Globals : none */
+/* Processing : */
+/* */
+/* Outputs : none */
+/* Returns : none */
+/* */
+/* Issues : none */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 25 11 2021 Kishore creation */
+/* */
+/*****************************************************************************/
+
+void isvcd_residual_reflayer_const_non_boundary_mb_sse42(
+ WORD16 *pi2_inp_data, WORD32 i4_inp_data_stride, WORD16 *pi2_ref_array, WORD32 i4_refarray_wd,
+ WORD32 i4_refarray_ht, WORD32 i4_ref_mb_type_q0, WORD32 i4_ref_mb_type_q1,
+ WORD32 i4_ref_mb_type_q2, WORD32 i4_ref_mb_type_q3, WORD32 i4_mb_quard1_part_x,
+ WORD32 i4_mb_quard1_part_y, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_y;
+
+ WORD16 *pi2_ref_data_byte;
+ WORD16 *pi2_ref_array_temp;
+ if(i4_chroma_flag == 0)
+ {
+ WORD8 index_0[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+ __m128i ref_mb_type_8x16_q0, ref_mb_type_8x16_q1, ref_mb_type_8x16_q2, ref_mb_type_8x16_q3,
+ mb_quard1_part_x_8x16;
+ __m128i ref_mb_type_8x16_0, ref_mb_type_8x16_1;
+ __m128i ref_mb_type_8x16_low_0, ref_mb_type_8x16_low_1;
+ __m128i mb_type_mask_8x16_0 = _mm_set1_epi8(-1);
+ __m128i mb_type_mask_8x16_1 = _mm_set1_epi8(-1);
+ __m128i mb_type_mask_8x16_low_0, mb_type_mask_8x16_low_1;
+ __m128i mask_8x16_0;
+ __m128i index_arr_0;
+ __m128i inp_data_16x8_0, inp_data_16x8_1;
+ __m128i res_16x8_0, res_16x8_1;
+ __m128i one_8x16 = _mm_set1_epi8(1);
+ __m128i zero_8x16 = _mm_set1_epi8(0);
+
+ index_arr_0 = _mm_loadu_si128((__m128i *) index_0);
+ ref_mb_type_8x16_q0 = _mm_set1_epi8(i4_ref_mb_type_q0);
+ ref_mb_type_8x16_q1 = _mm_set1_epi8(i4_ref_mb_type_q1);
+ ref_mb_type_8x16_q2 = _mm_set1_epi8(i4_ref_mb_type_q2);
+ ref_mb_type_8x16_q3 = _mm_set1_epi8(i4_ref_mb_type_q3);
+ if((i4_mb_quard1_part_x >= i4_refarray_wd) && (i4_mb_quard1_part_y >= i4_refarray_ht))
+ {
+ // Quard 0
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q0;
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ mb_type_mask_8x16_1 = mb_type_mask_8x16_0;
+ }
+ else if((i4_mb_quard1_part_y >= (i4_refarray_ht - 1)) &&
+ (i4_mb_quard1_part_x < i4_refarray_wd))
+ {
+ // Quard 0 & 1
+ if(i4_mb_quard1_part_x == 8)
+ {
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q1;
+ }
+ else if(i4_mb_quard1_part_x < 8)
+ {
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x << 1));
+ mask_8x16_0 =
+ _mm_cmplt_epi8(index_arr_0, mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q1;
+ }
+ else
+ {
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x - 8) << 1);
+ mask_8x16_0 =
+ _mm_cmplt_epi8(index_arr_0, mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+ }
+
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ mb_type_mask_8x16_1 = _mm_cmpeq_epi8(ref_mb_type_8x16_1, one_8x16);
+ }
+ else
+ {
+ if(i4_mb_quard1_part_x >= i4_refarray_wd)
+ {
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q0;
+
+ ref_mb_type_8x16_low_0 = ref_mb_type_8x16_q2;
+ ref_mb_type_8x16_low_1 = ref_mb_type_8x16_q2;
+ }
+ else
+ {
+ // Quard 0, 1, 2, 3
+ if(i4_mb_quard1_part_x == 8)
+ {
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q1;
+
+ ref_mb_type_8x16_low_0 = ref_mb_type_8x16_q2;
+ ref_mb_type_8x16_low_1 = ref_mb_type_8x16_q3;
+ }
+ else if(i4_mb_quard1_part_x < 8)
+ {
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x << 1));
+ mask_8x16_0 = _mm_cmplt_epi8(index_arr_0,
+ mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+ ref_mb_type_8x16_1 = ref_mb_type_8x16_q1;
+
+ ref_mb_type_8x16_low_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q3, ref_mb_type_8x16_q2, mask_8x16_0);
+ ref_mb_type_8x16_low_1 = ref_mb_type_8x16_q3;
+ }
+ else
+ {
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x - 8) << 1);
+ mask_8x16_0 = _mm_cmplt_epi8(index_arr_0,
+ mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_1 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+
+ ref_mb_type_8x16_low_0 = ref_mb_type_8x16_q2;
+ ref_mb_type_8x16_low_1 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q3, ref_mb_type_8x16_q2, mask_8x16_0);
+ }
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ mb_type_mask_8x16_1 = _mm_cmpeq_epi8(ref_mb_type_8x16_1, one_8x16);
+
+ mb_type_mask_8x16_low_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_low_0, one_8x16);
+ mb_type_mask_8x16_low_1 = _mm_cmpeq_epi8(ref_mb_type_8x16_low_1, one_8x16);
+ }
+ }
+
+ if(i4_mb_quard1_part_y < i4_refarray_ht - 1)
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte));
+ inp_data_16x8_1 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte + 8));
+
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ res_16x8_0 = _mm_blendv_epi8(zero_8x16, inp_data_16x8_0, mb_type_mask_8x16_0);
+ res_16x8_1 = _mm_blendv_epi8(zero_8x16, inp_data_16x8_1, mb_type_mask_8x16_1);
+ }
+ else
+ {
+ res_16x8_0 =
+ _mm_blendv_epi8(zero_8x16, inp_data_16x8_0, mb_type_mask_8x16_low_0);
+ res_16x8_1 =
+ _mm_blendv_epi8(zero_8x16, inp_data_16x8_1, mb_type_mask_8x16_low_1);
+ }
+
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp), res_16x8_0);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp + 8), res_16x8_1);
+ }
+ }
+ else
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte));
+ inp_data_16x8_1 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte + 8));
+
+ res_16x8_0 = _mm_blendv_epi8(zero_8x16, inp_data_16x8_0, mb_type_mask_8x16_0);
+ res_16x8_1 = _mm_blendv_epi8(zero_8x16, inp_data_16x8_1, mb_type_mask_8x16_1);
+
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp), res_16x8_0);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp + 8), res_16x8_1);
+ }
+ }
+ }
+ else
+ {
+ WORD8 index_0[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+ WORD8 even_mask_arr[16] = {0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15};
+ __m128i ref_mb_type_8x16_q0, ref_mb_type_8x16_q1, ref_mb_type_8x16_q2, ref_mb_type_8x16_q3,
+ mb_quard1_part_x_8x16;
+ __m128i ref_mb_type_8x16_0;
+ __m128i ref_mb_type_8x16_low_0;
+ __m128i mb_type_mask_8x16_0 = _mm_set1_epi8(-1);
+ __m128i mb_type_mask_8x16_low_0;
+ __m128i mask_8x16_0;
+ __m128i index_arr_0, even_mask;
+ __m128i inp_data_16x8_0, inp_data_16x8_1, inp_data_16x8;
+ __m128i res_16x8_0;
+ __m128i one_8x16 = _mm_set1_epi8(1);
+ __m128i zero_8x16 = _mm_set1_epi8(0);
+
+ index_arr_0 = _mm_loadu_si128((__m128i *) index_0);
+ even_mask = _mm_loadu_si128((__m128i *) even_mask_arr);
+
+ ref_mb_type_8x16_q0 = _mm_set1_epi8(i4_ref_mb_type_q0);
+ ref_mb_type_8x16_q1 = _mm_set1_epi8(i4_ref_mb_type_q1);
+ ref_mb_type_8x16_q2 = _mm_set1_epi8(i4_ref_mb_type_q2);
+ ref_mb_type_8x16_q3 = _mm_set1_epi8(i4_ref_mb_type_q3);
+ if((i4_mb_quard1_part_x >= i4_refarray_wd) && (i4_mb_quard1_part_y >= i4_refarray_ht))
+ {
+ // Quard 0
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ }
+ else if((i4_mb_quard1_part_y >= (i4_refarray_ht - 1)) &&
+ (i4_mb_quard1_part_x < i4_refarray_wd))
+ {
+ // Quard 0 & 1
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x << 1));
+ mask_8x16_0 =
+ _mm_cmplt_epi8(index_arr_0, mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ }
+ else
+ {
+ if(i4_mb_quard1_part_x >= i4_refarray_wd)
+ {
+ // Quard 0 & 2
+ ref_mb_type_8x16_0 = ref_mb_type_8x16_q0;
+ ref_mb_type_8x16_low_0 = ref_mb_type_8x16_q2;
+ }
+ else
+ {
+ // Quard 0, 1, 2, 3
+ mb_quard1_part_x_8x16 = _mm_set1_epi8((i4_mb_quard1_part_x << 1));
+ mask_8x16_0 =
+ _mm_cmplt_epi8(index_arr_0, mb_quard1_part_x_8x16); // return 1 if a<b, else 0
+
+ ref_mb_type_8x16_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q1, ref_mb_type_8x16_q0, mask_8x16_0);
+ ref_mb_type_8x16_low_0 =
+ _mm_blendv_epi8(ref_mb_type_8x16_q3, ref_mb_type_8x16_q2, mask_8x16_0);
+
+ mb_type_mask_8x16_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_0, one_8x16);
+ mb_type_mask_8x16_low_0 = _mm_cmpeq_epi8(ref_mb_type_8x16_low_0, one_8x16);
+ }
+ }
+
+ if(i4_mb_quard1_part_y < i4_refarray_ht - 1)
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte));
+ inp_data_16x8_1 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte + 8));
+
+ inp_data_16x8_0 = _mm_shuffle_epi8(inp_data_16x8_0, even_mask);
+ inp_data_16x8_1 = _mm_shuffle_epi8(inp_data_16x8_1, even_mask);
+
+ inp_data_16x8 = _mm_unpacklo_epi64(inp_data_16x8_0, inp_data_16x8_1);
+ if(i4_y < i4_mb_quard1_part_y)
+ {
+ res_16x8_0 = _mm_blendv_epi8(zero_8x16, inp_data_16x8, mb_type_mask_8x16_0);
+ }
+ else
+ {
+ res_16x8_0 = _mm_blendv_epi8(zero_8x16, inp_data_16x8, mb_type_mask_8x16_low_0);
+ }
+
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp), res_16x8_0);
+ }
+ }
+ else
+ {
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_y * i4_inp_data_stride);
+ inp_data_16x8_0 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte));
+ inp_data_16x8_1 = _mm_loadu_si128((__m128i *) (pi2_ref_data_byte + 8));
+
+ inp_data_16x8_0 = _mm_shuffle_epi8(inp_data_16x8_0, even_mask);
+ inp_data_16x8_1 = _mm_shuffle_epi8(inp_data_16x8_1, even_mask);
+ inp_data_16x8 = _mm_unpacklo_epi64(inp_data_16x8_0, inp_data_16x8_1);
+
+ res_16x8_0 = _mm_blendv_epi8(zero_8x16, inp_data_16x8, mb_type_mask_8x16_0);
+ pi2_ref_array_temp = pi2_ref_array + (i4_y * i4_refarray_wd);
+ _mm_storeu_si128((__m128i *) (pi2_ref_array_temp), res_16x8_0);
+ }
+ }
+ }
+}
diff --git a/encoder/arm/svc/isvce_downscaler_neon.c b/encoder/arm/svc/isvce_downscaler_neon.c
new file mode 100644
index 0000000..9f9bef4
--- /dev/null
+++ b/encoder/arm/svc/isvce_downscaler_neon.c
@@ -0,0 +1,927 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file ih264e_downscaler_neon.c
+*
+* @brief
+* This file contains the ARMV8 SIMD version of the function which does
+* horizontal scaling and transpose
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - ih264e_horizontal_downscale_and_transpose_av8()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <arm_neon.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvc_structs.h"
+#include "isvce_downscaler_private_defs.h"
+
+void isvce_horizontal_downscale_and_transpose_neon(
+ downscaler_ctxt_t *ps_scaler, buffer_container_t *ps_src, buffer_container_t *ps_dst,
+ FILTER_COEFF_ARRAY pai1_filters, UWORD32 u4_blk_wd, UWORD32 u4_blk_ht, UWORD8 u1_is_chroma)
+{
+ WORD32 i, j;
+ UWORD8 u1_phase;
+ UWORD8 *pu1_src_j, *pu1_dst_j;
+ UWORD8 *pu1_in_pixel;
+ UWORD8 *pu1_out_pixel;
+ WORD8 *pi1_filter_grid;
+ UWORD16 u2_full_pixel_inc;
+ UWORD32 u4_num_iterations_vertical_by_16, u4_num_iterations_vertical_by_8;
+ UWORD32 u4_rem_vert_loop_by_8, u4_rem_vert_loop_by_4;
+ UWORD32 u4_rem_vert_loop;
+ UWORD32 u4_height_finished;
+
+ uint8x8_t reg_8x8_src_r0, reg_8x8_src_r1, reg_8x8_src_r2, reg_8x8_src_r3, reg_8x8_src_r4,
+ reg_8x8_src_r5, reg_8x8_src_r6, reg_8x8_src_r7;
+
+ uint16x8_t reg_16x8_src_r0, reg_16x8_src_r1, reg_16x8_src_r2, reg_16x8_src_r3, reg_16x8_src_r4,
+ reg_16x8_src_r5, reg_16x8_src_r6, reg_16x8_src_r7;
+
+ int16x8_t reg_16x8_mul_r0, reg_16x8_mul_r1, reg_16x8_mul_r2, reg_16x8_mul_r3, reg_16x8_mul_r4,
+ reg_16x8_mul_r5, reg_16x8_mul_r6, reg_16x8_mul_r7;
+
+ int32x4_t reg_32x4_sum_r0, reg_32x4_sum_r1, reg_32x4_sum_r2, reg_32x4_sum_r3, reg_32x4_sum_r4,
+ reg_32x4_sum_r5, reg_32x4_sum_r6, reg_32x4_sum_r7;
+
+ int32x4_t reg_32x4_sum_r01, reg_32x4_sum_r23, reg_32x4_sum_r45, reg_32x4_sum_r67,
+ reg_32x4_sum_r89, reg_32x4_sum_r1011, reg_32x4_sum_r1213, reg_32x4_sum_r1415;
+
+ uint8x8_t reg_8x8_src_r8, reg_8x8_src_r9, reg_8x8_src_r10, reg_8x8_src_r11, reg_8x8_src_r12,
+ reg_8x8_src_r13, reg_8x8_src_r14, reg_8x8_src_r15;
+
+ uint16x8_t reg_16x8_src_r8, reg_16x8_src_r9, reg_16x8_src_r10, reg_16x8_src_r11,
+ reg_16x8_src_r12, reg_16x8_src_r13, reg_16x8_src_r14, reg_16x8_src_r15;
+
+ int16x8_t reg_16x8_mul_r8, reg_16x8_mul_r9, reg_16x8_mul_r10, reg_16x8_mul_r11,
+ reg_16x8_mul_r12, reg_16x8_mul_r13, reg_16x8_mul_r14, reg_16x8_mul_r15;
+
+ int32x4_t reg_32x4_sum_r8, reg_32x4_sum_r9, reg_32x4_sum_r10, reg_32x4_sum_r11,
+ reg_32x4_sum_r12, reg_32x4_sum_r13, reg_32x4_sum_r14, reg_32x4_sum_r15;
+
+ uint8x16_t reg_8x16_src_r0, reg_8x16_src_r1, reg_8x16_src_r2, reg_8x16_src_r3, reg_8x16_src_r4,
+ reg_8x16_src_r5, reg_8x16_src_r6, reg_8x16_src_r7;
+
+ uint16x8_t reg_16x8_src_cb_r0, reg_16x8_src_cb_r1, reg_16x8_src_cb_r2, reg_16x8_src_cb_r3,
+ reg_16x8_src_cb_r4, reg_16x8_src_cb_r5, reg_16x8_src_cb_r6, reg_16x8_src_cb_r7;
+
+ uint16x8_t reg_16x8_src_cr_r0, reg_16x8_src_cr_r1, reg_16x8_src_cr_r2, reg_16x8_src_cr_r3,
+ reg_16x8_src_cr_r4, reg_16x8_src_cr_r5, reg_16x8_src_cr_r6, reg_16x8_src_cr_r7;
+
+ int16x8_t reg_16x8_mul_cb_r0, reg_16x8_mul_cb_r1, reg_16x8_mul_cb_r2, reg_16x8_mul_cb_r3,
+ reg_16x8_mul_cb_r4, reg_16x8_mul_cb_r5, reg_16x8_mul_cb_r6, reg_16x8_mul_cb_r7;
+
+ int16x8_t reg_16x8_mul_cr_r0, reg_16x8_mul_cr_r1, reg_16x8_mul_cr_r2, reg_16x8_mul_cr_r3,
+ reg_16x8_mul_cr_r4, reg_16x8_mul_cr_r5, reg_16x8_mul_cr_r6, reg_16x8_mul_cr_r7;
+
+ int32x4_t reg_32x4_sum_cb_r0, reg_32x4_sum_cb_r1, reg_32x4_sum_cb_r2, reg_32x4_sum_cb_r3,
+ reg_32x4_sum_cb_r4, reg_32x4_sum_cb_r5, reg_32x4_sum_cb_r6, reg_32x4_sum_cb_r7;
+
+ int32x4_t reg_32x4_sum_cr_r0, reg_32x4_sum_cr_r1, reg_32x4_sum_cr_r2, reg_32x4_sum_cr_r3,
+ reg_32x4_sum_cr_r4, reg_32x4_sum_cr_r5, reg_32x4_sum_cr_r6, reg_32x4_sum_cr_r7;
+
+ int32x4_t reg_32x4_sum_cb_r01, reg_32x4_sum_cb_r23, reg_32x4_sum_cb_r45, reg_32x4_sum_cb_r67;
+ uint16x4_t reg_16x4_sum_cb_r01_23, reg_16x4_sum_cb_r45_67;
+ uint16x8_t reg_16x8_sum_cb_r0_r7;
+ uint8x8_t reg_8x8_sum_cb_r0_r7;
+
+ int32x4_t reg_32x4_sum_cr_r01, reg_32x4_sum_cr_r23, reg_32x4_sum_cr_r45, reg_32x4_sum_cr_r67;
+ uint16x4_t reg_16x4_sum_cr_r01_23, reg_16x4_sum_cr_r45_67;
+ uint16x8_t reg_16x8_sum_cr_r0_r7;
+ uint8x8_t reg_8x8_sum_cr_r0_r7;
+ uint16x8_t reg_16x8_sum_cb_cr_r0_r3;
+ uint8x8_t reg_8x8_sum_cb_cr_r0_r3;
+
+ int32x4_t reg_32x4_sum_cb_cr_r0;
+ uint16x4_t reg_16x4_sum_cb_cr_r0;
+
+ int32x4_t reg_32x4_zero = vdupq_n_s32(0);
+
+ uint16x4_t reg_16x4_sum_r01_23, reg_16x4_sum_r45_67;
+ uint16x4_t reg_16x4_sum_r8_r11, reg_16x4_sum_r12_r15;
+ uint16x8_t reg_16x8_sum_r0_r7, reg_16x8_sum_r8_r15;
+ uint8x8_t reg_8x8_sum_r0_r7, reg_8x8_sum_r8_r15;
+ uint8x16_t reg_8x16_sum_r0_r15;
+ int8x8_t reg_8x8_filt_coeff_grid;
+ int16x8_t reg_16x8_filt_coeff_grid;
+ int32x4x2_t reg_32x4x2_sum_r01, reg_32x4x2_sum_r23, reg_32x4x2_sum_r45, reg_32x4x2_sum_r67;
+ int32x4x2_t reg_32x4x2_sum_r89, reg_32x4x2_sum_r1011, reg_32x4x2_sum_r1213,
+ reg_32x4x2_sum_r1415;
+ uint8x16x2_t reg_8x16x2_src_r0, reg_8x16x2_src_r1, reg_8x16x2_src_r2, reg_8x16x2_src_r3;
+
+ downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state;
+
+ UWORD32 u4_center_pixel_pos = ps_scaler_state->i4_init_offset;
+ UWORD32 u4_src_vert_increments = ps_scaler_state->u4_vert_increment;
+ UWORD32 u4_src_horz_increments = ps_scaler_state->u4_horz_increment;
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD32 u4_in_stride = ps_src->i4_data_stride;
+ UWORD8 *pu1_dst = (UWORD8 *) ps_dst->pv_data;
+ UWORD32 u4_out_stride = ps_dst->i4_data_stride;
+ UWORD32 u4_center_pixel_pos_src = u4_center_pixel_pos;
+
+ /* Offset the input so that the input pixel to be processed
+ co-incides with the centre of filter (4th coefficient)*/
+ pu1_src += (1 + u1_is_chroma);
+
+ ASSERT((1 << DOWNSCALER_Q) == u4_src_vert_increments);
+
+ if(!u1_is_chroma)
+ {
+ u4_num_iterations_vertical_by_16 = u4_blk_ht >> 4;
+ u4_rem_vert_loop = u4_blk_ht % 16;
+
+ for(j = 0; j < (WORD32) u4_num_iterations_vertical_by_16; j++)
+ {
+ pu1_src_j = pu1_src + ((j << 4) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 4);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ /* Doing the Calculation for current Loop Count */
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ /* r0-r7 */
+ reg_8x8_src_r0 = vld1_u8(pu1_in_pixel);
+ reg_8x8_src_r1 = vld1_u8(pu1_in_pixel + u4_in_stride);
+ reg_8x8_src_r2 = vld1_u8(pu1_in_pixel + 2 * u4_in_stride);
+ reg_8x8_src_r3 = vld1_u8(pu1_in_pixel + 3 * u4_in_stride);
+ reg_8x8_src_r4 = vld1_u8(pu1_in_pixel + 4 * u4_in_stride);
+ reg_8x8_src_r5 = vld1_u8(pu1_in_pixel + 5 * u4_in_stride);
+ reg_8x8_src_r6 = vld1_u8(pu1_in_pixel + 6 * u4_in_stride);
+ reg_8x8_src_r7 = vld1_u8(pu1_in_pixel + 7 * u4_in_stride);
+
+ /* r0-r7 */
+ reg_16x8_src_r0 = vmovl_u8(reg_8x8_src_r0);
+ reg_16x8_src_r1 = vmovl_u8(reg_8x8_src_r1);
+ reg_16x8_src_r2 = vmovl_u8(reg_8x8_src_r2);
+ reg_16x8_src_r3 = vmovl_u8(reg_8x8_src_r3);
+ reg_16x8_src_r4 = vmovl_u8(reg_8x8_src_r4);
+ reg_16x8_src_r5 = vmovl_u8(reg_8x8_src_r5);
+ reg_16x8_src_r6 = vmovl_u8(reg_8x8_src_r6);
+ reg_16x8_src_r7 = vmovl_u8(reg_8x8_src_r7);
+
+ /* r8-r15 */
+ reg_8x8_src_r8 = vld1_u8(pu1_in_pixel + 8 * u4_in_stride);
+ reg_8x8_src_r9 = vld1_u8(pu1_in_pixel + 9 * u4_in_stride);
+ reg_8x8_src_r10 = vld1_u8(pu1_in_pixel + 10 * u4_in_stride);
+ reg_8x8_src_r11 = vld1_u8(pu1_in_pixel + 11 * u4_in_stride);
+ reg_8x8_src_r12 = vld1_u8(pu1_in_pixel + 12 * u4_in_stride);
+ reg_8x8_src_r13 = vld1_u8(pu1_in_pixel + 13 * u4_in_stride);
+ reg_8x8_src_r14 = vld1_u8(pu1_in_pixel + 14 * u4_in_stride);
+ reg_8x8_src_r15 = vld1_u8(pu1_in_pixel + 15 * u4_in_stride);
+
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ /*r0-r7 */
+ reg_16x8_mul_r0 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r0), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r1 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r1), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r2 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r2), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r3 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r3), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r4 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r4), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r5 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r5), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r6 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r6), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r7 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r7), reg_16x8_filt_coeff_grid);
+
+ /* r8-r15 */
+ reg_16x8_src_r8 = vmovl_u8(reg_8x8_src_r8);
+ reg_16x8_src_r9 = vmovl_u8(reg_8x8_src_r9);
+ reg_16x8_src_r10 = vmovl_u8(reg_8x8_src_r10);
+ reg_16x8_src_r11 = vmovl_u8(reg_8x8_src_r11);
+ reg_16x8_src_r12 = vmovl_u8(reg_8x8_src_r12);
+ reg_16x8_src_r13 = vmovl_u8(reg_8x8_src_r13);
+ reg_16x8_src_r14 = vmovl_u8(reg_8x8_src_r14);
+ reg_16x8_src_r15 = vmovl_u8(reg_8x8_src_r15);
+
+ /* r0-r7 */
+ reg_32x4_sum_r0 = vpaddlq_s16(reg_16x8_mul_r0);
+ reg_32x4_sum_r1 = vpaddlq_s16(reg_16x8_mul_r1);
+ reg_32x4_sum_r2 = vpaddlq_s16(reg_16x8_mul_r2);
+ reg_32x4_sum_r3 = vpaddlq_s16(reg_16x8_mul_r3);
+ reg_32x4_sum_r4 = vpaddlq_s16(reg_16x8_mul_r4);
+ reg_32x4_sum_r5 = vpaddlq_s16(reg_16x8_mul_r5);
+ reg_32x4_sum_r6 = vpaddlq_s16(reg_16x8_mul_r6);
+ reg_32x4_sum_r7 = vpaddlq_s16(reg_16x8_mul_r7);
+
+ /* r8-r15 */
+ reg_16x8_mul_r8 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r8), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r9 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r9), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r10 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r10), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r11 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r11), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r12 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r12), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r13 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r13), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r14 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r14), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r15 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r15), reg_16x8_filt_coeff_grid);
+
+ /* r0-r7 */
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r0, reg_32x4_sum_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_r2, reg_32x4_sum_r3);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_r4, reg_32x4_sum_r5);
+ reg_32x4x2_sum_r67 = vuzpq_s32(reg_32x4_sum_r6, reg_32x4_sum_r7);
+
+ reg_32x4_sum_r01 = vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_r23 = vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4_sum_r45 = vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+ reg_32x4_sum_r67 = vaddq_s32(reg_32x4x2_sum_r67.val[0], reg_32x4x2_sum_r67.val[1]);
+
+ /* r8-r15 */
+ reg_32x4_sum_r8 = vpaddlq_s16(reg_16x8_mul_r8);
+ reg_32x4_sum_r9 = vpaddlq_s16(reg_16x8_mul_r9);
+ reg_32x4_sum_r10 = vpaddlq_s16(reg_16x8_mul_r10);
+ reg_32x4_sum_r11 = vpaddlq_s16(reg_16x8_mul_r11);
+ reg_32x4_sum_r12 = vpaddlq_s16(reg_16x8_mul_r12);
+ reg_32x4_sum_r13 = vpaddlq_s16(reg_16x8_mul_r13);
+ reg_32x4_sum_r14 = vpaddlq_s16(reg_16x8_mul_r14);
+ reg_32x4_sum_r15 = vpaddlq_s16(reg_16x8_mul_r15);
+
+ /* r0-r7 */
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r01, reg_32x4_sum_r23);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_r45, reg_32x4_sum_r67);
+ reg_32x4_sum_r01 = vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_r45 = vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+
+ /* r8-r15 */
+ reg_32x4x2_sum_r89 = vuzpq_s32(reg_32x4_sum_r8, reg_32x4_sum_r9);
+ reg_32x4x2_sum_r1011 = vuzpq_s32(reg_32x4_sum_r10, reg_32x4_sum_r11);
+ reg_32x4x2_sum_r1213 = vuzpq_s32(reg_32x4_sum_r12, reg_32x4_sum_r13);
+ reg_32x4x2_sum_r1415 = vuzpq_s32(reg_32x4_sum_r14, reg_32x4_sum_r15);
+
+ reg_32x4_sum_r89 = vaddq_s32(reg_32x4x2_sum_r89.val[0], reg_32x4x2_sum_r89.val[1]);
+ reg_32x4_sum_r1011 =
+ vaddq_s32(reg_32x4x2_sum_r1011.val[0], reg_32x4x2_sum_r1011.val[1]);
+ reg_32x4_sum_r1213 =
+ vaddq_s32(reg_32x4x2_sum_r1213.val[0], reg_32x4x2_sum_r1213.val[1]);
+ reg_32x4_sum_r1415 =
+ vaddq_s32(reg_32x4x2_sum_r1415.val[0], reg_32x4x2_sum_r1415.val[1]);
+
+ /* r0-r7 */
+ reg_16x4_sum_r01_23 = vqrshrun_n_s32(reg_32x4_sum_r01, 7);
+ reg_16x4_sum_r45_67 = vqrshrun_n_s32(reg_32x4_sum_r45, 7);
+
+ /* r8-r15 */
+ reg_32x4x2_sum_r89 = vuzpq_s32(reg_32x4_sum_r89, reg_32x4_sum_r1011);
+ reg_32x4x2_sum_r1213 = vuzpq_s32(reg_32x4_sum_r1213, reg_32x4_sum_r1415);
+ reg_32x4_sum_r89 = vaddq_s32(reg_32x4x2_sum_r89.val[0], reg_32x4x2_sum_r89.val[1]);
+ reg_32x4_sum_r1213 =
+ vaddq_s32(reg_32x4x2_sum_r1213.val[0], reg_32x4x2_sum_r1213.val[1]);
+
+ /* r0-r7 */
+ reg_16x8_sum_r0_r7 = vcombine_u16(reg_16x4_sum_r01_23, reg_16x4_sum_r45_67);
+ reg_8x8_sum_r0_r7 = vqmovn_u16(reg_16x8_sum_r0_r7);
+
+ reg_16x4_sum_r8_r11 = vqrshrun_n_s32(reg_32x4_sum_r89, 7);
+ reg_16x4_sum_r12_r15 = vqrshrun_n_s32(reg_32x4_sum_r1213, 7);
+
+ reg_16x8_sum_r8_r15 = vcombine_u16(reg_16x4_sum_r8_r11, reg_16x4_sum_r12_r15);
+ reg_8x8_sum_r8_r15 = vqmovn_u16(reg_16x8_sum_r8_r15);
+
+ reg_8x16_sum_r0_r15 = vcombine_u8(reg_8x8_sum_r0_r7, reg_8x8_sum_r8_r15);
+
+ /* r0-r7 */
+ vst1q_u8(pu1_out_pixel, reg_8x16_sum_r0_r15);
+
+ pu1_out_pixel += 16;
+ pu1_in_pixel += (u4_src_vert_increments * (u4_in_stride << 4)) >> DOWNSCALER_Q;
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /* Loop for the remaining height less than 16 */
+ if(u4_rem_vert_loop)
+ {
+ u4_rem_vert_loop_by_8 = u4_rem_vert_loop >> 3;
+ u4_rem_vert_loop = u4_rem_vert_loop % 8;
+
+ u4_height_finished = (u4_num_iterations_vertical_by_16 << 4);
+
+ pu1_src_j = pu1_src + ((u4_height_finished) *u4_in_stride);
+ pu1_dst_j = pu1_dst + u4_height_finished;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ /* 8 <= remaining height < 16 */
+ if(u4_rem_vert_loop_by_8)
+ {
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ for(j = u4_rem_vert_loop_by_8; j > 0; j--)
+ {
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ reg_8x8_src_r0 = vld1_u8(pu1_in_pixel);
+ reg_8x8_src_r1 = vld1_u8(pu1_in_pixel + u4_in_stride);
+ reg_8x8_src_r2 = vld1_u8(pu1_in_pixel + 2 * u4_in_stride);
+ reg_8x8_src_r3 = vld1_u8(pu1_in_pixel + 3 * u4_in_stride);
+ reg_8x8_src_r4 = vld1_u8(pu1_in_pixel + 4 * u4_in_stride);
+ reg_8x8_src_r5 = vld1_u8(pu1_in_pixel + 5 * u4_in_stride);
+ reg_8x8_src_r6 = vld1_u8(pu1_in_pixel + 6 * u4_in_stride);
+ reg_8x8_src_r7 = vld1_u8(pu1_in_pixel + 7 * u4_in_stride);
+
+ reg_16x8_src_r0 = vmovl_u8(reg_8x8_src_r0);
+ reg_16x8_src_r1 = vmovl_u8(reg_8x8_src_r1);
+ reg_16x8_src_r2 = vmovl_u8(reg_8x8_src_r2);
+ reg_16x8_src_r3 = vmovl_u8(reg_8x8_src_r3);
+ reg_16x8_src_r4 = vmovl_u8(reg_8x8_src_r4);
+ reg_16x8_src_r5 = vmovl_u8(reg_8x8_src_r5);
+ reg_16x8_src_r6 = vmovl_u8(reg_8x8_src_r6);
+ reg_16x8_src_r7 = vmovl_u8(reg_8x8_src_r7);
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ reg_16x8_mul_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r0),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r1 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r1),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r2 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r2),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r3 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r3),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r4 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r4),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r5 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r5),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r6 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r6),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_r7 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r7),
+ reg_16x8_filt_coeff_grid);
+
+ reg_32x4_sum_r0 = vpaddlq_s16(reg_16x8_mul_r0);
+ reg_32x4_sum_r1 = vpaddlq_s16(reg_16x8_mul_r1);
+ reg_32x4_sum_r2 = vpaddlq_s16(reg_16x8_mul_r2);
+ reg_32x4_sum_r3 = vpaddlq_s16(reg_16x8_mul_r3);
+ reg_32x4_sum_r4 = vpaddlq_s16(reg_16x8_mul_r4);
+ reg_32x4_sum_r5 = vpaddlq_s16(reg_16x8_mul_r5);
+ reg_32x4_sum_r6 = vpaddlq_s16(reg_16x8_mul_r6);
+ reg_32x4_sum_r7 = vpaddlq_s16(reg_16x8_mul_r7);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r0, reg_32x4_sum_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_r2, reg_32x4_sum_r3);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_r4, reg_32x4_sum_r5);
+ reg_32x4x2_sum_r67 = vuzpq_s32(reg_32x4_sum_r6, reg_32x4_sum_r7);
+
+ reg_32x4_sum_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_r23 =
+ vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4_sum_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+ reg_32x4_sum_r67 =
+ vaddq_s32(reg_32x4x2_sum_r67.val[0], reg_32x4x2_sum_r67.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r01, reg_32x4_sum_r23);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_r45, reg_32x4_sum_r67);
+ reg_32x4_sum_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+
+ reg_16x4_sum_r01_23 = vqrshrun_n_s32(reg_32x4_sum_r01, 7);
+ reg_16x4_sum_r45_67 = vqrshrun_n_s32(reg_32x4_sum_r45, 7);
+
+ reg_16x8_sum_r0_r7 = vcombine_u16(reg_16x4_sum_r01_23, reg_16x4_sum_r45_67);
+ reg_8x8_sum_r0_r7 = vqmovn_u16(reg_16x8_sum_r0_r7);
+
+ vst1_u8(pu1_out_pixel, reg_8x8_sum_r0_r7);
+
+ pu1_out_pixel += 8;
+ pu1_in_pixel +=
+ (u4_src_vert_increments * (u4_in_stride << 3)) >> DOWNSCALER_Q;
+ }
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /* 1 <= remaining height < 8 */
+ if(u4_rem_vert_loop)
+ {
+ u4_height_finished =
+ ((u4_num_iterations_vertical_by_16 << 4) + (u4_rem_vert_loop_by_8 << 3));
+ pu1_src_j = pu1_src + u4_height_finished * u4_in_stride;
+ pu1_dst_j = pu1_dst + u4_height_finished;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ for(j = u4_rem_vert_loop; j > 0; j--)
+ {
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ reg_8x8_src_r0 = vld1_u8(pu1_in_pixel);
+ reg_16x8_src_r0 = vmovl_u8(reg_8x8_src_r0);
+
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ reg_16x8_mul_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_r0),
+ reg_16x8_filt_coeff_grid);
+
+ reg_32x4_sum_r0 = vpaddlq_s16(reg_16x8_mul_r0);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r0, reg_32x4_zero);
+ reg_32x4_sum_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_r01, reg_32x4_zero);
+ reg_32x4_sum_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+
+ reg_16x4_sum_r01_23 = vqrshrun_n_s32(reg_32x4_sum_r01, 7);
+
+ vst1_lane_u8(pu1_out_pixel, vreinterpret_u8_u16(reg_16x4_sum_r01_23), 0);
+ pu1_out_pixel += 1;
+ pu1_in_pixel += (u4_src_vert_increments * u4_in_stride) >> DOWNSCALER_Q;
+ }
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+ }
+ /* for chroma */
+ else
+ {
+ u4_num_iterations_vertical_by_8 = u4_blk_ht >> 3;
+ u4_rem_vert_loop = u4_blk_ht % 8;
+
+ for(j = 0; j < (WORD32) u4_num_iterations_vertical_by_8; j++)
+ {
+ pu1_src_j = pu1_src + ((j << 3) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 3);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ /*Doing the Calculation for current Loop Count */
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ reg_8x16_src_r0 = vld1q_u8(pu1_in_pixel);
+ reg_8x16_src_r1 = vld1q_u8(pu1_in_pixel + u4_in_stride);
+ reg_8x16_src_r2 = vld1q_u8(pu1_in_pixel + 2 * u4_in_stride);
+ reg_8x16_src_r3 = vld1q_u8(pu1_in_pixel + 3 * u4_in_stride);
+ reg_8x16_src_r4 = vld1q_u8(pu1_in_pixel + 4 * u4_in_stride);
+ reg_8x16_src_r5 = vld1q_u8(pu1_in_pixel + 5 * u4_in_stride);
+ reg_8x16_src_r6 = vld1q_u8(pu1_in_pixel + 6 * u4_in_stride);
+ reg_8x16_src_r7 = vld1q_u8(pu1_in_pixel + 7 * u4_in_stride);
+
+ reg_8x16x2_src_r0 = vuzpq_u8(reg_8x16_src_r0, reg_8x16_src_r1);
+ reg_8x16x2_src_r1 = vuzpq_u8(reg_8x16_src_r2, reg_8x16_src_r3);
+ reg_8x16x2_src_r2 = vuzpq_u8(reg_8x16_src_r4, reg_8x16_src_r5);
+ reg_8x16x2_src_r3 = vuzpq_u8(reg_8x16_src_r6, reg_8x16_src_r7);
+
+ reg_16x8_src_cb_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[0]));
+ reg_16x8_src_cb_r1 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r0.val[0]));
+ reg_16x8_src_cb_r2 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r1.val[0]));
+ reg_16x8_src_cb_r3 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r1.val[0]));
+ reg_16x8_src_cb_r4 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r2.val[0]));
+ reg_16x8_src_cb_r5 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r2.val[0]));
+ reg_16x8_src_cb_r6 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r3.val[0]));
+ reg_16x8_src_cb_r7 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r3.val[0]));
+
+ reg_16x8_src_cr_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[1]));
+ reg_16x8_src_cr_r1 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r0.val[1]));
+ reg_16x8_src_cr_r2 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r1.val[1]));
+ reg_16x8_src_cr_r3 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r1.val[1]));
+ reg_16x8_src_cr_r4 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r2.val[1]));
+ reg_16x8_src_cr_r5 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r2.val[1]));
+ reg_16x8_src_cr_r6 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r3.val[1]));
+ reg_16x8_src_cr_r7 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r3.val[1]));
+
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ reg_16x8_mul_cb_r0 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r0), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r1 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r1), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r2 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r2), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r3 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r3), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r4 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r4), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r5 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r5), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r6 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r6), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r7 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r7), reg_16x8_filt_coeff_grid);
+
+ reg_16x8_mul_cr_r0 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r0), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r1 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r1), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r2 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r2), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r3 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r3), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r4 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r4), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r5 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r5), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r6 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r6), reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r7 =
+ vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r7), reg_16x8_filt_coeff_grid);
+
+ reg_32x4_sum_cb_r0 = vpaddlq_s16(reg_16x8_mul_cb_r0);
+ reg_32x4_sum_cb_r1 = vpaddlq_s16(reg_16x8_mul_cb_r1);
+ reg_32x4_sum_cb_r2 = vpaddlq_s16(reg_16x8_mul_cb_r2);
+ reg_32x4_sum_cb_r3 = vpaddlq_s16(reg_16x8_mul_cb_r3);
+ reg_32x4_sum_cb_r4 = vpaddlq_s16(reg_16x8_mul_cb_r4);
+ reg_32x4_sum_cb_r5 = vpaddlq_s16(reg_16x8_mul_cb_r5);
+ reg_32x4_sum_cb_r6 = vpaddlq_s16(reg_16x8_mul_cb_r6);
+ reg_32x4_sum_cb_r7 = vpaddlq_s16(reg_16x8_mul_cb_r7);
+
+ reg_32x4_sum_cr_r0 = vpaddlq_s16(reg_16x8_mul_cr_r0);
+ reg_32x4_sum_cr_r1 = vpaddlq_s16(reg_16x8_mul_cr_r1);
+ reg_32x4_sum_cr_r2 = vpaddlq_s16(reg_16x8_mul_cr_r2);
+ reg_32x4_sum_cr_r3 = vpaddlq_s16(reg_16x8_mul_cr_r3);
+ reg_32x4_sum_cr_r4 = vpaddlq_s16(reg_16x8_mul_cr_r4);
+ reg_32x4_sum_cr_r5 = vpaddlq_s16(reg_16x8_mul_cr_r5);
+ reg_32x4_sum_cr_r6 = vpaddlq_s16(reg_16x8_mul_cr_r6);
+ reg_32x4_sum_cr_r7 = vpaddlq_s16(reg_16x8_mul_cr_r7);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_r0, reg_32x4_sum_cb_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_cb_r2, reg_32x4_sum_cb_r3);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_cb_r4, reg_32x4_sum_cb_r5);
+ reg_32x4x2_sum_r67 = vuzpq_s32(reg_32x4_sum_cb_r6, reg_32x4_sum_cb_r7);
+
+ reg_32x4_sum_cb_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cb_r23 =
+ vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4_sum_cb_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+ reg_32x4_sum_cb_r67 =
+ vaddq_s32(reg_32x4x2_sum_r67.val[0], reg_32x4x2_sum_r67.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_r01, reg_32x4_sum_cb_r23);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_cb_r45, reg_32x4_sum_cb_r67);
+ reg_32x4_sum_cb_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cb_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cr_r0, reg_32x4_sum_cr_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_cr_r2, reg_32x4_sum_cr_r3);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_cr_r4, reg_32x4_sum_cr_r5);
+ reg_32x4x2_sum_r67 = vuzpq_s32(reg_32x4_sum_cr_r6, reg_32x4_sum_cr_r7);
+
+ reg_32x4_sum_cr_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cr_r23 =
+ vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4_sum_cr_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+ reg_32x4_sum_cr_r67 =
+ vaddq_s32(reg_32x4x2_sum_r67.val[0], reg_32x4x2_sum_r67.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cr_r01, reg_32x4_sum_cr_r23);
+ reg_32x4x2_sum_r45 = vuzpq_s32(reg_32x4_sum_cr_r45, reg_32x4_sum_cr_r67);
+ reg_32x4_sum_cr_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cr_r45 =
+ vaddq_s32(reg_32x4x2_sum_r45.val[0], reg_32x4x2_sum_r45.val[1]);
+
+ reg_16x4_sum_cb_r01_23 = vqrshrun_n_s32(reg_32x4_sum_cb_r01, 7);
+ reg_16x4_sum_cb_r45_67 = vqrshrun_n_s32(reg_32x4_sum_cb_r45, 7);
+
+ reg_16x4_sum_cr_r01_23 = vqrshrun_n_s32(reg_32x4_sum_cr_r01, 7);
+ reg_16x4_sum_cr_r45_67 = vqrshrun_n_s32(reg_32x4_sum_cr_r45, 7);
+
+ reg_16x8_sum_cb_r0_r7 =
+ vcombine_u16(reg_16x4_sum_cb_r01_23, reg_16x4_sum_cb_r45_67);
+ reg_16x8_sum_cr_r0_r7 =
+ vcombine_u16(reg_16x4_sum_cr_r01_23, reg_16x4_sum_cr_r45_67);
+
+ reg_8x8_sum_cb_r0_r7 = vqmovn_u16(reg_16x8_sum_cb_r0_r7);
+ reg_8x8_sum_cr_r0_r7 = vqmovn_u16(reg_16x8_sum_cr_r0_r7);
+
+ vst1_u8(pu1_out_pixel, reg_8x8_sum_cb_r0_r7);
+ vst1_u8(pu1_out_pixel + u4_out_stride, reg_8x8_sum_cr_r0_r7);
+
+ pu1_out_pixel += 8;
+
+ pu1_in_pixel += (u4_src_vert_increments * (u4_in_stride << 3)) >> DOWNSCALER_Q;
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /* Loop for the remaining height less than 8 */
+ if(u4_rem_vert_loop)
+ {
+ u4_rem_vert_loop_by_4 = u4_rem_vert_loop >> 2;
+ u4_rem_vert_loop = u4_rem_vert_loop % 4;
+ u4_height_finished = (u4_num_iterations_vertical_by_8 << 3);
+ pu1_src_j = pu1_src + ((u4_height_finished) *u4_in_stride);
+ pu1_dst_j = pu1_dst + u4_height_finished;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ /* 4<= remaining height < 8 */
+ if(u4_rem_vert_loop_by_4)
+ {
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ for(j = u4_rem_vert_loop_by_4; j > 0; j--)
+ {
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ reg_8x16_src_r0 = vld1q_u8(pu1_in_pixel);
+ reg_8x16_src_r1 = vld1q_u8(pu1_in_pixel + u4_in_stride);
+ reg_8x16_src_r2 = vld1q_u8(pu1_in_pixel + 2 * u4_in_stride);
+ reg_8x16_src_r3 = vld1q_u8(pu1_in_pixel + 3 * u4_in_stride);
+
+ reg_8x16x2_src_r0 = vuzpq_u8(reg_8x16_src_r0, reg_8x16_src_r1);
+ reg_8x16x2_src_r1 = vuzpq_u8(reg_8x16_src_r2, reg_8x16_src_r3);
+
+ reg_16x8_src_cb_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[0]));
+ reg_16x8_src_cb_r1 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r0.val[0]));
+ reg_16x8_src_cb_r2 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r1.val[0]));
+ reg_16x8_src_cb_r3 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r1.val[0]));
+
+ reg_16x8_src_cr_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[1]));
+ reg_16x8_src_cr_r1 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r0.val[1]));
+ reg_16x8_src_cr_r2 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r1.val[1]));
+ reg_16x8_src_cr_r3 = vmovl_u8(vget_high_u8(reg_8x16x2_src_r1.val[1]));
+
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ reg_16x8_mul_cb_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r0),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r1 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r1),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r2 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r2),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cb_r3 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r3),
+ reg_16x8_filt_coeff_grid);
+
+ reg_16x8_mul_cr_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r0),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r1 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r1),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r2 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r2),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r3 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r3),
+ reg_16x8_filt_coeff_grid);
+
+ reg_32x4_sum_cb_r0 = vpaddlq_s16(reg_16x8_mul_cb_r0);
+ reg_32x4_sum_cb_r1 = vpaddlq_s16(reg_16x8_mul_cb_r1);
+ reg_32x4_sum_cb_r2 = vpaddlq_s16(reg_16x8_mul_cb_r2);
+ reg_32x4_sum_cb_r3 = vpaddlq_s16(reg_16x8_mul_cb_r3);
+
+ reg_32x4_sum_cr_r0 = vpaddlq_s16(reg_16x8_mul_cr_r0);
+ reg_32x4_sum_cr_r1 = vpaddlq_s16(reg_16x8_mul_cr_r1);
+ reg_32x4_sum_cr_r2 = vpaddlq_s16(reg_16x8_mul_cr_r2);
+ reg_32x4_sum_cr_r3 = vpaddlq_s16(reg_16x8_mul_cr_r3);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_r0, reg_32x4_sum_cb_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_cb_r2, reg_32x4_sum_cb_r3);
+ reg_32x4_sum_cb_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cb_r23 =
+ vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_r01, reg_32x4_sum_cb_r23);
+ reg_32x4_sum_cb_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cr_r0, reg_32x4_sum_cr_r1);
+ reg_32x4x2_sum_r23 = vuzpq_s32(reg_32x4_sum_cr_r2, reg_32x4_sum_cr_r3);
+ reg_32x4_sum_cr_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+ reg_32x4_sum_cr_r23 =
+ vaddq_s32(reg_32x4x2_sum_r23.val[0], reg_32x4x2_sum_r23.val[1]);
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cr_r01, reg_32x4_sum_cr_r23);
+ reg_32x4_sum_cr_r01 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+
+ reg_16x4_sum_cb_r01_23 = vqrshrun_n_s32(reg_32x4_sum_cb_r01, 7);
+ reg_16x4_sum_cr_r01_23 = vqrshrun_n_s32(reg_32x4_sum_cr_r01, 7);
+
+ reg_16x8_sum_cb_cr_r0_r3 =
+ vcombine_u16(reg_16x4_sum_cb_r01_23, reg_16x4_sum_cr_r01_23);
+ reg_8x8_sum_cb_cr_r0_r3 = vmovn_u16(reg_16x8_sum_cb_cr_r0_r3);
+ vst1_lane_u32((uint32_t *) (pu1_out_pixel),
+ vreinterpret_u32_u8(reg_8x8_sum_cb_cr_r0_r3), 0);
+ vst1_lane_u32((uint32_t *) (pu1_out_pixel + u4_out_stride),
+ vreinterpret_u32_u8(reg_8x8_sum_cb_cr_r0_r3), 1);
+
+ pu1_out_pixel += 4;
+
+ pu1_in_pixel +=
+ (u4_src_vert_increments * (u4_in_stride << 2)) >> DOWNSCALER_Q;
+ }
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /* 1<= remaining height < 4 */
+ if(u4_rem_vert_loop)
+ {
+ u4_height_finished =
+ ((u4_num_iterations_vertical_by_8 << 3) + (u4_rem_vert_loop_by_4 << 2));
+ pu1_src_j = pu1_src + u4_height_finished * u4_in_stride;
+ pu1_dst_j = pu1_dst + u4_height_finished;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ reg_8x8_filt_coeff_grid = vld1_s8(pi1_filter_grid);
+
+ for(j = u4_rem_vert_loop; j > 0; j--)
+ {
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ reg_8x16_src_r0 = vld1q_u8(pu1_in_pixel);
+
+ reg_8x16x2_src_r0 = vuzpq_u8(reg_8x16_src_r0, reg_8x16_src_r0);
+ reg_16x8_src_cb_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[0]));
+ reg_16x8_src_cr_r0 = vmovl_u8(vget_low_u8(reg_8x16x2_src_r0.val[1]));
+
+ reg_16x8_filt_coeff_grid = vmovl_s8(reg_8x8_filt_coeff_grid);
+
+ reg_16x8_mul_cb_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cb_r0),
+ reg_16x8_filt_coeff_grid);
+ reg_16x8_mul_cr_r0 = vmulq_s16(vreinterpretq_s16_u16(reg_16x8_src_cr_r0),
+ reg_16x8_filt_coeff_grid);
+
+ reg_32x4_sum_cb_r0 = vpaddlq_s16(reg_16x8_mul_cb_r0);
+ reg_32x4_sum_cr_r0 = vpaddlq_s16(reg_16x8_mul_cr_r0);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_r0, reg_32x4_sum_cr_r0);
+ reg_32x4_sum_cb_cr_r0 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+
+ reg_32x4x2_sum_r01 = vuzpq_s32(reg_32x4_sum_cb_cr_r0, reg_32x4_zero);
+ reg_32x4_sum_cb_cr_r0 =
+ vaddq_s32(reg_32x4x2_sum_r01.val[0], reg_32x4x2_sum_r01.val[1]);
+
+ reg_16x4_sum_cb_cr_r0 = vqrshrun_n_s32(reg_32x4_sum_cb_cr_r0, 7);
+ vst1_lane_u8((pu1_out_pixel), vreinterpret_u8_u16(reg_16x4_sum_cb_cr_r0),
+ 0);
+ vst1_lane_u8((pu1_out_pixel + u4_out_stride),
+ vreinterpret_u8_u16(reg_16x4_sum_cb_cr_r0), 2);
+
+ pu1_out_pixel += 1;
+
+ pu1_in_pixel += (u4_src_vert_increments * (u4_in_stride)) >> DOWNSCALER_Q;
+ }
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+ }
+}
diff --git a/encoder/arm/svc/isvce_function_selector.c b/encoder/arm/svc/isvce_function_selector.c
new file mode 100644
index 0000000..f1dc6f3
--- /dev/null
+++ b/encoder/arm/svc/isvce_function_selector.c
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in h264
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include Files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include Files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_platform_macros.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(void *pv_codec)
+{
+ isvce_codec_t *ps_codec = (isvce_codec_t *) pv_codec;
+ isvce_init_function_ptr_generic(ps_codec);
+ switch(ps_codec->s_cfg.e_arch)
+ {
+#if defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ default:
+ isvce_init_function_ptr_neon_av8(ps_codec);
+ break;
+#elif !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ default:
+ isvce_init_function_ptr_neon_a9q(ps_codec);
+ break;
+#else
+ default:
+#endif
+ case ARCH_X86_GENERIC:
+ break;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void)
+{
+#if defined(ARMV8)
+ return ARCH_ARM_V8_NEON;
+#elif !defined(DISABLE_NEON)
+ return ARCH_ARM_A9Q;
+#else
+ return ARCH_GENERIC;
+#endif
+}
diff --git a/encoder/arm/svc/isvce_function_selector_a9q.c b/encoder/arm/svc/isvce_function_selector_a9q.c
new file mode 100644
index 0000000..b5f8ba4
--- /dev/null
+++ b/encoder/arm/svc/isvce_function_selector_a9q.c
@@ -0,0 +1,270 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector_a9q.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_init_function_ptr_generic
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_mem_fns.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_cabac.h"
+#include "isvce_core_coding.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_intra_modes_eval.h"
+#include "ih264e_fmt_conv.h"
+#include "ih264e_half_pel.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_neon_a9q(isvce_codec_t *ps_codec)
+{
+ WORD32 i = 0;
+
+ /* curr proc ctxt */
+ isvce_process_ctxt_t *ps_proc = NULL;
+ isvce_me_ctxt_t *ps_me_ctxt = NULL;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 16x16 */
+ ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_a9q;
+ ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_a9q;
+ ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_a9q;
+ ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_a9q;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 4x4 */
+ ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_a9q;
+ ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_a9q;
+ ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_a9q;
+ ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_a9q;
+ ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_a9q;
+ ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_a9q;
+ ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_a9q;
+ ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_a9q;
+ ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_a9q;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_a9q;
+ ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_a9q;
+ ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_a9q;
+ ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_a9q;
+ ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_a9q;
+ ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_a9q;
+ ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_a9q;
+ ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_a9q;
+
+ /* Init function pointers for intra pred leaf level functions chroma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_c[0] = ih264_intra_pred_chroma_8x8_mode_dc_a9q;
+ ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_a9q;
+ ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_a9q;
+ ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_a9q;
+
+ /* Init forward transform fn ptr */
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[0] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[1] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[0] = isvc_resi_trans_quant_4x4_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[1] =
+ isvc_resi_trans_quant_4x4_with_residual_sub_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[0] = isvc_resi_trans_quant_chroma_4x4_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[1] =
+ isvc_resi_trans_quant_chroma_4x4_with_residual_sub_neon;
+
+ /* Init inverse transform fn ptr */
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[0] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[1] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[2] = isvc_iquant_itrans_recon_8x8;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[0] =
+ isvc_iquant_itrans_recon_4x4_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[1] =
+ isvc_iquant_itrans_recon_4x4_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[2] = isvc_iquant_itrans_recon_4x4_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[0] =
+ isvc_iquant_itrans_recon_4x4_dc_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[1] =
+ isvc_iquant_itrans_recon_4x4_dc_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[2] = isvc_iquant_itrans_recon_4x4_dc_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[0] =
+ isvc_iquant_itrans_recon_chroma_4x4_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[1] =
+ isvc_iquant_itrans_recon_chroma_4x4_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[0] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[1] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_neon;
+
+ ps_enc_loop_fxns->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_a9;
+ ps_enc_loop_fxns->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_a9;
+
+ /* Init fn ptr luma core coding */
+ ps_enc_loop_fxns->apf_luma_energy_compaction[0] = isvce_code_luma_intra_macroblock_16x16;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[1] = isvce_code_luma_intra_macroblock_4x4;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[3] = isvce_code_luma_inter_macroblock_16x16;
+
+ /* Init fn ptr chroma core coding */
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[0] = isvce_code_chroma_intra_macroblock_8x8;
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[1] = isvce_code_chroma_inter_macroblock_8x8;
+
+ /* Init fn ptr luma deblocking */
+ ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_a9;
+ ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_a9;
+ ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_a9;
+ ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_a9;
+
+ /* Init fn ptr chroma deblocking */
+ ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_a9;
+ ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_a9;
+ ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_a9;
+ ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_a9;
+
+ /* write mb syntax layer */
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][ISLICE] = isvce_write_islice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][PSLICE] = isvce_write_pslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][BSLICE] = isvce_write_bslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][ISLICE] = isvce_write_islice_mb_cabac;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][PSLICE] = isvce_write_pslice_mb_cabac;
+
+ /* Padding Functions */
+ ps_codec->pf_pad_top = ih264_pad_top_a9q;
+ ps_codec->pf_pad_bottom = ih264_pad_bottom;
+ ps_codec->pf_pad_left_luma = ih264_pad_left_luma_a9q;
+ ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_a9q;
+ ps_codec->pf_pad_right_luma = ih264_pad_right_luma_a9q;
+ ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_a9q;
+
+ /* Inter pred leaf level functions */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_a9q;
+ ps_inter_pred_fxns->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz_a9q;
+ ps_inter_pred_fxns->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert_a9q;
+ ps_inter_pred_fxns->pf_inter_pred_luma_bilinear = ih264_inter_pred_luma_bilinear_a9q;
+ ps_inter_pred_fxns->pf_inter_pred_chroma = ih264_inter_pred_chroma_a9q;
+
+ /* sad me level functions */
+ ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_a9q;
+ ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_a9q;
+ ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8_a9q;
+
+ /* memor handling operations */
+ ps_mem_fxns->pf_mem_cpy = ih264_memcpy_a9q;
+ ps_mem_fxns->pf_mem_cpy_mul8 = ih264_memcpy_mul_8_a9q;
+ ps_mem_fxns->pf_mem_set = ih264_memset_a9q;
+ ps_mem_fxns->pf_mem_set_mul8 = ih264_memset_mul_8_a9q;
+
+ /* sad me level functions */
+ for(i = 0; i < (MAX_PROCESS_CTXT); i++)
+ {
+ ps_proc = &ps_codec->as_process[i];
+ ps_me_ctxt = &ps_proc->s_me_ctxt;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_a9q;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_a9q;
+ ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_a9q;
+ ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_a9q;
+ ps_me_ctxt->pf_ime_compute_sad3_diamond = ime_calculate_sad3_prog_a9q;
+ ps_me_ctxt->pf_ime_compute_sad2_diamond = ime_calculate_sad2_prog_a9q;
+ ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_a9q;
+ ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_a9q;
+ }
+
+ /* intra mode eval -encoder level function */
+ ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes_a9q;
+ ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes_a9q;
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes_a9q;
+}
diff --git a/encoder/arm/svc/isvce_function_selector_av8.c b/encoder/arm/svc/isvce_function_selector_av8.c
new file mode 100644
index 0000000..16c08bb
--- /dev/null
+++ b/encoder/arm/svc/isvce_function_selector_av8.c
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector_av8.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_init_function_ptr_generic
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_mem_fns.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_cabac.h"
+#include "isvce_core_coding.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_intra_modes_eval.h"
+#include "ih264e_fmt_conv.h"
+#include "ih264e_half_pel.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_neon_av8(isvce_codec_t *ps_codec)
+{
+ WORD32 i = 0;
+
+ /* curr proc ctxt */
+ isvce_process_ctxt_t *ps_proc = NULL;
+ isvce_me_ctxt_t *ps_me_ctxt = NULL;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 16x16 */
+ ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_av8;
+ ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_av8;
+ ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_av8;
+ ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_av8;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 4x4 */
+ ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_av8;
+ ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_av8;
+ ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_av8;
+ ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_av8;
+ ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_av8;
+ ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_av8;
+ ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_av8;
+ ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_av8;
+ ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_av8;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_av8;
+ ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_av8;
+ ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_av8;
+ ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_av8;
+ ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_av8;
+ ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_av8;
+ ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_av8;
+ ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_av8;
+
+ /* Init function pointers for intra pred leaf level functions chroma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_c[0] = ih264_intra_pred_chroma_8x8_mode_dc_av8;
+ ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_av8;
+ ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_av8;
+ ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_av8;
+
+ /* Init forward transform fn ptr */
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[0] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[1] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[0] = isvc_resi_trans_quant_4x4_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[1] =
+ isvc_resi_trans_quant_4x4_with_residual_sub_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[0] = isvc_resi_trans_quant_chroma_4x4_neon;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[1] =
+ isvc_resi_trans_quant_chroma_4x4_with_residual_sub_neon;
+
+ /* Init inverse transform fn ptr */
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[0] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[1] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[2] = isvc_iquant_itrans_recon_8x8;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[0] =
+ isvc_iquant_itrans_recon_4x4_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[1] =
+ isvc_iquant_itrans_recon_4x4_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[2] = isvc_iquant_itrans_recon_4x4_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[0] =
+ isvc_iquant_itrans_recon_4x4_dc_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[1] =
+ isvc_iquant_itrans_recon_4x4_dc_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[2] = isvc_iquant_itrans_recon_4x4_dc_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[0] =
+ isvc_iquant_itrans_recon_chroma_4x4_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[1] =
+ isvc_iquant_itrans_recon_chroma_4x4_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_neon;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[0] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_output_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[1] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_with_res_accumulate_neon;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_neon;
+
+ ps_enc_loop_fxns->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_av8;
+ ps_enc_loop_fxns->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv_av8;
+
+ /* Init fn ptr luma core coding */
+ ps_enc_loop_fxns->apf_luma_energy_compaction[0] = isvce_code_luma_intra_macroblock_16x16;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[1] = isvce_code_luma_intra_macroblock_4x4;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[3] = isvce_code_luma_inter_macroblock_16x16;
+
+ /* Init fn ptr chroma core coding */
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[0] = isvce_code_chroma_intra_macroblock_8x8;
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[1] = isvce_code_chroma_inter_macroblock_8x8;
+
+ /* Init fn ptr luma deblocking */
+ ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_av8;
+ ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_av8;
+ ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_av8;
+ ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_av8;
+
+ /* Init fn ptr chroma deblocking */
+ ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_av8;
+ ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_av8;
+ ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_av8;
+ ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_av8;
+
+ /* write mb syntax layer */
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][ISLICE] = isvce_write_islice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][PSLICE] = isvce_write_pslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][BSLICE] = isvce_write_bslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][ISLICE] = isvce_write_islice_mb_cabac;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][PSLICE] = isvce_write_pslice_mb_cabac;
+
+ /* Padding Functions */
+ ps_codec->pf_pad_top = ih264_pad_top_av8;
+ ps_codec->pf_pad_bottom = ih264_pad_bottom;
+ ps_codec->pf_pad_left_luma = ih264_pad_left_luma_av8;
+ ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_av8;
+ ps_codec->pf_pad_right_luma = ih264_pad_right_luma_av8;
+ ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_av8;
+
+ /* Inter pred leaf level functions */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_av8;
+ ps_inter_pred_fxns->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz_av8;
+ ps_inter_pred_fxns->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert_av8;
+ ps_inter_pred_fxns->pf_inter_pred_luma_bilinear = ih264_inter_pred_luma_bilinear;
+ ps_inter_pred_fxns->pf_inter_pred_chroma = ih264_inter_pred_chroma_av8;
+
+ /* sad me level functions */
+ ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_av8;
+ ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8;
+ ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8_av8;
+
+ /* memor handling operations */
+ ps_mem_fxns->pf_mem_cpy = ih264_memcpy_av8;
+ ps_mem_fxns->pf_mem_cpy_mul8 = ih264_memcpy_mul_8_av8;
+ ps_mem_fxns->pf_mem_set = ih264_memset_av8;
+ ps_mem_fxns->pf_mem_set_mul8 = ih264_memset_mul_8_av8;
+
+ /* sad me level functions */
+ for(i = 0; i < (MAX_PROCESS_CTXT); i++)
+ {
+ ps_proc = &ps_codec->as_process[i];
+ ps_me_ctxt = &ps_proc->s_me_ctxt;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_av8;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_av8;
+ ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_av8;
+ ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_av8;
+ ps_me_ctxt->pf_ime_compute_sad3_diamond = ime_calculate_sad3_prog_av8;
+ ps_me_ctxt->pf_ime_compute_sad2_diamond = ime_calculate_sad2_prog_av8;
+ ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_av8;
+ ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_av8;
+ }
+
+ /* intra mode eval -encoder level function */
+ ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes_av8;
+ ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes_av8;
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes;
+
+ /* csc */
+ ps_codec->pf_ih264e_conv_420p_to_420sp = ih264e_fmt_conv_420p_to_420sp;
+ ps_codec->pf_ih264e_fmt_conv_422i_to_420sp = ih264e_fmt_conv_422i_to_420sp;
+
+ /* Halp pel generation function - encoder level*/
+ ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz_av8;
+ ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert_av8;
+}
diff --git a/encoder/arm/svc/isvce_platform_macros.h b/encoder/arm/svc/isvce_platform_macros.h
new file mode 100644
index 0000000..df18315
--- /dev/null
+++ b/encoder/arm/svc/isvce_platform_macros.h
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* ih264e_platform_macros.h
+*
+* @brief
+* Contains platform specific routines used for codec context intialization
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_PLATFORM_MACROS_H_
+#define _ISVCE_PLATFORM_MACROS_H_
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_neon_a9q(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_neon_av8(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_generic(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(void *pv_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void);
+
+#endif
diff --git a/encoder/arm/svc/isvce_rc_utils_neon.c b/encoder/arm/svc/isvce_rc_utils_neon.c
new file mode 100644
index 0000000..6ae04bd
--- /dev/null
+++ b/encoder/arm/svc/isvce_rc_utils_neon.c
@@ -0,0 +1,625 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file isvce_svc_rc_utils_neon.c
+*
+* @brief
+* This file contains the neom SIMD version of the function which computes
+* gradient per pixel value being used in Init Qp
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_get_gpp_neon()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include <arm_neon.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "isvc_structs.h"
+#include "isvce_rc_utils_private_defs.h"
+
+/**
+*******************************************************************************
+*
+* @brief
+* get gpp function
+*
+* @par Description:
+* computes gradient per pixel value for a given frame
+*
+* @param[in] ps_input_buf
+* pointer to yuv buffer properties
+*
+* @returns
+* calculated gpp value
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+DOUBLE isvce_get_gpp_neon(yuv_buf_props_t *ps_input_buf)
+{
+ UWORD8 *pu1_input_buf;
+ UWORD32 i, j, k;
+ UWORD32 u4_width, u4_height, i4_input_stride;
+ DOUBLE d_gpp_y, d_gpp_u, d_gpp_v, d_gpp;
+
+ uint8x8_t reg_8x8_src_r0, reg_8x8_src_r1, reg_8x8_src_r2, reg_8x8_src_r3, reg_8x8_src_r4,
+ reg_8x8_src_r5, reg_8x8_src_r6, reg_8x8_src_r7, reg_8x8_src_r8;
+ uint8x8_t reg_8x8_src_right_r0, reg_8x8_src_right_r1, reg_8x8_src_right_r2,
+ reg_8x8_src_right_r3, reg_8x8_src_right_r4, reg_8x8_src_right_r5, reg_8x8_src_right_r6,
+ reg_8x8_src_right_r7;
+ uint16x8_t reg_16x8_abs_diff_y, reg_16x8_abs_diff_uv;
+ uint64x2_t reg_64x2_gpp_y, reg_64x2_gpp_uv;
+
+ uint8x8_t reg_8x8_shuffle = {0, 2, 4, 6, 1, 3, 5, 7};
+ uint16x8_t reg_16x8_and_mask_y = {0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0x0000};
+ uint16x8_t reg_16x8_and_mask_uv = {0xffff, 0xffff, 0xffff, 0x0000,
+ 0xffff, 0xffff, 0xffff, 0x0000};
+ uint32x4_t reg_32x4_abs_diff_hadd_y = vdupq_n_u32(0);
+ uint32x4_t reg_32x4_abs_diff_hadd_uv = vdupq_n_u32(0);
+
+ d_gpp_y = 0;
+ d_gpp_u = 0;
+ d_gpp_v = 0;
+ d_gpp = 0;
+ pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[0].pv_data;
+ i4_input_stride = ps_input_buf->as_component_bufs[0].i4_data_stride;
+ u4_width = ps_input_buf->u4_width;
+ u4_height = ps_input_buf->u4_height;
+
+ ASSERT((u4_width % 8) == 0);
+
+ /***********************************************************/
+ /* For Luma - */
+ /* This code block calculates gpp value for luma by adding */
+ /* the absolute difference between the current pixel and */
+ /* it's immediate right pixel with the absolute difference */
+ /* between the current pixel and it's immediate bottom */
+ /* pixel and accumulating for every pixel in the frame. */
+ /***********************************************************/
+ /* -8 in the checks below since right column and bottow row being used for gradients, */
+ /* and last row and column are ignored for gradient computation. */
+ /* Note that input is not required to be padded */
+ for(i = 0; i < u4_height - 8; i += 8)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j);
+ reg_8x8_src_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j);
+ reg_8x8_src_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j);
+ reg_8x8_src_r8 = vld1_u8(pu1_input_buf + (i4_input_stride * 8) + j);
+
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 1);
+ reg_8x8_src_right_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j + 1);
+ reg_8x8_src_right_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j + 1);
+ reg_8x8_src_right_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j + 1);
+ reg_8x8_src_right_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j + 1);
+ reg_8x8_src_right_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j + 1);
+ reg_8x8_src_right_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j + 1);
+ reg_8x8_src_right_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j + 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r4, reg_8x8_src_r5);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r5, reg_8x8_src_r6);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r6, reg_8x8_src_r7);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r7, reg_8x8_src_r8);
+
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_right_r3);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r4, reg_8x8_src_right_r4);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r5, reg_8x8_src_right_r5);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r6, reg_8x8_src_right_r6);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r7, reg_8x8_src_right_r7);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 7 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_y */
+ /************************************************************/
+ ASSERT((u4_width - j) == 8);
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j);
+ reg_8x8_src_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j);
+ reg_8x8_src_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j);
+ reg_8x8_src_r8 = vld1_u8(pu1_input_buf + (i4_input_stride * 8) + j);
+
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 1);
+ reg_8x8_src_right_r1 = vext_u8(reg_8x8_src_r1, reg_8x8_src_r1, 1);
+ reg_8x8_src_right_r2 = vext_u8(reg_8x8_src_r2, reg_8x8_src_r2, 1);
+ reg_8x8_src_right_r3 = vext_u8(reg_8x8_src_r3, reg_8x8_src_r3, 1);
+ reg_8x8_src_right_r4 = vext_u8(reg_8x8_src_r4, reg_8x8_src_r4, 1);
+ reg_8x8_src_right_r5 = vext_u8(reg_8x8_src_r5, reg_8x8_src_r5, 1);
+ reg_8x8_src_right_r6 = vext_u8(reg_8x8_src_r6, reg_8x8_src_r6, 1);
+ reg_8x8_src_right_r7 = vext_u8(reg_8x8_src_r7, reg_8x8_src_r7, 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r4, reg_8x8_src_r5);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r5, reg_8x8_src_r6);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r6, reg_8x8_src_r7);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r7, reg_8x8_src_r8);
+
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_right_r3);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r4, reg_8x8_src_right_r4);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r5, reg_8x8_src_right_r5);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r6, reg_8x8_src_right_r6);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r7, reg_8x8_src_right_r7);
+
+ reg_16x8_abs_diff_y = vandq_u16(reg_16x8_abs_diff_y, reg_16x8_and_mask_y);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+
+ pu1_input_buf += (i4_input_stride * 8);
+ }
+
+ /* Loop for remaining height less than 8 */
+ /* 4 <= remaining_height < 8 */
+ for(k = i; k < u4_height - 4; k += 4, i += 4)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 1);
+ reg_8x8_src_right_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j + 1);
+ reg_8x8_src_right_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j + 1);
+ reg_8x8_src_right_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j + 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_r4);
+
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_right_r3);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 7 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_y */
+ /************************************************************/
+ ASSERT((u4_width - j) == 8);
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 1);
+ reg_8x8_src_right_r1 = vext_u8(reg_8x8_src_r1, reg_8x8_src_r1, 1);
+ reg_8x8_src_right_r2 = vext_u8(reg_8x8_src_r2, reg_8x8_src_r2, 1);
+ reg_8x8_src_right_r3 = vext_u8(reg_8x8_src_r3, reg_8x8_src_r3, 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_r4);
+
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r3, reg_8x8_src_right_r3);
+
+ reg_16x8_abs_diff_y = vandq_u16(reg_16x8_abs_diff_y, reg_16x8_and_mask_y);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+
+ pu1_input_buf += (i4_input_stride * 4);
+ }
+
+ /* Loop for remaining height less than 4 */
+ /* 0 <= remaining_height < 4 */
+ for(k = i; k < u4_height - 1; k++)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y =
+ vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 7 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_y */
+ /************************************************************/
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 1);
+
+ reg_16x8_abs_diff_y = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_y = vabal_u8(reg_16x8_abs_diff_y, reg_8x8_src_r0, reg_8x8_src_right_r0);
+
+ reg_16x8_abs_diff_y = vandq_u16(reg_16x8_abs_diff_y, reg_16x8_and_mask_y);
+
+ reg_32x4_abs_diff_hadd_y = vpadalq_u16(reg_32x4_abs_diff_hadd_y, reg_16x8_abs_diff_y);
+
+ pu1_input_buf += i4_input_stride;
+ }
+
+ /* Pairwise add reg_32x4_abs_diff_hadd_y to get final gpp value */
+ reg_64x2_gpp_y = vpaddlq_u32(reg_32x4_abs_diff_hadd_y);
+ d_gpp_y = vgetq_lane_u64(reg_64x2_gpp_y, 0);
+ d_gpp_y += vgetq_lane_u64(reg_64x2_gpp_y, 1);
+
+ pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[1].pv_data;
+ i4_input_stride = ps_input_buf->as_component_bufs[1].i4_data_stride;
+
+ /***************************************************************/
+ /* For Chroma - */
+ /* This code block first deinterleaves the Cb and Cr values, */
+ /* calculates gpp value for both Cb and Cr separately by */
+ /* adding the absolute difference between the current pixel */
+ /* and it's immediate right pixel with the absolute */
+ /* difference between the current pixel and it's immediate */
+ /* bottom pixel and accumulating for every pixel in the frame. */
+ /***************************************************************/
+ for(i = 0; i < (u4_height >> 1) - 8; i += 8)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j);
+ reg_8x8_src_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j);
+ reg_8x8_src_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j);
+ reg_8x8_src_r8 = vld1_u8(pu1_input_buf + (i4_input_stride * 8) + j);
+
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 2);
+ reg_8x8_src_right_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j + 2);
+ reg_8x8_src_right_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j + 2);
+ reg_8x8_src_right_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j + 2);
+ reg_8x8_src_right_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j + 2);
+ reg_8x8_src_right_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j + 2);
+ reg_8x8_src_right_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j + 2);
+ reg_8x8_src_right_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j + 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_r2 = vtbl1_u8(reg_8x8_src_r2, reg_8x8_shuffle);
+ reg_8x8_src_r3 = vtbl1_u8(reg_8x8_src_r3, reg_8x8_shuffle);
+ reg_8x8_src_r4 = vtbl1_u8(reg_8x8_src_r4, reg_8x8_shuffle);
+ reg_8x8_src_r5 = vtbl1_u8(reg_8x8_src_r5, reg_8x8_shuffle);
+ reg_8x8_src_r6 = vtbl1_u8(reg_8x8_src_r6, reg_8x8_shuffle);
+ reg_8x8_src_r7 = vtbl1_u8(reg_8x8_src_r7, reg_8x8_shuffle);
+ reg_8x8_src_r8 = vtbl1_u8(reg_8x8_src_r8, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+ reg_8x8_src_right_r1 = vtbl1_u8(reg_8x8_src_right_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r2 = vtbl1_u8(reg_8x8_src_right_r2, reg_8x8_shuffle);
+ reg_8x8_src_right_r3 = vtbl1_u8(reg_8x8_src_right_r3, reg_8x8_shuffle);
+ reg_8x8_src_right_r4 = vtbl1_u8(reg_8x8_src_right_r4, reg_8x8_shuffle);
+ reg_8x8_src_right_r5 = vtbl1_u8(reg_8x8_src_right_r5, reg_8x8_shuffle);
+ reg_8x8_src_right_r6 = vtbl1_u8(reg_8x8_src_right_r6, reg_8x8_shuffle);
+ reg_8x8_src_right_r7 = vtbl1_u8(reg_8x8_src_right_r7, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r4, reg_8x8_src_r5);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r5, reg_8x8_src_r6);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r6, reg_8x8_src_r7);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r7, reg_8x8_src_r8);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_right_r3);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r4, reg_8x8_src_right_r4);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r5, reg_8x8_src_right_r5);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r6, reg_8x8_src_right_r6);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r7, reg_8x8_src_right_r7);
+
+ reg_32x4_abs_diff_hadd_uv =
+ vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 6 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_uv */
+ /************************************************************/
+ ASSERT((u4_width - j) == 8);
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_r5 = vld1_u8(pu1_input_buf + (i4_input_stride * 5) + j);
+ reg_8x8_src_r6 = vld1_u8(pu1_input_buf + (i4_input_stride * 6) + j);
+ reg_8x8_src_r7 = vld1_u8(pu1_input_buf + (i4_input_stride * 7) + j);
+ reg_8x8_src_r8 = vld1_u8(pu1_input_buf + (i4_input_stride * 8) + j);
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 2);
+ reg_8x8_src_right_r1 = vext_u8(reg_8x8_src_r1, reg_8x8_src_r1, 2);
+ reg_8x8_src_right_r2 = vext_u8(reg_8x8_src_r2, reg_8x8_src_r2, 2);
+ reg_8x8_src_right_r3 = vext_u8(reg_8x8_src_r3, reg_8x8_src_r3, 2);
+ reg_8x8_src_right_r4 = vext_u8(reg_8x8_src_r4, reg_8x8_src_r4, 2);
+ reg_8x8_src_right_r5 = vext_u8(reg_8x8_src_r5, reg_8x8_src_r5, 2);
+ reg_8x8_src_right_r6 = vext_u8(reg_8x8_src_r6, reg_8x8_src_r6, 2);
+ reg_8x8_src_right_r7 = vext_u8(reg_8x8_src_r7, reg_8x8_src_r7, 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_r2 = vtbl1_u8(reg_8x8_src_r2, reg_8x8_shuffle);
+ reg_8x8_src_r3 = vtbl1_u8(reg_8x8_src_r3, reg_8x8_shuffle);
+ reg_8x8_src_r4 = vtbl1_u8(reg_8x8_src_r4, reg_8x8_shuffle);
+ reg_8x8_src_r5 = vtbl1_u8(reg_8x8_src_r5, reg_8x8_shuffle);
+ reg_8x8_src_r6 = vtbl1_u8(reg_8x8_src_r6, reg_8x8_shuffle);
+ reg_8x8_src_r7 = vtbl1_u8(reg_8x8_src_r7, reg_8x8_shuffle);
+ reg_8x8_src_r8 = vtbl1_u8(reg_8x8_src_r8, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+ reg_8x8_src_right_r1 = vtbl1_u8(reg_8x8_src_right_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r2 = vtbl1_u8(reg_8x8_src_right_r2, reg_8x8_shuffle);
+ reg_8x8_src_right_r3 = vtbl1_u8(reg_8x8_src_right_r3, reg_8x8_shuffle);
+ reg_8x8_src_right_r4 = vtbl1_u8(reg_8x8_src_right_r4, reg_8x8_shuffle);
+ reg_8x8_src_right_r5 = vtbl1_u8(reg_8x8_src_right_r5, reg_8x8_shuffle);
+ reg_8x8_src_right_r6 = vtbl1_u8(reg_8x8_src_right_r6, reg_8x8_shuffle);
+ reg_8x8_src_right_r7 = vtbl1_u8(reg_8x8_src_right_r7, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r4, reg_8x8_src_r5);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r5, reg_8x8_src_r6);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r6, reg_8x8_src_r7);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r7, reg_8x8_src_r8);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_right_r3);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r4, reg_8x8_src_right_r4);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r5, reg_8x8_src_right_r5);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r6, reg_8x8_src_right_r6);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r7, reg_8x8_src_right_r7);
+
+ reg_16x8_abs_diff_uv = vandq_u16(reg_16x8_abs_diff_uv, reg_16x8_and_mask_uv);
+
+ reg_32x4_abs_diff_hadd_uv = vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+
+ pu1_input_buf += (i4_input_stride * 8);
+ }
+
+ /* Loop for remaining height less than 8 */
+ /* 4 <= remaining_height < 8 */
+ for(k = i; k < (u4_height >> 1) - 4; k += 4, i += 4)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 2);
+ reg_8x8_src_right_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j + 2);
+ reg_8x8_src_right_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j + 2);
+ reg_8x8_src_right_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j + 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_r2 = vtbl1_u8(reg_8x8_src_r2, reg_8x8_shuffle);
+ reg_8x8_src_r3 = vtbl1_u8(reg_8x8_src_r3, reg_8x8_shuffle);
+ reg_8x8_src_r4 = vtbl1_u8(reg_8x8_src_r4, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+ reg_8x8_src_right_r1 = vtbl1_u8(reg_8x8_src_right_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r2 = vtbl1_u8(reg_8x8_src_right_r2, reg_8x8_shuffle);
+ reg_8x8_src_right_r3 = vtbl1_u8(reg_8x8_src_right_r3, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_right_r3);
+
+ reg_32x4_abs_diff_hadd_uv =
+ vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 6 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_uv */
+ /************************************************************/
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_r2 = vld1_u8(pu1_input_buf + (i4_input_stride * 2) + j);
+ reg_8x8_src_r3 = vld1_u8(pu1_input_buf + (i4_input_stride * 3) + j);
+ reg_8x8_src_r4 = vld1_u8(pu1_input_buf + (i4_input_stride * 4) + j);
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 2);
+ reg_8x8_src_right_r1 = vext_u8(reg_8x8_src_r1, reg_8x8_src_r1, 2);
+ reg_8x8_src_right_r2 = vext_u8(reg_8x8_src_r2, reg_8x8_src_r2, 2);
+ reg_8x8_src_right_r3 = vext_u8(reg_8x8_src_r3, reg_8x8_src_r3, 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_r2 = vtbl1_u8(reg_8x8_src_r2, reg_8x8_shuffle);
+ reg_8x8_src_r3 = vtbl1_u8(reg_8x8_src_r3, reg_8x8_shuffle);
+ reg_8x8_src_r4 = vtbl1_u8(reg_8x8_src_r4, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+ reg_8x8_src_right_r1 = vtbl1_u8(reg_8x8_src_right_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r2 = vtbl1_u8(reg_8x8_src_right_r2, reg_8x8_shuffle);
+ reg_8x8_src_right_r3 = vtbl1_u8(reg_8x8_src_right_r3, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_r3);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_r4);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r1, reg_8x8_src_right_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r2, reg_8x8_src_right_r2);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r3, reg_8x8_src_right_r3);
+
+ reg_16x8_abs_diff_uv = vandq_u16(reg_16x8_abs_diff_uv, reg_16x8_and_mask_uv);
+
+ reg_32x4_abs_diff_hadd_uv = vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+
+ pu1_input_buf += (i4_input_stride * 4);
+ }
+
+ /* Loop for remaining height less than 4 */
+ /* 0 <= remaining_height < 4 */
+ for(k = i; k < (u4_height >> 1) - 1; k++)
+ {
+ for(j = 0; j < u4_width - 8; j += 8)
+ {
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_right_r0 = vld1_u8(pu1_input_buf + j + 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv =
+ vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+
+ reg_32x4_abs_diff_hadd_uv =
+ vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 6 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with reg_16x8_and_mask_uv */
+ /************************************************************/
+ reg_8x8_src_r0 = vld1_u8(pu1_input_buf + j);
+ reg_8x8_src_r1 = vld1_u8(pu1_input_buf + i4_input_stride + j);
+ reg_8x8_src_right_r0 = vext_u8(reg_8x8_src_r0, reg_8x8_src_r0, 2);
+
+ /* separating u and v */
+ reg_8x8_src_r0 = vtbl1_u8(reg_8x8_src_r0, reg_8x8_shuffle);
+ reg_8x8_src_r1 = vtbl1_u8(reg_8x8_src_r1, reg_8x8_shuffle);
+ reg_8x8_src_right_r0 = vtbl1_u8(reg_8x8_src_right_r0, reg_8x8_shuffle);
+
+ reg_16x8_abs_diff_uv = vabdl_u8(reg_8x8_src_r0, reg_8x8_src_r1);
+ reg_16x8_abs_diff_uv = vabal_u8(reg_16x8_abs_diff_uv, reg_8x8_src_r0, reg_8x8_src_right_r0);
+
+ reg_16x8_abs_diff_uv = vandq_u16(reg_16x8_abs_diff_uv, reg_16x8_and_mask_uv);
+
+ reg_32x4_abs_diff_hadd_uv = vpadalq_u16(reg_32x4_abs_diff_hadd_uv, reg_16x8_abs_diff_uv);
+
+ pu1_input_buf += i4_input_stride;
+ }
+
+ /* Pairwise add u4_abd_hadd_uv to get final gpp_u and gpp_v value */
+ reg_64x2_gpp_uv = vpaddlq_u32(reg_32x4_abs_diff_hadd_uv);
+ d_gpp_u = vgetq_lane_u64(reg_64x2_gpp_uv, 0);
+ d_gpp_v = vgetq_lane_u64(reg_64x2_gpp_uv, 1);
+
+ d_gpp_y /= (u4_width * u4_height);
+ d_gpp_u /= ((u4_width / 2) * (u4_height / 2));
+ d_gpp_v /= ((u4_width / 2) * (u4_height / 2));
+
+ d_gpp = (DOUBLE) ((WT_LUMA_GPP * d_gpp_y) + d_gpp_u + d_gpp_v) / WT_TOTAL_GPP;
+
+ return d_gpp;
+}
diff --git a/encoder/arm/svc/isvce_residual_pred_neon.c b/encoder/arm/svc/isvce_residual_pred_neon.c
new file mode 100644
index 0000000..37065f5
--- /dev/null
+++ b/encoder/arm/svc/isvce_residual_pred_neon.c
@@ -0,0 +1,666 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+*
+* @file
+* isvce_svc_residual_pred_neon.c
+*
+* @brief
+* Contains functions
+* used for SVC residual
+* prediction
+*
+*******************************************************************************
+*/
+#include <arm_neon.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "ih264_size_defs.h"
+#include "isvc_macros.h"
+#include "isvc_structs.h"
+
+void isvce_luma_residual_sampler_2x_neon(coordinates_t *ps_ref_array_positions,
+ coordinates_t *ps_ref_array_phases,
+ buffer_container_t *ps_inp, buffer_container_t *ps_out,
+ buffer_container_t *ps_scratch, UWORD32 u4_ref_nnz,
+ UWORD8 u1_ref_tx_size)
+{
+ WORD16 *pi2_inp_data = (WORD16 *) ps_inp->pv_data;
+ WORD16 *pi2_out_res = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_inp_data_stride = ps_inp->i4_data_stride;
+ WORD32 i4_out_res_stride = ps_out->i4_data_stride;
+ WORD16 *pi2_refarray_buffer = (WORD16 *) ps_scratch->pv_data;
+ WORD32 i4_blk_ctr;
+
+ UNUSED(ps_ref_array_positions);
+ UNUSED(ps_ref_array_phases);
+
+ /* For 2x scaling, offsets always point to TL pixel outside MB */
+ /* Hence, refTransBlkIdc will be different and since phase */
+ /* for first refArray pos for horiz filtering samples > 8, */
+ /* first row and first column from the refArray is never used */
+ pi2_inp_data += 1 + i4_inp_data_stride;
+
+ if((u1_ref_tx_size) && (0 != u4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i, i4_j;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ int16x8_t i2_coeff_add_16x8_r0;
+ int16x8_t i2_coeff_16x8_r0_0, i2_coeff_16x8_r0_1;
+ int16x8_t i2_coeff_16x8_sl_r0_0, i2_coeff_16x8_sl_r0_1;
+ int16x8_t result_16x8_r0_0, result_16x8_r0_1;
+
+ int16x8_t i2_coeff_add_16x8_r1;
+ int16x8_t i2_coeff_16x8_r1_0, i2_coeff_16x8_r1_1;
+ int16x8_t i2_coeff_16x8_sl_r1_0, i2_coeff_16x8_sl_r1_1;
+ int16x8_t result_16x8_r1_0, result_16x8_r1_1;
+ int16x8x2_t final_result_16x8x2_r0, final_result_16x8x2_r1;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLK8x8SIZE; i4_i += 2)
+ {
+ i2_coeff_16x8_r0_0 = vld1q_s16(pi2_ref_data_byte);
+ i2_coeff_16x8_r0_1 = vld1q_s16((pi2_ref_data_byte + 1));
+
+ i2_coeff_16x8_r1_0 = vld1q_s16(pi2_ref_data_byte + i4_inp_data_stride);
+ i2_coeff_16x8_r1_1 = vld1q_s16((pi2_ref_data_byte + i4_inp_data_stride + 1));
+
+ i2_coeff_add_16x8_r0 = vaddq_s16(i2_coeff_16x8_r0_0, i2_coeff_16x8_r0_1);
+ i2_coeff_16x8_sl_r0_0 = vshlq_n_s16(i2_coeff_16x8_r0_0, 1);
+ i2_coeff_16x8_sl_r0_1 = vshlq_n_s16(i2_coeff_16x8_r0_1, 1);
+
+ i2_coeff_add_16x8_r1 = vaddq_s16(i2_coeff_16x8_r1_0, i2_coeff_16x8_r1_1);
+ i2_coeff_16x8_sl_r1_0 = vshlq_n_s16(i2_coeff_16x8_r1_0, 1);
+ i2_coeff_16x8_sl_r1_1 = vshlq_n_s16(i2_coeff_16x8_r1_1, 1);
+
+ result_16x8_r0_0 = vaddq_s16(i2_coeff_16x8_sl_r0_0, i2_coeff_add_16x8_r0);
+ result_16x8_r0_1 = vaddq_s16(i2_coeff_16x8_sl_r0_1, i2_coeff_add_16x8_r0);
+
+ result_16x8_r1_0 = vaddq_s16(i2_coeff_16x8_sl_r1_0, i2_coeff_add_16x8_r1);
+ result_16x8_r1_1 = vaddq_s16(i2_coeff_16x8_sl_r1_1, i2_coeff_add_16x8_r1);
+
+ final_result_16x8x2_r0 = vzipq_s16(result_16x8_r0_0, result_16x8_r0_1);
+ final_result_16x8x2_r1 = vzipq_s16(result_16x8_r1_0, result_16x8_r1_1);
+
+ vst1q_s32(pi4_ref_array + 1, vmovl_s16(vget_low_s16(final_result_16x8x2_r0.val[0])));
+ vst1q_s32(pi4_ref_array + 5, vmovl_s16(vget_high_s16(final_result_16x8x2_r0.val[0])));
+ vst1q_s32(pi4_ref_array + 9, vmovl_s16(vget_low_s16(final_result_16x8x2_r0.val[1])));
+ vst1q_s32(pi4_ref_array + 13, vmovl_s16(vget_high_s16(final_result_16x8x2_r0.val[1])));
+
+ pi4_ref_array[0] = pi2_ref_data_byte[0] << 2;
+ pi4_ref_array[15] = pi2_ref_data_byte[7] << 2;
+ pi4_ref_array += 16;
+ pi2_ref_data_byte += i4_inp_data_stride;
+
+ vst1q_s32(pi4_ref_array + 1, vmovl_s16(vget_low_s16(final_result_16x8x2_r1.val[0])));
+ vst1q_s32(pi4_ref_array + 5, vmovl_s16(vget_high_s16(final_result_16x8x2_r1.val[0])));
+ vst1q_s32(pi4_ref_array + 9, vmovl_s16(vget_low_s16(final_result_16x8x2_r1.val[1])));
+ vst1q_s32(pi4_ref_array + 13, vmovl_s16(vget_high_s16(final_result_16x8x2_r1.val[1])));
+
+ pi4_ref_array[0] = pi2_ref_data_byte[0] << 2;
+ pi4_ref_array[15] = pi2_ref_data_byte[7] << 2;
+ pi4_ref_array += 16;
+ /* vertical loop updates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 2) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ int32x4_t i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r1_2, i4_horz_samp_32x4_r1_3,
+ i4_horz_samp_32x4_r1_4;
+ int32x4_t i4_horz_samp_32x4_r2_1, i4_horz_samp_32x4_r2_2, i4_horz_samp_32x4_r2_3,
+ i4_horz_samp_32x4_r2_4;
+
+ int32x4_t i4_horz_res_32x4_r1_1, i4_horz_res_32x4_r1_2, i4_horz_res_32x4_r1_3,
+ i4_horz_res_32x4_r1_4;
+ int32x4_t i4_horz_res_32x4_r2_1, i4_horz_res_32x4_r2_2, i4_horz_res_32x4_r2_3,
+ i4_horz_res_32x4_r2_4;
+ int32x4_t i4_horz_res_32x4_r3_1, i4_horz_res_32x4_r3_2, i4_horz_res_32x4_r3_3,
+ i4_horz_res_32x4_r3_4;
+ int32x4_t horz_add_32x4_r2_1, horz_add_32x4_r2_2, horz_add_32x4_r2_3,
+ horz_add_32x4_r2_4;
+
+ int16x8_t comb_horz_16x8_1, comb_horz_16x8_2, comb_horz_16x8_3, comb_horz_16x8_4;
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+
+ i4_horz_samp_32x4_r1_1 = vld1q_s32(pi4_ref_array_temp);
+ i4_horz_samp_32x4_r1_2 = vld1q_s32(pi4_ref_array_temp + 4);
+ i4_horz_samp_32x4_r1_3 = vld1q_s32(pi4_ref_array_temp + 8);
+ i4_horz_samp_32x4_r1_4 = vld1q_s32(pi4_ref_array_temp + 12);
+
+ /* populate the first inter sample */
+ i4_horz_res_32x4_r1_1 = vrshrq_n_s32(i4_horz_samp_32x4_r1_1, 2);
+ i4_horz_res_32x4_r1_2 = vrshrq_n_s32(i4_horz_samp_32x4_r1_2, 2);
+ i4_horz_res_32x4_r1_3 = vrshrq_n_s32(i4_horz_samp_32x4_r1_3, 2);
+ i4_horz_res_32x4_r1_4 = vrshrq_n_s32(i4_horz_samp_32x4_r1_4, 2);
+
+ comb_horz_16x8_1 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_1), vmovn_s32(i4_horz_res_32x4_r1_2));
+ comb_horz_16x8_2 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_3), vmovn_s32(i4_horz_res_32x4_r1_4));
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi4_ref_array_temp += MB_SIZE;
+ i4_horz_samp_32x4_r2_1 = vld1q_s32(pi4_ref_array_temp);
+ i4_horz_samp_32x4_r2_2 = vld1q_s32(pi4_ref_array_temp + 4);
+ i4_horz_samp_32x4_r2_3 = vld1q_s32(pi4_ref_array_temp + 8);
+ i4_horz_samp_32x4_r2_4 = vld1q_s32(pi4_ref_array_temp + 12);
+
+ horz_add_32x4_r2_1 = vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r2_1);
+ horz_add_32x4_r2_2 = vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_samp_32x4_r2_2);
+ horz_add_32x4_r2_3 = vaddq_s32(i4_horz_samp_32x4_r1_3, i4_horz_samp_32x4_r2_3);
+ horz_add_32x4_r2_4 = vaddq_s32(i4_horz_samp_32x4_r1_4, i4_horz_samp_32x4_r2_4);
+
+ i4_horz_res_32x4_r2_1 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_1, 1), horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r2_2 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_2, 1), horz_add_32x4_r2_2);
+ i4_horz_res_32x4_r2_3 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_3, 1), horz_add_32x4_r2_3);
+ i4_horz_res_32x4_r2_4 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r1_4, 1), horz_add_32x4_r2_4);
+
+ i4_horz_res_32x4_r3_1 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_1, 1), horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r3_2 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_2, 1), horz_add_32x4_r2_2);
+ i4_horz_res_32x4_r3_3 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_3, 1), horz_add_32x4_r2_3);
+ i4_horz_res_32x4_r3_4 =
+ vaddq_s32(vshlq_n_s32(i4_horz_samp_32x4_r2_4, 1), horz_add_32x4_r2_4);
+
+ i4_horz_res_32x4_r2_1 = vrshrq_n_s32(i4_horz_res_32x4_r2_1, 4);
+ i4_horz_res_32x4_r2_2 = vrshrq_n_s32(i4_horz_res_32x4_r2_2, 4);
+ i4_horz_res_32x4_r2_3 = vrshrq_n_s32(i4_horz_res_32x4_r2_3, 4);
+ i4_horz_res_32x4_r2_4 = vrshrq_n_s32(i4_horz_res_32x4_r2_4, 4);
+
+ i4_horz_res_32x4_r3_1 = vrshrq_n_s32(i4_horz_res_32x4_r3_1, 4);
+ i4_horz_res_32x4_r3_2 = vrshrq_n_s32(i4_horz_res_32x4_r3_2, 4);
+ i4_horz_res_32x4_r3_3 = vrshrq_n_s32(i4_horz_res_32x4_r3_3, 4);
+ i4_horz_res_32x4_r3_4 = vrshrq_n_s32(i4_horz_res_32x4_r3_4, 4);
+
+ comb_horz_16x8_1 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r2_1),
+ vmovn_s32(i4_horz_res_32x4_r2_2));
+ comb_horz_16x8_2 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r2_3),
+ vmovn_s32(i4_horz_res_32x4_r2_4));
+
+ comb_horz_16x8_3 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r3_1),
+ vmovn_s32(i4_horz_res_32x4_r3_2));
+ comb_horz_16x8_4 = vcombine_s16(vmovn_s32(i4_horz_res_32x4_r3_3),
+ vmovn_s32(i4_horz_res_32x4_r3_4));
+
+ /* populate 2 samples based on current coeffs */
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+ pi2_out += i4_out_res_stride;
+
+ vst1q_s16(pi2_out, comb_horz_16x8_3);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_4);
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_32x4_r1_1 = i4_horz_samp_32x4_r2_1;
+ i4_horz_samp_32x4_r1_2 = i4_horz_samp_32x4_r2_2;
+ i4_horz_samp_32x4_r1_3 = i4_horz_samp_32x4_r2_3;
+ i4_horz_samp_32x4_r1_4 = i4_horz_samp_32x4_r2_4;
+ }
+
+ /* populate the first inter sample */
+ i4_horz_res_32x4_r1_1 = vrshrq_n_s32(i4_horz_samp_32x4_r1_1, 2);
+ i4_horz_res_32x4_r1_2 = vrshrq_n_s32(i4_horz_samp_32x4_r1_2, 2);
+ i4_horz_res_32x4_r1_3 = vrshrq_n_s32(i4_horz_samp_32x4_r1_3, 2);
+ i4_horz_res_32x4_r1_4 = vrshrq_n_s32(i4_horz_samp_32x4_r1_4, 2);
+
+ comb_horz_16x8_1 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_1), vmovn_s32(i4_horz_res_32x4_r1_2));
+ comb_horz_16x8_2 =
+ vcombine_s16(vmovn_s32(i4_horz_res_32x4_r1_3), vmovn_s32(i4_horz_res_32x4_r1_4));
+ vst1q_s16(pi2_out, comb_horz_16x8_1);
+ vst1q_s16(pi2_out + 8, comb_horz_16x8_2);
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ /* if reference layer is not coded then no processing */
+ if(0 != (u4_ref_nnz & 0x1))
+ {
+ int16x8_t i2_coeff1_16x8_r0_0, i2_coeff1_16x8_r0_1;
+ int16x8_t i2_coeff1_16x8_r1_0, i2_coeff1_16x8_r1_1;
+ int16x8_t i2_coeff1_16x8_r2_0, i2_coeff1_16x8_r2_1;
+ int16x8_t i2_coeff1_16x8_r3_0, i2_coeff1_16x8_r3_1;
+ int16x8_t i2_add_16x8_r0_0;
+ int16x8_t i2_add_16x8_r1_0;
+ int16x8_t i2_add_16x8_r2_0;
+ int16x8_t i2_add_16x8_r3_0;
+ int16x8_t i2_res_16x8_r0_0, i2_res_16x8_r0_1;
+ int16x8_t i2_res_16x8_r1_0, i2_res_16x8_r1_1;
+ int16x8_t i2_res_16x8_r2_0, i2_res_16x8_r2_1;
+ int16x8_t i2_res_16x8_r3_0, i2_res_16x8_r3_1;
+ int16x4_t i4_horz_samp_16x4_r0_1, i4_horz_samp_16x4_r0_2;
+ int16x4_t i4_horz_samp_16x4_r1_1, i4_horz_samp_16x4_r1_2;
+ int16x4_t i4_horz_samp_16x4_r2_1, i4_horz_samp_16x4_r2_2;
+ int16x4_t i4_horz_samp_16x4_r3_1, i4_horz_samp_16x4_r3_2;
+ int32x4_t i4_horz_samp_32x4_r0_1, i4_horz_samp_32x4_r0_2;
+ int32x4_t i4_horz_samp_32x4_r1_1, i4_horz_samp_32x4_r1_2;
+ int32x4_t i4_horz_samp_32x4_r2_1, i4_horz_samp_32x4_r2_2;
+ int32x4_t i4_horz_samp_32x4_r3_1, i4_horz_samp_32x4_r3_2;
+ int32x4_t i4_horz_add_32x4_r1_1, i4_horz_add_32x4_r1_2;
+ int32x4_t i4_horz_add_32x4_r2_1, i4_horz_add_32x4_r2_2;
+ int32x4_t i4_horz_add_32x4_r3_1, i4_horz_add_32x4_r3_2;
+ int16x4_t i4_horz_res_16x4_r0_1, i4_horz_res_16x4_r0_2;
+ int16x4_t i4_horz_res_16x4_r1_1, i4_horz_res_16x4_r1_2;
+ int16x4_t i4_horz_res_16x4_r2_1, i4_horz_res_16x4_r2_2;
+ int16x4_t i4_horz_res_16x4_r3_1, i4_horz_res_16x4_r3_2;
+ int16x4_t i4_horz_res_16x4_r4_1, i4_horz_res_16x4_r4_2;
+ int16x4_t i4_horz_res_16x4_r5_1, i4_horz_res_16x4_r5_2;
+ int16x4_t i4_horz_res_16x4_r6_1, i4_horz_res_16x4_r6_2;
+ int16x4_t i4_horz_res_16x4_r7_1, i4_horz_res_16x4_r7_2;
+ int32x4_t i4_horz_res_32x4_r1_1, i4_horz_res_32x4_r1_2;
+ int32x4_t i4_horz_res_32x4_r2_1, i4_horz_res_32x4_r2_2;
+ int32x4_t i4_horz_res_32x4_r3_1, i4_horz_res_32x4_r3_2;
+ int32x4_t i4_horz_res_32x4_r4_1, i4_horz_res_32x4_r4_2;
+ int32x4_t i4_horz_res_32x4_r5_1, i4_horz_res_32x4_r5_2;
+ int32x4_t i4_horz_res_32x4_r6_1, i4_horz_res_32x4_r6_2;
+ int16x8x2_t ti2_res_16x8x2_r0, ti2_res_16x8x2_r1;
+ int16x8x2_t ti2_res_16x8x2_r2, ti2_res_16x8x2_r3;
+
+ i2_coeff1_16x8_r0_0 = vld1q_s16(pi2_inp_data);
+ i2_coeff1_16x8_r1_0 = vld1q_s16(pi2_inp_data + i4_inp_data_stride);
+ i2_coeff1_16x8_r2_0 = vld1q_s16(pi2_inp_data + (i4_inp_data_stride << 1));
+ i2_coeff1_16x8_r3_0 =
+ vld1q_s16(pi2_inp_data + (i4_inp_data_stride << 1) + i4_inp_data_stride);
+
+ i2_coeff1_16x8_r0_1 = vextq_s16(i2_coeff1_16x8_r0_0, i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_1 = vextq_s16(i2_coeff1_16x8_r1_0, i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_1 = vextq_s16(i2_coeff1_16x8_r2_0, i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_1 = vextq_s16(i2_coeff1_16x8_r3_0, i2_coeff1_16x8_r3_0, 1);
+
+ i2_add_16x8_r0_0 = vaddq_s16(i2_coeff1_16x8_r0_1, i2_coeff1_16x8_r0_0);
+ i2_add_16x8_r1_0 = vaddq_s16(i2_coeff1_16x8_r1_1, i2_coeff1_16x8_r1_0);
+ i2_add_16x8_r2_0 = vaddq_s16(i2_coeff1_16x8_r2_1, i2_coeff1_16x8_r2_0);
+ i2_add_16x8_r3_0 = vaddq_s16(i2_coeff1_16x8_r3_1, i2_coeff1_16x8_r3_0);
+
+ i2_coeff1_16x8_r0_0 = vshlq_n_s16(i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_0 = vshlq_n_s16(i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_0 = vshlq_n_s16(i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_0 = vshlq_n_s16(i2_coeff1_16x8_r3_0, 1);
+
+ i2_coeff1_16x8_r0_1 = vshlq_n_s16(i2_coeff1_16x8_r0_1, 1);
+ i2_coeff1_16x8_r1_1 = vshlq_n_s16(i2_coeff1_16x8_r1_1, 1);
+ i2_coeff1_16x8_r2_1 = vshlq_n_s16(i2_coeff1_16x8_r2_1, 1);
+ i2_coeff1_16x8_r3_1 = vshlq_n_s16(i2_coeff1_16x8_r3_1, 1);
+
+ i2_res_16x8_r0_0 = vaddq_s16(i2_coeff1_16x8_r0_0, i2_add_16x8_r0_0);
+ i2_res_16x8_r1_0 = vaddq_s16(i2_coeff1_16x8_r1_0, i2_add_16x8_r1_0);
+ i2_res_16x8_r2_0 = vaddq_s16(i2_coeff1_16x8_r2_0, i2_add_16x8_r2_0);
+ i2_res_16x8_r3_0 = vaddq_s16(i2_coeff1_16x8_r3_0, i2_add_16x8_r3_0);
+
+ i2_res_16x8_r0_1 = vaddq_s16(i2_coeff1_16x8_r0_1, i2_add_16x8_r0_0);
+ i2_res_16x8_r1_1 = vaddq_s16(i2_coeff1_16x8_r1_1, i2_add_16x8_r1_0);
+ i2_res_16x8_r2_1 = vaddq_s16(i2_coeff1_16x8_r2_1, i2_add_16x8_r2_0);
+ i2_res_16x8_r3_1 = vaddq_s16(i2_coeff1_16x8_r3_1, i2_add_16x8_r3_0);
+
+ ti2_res_16x8x2_r0 = vzipq_s16(i2_res_16x8_r0_0, i2_res_16x8_r0_1);
+ ti2_res_16x8x2_r1 = vzipq_s16(i2_res_16x8_r1_0, i2_res_16x8_r1_1);
+ ti2_res_16x8x2_r2 = vzipq_s16(i2_res_16x8_r2_0, i2_res_16x8_r2_1);
+ ti2_res_16x8x2_r3 = vzipq_s16(i2_res_16x8_r3_0, i2_res_16x8_r3_1);
+
+ i2_coeff1_16x8_r0_0 = vshlq_n_s16(i2_coeff1_16x8_r0_0, 1);
+ i2_coeff1_16x8_r1_0 = vshlq_n_s16(i2_coeff1_16x8_r1_0, 1);
+ i2_coeff1_16x8_r2_0 = vshlq_n_s16(i2_coeff1_16x8_r2_0, 1);
+ i2_coeff1_16x8_r3_0 = vshlq_n_s16(i2_coeff1_16x8_r3_0, 1);
+
+ vst1q_s16(pi2_refarray_buffer + 1, ti2_res_16x8x2_r0.val[0]);
+ vst1q_lane_s16(pi2_refarray_buffer, i2_coeff1_16x8_r0_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 7, i2_coeff1_16x8_r0_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 9, ti2_res_16x8x2_r1.val[0]);
+ vst1q_lane_s16(pi2_refarray_buffer + 8, i2_coeff1_16x8_r1_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 15, i2_coeff1_16x8_r1_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 17, ti2_res_16x8x2_r2.val[0]);
+ vst1q_lane_s16(pi2_refarray_buffer + 16, i2_coeff1_16x8_r2_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 23, i2_coeff1_16x8_r2_0, 3);
+
+ vst1q_s16(pi2_refarray_buffer + 25, ti2_res_16x8x2_r3.val[0]);
+ vst1q_lane_s16(pi2_refarray_buffer + 24, i2_coeff1_16x8_r3_0, 0);
+ vst1q_lane_s16(pi2_refarray_buffer + 31, i2_coeff1_16x8_r3_0, 3);
+
+ i4_horz_samp_16x4_r0_1 = vld1_s16(pi2_refarray_buffer);
+ i4_horz_samp_16x4_r0_2 = vld1_s16(pi2_refarray_buffer + 4);
+
+ i4_horz_samp_16x4_r1_1 = vld1_s16(pi2_refarray_buffer + 8);
+ i4_horz_samp_16x4_r1_2 = vld1_s16(pi2_refarray_buffer + 12);
+
+ i4_horz_samp_16x4_r2_1 = vld1_s16(pi2_refarray_buffer + 16);
+ i4_horz_samp_16x4_r2_2 = vld1_s16(pi2_refarray_buffer + 20);
+
+ i4_horz_samp_16x4_r3_1 = vld1_s16(pi2_refarray_buffer + 24);
+ i4_horz_samp_16x4_r3_2 = vld1_s16(pi2_refarray_buffer + 28);
+
+ i4_horz_res_16x4_r0_1 = vrshr_n_s16(i4_horz_samp_16x4_r0_1, 2);
+ i4_horz_res_16x4_r0_2 = vrshr_n_s16(i4_horz_samp_16x4_r0_2, 2);
+
+ i4_horz_add_32x4_r1_1 = vaddl_s16(i4_horz_samp_16x4_r0_1, i4_horz_samp_16x4_r1_1);
+ i4_horz_add_32x4_r1_2 = vaddl_s16(i4_horz_samp_16x4_r0_2, i4_horz_samp_16x4_r1_2);
+
+ i4_horz_add_32x4_r2_1 = vaddl_s16(i4_horz_samp_16x4_r1_1, i4_horz_samp_16x4_r2_1);
+ i4_horz_add_32x4_r2_2 = vaddl_s16(i4_horz_samp_16x4_r1_2, i4_horz_samp_16x4_r2_2);
+
+ i4_horz_add_32x4_r3_1 = vaddl_s16(i4_horz_samp_16x4_r2_1, i4_horz_samp_16x4_r3_1);
+ i4_horz_add_32x4_r3_2 = vaddl_s16(i4_horz_samp_16x4_r2_2, i4_horz_samp_16x4_r3_2);
+
+ i4_horz_samp_32x4_r0_1 = vshll_n_s16(i4_horz_samp_16x4_r0_1, 1);
+ i4_horz_samp_32x4_r0_2 = vshll_n_s16(i4_horz_samp_16x4_r0_2, 1);
+
+ i4_horz_samp_32x4_r1_1 = vshll_n_s16(i4_horz_samp_16x4_r1_1, 1);
+ i4_horz_samp_32x4_r1_2 = vshll_n_s16(i4_horz_samp_16x4_r1_2, 1);
+
+ i4_horz_samp_32x4_r2_1 = vshll_n_s16(i4_horz_samp_16x4_r2_1, 1);
+ i4_horz_samp_32x4_r2_2 = vshll_n_s16(i4_horz_samp_16x4_r2_2, 1);
+
+ i4_horz_samp_32x4_r3_1 = vshll_n_s16(i4_horz_samp_16x4_r3_1, 1);
+ i4_horz_samp_32x4_r3_2 = vshll_n_s16(i4_horz_samp_16x4_r3_2, 1);
+
+ i4_horz_res_32x4_r1_1 = vaddq_s32(i4_horz_samp_32x4_r0_1, i4_horz_add_32x4_r1_1);
+ i4_horz_res_32x4_r1_2 = vaddq_s32(i4_horz_samp_32x4_r0_2, i4_horz_add_32x4_r1_2);
+
+ i4_horz_res_32x4_r2_1 = vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_add_32x4_r1_1);
+ i4_horz_res_32x4_r2_2 = vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_add_32x4_r1_2);
+
+ i4_horz_res_32x4_r3_1 = vaddq_s32(i4_horz_samp_32x4_r1_1, i4_horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r3_2 = vaddq_s32(i4_horz_samp_32x4_r1_2, i4_horz_add_32x4_r2_2);
+
+ i4_horz_res_32x4_r4_1 = vaddq_s32(i4_horz_samp_32x4_r2_1, i4_horz_add_32x4_r2_1);
+ i4_horz_res_32x4_r4_2 = vaddq_s32(i4_horz_samp_32x4_r2_2, i4_horz_add_32x4_r2_2);
+
+ i4_horz_res_32x4_r5_1 = vaddq_s32(i4_horz_samp_32x4_r2_1, i4_horz_add_32x4_r3_1);
+ i4_horz_res_32x4_r5_2 = vaddq_s32(i4_horz_samp_32x4_r2_2, i4_horz_add_32x4_r3_2);
+
+ i4_horz_res_32x4_r6_1 = vaddq_s32(i4_horz_samp_32x4_r3_1, i4_horz_add_32x4_r3_1);
+ i4_horz_res_32x4_r6_2 = vaddq_s32(i4_horz_samp_32x4_r3_2, i4_horz_add_32x4_r3_2);
+
+ i4_horz_res_16x4_r1_1 = vqrshrn_n_s32(i4_horz_res_32x4_r1_1, 4);
+ i4_horz_res_16x4_r1_2 = vqrshrn_n_s32(i4_horz_res_32x4_r1_2, 4);
+
+ i4_horz_res_16x4_r2_1 = vqrshrn_n_s32(i4_horz_res_32x4_r2_1, 4);
+ i4_horz_res_16x4_r2_2 = vqrshrn_n_s32(i4_horz_res_32x4_r2_2, 4);
+
+ i4_horz_res_16x4_r3_1 = vqrshrn_n_s32(i4_horz_res_32x4_r3_1, 4);
+ i4_horz_res_16x4_r3_2 = vqrshrn_n_s32(i4_horz_res_32x4_r3_2, 4);
+
+ i4_horz_res_16x4_r4_1 = vqrshrn_n_s32(i4_horz_res_32x4_r4_1, 4);
+ i4_horz_res_16x4_r4_2 = vqrshrn_n_s32(i4_horz_res_32x4_r4_2, 4);
+
+ i4_horz_res_16x4_r5_1 = vqrshrn_n_s32(i4_horz_res_32x4_r5_1, 4);
+ i4_horz_res_16x4_r5_2 = vqrshrn_n_s32(i4_horz_res_32x4_r5_2, 4);
+
+ i4_horz_res_16x4_r6_1 = vqrshrn_n_s32(i4_horz_res_32x4_r6_1, 4);
+ i4_horz_res_16x4_r6_2 = vqrshrn_n_s32(i4_horz_res_32x4_r6_2, 4);
+
+ i4_horz_res_16x4_r7_1 = vrshr_n_s16(i4_horz_samp_16x4_r3_1, 2);
+ i4_horz_res_16x4_r7_2 = vrshr_n_s16(i4_horz_samp_16x4_r3_2, 2);
+
+ vst1_s16(pi2_out_res, i4_horz_res_16x4_r0_1);
+ vst1_s16(pi2_out_res + 4, i4_horz_res_16x4_r0_2);
+
+ vst1_s16(pi2_out_res + i4_out_res_stride, i4_horz_res_16x4_r1_1);
+ vst1_s16(pi2_out_res + i4_out_res_stride + 4, i4_horz_res_16x4_r1_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 1), i4_horz_res_16x4_r2_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 1) + 4, i4_horz_res_16x4_r2_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 3), i4_horz_res_16x4_r3_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 3) + 4, i4_horz_res_16x4_r3_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 2), i4_horz_res_16x4_r4_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride << 2) + 4, i4_horz_res_16x4_r4_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 5), i4_horz_res_16x4_r5_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 5) + 4, i4_horz_res_16x4_r5_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 6), i4_horz_res_16x4_r6_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 6) + 4, i4_horz_res_16x4_r6_2);
+
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 7), i4_horz_res_16x4_r7_1);
+ vst1_s16(pi2_out_res + (i4_out_res_stride * 7) + 4, i4_horz_res_16x4_r7_2);
+
+ pi2_out_res += BLK8x8SIZE;
+ }
+ else
+ {
+ pi2_out_res += BLK8x8SIZE;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= SUB_BLK_WIDTH_4x4;
+ pi2_inp_data += (i4_inp_data_stride * SUB_BLK_HEIGHT_4x4);
+ pi2_out_res -= MB_SIZE;
+ pi2_out_res += (i4_out_res_stride * BLK8x8SIZE);
+ u4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += SUB_BLK_HEIGHT_4x4;
+ }
+ u4_ref_nnz >>= 1;
+ }
+ /* The above loop iterates over all the blocks */
+ }
+}
+
+UWORD32 isvce_get_sad_with_residual_pred_neon(buffer_container_t *ps_src,
+ buffer_container_t *ps_pred,
+ buffer_container_t *ps_res, UWORD32 u4_mb_wd,
+ UWORD32 u4_mb_ht)
+{
+ UWORD32 i, j, u4_sad = 0;
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ UWORD32 u4_num_rows_per_loop = 8;
+ UWORD32 u4_ht_by_8 = u4_mb_ht / u4_num_rows_per_loop;
+ uint8x8_t src0, src1, src2, src3;
+ uint8x8_t src4, src5, src6, src7;
+ uint8x8_t pred0, pred1, pred2, pred3;
+ uint8x8_t pred4, pred5, pred6, pred7;
+ int16x8_t res0_16x8, res1_16x8, res2_16x8, res3_16x8, res4_16x8, res5_16x8, res6_16x8,
+ res7_16x8;
+ uint16x8_t res0_u16x8, res1_u16x8, res2_u16x8, res3_u16x8, res4_u16x8, res5_u16x8, res6_u16x8,
+ res7_u16x8;
+ int16x8_t respred0_16x8, respred1_16x8, respred2_16x8, respred3_16x8, respred4_16x8,
+ respred5_16x8, respred6_16x8, respred7_16x8;
+ int16x8_t temp0_16x8, temp1_16x8, temp2_16x8, temp3_16x8, temp4_16x8, temp5_16x8, temp6_16x8,
+ temp7_16x8;
+ int32x4_t temp0_32x4;
+ int32x2_t temp0_32x2;
+
+ if((u4_mb_wd == 16) && (u4_mb_ht % 8 == 0))
+ {
+ for(i = 0; i < u4_ht_by_8; i++)
+ {
+ /* This loop processes 4 rows of 16 bytes each iteration */
+ /* So, 8 rows are processed across two iterations */
+ for(j = 0; j < 2; j++)
+ {
+ src0 = vld1_u8(pu1_src);
+ src1 = vld1_u8(pu1_src + 8);
+
+ pu1_src += i4_src_stride;
+
+ src2 = vld1_u8(pu1_src);
+ src3 = vld1_u8(pu1_src + 8);
+
+ pu1_src += i4_src_stride;
+
+ src4 = vld1_u8(pu1_src);
+ src5 = vld1_u8(pu1_src + 8);
+
+ pu1_src += i4_src_stride;
+
+ src6 = vld1_u8(pu1_src);
+ src7 = vld1_u8(pu1_src + 8);
+
+ pu1_src += i4_src_stride;
+
+ pred0 = vld1_u8(pu1_pred);
+ pred1 = vld1_u8(pu1_pred + 8);
+
+ pu1_pred += i4_pred_stride;
+
+ pred2 = vld1_u8(pu1_pred);
+ pred3 = vld1_u8(pu1_pred + 8);
+
+ pu1_pred += i4_pred_stride;
+
+ pred4 = vld1_u8(pu1_pred);
+ pred5 = vld1_u8(pu1_pred + 8);
+
+ pu1_pred += i4_pred_stride;
+
+ pred6 = vld1_u8(pu1_pred);
+ pred7 = vld1_u8(pu1_pred + 8);
+
+ pu1_pred += i4_pred_stride;
+
+ res0_u16x8 = vsubl_u8(src0, pred0);
+ res1_u16x8 = vsubl_u8(src1, pred1);
+ res2_u16x8 = vsubl_u8(src2, pred2);
+ res3_u16x8 = vsubl_u8(src3, pred3);
+ res4_u16x8 = vsubl_u8(src4, pred4);
+ res5_u16x8 = vsubl_u8(src5, pred5);
+ res6_u16x8 = vsubl_u8(src6, pred6);
+ res7_u16x8 = vsubl_u8(src7, pred7);
+
+ res0_16x8 = vreinterpretq_s16_u16(res0_u16x8);
+ res1_16x8 = vreinterpretq_s16_u16(res1_u16x8);
+ res2_16x8 = vreinterpretq_s16_u16(res2_u16x8);
+ res3_16x8 = vreinterpretq_s16_u16(res3_u16x8);
+ res4_16x8 = vreinterpretq_s16_u16(res4_u16x8);
+ res5_16x8 = vreinterpretq_s16_u16(res5_u16x8);
+ res6_16x8 = vreinterpretq_s16_u16(res6_u16x8);
+ res7_16x8 = vreinterpretq_s16_u16(res7_u16x8);
+
+ respred0_16x8 = vld1q_s16(pi2_res);
+ respred1_16x8 = vld1q_s16(pi2_res + 8);
+
+ pi2_res += i4_res_stride;
+
+ respred2_16x8 = vld1q_s16(pi2_res);
+ respred3_16x8 = vld1q_s16(pi2_res + 8);
+
+ pi2_res += i4_res_stride;
+
+ respred4_16x8 = vld1q_s16(pi2_res);
+ respred5_16x8 = vld1q_s16(pi2_res + 8);
+
+ pi2_res += i4_res_stride;
+
+ respred6_16x8 = vld1q_s16(pi2_res);
+ respred7_16x8 = vld1q_s16(pi2_res + 8);
+
+ pi2_res += i4_res_stride;
+
+ temp0_16x8 = vsubq_s16(res0_16x8, respred0_16x8);
+ temp1_16x8 = vsubq_s16(res1_16x8, respred1_16x8);
+ temp2_16x8 = vsubq_s16(res2_16x8, respred2_16x8);
+ temp3_16x8 = vsubq_s16(res3_16x8, respred3_16x8);
+ temp4_16x8 = vsubq_s16(res4_16x8, respred4_16x8);
+ temp5_16x8 = vsubq_s16(res5_16x8, respred5_16x8);
+ temp6_16x8 = vsubq_s16(res6_16x8, respred6_16x8);
+ temp7_16x8 = vsubq_s16(res7_16x8, respred7_16x8);
+
+ temp0_16x8 = vabsq_s16(temp0_16x8);
+ temp1_16x8 = vabsq_s16(temp1_16x8);
+ temp2_16x8 = vabsq_s16(temp2_16x8);
+ temp3_16x8 = vabsq_s16(temp3_16x8);
+ temp4_16x8 = vabsq_s16(temp4_16x8);
+ temp5_16x8 = vabsq_s16(temp5_16x8);
+ temp6_16x8 = vabsq_s16(temp6_16x8);
+ temp7_16x8 = vabsq_s16(temp7_16x8);
+
+ temp0_16x8 = vaddq_s16(temp0_16x8, temp1_16x8);
+ temp1_16x8 = vaddq_s16(temp2_16x8, temp3_16x8);
+ temp2_16x8 = vaddq_s16(temp4_16x8, temp5_16x8);
+ temp3_16x8 = vaddq_s16(temp6_16x8, temp7_16x8);
+
+ temp0_16x8 = vaddq_s16(temp0_16x8, temp1_16x8);
+ temp1_16x8 = vaddq_s16(temp2_16x8, temp3_16x8);
+
+ temp0_16x8 = vaddq_s16(temp0_16x8, temp1_16x8);
+
+ temp0_32x4 = vpaddlq_s16(temp0_16x8);
+ temp0_32x2 = vpadd_s32(vget_low_s32(temp0_32x4), vget_high_s32(temp0_32x4));
+
+ u4_sad += vget_lane_s32(temp0_32x2, 0);
+ u4_sad += vget_lane_s32(temp0_32x2, 1);
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < u4_mb_ht; i++)
+ {
+ for(j = 0; j < u4_mb_wd; j++)
+ {
+ WORD16 i2_src = pu1_src[j + i * i4_src_stride];
+ WORD16 i2_pred = pu1_pred[j + i * i4_pred_stride];
+ WORD16 i2_res = pi2_res[j + i * i4_res_stride];
+ u4_sad += ABS(i2_src - i2_pred - i2_res);
+ }
+ }
+ }
+
+ return u4_sad;
+}
diff --git a/encoder/ih264e.h b/encoder/ih264e.h
index c736d9b..bf874eb 100644
--- a/encoder/ih264e.h
+++ b/encoder/ih264e.h
@@ -837,6 +837,78 @@ typedef struct
}ih264e_ctl_set_sei_ccv_params_op_t;
+/*****************************************************************************/
+/* Video control Set SEI SII params */
+/*****************************************************************************/
+
+typedef struct
+{
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : IVE_CMD_VIDEO_CTL */
+ IVE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : IVE_CMD_CTL_SET_SEI_SII_PARAMS */
+ IVE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /**
+ * specifies if the sei sii is enabled */
+ UWORD8 u1_shutter_interval_info_present_flag;
+
+ /**
+ * specifies the shutter interval temporal sub-layer index
+ * of the current picture */
+ UWORD32 u4_sii_sub_layer_idx;
+
+ /**
+ * specify the number of time units that pass in one second */
+ UWORD32 u4_sii_time_scale;
+
+ /**
+ * specifies that the indicated shutter interval is the same
+ * for all pictures in the coded video sequence */
+ UWORD8 u1_fixed_shutter_interval_within_cvs_flag;
+
+ /**
+ * specifies the the number of time units of a clock operating at
+ * the frequency sii_time_scale Hz that corresponds to the indicated
+ * shutter interval of each picture in the coded video sequence */
+ UWORD32 u4_sii_num_units_in_shutter_interval;
+
+ /**
+ * sii_max_sub_layers_minus1 plus 1 specifies the maximum number of
+ * shutter interval temporal sub-layers indexes that may be present
+ * in the coded video sequence */
+ UWORD8 u1_sii_max_sub_layers_minus1;
+
+ /**
+ * specifies the number of time units of a clock operating at the
+ * frequency sii_time_scale Hz that corresponds to the shutter
+ * interval of each picture in the coded video sequence */
+ UWORD32 au4_sub_layer_num_units_in_shutter_interval[8];
+
+ /**
+ * Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /**
+ * Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+} ih264e_ctl_set_sei_sii_params_ip_t;
+
+typedef struct
+{
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+
+} ih264e_ctl_set_sei_sii_params_op_t;
/* The enum values should not have greater than 8 bits as this is assigned to WORD8 */
typedef enum
diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c
index 502c957..055c6e2 100644
--- a/encoder/ih264e_api.c
+++ b/encoder/ih264e_api.c
@@ -194,7 +194,7 @@ static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec,
break;
case IV_YUV_420SP_UV:
case IV_YUV_420SP_VU:
- if ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1])
+ if (ps_inp_buf->au4_wd[0] != ps_inp_buf->au4_wd[1])
{
ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
@@ -2138,6 +2138,59 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
break;
}
+ case IVE_CMD_CTL_SET_SEI_SII_PARAMS:
+ {
+ ih264e_ctl_set_sei_sii_params_ip_t *ps_ip = pv_api_ip;
+ ih264e_ctl_set_sei_sii_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(ih264e_ctl_set_sei_sii_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_SEI_SII_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(ih264e_ctl_set_sei_sii_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_SEI_SII_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ /* The below error check is based on H264 spec docs SII syntax */
+ if(0 != ps_ip->u4_sii_sub_layer_idx)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_SII_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u1_sii_max_sub_layers_minus1 > 7)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_SII_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u4_sii_sub_layer_idx > 0) &&
+ (ps_ip->u1_fixed_shutter_interval_within_cvs_flag == 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_SEI_SII_FAILED_TO_MATCH_SPEC_COND;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u4_sii_sub_layer_idx > ps_ip->u1_sii_max_sub_layers_minus1) &&
+ (ps_ip->u1_fixed_shutter_interval_within_cvs_flag == 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_SEI_SII_FAILED_TO_MATCH_SPEC_COND;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+
case IVE_CMD_CTL_SET_ENC_MODE:
{
ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
@@ -2768,6 +2821,12 @@ IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec,
ps_cfg->s_sei.u1_sei_ccv_params_present_flag;
ps_codec->s_cfg.s_sei.s_sei_ccv_params = ps_cfg->s_sei.s_sei_ccv_params;
}
+ else if(ps_cfg->e_cmd == IVE_CMD_CTL_SET_SEI_SII_PARAMS)
+ {
+ ps_codec->s_cfg.s_sei.u1_sei_sii_params_present_flag =
+ ps_cfg->s_sei.u1_sei_sii_params_present_flag;
+ ps_codec->s_cfg.s_sei.s_sei_sii_params = ps_cfg->s_sei.s_sei_sii_params;
+ }
/* reset RC model */
if (u4_init_rc)
@@ -2873,6 +2932,7 @@ static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg)
ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV;
ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE;
+ ps_cfg->u4_enable_quality_metrics = DEFAULT_QUALITY_METRICS_ENABLE;
ps_cfg->e_recon_color_fmt = IV_YUV_420P;
ps_cfg->u4_enc_speed_preset = IVE_FASTEST;
ps_cfg->e_rc_mode = DEFAULT_RC;
@@ -3045,6 +3105,8 @@ static WORD32 ih264e_init(codec_t *ps_codec)
/* Process thread created status */
memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS);
+ memset(&ps_codec->s_global_quality_stats, 0, sizeof(ps_codec->s_global_quality_stats));
+
/* Number of MBs processed together */
ps_codec->i4_proc_nmb = 8;
@@ -6102,6 +6164,78 @@ static WORD32 ih264e_set_sei_ccv_params(void *pv_api_ip,
*******************************************************************************
*
* @brief
+ * Sets shutter interval info sei params
+ *
+ * @par Description:
+ * Supplemental enhancement information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @return error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 ih264e_set_sei_sii_params(void *pv_api_ip, void *pv_api_op, cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ ih264e_ctl_set_sei_sii_params_ip_t *ps_ip = pv_api_ip;
+ ih264e_ctl_set_sei_sii_params_op_t *ps_op = pv_api_op;
+ sei_params_t *ps_sei = &ps_cfg->s_sei;
+
+ ps_op->u4_error_code = 0;
+ ps_sei->u1_sei_sii_params_present_flag = ps_ip->u1_shutter_interval_info_present_flag;
+ ps_sei->s_sei_sii_params.u4_sii_sub_layer_idx = ps_ip->u4_sii_sub_layer_idx;
+
+ if(0 == ps_sei->s_sei_sii_params.u4_sii_sub_layer_idx)
+ {
+ ps_sei->s_sei_sii_params.u1_shutter_interval_info_present_flag =
+ ps_ip->u1_shutter_interval_info_present_flag;
+
+ if(1 == ps_sei->s_sei_sii_params.u1_shutter_interval_info_present_flag)
+ {
+ ps_sei->s_sei_sii_params.u4_sii_time_scale = ps_ip->u4_sii_time_scale;
+ ps_sei->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag =
+ ps_ip->u1_fixed_shutter_interval_within_cvs_flag;
+
+ if(1 == ps_sei->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ ps_sei->s_sei_sii_params.u4_sii_num_units_in_shutter_interval =
+ ps_ip->u4_sii_num_units_in_shutter_interval;
+ }
+ else
+ {
+ int i;
+ ps_sei->s_sei_sii_params.u1_sii_max_sub_layers_minus1 =
+ ps_ip->u1_sii_max_sub_layers_minus1;
+
+ for(i = 0; i <= ps_ip->u1_sii_max_sub_layers_minus1; i++)
+ {
+ ps_sei->s_sei_sii_params.au4_sub_layer_num_units_in_shutter_interval[i] =
+ ps_ip->au4_sub_layer_num_units_in_shutter_interval[i];
+ }
+ }
+ }
+ }
+
+ ps_cfg->u4_timestamp_high = ps_ip->u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
* Sets number of cores
*
* @par Description:
@@ -6341,6 +6475,10 @@ static WORD32 ih264e_ctl(iv_obj_t *ps_codec_obj,
ret = ih264e_set_sei_ccv_params(pv_api_ip, pv_api_op, ps_cfg);
break;
+ case IVE_CMD_CTL_SET_SEI_SII_PARAMS:
+ ret = ih264e_set_sei_sii_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
case IVE_CMD_CTL_RESET:
/* invalidate config param struct as it is being served right away */
diff --git a/encoder/ih264e_defs.h b/encoder/ih264e_defs.h
index 33fafd1..7f69554 100644
--- a/encoder/ih264e_defs.h
+++ b/encoder/ih264e_defs.h
@@ -205,6 +205,7 @@
/* Generic declarations */
#define DEFAULT_MAX_LEVEL 40
#define DEFAULT_RECON_ENABLE 0
+#define DEFAULT_QUALITY_METRICS_ENABLE 0
#define DEFAULT_RC IVE_RC_STORAGE
#define DEFAULT_MAX_FRAMERATE 120000
#define DEFAULT_MAX_BITRATE 240000000
@@ -267,6 +268,8 @@
/** Number of buffers Needed for SUBPEL and BIPRED computation */
#define SUBPEL_BUFF_CNT 4
+/** Mask value for PSNR. Needed when quality metrics is enabled */
+#define QUALITY_MASK_PSNR 0x1
/**
*****************************************************************************
* Macro to compute total size required to hold on set of scaling matrices
diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c
index defec7e..75a8335 100644
--- a/encoder/ih264e_encode.c
+++ b/encoder/ih264e_encode.c
@@ -49,6 +49,7 @@
#include <string.h>
#include <assert.h>
#include <limits.h>
+#include <stdbool.h>
/* User Include files */
#include "ih264e_config.h"
#include "ih264_typedefs.h"
@@ -293,6 +294,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
/* Force IDR based on SEI params */
#if SEI_BASED_FORCE_IDR
{
+ int i;
+ bool au4_sub_layer_num_units_in_shutter_interval_flag = 0;
+
sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params;
sei_mdcv_params_t *ps_cfg_sei_mdcv_params =
&ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
@@ -302,6 +306,8 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params;
sei_ave_params_t *ps_cfg_sei_ave_params =
&ps_codec->s_cfg.s_sei.s_sei_ave_params;
+ sei_sii_params_t *ps_sei_sii_params = &ps_codec->s_sei.s_sei_sii_params;
+ sei_sii_params_t *ps_cfg_sei_sii_params = &ps_codec->s_cfg.s_sei.s_sei_sii_params;
if((ps_sei_mdcv_params->au2_display_primaries_x[0]!=
ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) ||
@@ -360,9 +366,39 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ps_codec->s_sei.u1_sei_ave_params_present_flag = 0;
}
+ for(i = 0; i <= ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1; i++)
+ {
+ au4_sub_layer_num_units_in_shutter_interval_flag =
+ (au4_sub_layer_num_units_in_shutter_interval_flag ||
+ (ps_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i] !=
+ ps_cfg_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i]));
+ }
+
+ if((ps_sei_sii_params->u4_sii_sub_layer_idx !=
+ ps_cfg_sei_sii_params->u4_sii_sub_layer_idx) ||
+ (ps_sei_sii_params->u1_shutter_interval_info_present_flag !=
+ ps_cfg_sei_sii_params->u1_shutter_interval_info_present_flag) ||
+ (ps_sei_sii_params->u4_sii_time_scale != ps_cfg_sei_sii_params->u4_sii_time_scale) ||
+ (ps_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag !=
+ ps_cfg_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag) ||
+ (ps_sei_sii_params->u4_sii_num_units_in_shutter_interval !=
+ ps_cfg_sei_sii_params->u4_sii_num_units_in_shutter_interval) ||
+ (ps_sei_sii_params->u1_sii_max_sub_layers_minus1 !=
+ ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1) ||
+ au4_sub_layer_num_units_in_shutter_interval_flag)
+ {
+ ps_codec->s_sei.s_sei_sii_params = ps_codec->s_cfg.s_sei.s_sei_sii_params;
+ ps_codec->s_sei.u1_sei_sii_params_present_flag = 1;
+ }
+ else
+ {
+ ps_codec->s_sei.u1_sei_sii_params_present_flag = 0;
+ }
+
if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) ||
(1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) ||
- (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag))
+ (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag) ||
+ (1 == ps_codec->s_sei.u1_sei_sii_params_present_flag))
{
ps_codec->force_curr_frame_type = IV_IDR_FRAME;
}
@@ -531,6 +567,12 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ih264_list_reset(ps_codec->pv_proc_jobq);
ih264_list_reset(ps_codec->pv_entropy_jobq);
+
+ if (ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR)
+ {
+ ih264e_compute_quality_stats(ps_proc);
+ }
+
}
@@ -566,6 +608,7 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
IH264_ERROR_T ret = IH264_SUCCESS;
pic_buf_t *ps_pic_buf = NULL;
WORD32 i4_buf_status, i4_curr_poc = 32768;
+ WORD8 buf_idx = -1;
/* In case of skips we return recon, but indicate that buffer is zero size */
if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
@@ -593,6 +636,17 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
{
ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
+ buf_idx = i;
+ }
+ }
+ if ((ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR)
+ && buf_idx >= 0)
+ {
+ UWORD8 comp;
+ for(comp = 0; comp < 3; comp++)
+ {
+ DEBUG("PSNR[%d]: %f\n", comp,
+ ps_codec->as_ref_set[buf_idx].s_pic_quality_stats.total_psnr[comp]);
}
}
diff --git a/encoder/ih264e_encode_header.c b/encoder/ih264e_encode_header.c
index 16cf28e..4eb0017 100644
--- a/encoder/ih264e_encode_header.c
+++ b/encoder/ih264e_encode_header.c
@@ -786,6 +786,16 @@ IH264E_ERROR_T ih264e_generate_sei(bitstrm_t *ps_bitstrm, sei_params_t *ps_sei,
}
}
+ /* Shutter Interval Information*/
+ if(1 == ps_sei->u1_sei_sii_params_present_flag)
+ {
+ return_status = ih264e_put_sei_msg(IH264_SEI_SHUTTER_INTERVAL_INFO, ps_sei, ps_bitstrm);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+ }
+
/* rbsp trailing bits */
return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
diff --git a/encoder/ih264e_error.h b/encoder/ih264e_error.h
index c11d857..a460e5a 100644
--- a/encoder/ih264e_error.h
+++ b/encoder/ih264e_error.h
@@ -241,6 +241,12 @@ typedef enum
/**Invalid content color volume sei params */
IH264E_INVALID_SEI_CCV_PARAMS = IH264E_CODEC_ERROR_START + 0x36,
+ /**Invalid shutter interval info sei params */
+ IH264E_INVALID_SEI_SII_PARAMS = IH264E_CODEC_ERROR_START + 0x37,
+
+ /**Invalid shutter interval info sei params. Does not match H264 sii spec requirements*/
+ IH264E_SEI_SII_FAILED_TO_MATCH_SPEC_COND = IH264E_CODEC_ERROR_START + 0x38,
+
/**max failure error code to ensure enum is 32 bits wide */
IH264E_FAIL = -1,
diff --git a/encoder/ih264e_master.h b/encoder/ih264e_master.h
index 6c7505a..67354fd 100644
--- a/encoder/ih264e_master.h
+++ b/encoder/ih264e_master.h
@@ -63,6 +63,23 @@ void ih264e_join_threads(codec_t *ps_codec);
/**
******************************************************************************
*
+* @brief
+* This function calculates various quality metrics; the initial one is PSNR.
+*
+* @par Description
+*
+* @param[in] ps_codec
+* pointer to process context
+*
+* @returns none
+*
+******************************************************************************
+*/
+void ih264e_compute_quality_stats(process_ctxt_t *ps_proc);
+
+/**
+******************************************************************************
+*
* @brief This function puts the current thread to sleep for a duration
* of sleep_us
*
diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c
index 818e192..afb1bbd 100644
--- a/encoder/ih264e_process.c
+++ b/encoder/ih264e_process.c
@@ -408,6 +408,8 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc)
s_sei.u1_sei_ccv_params_present_flag = 0;
s_sei.s_sei_ccv_params =
ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].s_sei_ccv;
+ s_sei.u1_sei_sii_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_sii_params_present_flag;
+ s_sei.s_sei_sii_params = ps_codec->s_cfg.s_sei.s_sei_sii_params;
if((1 == ps_sps->i1_vui_parameters_present_flag) &&
(1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
@@ -425,7 +427,8 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc)
if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
(1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
(1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
- (1 == s_sei.u1_sei_ccv_params_present_flag))
+ (1 == s_sei.u1_sei_ccv_params_present_flag) ||
+ (1 == s_sei.u1_sei_sii_params_present_flag))
{
ps_entropy->i4_error_code =
ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
@@ -1260,6 +1263,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
convert_uv_only = 1;
if (u4_pad_bottom_sz || u4_pad_right_sz ||
ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
+ ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR ||
ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
{
if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
@@ -1279,6 +1283,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P ||
ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) ||
+ ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR ||
u4_pad_bottom_sz || u4_pad_right_sz)
{
if ((ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_UV) ||
@@ -2070,7 +2075,8 @@ WORD32 ih264e_process(process_ctxt_t *ps_proc)
* 2. dump recon for bit stream sanity check
*/
ps_proc->u4_compute_recon = ps_codec->u4_is_curr_frm_ref ||
- ps_codec->s_cfg.u4_enable_recon;
+ ps_codec->s_cfg.u4_enable_recon ||
+ ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR;
/* Encode 'n' macroblocks,
* 'n' being the number of mbs dictated by current proc ctxt */
diff --git a/encoder/ih264e_sei.c b/encoder/ih264e_sei.c
index bffdeb2..979d8a5 100644
--- a/encoder/ih264e_sei.c
+++ b/encoder/ih264e_sei.c
@@ -35,6 +35,7 @@
* - ih264e_put_sei_ave_params
* - ih264e_put_sei_ccv_params
* - ih264e_put_sei_msg
+* - ih264e_put_sei_sii_params
*
* @remarks
* None
@@ -372,6 +373,108 @@ IH264E_ERROR_T ih264e_put_sei_ccv_params(sei_ccv_params_t *ps_sei_ccv,
/**
******************************************************************************
*
+* @brief Signal shutter interval info in the bitstream
+*
+* @par Description
+* Parse Supplemental Enhancement Information
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_sei_sii
+* pointer to shutter interval info
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T ih264e_put_sei_sii_params(sei_sii_params_t *ps_sei_sii, bitstrm_t *ps_bitstrm)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ UWORD16 u2_payload_bits = 0;
+ UWORD8 u1_payload_bytes = 0;
+
+ if(ps_sei_sii == NULL)
+ {
+ return IH264E_FAIL;
+ }
+
+ if(0 == ps_sei_sii->u4_sii_sub_layer_idx)
+ {
+ u2_payload_bits += 1; /* shutter interval info present flag */
+
+ if(1 == ps_sei_sii->u1_shutter_interval_info_present_flag)
+ {
+ u2_payload_bits += 32; /* sii time scale */
+ u2_payload_bits += 1; /* fixed shutter interval within cvs flag */
+
+ if(1 == ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ u2_payload_bits += 32; /* sii num units in shutter interval */
+ }
+ else
+ {
+ int sizeofSubLayer;
+ u2_payload_bits += 3; /* sii max sub layers minus1 */
+ sizeofSubLayer =
+ sizeof(ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval) /
+ sizeof(ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval[0]);
+ u2_payload_bits +=
+ 32 * sizeofSubLayer; /* sii sub layer num units in shutter interval */
+ }
+ }
+ }
+
+ u1_payload_bytes = (UWORD8) ((u2_payload_bits + 7) >> 3);
+ /************************************************************************/
+ /* PayloadSize : This is the size of the payload in bytes */
+ /************************************************************************/
+ PUT_BITS(ps_bitstrm, u1_payload_bytes, 8, return_status, "u1_payload_bytes");
+
+ /*******************************************************************************/
+ /* Put the Shutter Interval Info SEI parameters into the bitstream. */
+ /*******************************************************************************/
+
+ PUT_BITS_UEV(ps_bitstrm, ps_sei_sii->u4_sii_sub_layer_idx, return_status,
+ "u4_sii_sub_layer_idx");
+
+ if(0 == ps_sei_sii->u4_sii_sub_layer_idx)
+ {
+ PUT_BITS(ps_bitstrm, ps_sei_sii->u1_shutter_interval_info_present_flag, 1, return_status,
+ "u1_shutter_interval_info_present_flag");
+
+ if(1 == ps_sei_sii->u1_shutter_interval_info_present_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_sei_sii->u4_sii_time_scale, 32, return_status,
+ "u4_sii_time_scale");
+ PUT_BITS(ps_bitstrm, ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag, 1,
+ return_status, "u1_fixed_shutter_interval_within_cvs_flag");
+
+ if(1 == ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_sei_sii->u4_sii_num_units_in_shutter_interval, 32,
+ return_status, "u4_sii_num_units_in_shutter_interval");
+ }
+ else
+ {
+ int i;
+ PUT_BITS(ps_bitstrm, ps_sei_sii->u1_sii_max_sub_layers_minus1, 3, return_status,
+ "u1_sii_max_sub_layers_minus1");
+
+ for(i = 0; i <= ps_sei_sii->u1_sii_max_sub_layers_minus1; i++)
+ {
+ PUT_BITS(ps_bitstrm, ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval[i],
+ 32, return_status, "au4_sub_layer_num_units_in_shutter_interval[i]");
+ }
+ }
+ }
+ }
+ return (return_status);
+}
+
+/**
+******************************************************************************
+*
* @brief Generates SEI (Supplemental Enhancement Information )
*
* @par Description
@@ -433,6 +536,11 @@ IH264E_ERROR_T ih264e_put_sei_msg(IH264_SEI_TYPE e_payload_type,
ps_bitstrm);
break;
+ case IH264_SEI_SHUTTER_INTERVAL_INFO:
+ return_status = ih264e_put_sei_sii_params(&(ps_sei_params->s_sei_sii_params), ps_bitstrm);
+
+ break;
+
default :
return_status = IH264E_FAIL;
}
diff --git a/encoder/ih264e_sei.h b/encoder/ih264e_sei.h
index a5b1d9d..d31f728 100644
--- a/encoder/ih264e_sei.h
+++ b/encoder/ih264e_sei.h
@@ -49,8 +49,8 @@ typedef enum
IH264_SEI_MASTERING_DISP_COL_VOL = 137,
IH264_SEI_CONTENT_LIGHT_LEVEL_DATA = 144,
IH264_SEI_AMBIENT_VIEWING_ENVIRONMENT = 148,
- IH264_SEI_CONTENT_COLOR_VOLUME = 149
-
+ IH264_SEI_CONTENT_COLOR_VOLUME = 149,
+ IH264_SEI_SHUTTER_INTERVAL_INFO = 205
}IH264_SEI_TYPE;
/*****************************************************************************/
@@ -166,5 +166,24 @@ IH264E_ERROR_T ih264e_put_sei_msg(IH264_SEI_TYPE e_payload_type,
sei_params_t *ps_sei_params,
bitstrm_t *ps_bitstrm);
+/**
+******************************************************************************
+*
+* @brief Signal shutter interval info in the bitstream
+*
+* @par Description
+* Parse Supplemental Enhancement Information
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_sei_sii
+* pointer to shutter interval info
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T ih264e_put_sei_sii_params(sei_sii_params_t *ps_sei_sii, bitstrm_t *ps_bitstrm);
#endif /* ENCODER_IH264E_SEI_H_ */
diff --git a/encoder/ih264e_structs.h b/encoder/ih264e_structs.h
index 8674470..4c3f63f 100644
--- a/encoder/ih264e_structs.h
+++ b/encoder/ih264e_structs.h
@@ -312,6 +312,12 @@ typedef struct
/** SEI CCV params info */
sei_ccv_params_t s_sei_ccv;
+ /** SEI SII params flag */
+ UWORD8 u1_sei_sii_params_present_flag;
+
+ /** SEI SII params info */
+ sei_sii_params_t s_sei_sii;
+
}inp_buf_t;
typedef struct
@@ -369,9 +375,12 @@ typedef struct
/** Input color format */
IV_COLOR_FORMAT_T e_inp_color_fmt;
- /** Flag to enable/disable - To be used only for debugging/testing */
+ /** Flag to enable/disable recon */
UWORD32 u4_enable_recon;
+ /** Flag to enable/disable quality metrics */
+ UWORD32 u4_enable_quality_metrics;
+
/** Recon color format */
IV_COLOR_FORMAT_T e_recon_color_fmt;
@@ -627,6 +636,22 @@ typedef struct
/**
+ *****************************************************************************
+ * @brief Structure to store psnr of the sequence
+ *****************************************************************************
+ */
+typedef struct {
+ UWORD64 total_sse[3];
+ double global_psnr[3]; // total_sse / total_samples
+ double total_psnr[3]; // sum (per_frame_sse / per_frame_samples)
+ double avg_psnr[3]; // total_psnr / total_frames
+ UWORD32 total_samples[3];
+ WORD32 total_frames;
+} quality_stats_t;
+
+
+
+/**
* Structure to represent a MV Bank buffer
*/
typedef struct
@@ -669,6 +694,9 @@ typedef struct
*/
typedef struct
{
+ /** Per pic PSNR */
+ quality_stats_t s_pic_quality_stats;
+
/** Picture count */
WORD32 i4_pic_cnt;
@@ -2474,6 +2502,11 @@ struct _codec_t
void *apv_proc_thread_handle[MAX_PROCESS_THREADS];
/**
+ * Structure for global PSNR
+ */
+ quality_stats_t s_global_quality_stats;
+
+ /**
* Thread created flag for each of the processing threads
*/
WORD32 ai4_process_thread_created[MAX_PROCESS_THREADS];
diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c
index 239271e..d83b8be 100644
--- a/encoder/ih264e_utils.c
+++ b/encoder/ih264e_utils.c
@@ -70,6 +70,7 @@
#include "ime_distortion_metrics.h"
#include "ime_defs.h"
#include "ime_structs.h"
+#include "psnr.h"
#include "ih264_error.h"
#include "ih264_structs.h"
#include "ih264_trans_quant_itrans_iquant.h"
@@ -251,6 +252,10 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec,
ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag;
ps_inp_buf->s_sei_ccv = ps_codec->s_cfg.s_sei.s_sei_ccv_params;
+ ps_inp_buf->u1_sei_sii_params_present_flag =
+ ps_codec->s_cfg.s_sei.u1_sei_sii_params_present_flag;
+ ps_inp_buf->s_sei_sii = ps_codec->s_cfg.s_sei.s_sei_sii_params;
+
/***************************************************************************
* Now we should add the picture to RC stack here
**************************************************************************/
@@ -360,6 +365,8 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec,
ps_enc_buff->u1_sei_ccv_params_present_flag = ps_inp_buf->u1_sei_ccv_params_present_flag;
ps_enc_buff->s_sei_ccv = ps_inp_buf->s_sei_ccv;
+ ps_enc_buff->u1_sei_sii_params_present_flag = ps_inp_buf->u1_sei_sii_params_present_flag;
+ ps_enc_buff->s_sei_sii = ps_inp_buf->s_sei_sii;
/* Special case for encoding trailing B frames
*
@@ -2204,3 +2211,77 @@ IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf)
return error_status;
}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Calculate the per-pic and global PSNR
+*
+* @par Description:
+* This function takes the source and recon luma/chroma buffer pointers from the
+* codec context and calculates the per-pic and global PSNR for the current encoding
+* frame.
+*
+* @param[in] ps_codec
+* Pointer to process context
+*
+* @returns none
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+void ih264e_compute_quality_stats(process_ctxt_t *ps_proc)
+{
+ codec_t *ps_codec = ps_proc->ps_codec;
+ WORD32 wd = ps_codec->s_cfg.u4_wd;
+ WORD32 ht = ps_codec->s_cfg.u4_ht;
+ WORD32 disp_wd = ps_codec->s_cfg.u4_disp_wd;
+ WORD32 disp_ht = ps_codec->s_cfg.u4_disp_ht;
+ WORD32 src_strds = ps_proc->i4_src_strd;
+ WORD32 rec_strds = ps_proc->i4_rec_strd;
+ quality_stats_t *ps_pic_quality_stats = NULL;
+ double sum_squared_error[3] = {0.0, 0.0, 0.0};
+ double total_samples[3];
+ WORD32 i;
+ for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if (ps_codec->as_ref_set[i].i4_pic_cnt != -1 &&
+ ps_codec->as_ref_set[i].i4_poc == ps_codec->i4_poc)
+ {
+ ps_pic_quality_stats = &ps_codec->as_ref_set[i].s_pic_quality_stats;
+ break;
+ }
+ }
+
+ if(ps_pic_quality_stats == NULL) return;
+
+ get_sse(
+ ps_proc->pu1_src_buf_luma_base, ps_proc->pu1_rec_buf_luma_base,
+ ps_proc->pu1_src_buf_chroma_base, ps_proc->pu1_rec_buf_chroma_base,
+ src_strds, rec_strds, wd, ht, sum_squared_error);
+
+ total_samples[0] = disp_wd * disp_ht;
+ total_samples[1] = total_samples[2] = total_samples[0] / 4;
+
+ ps_pic_quality_stats->total_frames = 1;
+ ps_codec->s_global_quality_stats.total_frames += 1;
+ for (i = 0; i < 3; i++)
+ {
+ double psnr = sse_to_psnr(total_samples[i], sum_squared_error[i]);
+ ps_pic_quality_stats->total_samples[i] = total_samples[i];
+ ps_pic_quality_stats->total_sse[i] = sum_squared_error[i];
+ ps_pic_quality_stats->global_psnr[i] = ps_pic_quality_stats->avg_psnr[i] =
+ ps_pic_quality_stats->total_psnr[i] = psnr;
+ ps_codec->s_global_quality_stats.total_sse[i] += sum_squared_error[i];
+ ps_codec->s_global_quality_stats.global_psnr[i] =
+ sse_to_psnr(ps_codec->s_global_quality_stats.total_samples[i],
+ ps_codec->s_global_quality_stats.total_sse[i]);
+ ps_codec->s_global_quality_stats.total_psnr[i] += psnr;
+ ps_codec->s_global_quality_stats.avg_psnr[i] =
+ ps_codec->s_global_quality_stats.total_psnr[i] /
+ ps_codec->s_global_quality_stats.total_frames;
+ }
+}
diff --git a/encoder/irc_rate_control_api_structs.h b/encoder/irc_rate_control_api_structs.h
index ba39e7f..3248c74 100644
--- a/encoder/irc_rate_control_api_structs.h
+++ b/encoder/irc_rate_control_api_structs.h
@@ -16,7 +16,7 @@
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
-*/
+ */
#ifndef _RATE_CONTROL_API_STRUCTS_H_
#define _RATE_CONTROL_API_STRUCTS_H_
@@ -74,7 +74,9 @@ typedef struct rate_control_api_t
UWORD8 u1_is_first_frm;
- UWORD8 au1_min_max_qp[(MAX_PIC_TYPE << 1)];
+ UWORD8 au1_min_max_qp[MAX_PIC_TYPE * 2];
+
+ UWORD8 au1_min_max_avc_qp[MAX_PIC_TYPE * 2];
WORD32 i4_prev_frm_est_bits;
@@ -89,5 +91,4 @@ typedef struct rate_control_api_t
} rate_control_api_t;
-#endif/*_RATE_CONTROL_API_STRUCTS_H_*/
-
+#endif /*_RATE_CONTROL_API_STRUCTS_H_*/
diff --git a/encoder/ive2.h b/encoder/ive2.h
index f3f1bd9..2ba0ec8 100644
--- a/encoder/ive2.h
+++ b/encoder/ive2.h
@@ -149,6 +149,7 @@ typedef enum
IVE_CMD_CTL_SET_SEI_CLL_PARAMS = 0xD1,
IVE_CMD_CTL_SET_SEI_AVE_PARAMS = 0xD2,
IVE_CMD_CTL_SET_SEI_CCV_PARAMS = 0xD3,
+ IVE_CMD_CTL_SET_SEI_SII_PARAMS = 0xD4,
IVE_CMD_CTL_CODEC_SUBCMD_START = 0x100,
}IVE_CONTROL_API_COMMAND_TYPE_T;
@@ -250,6 +251,8 @@ typedef enum
IVE_ERR_OP_CTL_SET_SEI_AVE_STRUCT_SIZE_INCORRECT = 0x47,
IVE_ERR_IP_CTL_SET_SEI_CCV_STRUCT_SIZE_INCORRECT = 0x48,
IVE_ERR_OP_CTL_SET_SEI_CCV_STRUCT_SIZE_INCORRECT = 0x49,
+ IVE_ERR_IP_CTL_SET_SEI_SII_STRUCT_SIZE_INCORRECT = 0x4A,
+ IVE_ERR_OP_CTL_SET_SEI_SII_STRUCT_SIZE_INCORRECT = 0x4B,
}IVE_ERROR_CODES_T;
diff --git a/encoder/libavcenc.cmake b/encoder/libavcenc.cmake
index b948a6e..cf7be9c 100644
--- a/encoder/libavcenc.cmake
+++ b/encoder/libavcenc.cmake
@@ -39,7 +39,8 @@ list(
"${AVC_ROOT}/encoder/irc_rate_control_api.c"
"${AVC_ROOT}/encoder/irc_rd_model.c"
"${AVC_ROOT}/encoder/irc_vbr_storage_vbv.c"
- "${AVC_ROOT}/encoder/irc_vbr_str_prms.c")
+ "${AVC_ROOT}/encoder/irc_vbr_str_prms.c"
+ "${AVC_ROOT}/encoder/psnr.c")
include_directories(${AVC_ROOT}/encoder)
diff --git a/encoder/psnr.c b/encoder/psnr.c
new file mode 100644
index 0000000..5f53a1f
--- /dev/null
+++ b/encoder/psnr.c
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************/
+
+/* System Include Files */
+#include <math.h>
+
+#include "ih264_macros.h"
+#include "ih264_typedefs.h"
+#include "psnr.h"
+
+void get_sse(UWORD8 *pu1_src_luma, UWORD8 *pu1_rec_luma, UWORD8 *pu1_src_chroma,
+ UWORD8 *pu1_rec_chroma, WORD32 src_strd, WORD32 rec_strd, WORD32 width, WORD32 height,
+ DOUBLE pd_sse[3])
+{
+ WORD32 i, j;
+
+ for(j = 0; j < height; j++)
+ {
+ for(i = 0; i < width; i++)
+ {
+ WORD32 diff = pu1_src_luma[i] - pu1_rec_luma[i];
+ pd_sse[0] += diff * diff;
+ }
+ pu1_src_luma += src_strd;
+ pu1_rec_luma += rec_strd;
+ }
+
+ for(j = 0; j < height / 2; j++)
+ {
+ for(i = 0; i < width / 2; i++)
+ {
+ WORD32 diff = pu1_src_chroma[i * 2] - pu1_rec_chroma[i * 2];
+ pd_sse[1] += diff * diff;
+ diff = pu1_src_chroma[i * 2 + 1] - pu1_rec_chroma[i * 2 + 1];
+ pd_sse[2] += diff * diff;
+ }
+ pu1_src_chroma += src_strd;
+ pu1_rec_chroma += rec_strd;
+ }
+}
+
+DOUBLE sse_to_psnr(DOUBLE samples, DOUBLE sse)
+{
+ DOUBLE psnr;
+ if(samples <= 0) return -1;
+ if (sse<=0) return MAX_PSNR;
+ psnr = 10.0 * (log10(samples) + 2*log10(255) - log10(sse));
+ psnr = MIN(MAX_PSNR, psnr);
+ return psnr;
+}
diff --git a/encoder/psnr.h b/encoder/psnr.h
new file mode 100644
index 0000000..546dd0d
--- /dev/null
+++ b/encoder/psnr.h
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************/
+
+#ifndef __PSNR_H__
+#define __PSNR_H__
+
+#define MAX_PSNR 100.0
+
+void get_sse(UWORD8 *pu1_src_luma, UWORD8 *pu1_rec_luma, UWORD8 *pu1_src_chroma,
+ UWORD8 *pu1_rec_chroma, WORD32 src_strd, WORD32 rec_strd, WORD32 width, WORD32 height,
+ DOUBLE *pd_sse);
+
+DOUBLE sse_to_psnr(DOUBLE samples, DOUBLE sse);
+
+#endif
diff --git a/encoder/mips/ih264e_function_selector.c b/encoder/riscv/ih264e_function_selector.c
index 980a744..14b2082 100644
--- a/encoder/mips/ih264e_function_selector.c
+++ b/encoder/riscv/ih264e_function_selector.c
@@ -108,4 +108,3 @@ IV_ARCH_T ih264e_default_arch(void)
{
return ARCH_NA;
}
-
diff --git a/encoder/mips/ih264e_platform_macros.h b/encoder/riscv/ih264e_platform_macros.h
index ed1edd4..002500b 100644
--- a/encoder/mips/ih264e_platform_macros.h
+++ b/encoder/riscv/ih264e_platform_macros.h
@@ -38,7 +38,6 @@
#ifndef IH264E_PLATFORM_MACROS_H_
#define IH264E_PLATFORM_MACROS_H_
-#define DATA_SYNC()
/*****************************************************************************/
/* Extern Function Declarations */
/*****************************************************************************/
diff --git a/encoder/mips/ime_platform_macros.h b/encoder/riscv/ime_platform_macros.h
index 18e2e8f..18e2e8f 100644
--- a/encoder/mips/ime_platform_macros.h
+++ b/encoder/riscv/ime_platform_macros.h
diff --git a/encoder/riscv/svc/isvce_function_selector.c b/encoder/riscv/svc/isvce_function_selector.c
new file mode 100644
index 0000000..8030a45
--- /dev/null
+++ b/encoder/riscv/svc/isvce_function_selector.c
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in svc
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvce_platform_macros.h"
+#include "isvce_structs.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(isvce_codec_t *ps_codec) { isvce_init_function_ptr_generic(ps_codec); }
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void) { return ARCH_NA; }
diff --git a/encoder/riscv/svc/isvce_platform_macros.h b/encoder/riscv/svc/isvce_platform_macros.h
new file mode 100644
index 0000000..06ba25d
--- /dev/null
+++ b/encoder/riscv/svc/isvce_platform_macros.h
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvce_platform_macros.h
+ *
+ * @brief
+ * Contains platform specific routines used for codec context intialization
+ *
+ * @author
+ * ittiam
+ *
+ * @remarks
+ * none
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCE_PLATFORM_MACROS_H_
+#define _ISVCE_PLATFORM_MACROS_H_
+
+#include "isvce_structs.h"
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_generic(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void);
+
+#endif
diff --git a/encoder/svc/irc_svc_rate_control_api.c b/encoder/svc/irc_svc_rate_control_api.c
new file mode 100644
index 0000000..a2e9453
--- /dev/null
+++ b/encoder/svc/irc_svc_rate_control_api.c
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include "stdio.h"
+
+/* User include files */
+#include "irc_datatypes.h"
+#include "irc_common.h"
+#include "irc_cntrl_param.h"
+#include "irc_mem_req_and_acq.h"
+#include "irc_rd_model.h"
+#include "irc_est_sad.h"
+#include "irc_fixed_point_error_bits.h"
+#include "irc_vbr_storage_vbv.h"
+#include "irc_picture_type.h"
+#include "irc_bit_allocation.h"
+#include "irc_mb_model_based.h"
+#include "irc_cbr_buffer_control.h"
+#include "irc_vbr_str_prms.h"
+#include "irc_rate_control_api.h"
+#include "irc_rate_control_api_structs.h"
+#include "irc_trace_support.h"
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+#define DEV_Q 4 /*Q format(Shift) for Deviation range factor */
+#define HI_DEV_FCTR 22 /* 1.4*16 */
+#define LO_DEV_FCTR 12 /* 0.75*16 */
+#define GET_HI_DEV_QP(Qprev) ((((WORD32) Qprev) * HI_DEV_FCTR + (1 << (DEV_Q - 1))) >> DEV_Q)
+#define GET_LO_DEV_QP(Qprev) ((((WORD32) Qprev) * LO_DEV_FCTR + (1 << (DEV_Q - 1))) >> DEV_Q)
+#define CLIP_QP(Qc, hi_d, lo_d) (((Qc) < (lo_d)) ? ((lo_d)) : (((Qc) > (hi_d)) ? (hi_d) : (Qc)))
+
+/*******************************************************************************
+ * Description : Gets the frame level qp for the given picture type
+ * based on bits per pixel and gradient per pixel
+ ******************************************************************************/
+/* Get frame level QP based on BPP and GPP */
+UWORD8 irc_get_frame_level_init_qp(rate_control_handle *ps_rate_control_api, rc_type_e e_rc_type,
+ picture_type_e e_pic_type, DOUBLE d_bpp, DOUBLE d_gpp)
+{
+ DOUBLE d_frame_qp;
+
+ UWORD8 u1_min_qp =
+ ((rate_control_api_t *) (ps_rate_control_api))->au1_min_max_avc_qp[(e_pic_type << 1)];
+ UWORD8 u1_max_qp =
+ ((rate_control_api_t *) (ps_rate_control_api))->au1_min_max_avc_qp[(e_pic_type << 1) + 1];
+
+ if((e_rc_type != VBR_STORAGE) && (e_rc_type != VBR_STORAGE_DVD_COMP) &&
+ (e_rc_type != CBR_NLDRC) && (e_rc_type != CONST_QP) && (e_rc_type != VBR_STREAMING))
+ {
+ trace_printf(
+ (const WORD8 *) (const WORD8 *) " Only VBR,NLDRC and CONST QP supported for now \n");
+ return (0);
+ }
+
+ if(d_bpp <= 0.18)
+ {
+ d_frame_qp = 43.49 + (0.59 * d_gpp) - (106.45 * d_bpp);
+ }
+ else if(d_bpp <= 0.6)
+ {
+ d_frame_qp = 25.12 + (0.69 * d_gpp) - (29.23 * (d_bpp - 0.18));
+ }
+ else
+ {
+ d_frame_qp = 13.93 + (0.74 * d_gpp) - (18.4 * (d_bpp - 0.6));
+ }
+
+ /* Truncating the QP to the Max and Min Qp values possible */
+ if(d_frame_qp < u1_min_qp) d_frame_qp = u1_min_qp;
+ if(d_frame_qp > u1_max_qp) d_frame_qp = u1_max_qp;
+
+ return ((UWORD8) (d_frame_qp + 0.5));
+}
+
+void irc_change_qp_constraints(rate_control_api_t *ps_rate_control_api, UWORD8 *pu1_min_max_qp,
+ UWORD8 *pu1_min_max_avc_qp)
+{
+ WORD32 i;
+
+ for(i = 0; i < MAX_PIC_TYPE; i++)
+ {
+ ps_rate_control_api->au1_min_max_qp[(i << 1)] = pu1_min_max_qp[(i << 1)];
+ ps_rate_control_api->au1_min_max_qp[(i << 1) + 1] = pu1_min_max_qp[(i << 1) + 1];
+ ps_rate_control_api->au1_min_max_avc_qp[(i << 1)] = pu1_min_max_avc_qp[(i << 1)];
+ ps_rate_control_api->au1_min_max_avc_qp[(i << 1) + 1] = pu1_min_max_avc_qp[(i << 1) + 1];
+ }
+}
+
+UWORD8 irc_is_scenecut(rate_control_api_t *ps_rate_control_api)
+{
+ return ((rate_control_api_t *) (ps_rate_control_api))->u1_scd_detected;
+}
diff --git a/encoder/svc/irc_svc_rate_control_api.h b/encoder/svc/irc_svc_rate_control_api.h
new file mode 100644
index 0000000..7400b3d
--- /dev/null
+++ b/encoder/svc/irc_svc_rate_control_api.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _IRC_SVC_RATE_CONTROL_API_H_
+#define _IRC_SVC_RATE_CONTROL_API_H_
+
+/* Dependencies of 'irc_rate_control_api_structs' */
+#include "irc_picture_type.h"
+#include "irc_rd_model.h"
+#include "irc_vbr_storage_vbv.h"
+#include "irc_est_sad.h"
+#include "irc_bit_allocation.h"
+#include "irc_mb_model_based.h"
+#include "irc_cbr_buffer_control.h"
+#include "irc_vbr_str_prms.h"
+#include "irc_common.h"
+
+#include "irc_rate_control_api_structs.h"
+
+/* Get frame level QP based on BPP and GPP */
+UWORD8 irc_get_frame_level_init_qp(rate_control_api_t *ps_rate_control_api, rc_type_e e_rc_type,
+ picture_type_e e_pic_type, DOUBLE d_bpp, DOUBLE d_gpp);
+
+void irc_change_qp_constraints(rate_control_api_t *ps_rate_control_api, UWORD8 *pu1_min_max_qp,
+ UWORD8 *pu1_min_max_avc_qp);
+
+extern UWORD8 irc_is_scenecut(rate_control_api_t *ps_rate_control_api);
+
+#endif
diff --git a/encoder/svc/isvce.h b/encoder/svc/isvce.h
new file mode 100644
index 0000000..9b914a7
--- /dev/null
+++ b/encoder/svc/isvce.h
@@ -0,0 +1,1023 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*****************************************************************************/
+/* */
+/* File Name : isvce.h */
+/* */
+/* Description : This file contains all the necessary structure and */
+/* enumeration definitions needed for the Application */
+/* Program Interface(API) of the Ittiam SVC Encoder */
+/* */
+/* List of Functions : isvce_api_function */
+/* */
+/*****************************************************************************/
+
+#ifndef _ISVCE_H_
+#define _ISVCE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdbool.h>
+
+#include "iv2.h"
+#include "ive2.h"
+
+ /*****************************************************************************/
+ /* Enums */
+ /*****************************************************************************/
+ typedef enum ISVCE_API_COMMAND_TYPE_T
+ {
+ ISVCE_CMD_VIDEO_NA = 0x7FFFFFFF,
+ ISVCE_CMD_GET_NUM_MEM_REC = 0x0,
+ ISVCE_CMD_FILL_NUM_MEM_REC = 0x1,
+ ISVCE_CMD_RETRIEVE_MEMREC = 0x2,
+ ISVCE_CMD_INIT = 0x3,
+ ISVCE_CMD_EXTENSIONS = 0x100,
+ ISVCE_CMD_VIDEO_CTL,
+ ISVCE_CMD_VIDEO_ENCODE
+ } ISVCE_API_COMMAND_TYPE_T;
+
+ typedef enum ISVCE_CONTROL_API_COMMAND_TYPE_T
+ {
+ ISVCE_CMD_CT_NA = 0x7FFFFFFF,
+ ISVCE_CMD_CTL_SETDEFAULT = 0x0,
+ ISVCE_CMD_CTL_SET_DIMENSIONS = 0x1,
+ ISVCE_CMD_CTL_SET_FRAMERATE = 0x2,
+ ISVCE_CMD_CTL_SET_BITRATE = 0x3,
+ ISVCE_CMD_CTL_SET_FRAMETYPE = 0x4,
+ ISVCE_CMD_CTL_SET_QP = 0x5,
+ ISVCE_CMD_CTL_SET_ENC_MODE = 0x6,
+ ISVCE_CMD_CTL_SET_VBV_PARAMS = 0x7,
+ ISVCE_CMD_CTL_SET_AIR_PARAMS = 0x8,
+ ISVCE_CMD_CTL_SET_ME_PARAMS = 0X9,
+ ISVCE_CMD_CTL_SET_GOP_PARAMS = 0XA,
+ ISVCE_CMD_CTL_SET_PROFILE_PARAMS = 0XB,
+ ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS = 0XC,
+ ISVCE_CMD_CTL_SET_IPE_PARAMS = 0XD,
+ ISVCE_CMD_CTL_SET_VUI_PARAMS = 0XE,
+ ISVCE_CMD_CTL_SET_NUM_CORES = 0x30,
+ ISVCE_CMD_CTL_RESET = 0xA0,
+ ISVCE_CMD_CTL_FLUSH = 0xB0,
+ ISVCE_CMD_CTL_GETBUFINFO = 0xC0,
+ ISVCE_CMD_CTL_GETVERSION = 0xC1,
+ ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS = 0xD0,
+ ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS = 0xD1,
+ ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS = 0xD2,
+ ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS = 0xD3,
+ ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS = 0xE1
+ } ISVCE_CONTROL_API_COMMAND_TYPE_T;
+
+ /*****************************************************************************/
+ /* Extended Structures */
+ /*****************************************************************************/
+
+ /*****************************************************************************/
+ /* Get Number of Memory Records */
+ /*****************************************************************************/
+ typedef struct svc_inp_params_t
+ {
+ /**
+ * Num Temporal Layers
+ */
+ UWORD8 u1_num_temporal_layers;
+
+ /**
+ * Num Spatial Layers
+ */
+ UWORD8 u1_num_spatial_layers;
+
+ /**
+ * Resolution ration b/w spatial layers
+ */
+ DOUBLE d_spatial_res_ratio;
+
+ } svc_inp_params_t;
+
+ typedef struct isvce_num_mem_rec_ip_t
+ {
+ iv_num_mem_rec_ip_t s_ive_ip;
+ } isvce_num_mem_rec_ip_t;
+
+ typedef struct isvce_num_mem_rec_op_t
+ {
+ iv_num_mem_rec_op_t s_ive_op;
+ } isvce_num_mem_rec_op_t;
+
+ /*****************************************************************************/
+ /* Fill Memory Records */
+ /*****************************************************************************/
+
+ typedef struct isvce_fill_mem_rec_ip_t
+ {
+ iv_fill_mem_rec_ip_t s_ive_ip;
+
+ svc_inp_params_t s_svc_inp_params;
+
+ UWORD32 u4_wd;
+
+ UWORD32 u4_ht;
+
+ } isvce_fill_mem_rec_ip_t;
+
+ typedef struct isvce_fill_mem_rec_op_t
+ {
+ iv_fill_mem_rec_op_t s_ive_op;
+ } isvce_fill_mem_rec_op_t;
+
+ /*****************************************************************************/
+ /* Retrieve Memory Records */
+ /*****************************************************************************/
+
+ typedef struct isvce_retrieve_mem_rec_ip_t
+ {
+ iv_retrieve_mem_rec_ip_t s_ive_ip;
+ } isvce_retrieve_mem_rec_ip_t;
+
+ typedef struct isvce_retrieve_mem_rec_op_t
+ {
+ iv_retrieve_mem_rec_op_t s_ive_op;
+ } isvce_retrieve_mem_rec_op_t;
+
+ /*****************************************************************************/
+ /* Initialize encoder */
+ /*****************************************************************************/
+
+ typedef struct isvce_init_ip_t
+ {
+ ive_init_ip_t s_ive_ip;
+
+ svc_inp_params_t s_svc_inp_params;
+
+ UWORD32 *pu4_max_bitrate;
+
+ UWORD32 u4_wd;
+
+ UWORD32 u4_ht;
+
+ bool b_use_default_vui;
+
+ bool b_nalu_info_export_enable;
+
+ } isvce_init_ip_t;
+
+ typedef struct isvce_init_op_t
+ {
+ ive_init_op_t s_ive_op;
+ } isvce_init_op_t;
+
+ /*****************************************************************************/
+ /* Video control Flush */
+ /*****************************************************************************/
+
+ typedef struct isvce_ctl_flush_ip_t
+ {
+ ive_ctl_flush_ip_t s_ive_ip;
+ } isvce_ctl_flush_ip_t;
+
+ typedef struct isvce_ctl_flush_op_t
+ {
+ ive_ctl_flush_op_t s_ive_op;
+ } isvce_ctl_flush_op_t;
+
+ /*****************************************************************************/
+ /* Video control reset */
+ /*****************************************************************************/
+
+ typedef struct isvce_ctl_reset_ip_t
+ {
+ ive_ctl_reset_ip_t s_ive_ip;
+ } isvce_ctl_reset_ip_t;
+
+ typedef struct isvce_ctl_reset_op_t
+ {
+ ive_ctl_reset_op_t s_ive_op;
+ } isvce_ctl_reset_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Get Buf Info */
+ /*****************************************************************************/
+
+ typedef struct isvce_ctl_getbufinfo_ip_t
+ {
+ ive_ctl_getbufinfo_ip_t s_ive_ip;
+ } isvce_ctl_getbufinfo_ip_t;
+
+ typedef struct isvce_ctl_getbufinfo_op_t
+ {
+ ive_ctl_getbufinfo_op_t s_ive_op;
+
+ UWORD32 au4_min_rec_buf_size[IVE_MAX_IO_BUFFER_COMPONENTS];
+
+ UWORD32 u4_rec_comp_cnt;
+
+ UWORD32 u4_min_rec_bufs;
+
+ UWORD32 u4_min_nalu_info_bufs;
+
+ UWORD32 u4_min_nalu_info_buf_size;
+ } isvce_ctl_getbufinfo_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Get Version Info */
+ /*****************************************************************************/
+
+ typedef struct isvce_ctl_getversioninfo_ip_t
+ {
+ ive_ctl_getversioninfo_ip_t s_ive_ip;
+ } isvce_ctl_getversioninfo_ip_t;
+
+ typedef struct isvce_ctl_getversioninfo_op_t
+ {
+ ive_ctl_getversioninfo_op_t s_ive_op;
+ } isvce_ctl_getversioninfo_op_t;
+
+ /*****************************************************************************/
+ /* Video control:Set default params */
+ /*****************************************************************************/
+
+ typedef struct isvce_ctl_setdefault_ip_t
+ {
+ ive_ctl_setdefault_ip_t s_ive_ip;
+ } isvce_ctl_setdefault_ip_t;
+
+ typedef struct isvce_ctl_setdefault_op_t
+ {
+ ive_ctl_setdefault_op_t s_ive_op;
+ } isvce_ctl_setdefault_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set IPE params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_ipe_params_ip_t
+ {
+ ive_ctl_set_ipe_params_ip_t s_ive_ip;
+ } isvce_ctl_set_ipe_params_ip_t;
+
+ typedef struct isvce_ctl_set_ipe_params_op_t
+ {
+ ive_ctl_set_ipe_params_op_t s_ive_op;
+ } isvce_ctl_set_ipe_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Frame dimensions */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_dimensions_ip_t
+ {
+ ive_ctl_set_dimensions_ip_t s_ive_ip;
+ } isvce_ctl_set_dimensions_ip_t;
+
+ typedef struct isvce_ctl_set_dimensions_op_t
+ {
+ ive_ctl_set_dimensions_op_t s_ive_op;
+ } isvce_ctl_set_dimensions_op_t;
+
+ /* Video control - Get Enc Frame dimensions */
+ typedef struct isvce_ctl_get_enc_dimensions_ip_t
+ {
+ UWORD32 u4_inp_frame_wd;
+
+ UWORD32 u4_inp_frame_ht;
+ } isvce_ctl_get_enc_dimensions_ip_t;
+
+ typedef struct isvce_ctl_get_enc_dimensions_op_t
+ {
+ UWORD32 u4_error_code;
+
+ UWORD32 u4_enc_frame_wd;
+
+ UWORD32 u4_enc_frame_ht;
+
+ } isvce_ctl_get_enc_dimensions_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Frame rates */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_frame_rate_ip_t
+ {
+ ive_ctl_set_frame_rate_ip_t s_ive_ip;
+ } isvce_ctl_set_frame_rate_ip_t;
+
+ typedef struct isvce_ctl_set_frame_rate_op_t
+ {
+ ive_ctl_set_frame_rate_op_t s_ive_op;
+ } isvce_ctl_set_frame_rate_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Bitrate */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_bitrate_ip_t
+ {
+ ive_ctl_set_bitrate_ip_t s_ive_ip;
+
+ UWORD32 *pu4_target_bitrate;
+ } isvce_ctl_set_bitrate_ip_t;
+
+ typedef struct isvce_ctl_set_bitrate_op_t
+ {
+ ive_ctl_set_bitrate_op_t s_ive_op;
+ } isvce_ctl_set_bitrate_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Frame type */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_frame_type_ip_t
+ {
+ ive_ctl_set_frame_type_ip_t s_ive_ip;
+ } isvce_ctl_set_frame_type_ip_t;
+
+ typedef struct isvce_ctl_set_frame_type_op_t
+ {
+ ive_ctl_set_frame_type_op_t s_ive_op;
+ } isvce_ctl_set_frame_type_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Encode mode */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_enc_mode_ip_t
+ {
+ ive_ctl_set_enc_mode_ip_t s_ive_ip;
+ } isvce_ctl_set_enc_mode_ip_t;
+
+ typedef struct isvce_ctl_set_enc_mode_op_t
+ {
+ ive_ctl_set_enc_mode_op_t s_ive_op;
+ } isvce_ctl_set_enc_mode_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set QP */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_qp_ip_t
+ {
+ ive_ctl_set_qp_ip_t s_ive_ip;
+
+ UWORD32 *pu4_i_qp;
+
+ UWORD32 *pu4_i_qp_max;
+
+ UWORD32 *pu4_i_qp_min;
+
+ UWORD32 *pu4_p_qp;
+
+ UWORD32 *pu4_p_qp_max;
+
+ UWORD32 *pu4_p_qp_min;
+
+ UWORD32 *pu4_b_qp;
+
+ UWORD32 *pu4_b_qp_max;
+
+ UWORD32 *pu4_b_qp_min;
+
+ } isvce_ctl_set_qp_ip_t;
+
+ typedef struct isvce_ctl_set_qp_op_t
+ {
+ ive_ctl_set_qp_op_t s_ive_op;
+ } isvce_ctl_set_qp_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set AIR params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_air_params_ip_t
+ {
+ ive_ctl_set_air_params_ip_t s_ive_ip;
+ } isvce_ctl_set_air_params_ip_t;
+
+ typedef struct isvce_ctl_set_air_params_op_t
+ {
+ ive_ctl_set_air_params_op_t s_ive_op;
+ } isvce_ctl_set_air_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set VBV params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_vbv_params_ip_t
+ {
+ ive_ctl_set_vbv_params_ip_t s_ive_ip;
+
+ UWORD32 *pu4_vbv_buffer_delay;
+ } isvce_ctl_set_vbv_params_ip_t;
+
+ typedef struct isvce_ctl_set_vbv_params_op_t
+ {
+ ive_ctl_set_vbv_params_op_t s_ive_op;
+ } isvce_ctl_set_vbv_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Processor Details */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_num_cores_ip_t
+ {
+ ive_ctl_set_num_cores_ip_t s_ive_ip;
+ } isvce_ctl_set_num_cores_ip_t;
+
+ typedef struct isvce_ctl_set_num_cores_op_t
+ {
+ ive_ctl_set_num_cores_op_t s_ive_op;
+ } isvce_ctl_set_num_cores_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Motion estimation params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_me_params_ip_t
+ {
+ ive_ctl_set_me_params_ip_t s_ive_ip;
+ } isvce_ctl_set_me_params_ip_t;
+
+ typedef struct isvce_ctl_set_me_params_op_t
+ {
+ ive_ctl_set_me_params_op_t s_ive_op;
+ } isvce_ctl_set_me_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set GOP params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_gop_params_ip_t
+ {
+ ive_ctl_set_gop_params_ip_t s_ive_ip;
+ } isvce_ctl_set_gop_params_ip_t;
+
+ typedef struct isvce_ctl_set_gop_params_op_t
+ {
+ ive_ctl_set_gop_params_op_t s_ive_op;
+ } isvce_ctl_set_gop_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Deblock params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_deblock_params_ip_t
+ {
+ ive_ctl_set_deblock_params_ip_t s_ive_ip;
+ } isvce_ctl_set_deblock_params_ip_t;
+
+ typedef struct isvce_ctl_set_deblock_params_op_t
+ {
+ ive_ctl_set_deblock_params_op_t s_ive_op;
+ } isvce_ctl_set_deblock_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set Profile params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_profile_params_ip_t
+ {
+ ive_ctl_set_profile_params_ip_t s_ive_ip;
+ } isvce_ctl_set_profile_params_ip_t;
+
+ typedef struct isvce_ctl_set_profile_params_op_t
+ {
+ ive_ctl_set_profile_params_op_t s_ive_op;
+ } isvce_ctl_set_profile_params_op_t;
+
+ /*****************************************************************************/
+ /* Synchronous video encode call */
+ /*****************************************************************************/
+ typedef struct isvce_nalu_info_buf_t
+ {
+ /* For each NALU, following info will be copied as a csv string - */
+ /* 'type,length,SId,TID,isIDR,isFirstSliceInLayer,isLastSliceInLayer' */
+ UWORD8 *pu1_buf;
+
+ UWORD32 u4_num_bytes;
+
+ UWORD32 u4_buf_size;
+ } isvce_nalu_info_buf_t;
+
+ typedef struct isvce_video_encode_ip_t
+ {
+ ive_video_encode_ip_t s_ive_ip;
+
+ isvce_nalu_info_buf_t *ps_nalu_info_buf;
+
+ } isvce_video_encode_ip_t;
+
+ typedef struct isvce_video_encode_op_t
+ {
+ ive_video_encode_op_t s_ive_op;
+
+ bool b_is_nalu_info_present;
+
+ isvce_nalu_info_buf_t *ps_nalu_info_buf;
+
+ } isvce_video_encode_op_t;
+
+ /*****************************************************************************/
+ /* Video usability information */
+ /*****************************************************************************/
+ typedef struct isvce_vui_ip_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : ISVCE_CMD_VIDEO_CTL */
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : ISVCE_CMD_CTL_SET_GOP_PARAMS */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /** indicates the presence of aspect_ratio */
+ UWORD8 u1_aspect_ratio_info_present_flag;
+
+ /** specifies the aspect ratio of the luma samples */
+ UWORD8 u1_aspect_ratio_idc;
+
+ /** width of the luma samples. user dependent */
+ UWORD16 u2_sar_width;
+
+ /** Height of the luma samples. user dependent */
+ UWORD16 u2_sar_height;
+
+ /** if 1, specifies that the overscan_appropriate_flag is present
+ * if 0, the preferred display method for the video signal is unspecified */
+ UWORD8 u1_overscan_info_present_flag;
+
+ /** if 1,indicates that the cropped decoded pictures output
+ * are suitable for display using overscan */
+ UWORD8 u1_overscan_appropriate_flag;
+
+ /** if 1 specifies that video_format, video_full_range_flag and
+ * colour_description_present_flag are present */
+ UWORD8 u1_video_signal_type_present_flag;
+
+ /** pal, secam, ntsc, ... */
+ UWORD8 u1_video_format;
+
+ /** indicates the black level and range of the luma and chroma signals */
+ UWORD8 u1_video_full_range_flag;
+
+ /** if 1,specifies that colour_primaries, transfer_characteristics
+ * and matrix_coefficients are present */
+ UWORD8 u1_colour_description_present_flag;
+
+ /** indicates the chromaticity coordinates of the source primaries */
+ UWORD8 u1_colour_primaries;
+
+ /** indicates the opto-electronic transfer characteristic of the source picture */
+ UWORD8 u1_transfer_characteristics;
+
+ /** the matrix coefficients used in deriving luma and chroma signals
+ * from the green, blue, and red primaries */
+ UWORD8 u1_matrix_coefficients;
+
+ /** if 1, specifies that chroma_sample_loc_type_top_field and
+ * chroma_sample_loc_type_bottom_field are present */
+ UWORD8 u1_chroma_loc_info_present_flag;
+
+ /** location of chroma samples */
+ UWORD8 u1_chroma_sample_loc_type_top_field;
+
+ UWORD8 u1_chroma_sample_loc_type_bottom_field;
+
+ /** Indicates the presence of the num_units_in_ticks, time_scale flag */
+ UWORD8 u1_vui_timing_info_present_flag;
+
+ /** Number of units that correspond to one increment of the
+ * clock. Indicates the resolution */
+ UWORD32 u4_vui_num_units_in_tick;
+
+ /** The number of time units that pass in one second */
+ UWORD32 u4_vui_time_scale;
+
+ /** Flag indicating that time difference between two frames is a constant */
+ UWORD8 u1_fixed_frame_rate_flag;
+
+ /** Indicates the presence of NAL HRD parameters */
+ UWORD8 u1_nal_hrd_parameters_present_flag;
+
+ /** Indicates the presence of VCL HRD parameters */
+ UWORD8 u1_vcl_hrd_parameters_present_flag;
+
+ /** Specifies the HRD operational mode */
+ UWORD8 u1_low_delay_hrd_flag;
+
+ /** Indicates presence of SEI messages which include pic_struct syntax element */
+ UWORD8 u1_pic_struct_present_flag;
+
+ /** 1, specifies that the following cvs bitstream restriction parameters are present */
+ UWORD8 u1_bitstream_restriction_flag;
+
+ /** if 0, indicates that no pel outside the pic boundaries and
+ * no sub-pels derived using pels outside the pic boundaries is used for inter prediction */
+ UWORD8 u1_motion_vectors_over_pic_boundaries_flag;
+
+ /** Indicates a number of bytes not exceeded by the sum of the sizes of the VCL NAL units
+ * associated with any coded picture */
+ UWORD8 u1_max_bytes_per_pic_denom;
+
+ /** Indicates an upper bound for the number of bits of coding_unit() data */
+ UWORD8 u1_max_bits_per_mb_denom;
+
+ /** Indicate the maximum absolute value of a decoded horizontal MV component
+ * in quarter-pel luma units */
+ UWORD8 u1_log2_max_mv_length_horizontal;
+
+ /** Indicate the maximum absolute value of a decoded vertical MV component
+ * in quarter-pel luma units */
+ UWORD8 u1_log2_max_mv_length_vertical;
+
+ /** Max number of frames that are not synchronized in display and decode order */
+ UWORD8 u1_num_reorder_frames;
+
+ /** specifies required size of the HRD DPB in units of frame buffers */
+ UWORD8 u1_max_dec_frame_buffering;
+
+ } isvce_vui_ip_t;
+
+ typedef struct isvce_vui_op_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+ } isvce_vui_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set SEI MDCV params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_sei_mdcv_params_ip_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : ISVCE_CMD_VIDEO_CTL */
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /** mastering display color volume info present flag */
+ UWORD8 u1_sei_mdcv_params_present_flag;
+
+ /** Array to store the display_primaries_x values */
+ UWORD16 au2_display_primaries_x[3];
+
+ /** Array to store the display_primaries_y values */
+ UWORD16 au2_display_primaries_y[3];
+
+ /** Variable to store the white point x value */
+ UWORD16 u2_white_point_x;
+
+ /** Variable to store the white point y value */
+ UWORD16 u2_white_point_y;
+
+ /** Variable to store the max display mastering luminance value */
+ UWORD32 u4_max_display_mastering_luminance;
+
+ /** Variable to store the min display mastering luminance value */
+ UWORD32 u4_min_display_mastering_luminance;
+
+ /** Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+ } isvce_ctl_set_sei_mdcv_params_ip_t;
+
+ typedef struct isvce_ctl_set_sei_mdcv_params_op_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+
+ } isvce_ctl_set_sei_mdcv_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set SEI CLL params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_sei_cll_params_ip_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : ISVCE_CMD_VIDEO_CTL */
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /** content light level info present flag */
+ UWORD8 u1_sei_cll_params_present_flag;
+
+ /** The maximum pixel intensity of all samples */
+ UWORD16 u2_max_content_light_level;
+
+ /** The average pixel intensity of all samples */
+ UWORD16 u2_max_pic_average_light_level;
+
+ /** Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+ } isvce_ctl_set_sei_cll_params_ip_t;
+
+ typedef struct isvce_ctl_set_sei_cll_params_op_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+
+ } isvce_ctl_set_sei_cll_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set SEI AVE params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_sei_ave_params_ip_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : ISVCE_CMD_VIDEO_CTL */
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /** ambient viewing environment info present flag */
+ UWORD8 u1_sei_ave_params_present_flag;
+
+ /** specifies the environmental illluminance of the ambient viewing
+ * environment */
+ UWORD32 u4_ambient_illuminance;
+
+ /** specify the normalized x chromaticity coordinates of the
+ * environmental ambient light in the nominal viewing environment */
+ UWORD16 u2_ambient_light_x;
+
+ /** specify the normalized y chromaticity coordinates of the
+ * environmental ambient light in the nominal viewing environment */
+ UWORD16 u2_ambient_light_y;
+
+ /** Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+ } isvce_ctl_set_sei_ave_params_ip_t;
+
+ typedef struct isvce_ctl_set_sei_ave_params_op_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+
+ } isvce_ctl_set_sei_ave_params_op_t;
+
+ /*****************************************************************************/
+ /* Video control Set SEI CCV params */
+ /*****************************************************************************/
+ typedef struct isvce_ctl_set_sei_ccv_params_ip_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Command type : ISVCE_CMD_VIDEO_CTL */
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ /** Sub command type : ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd;
+
+ /** content color volume info present flag */
+ UWORD8 u1_sei_ccv_params_present_flag;
+
+ /** Flag used to control persistence of CCV SEI messages */
+ UWORD8 u1_ccv_cancel_flag;
+
+ /** specifies the persistence of the CCV SEI message for the
+ * current layer */
+ UWORD8 u1_ccv_persistence_flag;
+
+ /** specifies the presence of syntax elements ccv_primaries_x
+ * and ccv_primaries_y */
+ UWORD8 u1_ccv_primaries_present_flag;
+
+ /** specifies that the syntax element ccv_min_luminance_value
+ * is present */
+ UWORD8 u1_ccv_min_luminance_value_present_flag;
+
+ /** specifies that the syntax element ccv_max_luminance_value
+ * is present */
+ UWORD8 u1_ccv_max_luminance_value_present_flag;
+
+ /** specifies that the syntax element ccv_avg_luminance_value
+ * is present */
+ UWORD8 u1_ccv_avg_luminance_value_present_flag;
+
+ /** shall be equal to 0 in bitstreams conforming to this version.
+ * Other values for reserved_zero_2bits are reserved for future use */
+ UWORD8 u1_ccv_reserved_zero_2bits;
+
+ /** specify the normalized x chromaticity coordinates of the colour
+ * primary component c of the nominal content colour volume */
+ WORD32 ai4_ccv_primaries_x[3];
+
+ /** specify the normalized y chromaticity coordinates of the colour
+ * primary component c of the nominal content colour volume */
+ WORD32 ai4_ccv_primaries_y[3];
+
+ /** specifies the normalized minimum luminance value */
+ UWORD32 u4_ccv_min_luminance_value;
+
+ /** specifies the normalized maximum luminance value */
+ UWORD32 u4_ccv_max_luminance_value;
+
+ /** specifies the normalized average luminance value */
+ UWORD32 u4_ccv_avg_luminance_value;
+
+ /** Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+ } isvce_ctl_set_sei_ccv_params_ip_t;
+
+ typedef struct isvce_ctl_set_sei_ccv_params_op_t
+ {
+ /** size of the structure */
+ UWORD32 u4_size;
+
+ /** Return error code */
+ UWORD32 u4_error_code;
+
+ } isvce_ctl_set_sei_ccv_params_op_t;
+
+ /* The enum values should not have greater than 8 bits as this is assigned to WORD8 */
+ typedef enum IV_MB_TYPE_T
+ {
+ INTRA16x16 = 0,
+ INTRA4x4,
+ INTER16x16
+ } IV_MB_TYPE_T;
+
+ /*****************************************************************************/
+ /* Pic info structures */
+ /*****************************************************************************/
+ typedef struct isvce_pic_info1_t
+ {
+ /** Qp */
+ UWORD32 u4_qp;
+
+ /** Pic Type */
+ IV_PICTURE_CODING_TYPE_T e_frame_type;
+
+ } isvce_pic_info1_t;
+
+ /*****************************************************************************/
+ /* MB info structures */
+ /*****************************************************************************/
+ typedef struct isvce_mv_t
+ {
+ /** MV X */
+ WORD16 i2_mv_x;
+
+ /** MV Y */
+ WORD16 i2_mv_y;
+ } isvce_mv_t;
+
+ typedef struct isvce_mb_info1_t
+ {
+ /** Intra / Inter */
+ WORD8 i1_mb_type;
+
+ union
+ {
+ isvce_mv_t as_mv[1];
+
+ /** Intra mode */
+ WORD8 ai1_intra_mode[1];
+ };
+ } isvce_mb_info1_t;
+
+ typedef struct isvce_mb_info2_t
+ {
+ /** Intra / Inter */
+ WORD8 i1_mb_type;
+
+ /** SAD */
+ UWORD16 u2_sad;
+
+ union
+ {
+ isvce_mv_t as_mv[1];
+
+ /** Intra mode */
+ WORD8 ai1_intra_mode[1];
+ };
+
+ } isvce_mb_info2_t;
+
+ typedef struct isvce_mb_info3_t
+ {
+ /** Intra / Inter */
+ WORD8 i1_mb_type;
+
+ union
+ {
+ isvce_mv_t as_mv[4];
+
+ /** Intra mode */
+ WORD8 ai1_intra_mode[16];
+ };
+
+ } isvce_mb_info3_t;
+
+ typedef struct isvce_mb_info4_t
+ {
+ /** Intra / Inter */
+ WORD8 i1_mb_type;
+
+ /** Intra Mode */
+ WORD8 i1_intra_mode;
+
+ /** SAD */
+ UWORD16 u2_sad;
+
+ union
+ {
+ isvce_mv_t as_mv[16];
+
+ /** Intra mode */
+ WORD8 ai1_intra_mode[16];
+ };
+
+ } isvce_mb_info4_t;
+
+ /* Add any new structures to the following union. It is used to calculate the
+ * max size needed for allocation of memory */
+ typedef struct isvce_api_mb_info_t
+ {
+ union
+ {
+ isvce_mb_info1_t s_mb_info1;
+ isvce_mb_info2_t s_mb_info2;
+ isvce_mb_info3_t s_mb_info3;
+ isvce_mb_info4_t s_mb_info4;
+ };
+ } isvce_api_mb_info_t;
+
+ typedef struct isvce_pic_info2_t
+ {
+ /** Qp */
+ UWORD32 u4_qp;
+
+ /** Pic Type */
+ IV_PICTURE_CODING_TYPE_T e_frame_type;
+
+ /** Disable deblock level (0: Enable completely, 3: Disable completely */
+ UWORD32 u4_disable_deblock_level;
+
+ } isvce_pic_info2_t;
+
+ typedef struct isvce_api_cmds_t
+ {
+ ISVCE_API_COMMAND_TYPE_T e_cmd;
+
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_ctl_cmd;
+ } isvce_api_cmds_t;
+
+ extern IV_STATUS_T isvce_api_function(iv_obj_t *ps_handle, void *pv_api_ip, void *pv_api_op,
+ isvce_api_cmds_t *ps_iv_api_cmds);
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+
+#endif
diff --git a/encoder/svc/isvce_api.c b/encoder/svc/isvce_api.c
new file mode 100644
index 0000000..8900995
--- /dev/null
+++ b/encoder/svc/isvce_api.c
@@ -0,0 +1,6052 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_api.c
+*
+* @brief
+* Contains api function definitions for H264 encoder
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - api_check_struct_sanity()
+* - isvce_codec_update_config()
+* - isvce_set_default_params()
+* - isvce_init()
+* - isvce_get_num_rec()
+* - isvce_fill_num_mem_rec()
+* - isvce_init_mem_rec()
+* - isvce_retrieve_memrec()
+* - isvce_set_flush_mode()
+* - isvce_get_buf_info()
+* - isvce_set_dimensions()
+* - isvce_set_frame_rate()
+* - isvce_set_bit_rate()
+* - isvce_set_frame_type()
+* - isvce_set_qp()
+* - isvce_set_enc_mode()
+* - isvce_set_vbv_params()
+* - isvc_set_air_params()
+* - isvc_set_me_params()
+* - isvc_set_ipe_params()
+* - isvc_set_gop_params()
+* - isvc_set_profile_params()
+* - isvc_set_deblock_params()
+* - isvce_set_num_cores()
+* - isvce_reset()
+* - isvce_ctl()
+* - isvce_api_function()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+/* Dependencies of ih264_buf_mgr.h */
+/* Dependencies of ih264_list.h */
+#include "ih264_error.h"
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_common_tables.h"
+#include "ih264_dpb_mgr.h"
+#include "ih264_list.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+/* Dependencies of ih264e_structs.h */
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ime_statistics.h"
+#include "ime_structs.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_defs.h"
+#include "ih264e_rc_mem_interface.h"
+#include "ih264e_structs.h"
+#include "ih264e_utils.h"
+#include "ih264e_version.h"
+#include "ime.h"
+#include "isvce.h"
+#include "isvce_cabac.h"
+#include "isvce_deblk.h"
+#include "isvce_defs.h"
+#include "isvce_downscaler.h"
+#include "isvce_encode.h"
+#include "isvce_encode_header.h"
+#include "isvce_ibl_eval.h"
+#include "isvce_ilp_mv.h"
+#include "isvce_intra_modes_eval.h"
+#include "isvce_me.h"
+#include "isvce_platform_macros.h"
+#include "isvce_rate_control.h"
+#include "isvce_rc_mem_interface.h"
+#include "isvce_residual_pred.h"
+#include "isvce_sub_pic_rc.h"
+#include "isvce_utils.h"
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* Used to test arguments for corresponding API call
+*
+* @par Description:
+* For each command the arguments are validated
+*
+* @param[in] ps_handle
+* Codec handle at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input structure
+*
+* @param[out] pv_api_op
+* Pointer to output structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, void *pv_api_ip, void *pv_api_op,
+ isvce_api_cmds_t *ps_iv_api_cmds)
+{
+ WORD32 i, j;
+
+ /* output structure expected by the api call */
+ UWORD32 *pu4_api_op = pv_api_op;
+
+ ISVCE_API_COMMAND_TYPE_T e_cmd = ps_iv_api_cmds->e_cmd;
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_ctl_cmd = ps_iv_api_cmds->e_ctl_cmd;
+
+ if(NULL == pv_api_op || NULL == pv_api_ip)
+ {
+ return (IV_FAIL);
+ }
+
+ /* set error code */
+ pu4_api_op[1] = 0;
+
+ /* error checks on handle */
+ switch(e_cmd)
+ {
+ case ISVCE_CMD_GET_NUM_MEM_REC:
+ case ISVCE_CMD_FILL_NUM_MEM_REC:
+ {
+ break;
+ }
+
+ case ISVCE_CMD_INIT:
+ {
+ if(ps_handle == NULL)
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->u4_size != sizeof(iv_obj_t))
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_RETRIEVE_MEMREC:
+ case ISVCE_CMD_VIDEO_CTL:
+ case ISVCE_CMD_VIDEO_ENCODE:
+ {
+ if(ps_handle == NULL)
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->u4_size != sizeof(iv_obj_t))
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->pv_fxns != isvce_api_function)
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_API_FUNCTION_PTR_NULL;
+ return IV_FAIL;
+ }
+
+ if(ps_handle->pv_codec_handle == NULL)
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_INVALID_CODEC_HANDLE;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ default:
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD;
+
+ return IV_FAIL;
+ }
+ }
+
+ /* error checks on input output structures */
+ switch(e_cmd)
+ {
+ case ISVCE_CMD_GET_NUM_MEM_REC:
+ {
+ isvce_num_mem_rec_ip_t *ps_ip = pv_api_ip;
+ isvce_num_mem_rec_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_num_mem_rec_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_IP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_num_mem_rec_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_FILL_NUM_MEM_REC:
+ {
+ isvce_fill_mem_rec_ip_t *ps_ip = pv_api_ip;
+ isvce_fill_mem_rec_op_t *ps_op = pv_api_op;
+
+ iv_mem_rec_t *ps_mem_rec = NULL;
+
+ WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
+ WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_fill_mem_rec_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_IP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_fill_mem_rec_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(max_wd < MIN_WD || max_wd > MAX_WD)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(max_ht < MIN_HT || max_ht > MAX_HT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ /* verify number of mem rec ptr */
+ if(NULL == ps_ip->s_ive_ip.ps_mem_rec)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
+ return (IV_FAIL);
+ }
+
+ /* verify number of mem records */
+ if(ps_ip->s_ive_ip.u4_num_mem_rec != ISVCE_MEM_REC_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT;
+ return IV_FAIL;
+ }
+
+ /* check mem records sizes are correct */
+ ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
+ for(i = 0; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_INIT:
+ {
+ isvce_init_ip_t *ps_ip = pv_api_ip;
+ isvce_init_op_t *ps_op = pv_api_op;
+
+ iv_mem_rec_t *ps_mem_rec = NULL;
+
+ WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
+ WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
+ WORD32 wd = ALIGN16(ps_ip->u4_wd);
+ WORD32 ht = ALIGN16(ps_ip->u4_ht);
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_init_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_IP_INIT_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_init_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_INIT_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(max_wd < MIN_WD || max_wd > MAX_WD)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(max_ht < MIN_HT || max_ht > MAX_HT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_PIC_CNT ||
+ ps_ip->s_ive_ip.u4_max_ref_cnt < MIN_REF_PIC_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_reorder_cnt != 0)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if((ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_10) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_1B) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_11) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_12) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_13) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_20) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_21) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_22) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_30) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_31) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_32) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_40) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_41) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_42) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_50) &&
+ (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_51))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420P)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_RECON_CHROMA_FORMAT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if((ps_ip->s_ive_ip.e_rc_mode != IVE_RC_NONE) &&
+ (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_STORAGE) &&
+ (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_CBR_NON_LOW_DELAY))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_RATE_CONTROL_MODE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_framerate > DEFAULT_MAX_FRAMERATE)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_FRAME_RATE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ for(i = 0; i < ps_ip->s_svc_inp_params.u1_num_spatial_layers; i++)
+ {
+ if(ps_ip->pu4_max_bitrate[i] > DEFAULT_MAX_BITRATE)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_BITRATE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+ }
+
+ if(ps_ip->s_ive_ip.u4_num_bframes > SVC_MAX_NUM_BFRAMES)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_num_bframes && (ps_ip->s_ive_ip.u4_max_ref_cnt < 2))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.e_content_type != IV_PROGRESSIVE)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_CONTENT_TYPE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_srch_rng_x > DEFAULT_MAX_SRCH_RANGE_X)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_srch_rng_y > DEFAULT_MAX_SRCH_RANGE_Y)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_NONE)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_SLICE_TYPE_INPUT_INVALID;
+ return (IV_FAIL);
+ }
+
+ if(NULL == ps_ip->s_ive_ip.ps_mem_rec)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
+ return (IV_FAIL);
+ }
+
+ /* verify number of mem records */
+ if(ps_ip->s_ive_ip.u4_num_mem_rec != ISVCE_MEM_REC_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT;
+ return (IV_FAIL);
+ }
+
+ ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
+
+ /* check memrecords sizes are correct */
+ for(i = 0; i < ((WORD32) ps_ip->s_ive_ip.u4_num_mem_rec); i++)
+ {
+ if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ /* check memrecords pointers are not NULL */
+ if(ps_mem_rec[i].pv_base == NULL)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_BASE_POINTER_NULL;
+ return IV_FAIL;
+ }
+ }
+
+ /* verify memtabs for overlapping regions */
+ {
+ void *start[ISVCE_MEM_REC_CNT];
+ void *end[ISVCE_MEM_REC_CNT];
+
+ start[0] = (ps_mem_rec[0].pv_base);
+ end[0] = ((UWORD8 *) ps_mem_rec[0].pv_base) + ps_mem_rec[0].u4_mem_size - 1;
+
+ for(i = 1; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ /* This array is populated to check memtab overlap */
+ start[i] = (ps_mem_rec[i].pv_base);
+ end[i] = ((UWORD8 *) ps_mem_rec[i].pv_base) + ps_mem_rec[i].u4_mem_size - 1;
+
+ for(j = 0; j < i; j++)
+ {
+ if((start[i] >= start[j]) && (start[i] <= end[j]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_OVERLAP_ERR;
+ return IV_FAIL;
+ }
+
+ if((end[i] >= start[j]) && (end[i] <= end[j]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_OVERLAP_ERR;
+ return IV_FAIL;
+ }
+
+ if((start[i] < start[j]) && (end[i] > end[j]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_OVERLAP_ERR;
+ return IV_FAIL;
+ }
+ }
+ }
+ }
+
+ /* re-validate mem records with init config */
+ {
+ /* mem records */
+ iv_mem_rec_t s_mem_rec_ittiam_api[ISVCE_MEM_REC_CNT];
+
+ /* api interface structs */
+ isvce_fill_mem_rec_ip_t s_ip;
+ isvce_fill_mem_rec_op_t s_op;
+
+ /* error status */
+ IV_STATUS_T e_status;
+
+ /* temp var */
+ WORD32 i;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_FILL_NUM_MEM_REC, ISVCE_CMD_CT_NA};
+
+ s_ip.s_ive_ip.u4_size = sizeof(isvce_fill_mem_rec_ip_t);
+ s_op.s_ive_op.u4_size = sizeof(isvce_fill_mem_rec_op_t);
+
+ s_ip.s_ive_ip.ps_mem_rec = s_mem_rec_ittiam_api;
+ s_ip.s_ive_ip.u4_max_wd = max_wd;
+ s_ip.s_ive_ip.u4_max_ht = max_ht;
+ s_ip.u4_wd = wd;
+ s_ip.u4_ht = ht;
+ s_ip.s_ive_ip.u4_num_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec;
+ s_ip.s_ive_ip.u4_max_level = ps_ip->s_ive_ip.u4_max_level;
+ s_ip.s_ive_ip.u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;
+ s_ip.s_ive_ip.u4_max_reorder_cnt = ps_ip->s_ive_ip.u4_max_reorder_cnt;
+ s_ip.s_ive_ip.e_color_format = ps_ip->s_ive_ip.e_inp_color_fmt;
+ s_ip.s_ive_ip.u4_max_srch_rng_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
+ s_ip.s_ive_ip.u4_max_srch_rng_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
+
+ s_ip.s_svc_inp_params = ps_ip->s_svc_inp_params;
+
+ for(i = 0; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ s_mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t);
+ }
+
+ /* fill mem records */
+ e_status = isvce_api_function(NULL, (void *) &s_ip, (void *) &s_op, &s_api_cmds);
+
+ if(IV_FAIL == e_status)
+ {
+ ps_op->s_ive_op.u4_error_code = s_op.s_ive_op.u4_error_code;
+ return (IV_FAIL);
+ }
+
+ /* verify mem records */
+ for(i = 0; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ if(ps_mem_rec[i].u4_mem_size < s_mem_rec_ittiam_api[i].u4_mem_size)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_INSUFFICIENT_SIZE;
+
+ return IV_FAIL;
+ }
+
+ if(ps_mem_rec[i].u4_mem_alignment != s_mem_rec_ittiam_api[i].u4_mem_alignment)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_ALIGNMENT_ERR;
+
+ return IV_FAIL;
+ }
+
+ if(ps_mem_rec[i].e_mem_type != s_mem_rec_ittiam_api[i].e_mem_type)
+ {
+ UWORD32 check = IV_SUCCESS;
+ UWORD32 diff =
+ s_mem_rec_ittiam_api[i].e_mem_type - ps_mem_rec[i].e_mem_type;
+
+ if((ps_mem_rec[i].e_mem_type <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM) &&
+ (s_mem_rec_ittiam_api[i].e_mem_type >=
+ IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM))
+ {
+ check = IV_FAIL;
+ }
+
+ if(3 != (s_mem_rec_ittiam_api[i].e_mem_type % 4))
+ {
+ /* It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or
+ * IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM */
+
+ if((diff < 1) || (diff > 3))
+ {
+ /* Difference between 1 and 3 is okay for all cases other than
+ * the two filtered with the MOD condition above */
+ check = IV_FAIL;
+ }
+ }
+ else
+ {
+ if(diff == 1)
+ {
+ /* This particular case is when codec asked for External
+ * Persistent, but got Internal Scratch */
+ check = IV_FAIL;
+ }
+ if((diff != 2) && (diff != 3))
+ {
+ check = IV_FAIL;
+ }
+ }
+
+ if(check == IV_FAIL)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_INCORRECT_TYPE;
+
+ return IV_FAIL;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_RETRIEVE_MEMREC:
+ {
+ isvce_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip;
+ isvce_retrieve_mem_rec_op_t *ps_op = pv_api_op;
+
+ iv_mem_rec_t *ps_mem_rec = NULL;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_retrieve_mem_rec_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_retrieve_mem_rec_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(NULL == ps_ip->s_ive_ip.ps_mem_rec)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
+ return (IV_FAIL);
+ }
+
+ ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
+
+ /* check memrecords sizes are correct */
+ for(i = 0; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_VIDEO_ENCODE:
+ {
+ isvce_video_encode_ip_t *ps_ip = pv_api_ip;
+ isvce_video_encode_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_video_encode_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_IP_ENCODE_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_video_encode_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_VIDEO_CTL:
+ {
+ switch(e_ctl_cmd)
+ {
+ case ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS:
+ {
+ break;
+ }
+ case ISVCE_CMD_CTL_SETDEFAULT:
+ {
+ isvce_ctl_setdefault_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_setdefault_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_setdefault_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_setdefault_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_GETBUFINFO:
+ {
+ isvce_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_getbufinfo_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_getbufinfo_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_getbufinfo_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_wd < MIN_WD)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_ht < MIN_HT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) &&
+ (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE) &&
+ (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV) &&
+ (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_GETVERSION:
+ {
+ isvce_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_getversioninfo_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_getversioninfo_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_getversioninfo_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.pu1_version == NULL)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IVE_ERR_CTL_GET_VERSION_BUFFER_IS_NULL;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_FLUSH:
+ {
+ isvce_ctl_flush_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_flush_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_flush_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_flush_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_RESET:
+ {
+ isvce_ctl_reset_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_reset_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_reset_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_RESET_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_reset_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_RESET_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_NUM_CORES:
+ {
+ isvce_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_num_cores_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_num_cores_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_num_cores_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_num_cores < 1) ||
+ (ps_ip->s_ive_ip.u4_num_cores > MAX_NUM_CORES))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_NUM_CORES;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_DIMENSIONS:
+ {
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_handle->pv_codec_handle);
+
+ isvce_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_dimensions_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_dimensions_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_dimensions_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_wd < MIN_WD)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_wd > ps_codec->s_cfg.u4_max_wd)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_ht < MIN_HT)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_ht > ps_codec->s_cfg.u4_max_ht)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_wd & 1)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_ht & 1)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_FRAMERATE:
+ {
+ isvce_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_frame_rate_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_frame_rate_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_frame_rate_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(((ps_ip->s_ive_ip.u4_src_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE) ||
+ ((ps_ip->s_ive_ip.u4_tgt_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_FRAME_RATE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if((ps_ip->s_ive_ip.u4_src_frame_rate == 0) ||
+ (ps_ip->s_ive_ip.u4_tgt_frame_rate == 0))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_FRAME_RATE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_tgt_frame_rate > ps_ip->s_ive_ip.u4_src_frame_rate)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IH264E_TGT_FRAME_RATE_EXCEEDS_SRC_FRAME_RATE;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_BITRATE:
+ {
+ isvce_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_bitrate_op_t *ps_op = pv_api_op;
+
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_handle->pv_codec_handle);
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_bitrate_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_bitrate_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ if((ps_ip->pu4_target_bitrate[i] > DEFAULT_MAX_BITRATE) ||
+ (ps_ip->pu4_target_bitrate[i] == 0))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_BITRATE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_FRAMETYPE:
+ {
+ isvce_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_frame_type_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_frame_type_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_frame_type_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.e_frame_type != IV_I_FRAME) &&
+ (ps_ip->s_ive_ip.e_frame_type != IV_P_FRAME) &&
+ (ps_ip->s_ive_ip.e_frame_type != IV_IDR_FRAME))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_FORCE_FRAME_INPUT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_ME_PARAMS:
+ {
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_handle->pv_codec_handle);
+
+ isvce_ctl_set_me_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_me_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_me_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_me_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_ME_SPEED_PRESET;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_enable_hpel != 0) &&
+ (ps_ip->s_ive_ip.u4_enable_hpel != 1))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_HALFPEL_OPTION;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_enable_qpel != 0) &&
+ (ps_ip->s_ive_ip.u4_enable_qpel != 1))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_QPEL_OPTION;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_enable_fast_sad != 0))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_FAST_SAD_OPTION;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_enable_alt_ref > 0)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_ALT_REF_OPTION;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_srch_rng_x > ps_codec->s_cfg.u4_max_srch_rng_x)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ if(ps_ip->s_ive_ip.u4_srch_rng_y > ps_codec->s_cfg.u4_max_srch_rng_y)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED;
+ return (IV_FAIL);
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_IPE_PARAMS:
+ {
+ isvce_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_ipe_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_ipe_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_ipe_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_enable_intra_4x4 != 0) &&
+ (ps_ip->s_ive_ip.u4_enable_intra_4x4 != 1))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INTRA4x4_OPTION;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG) &&
+ (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST) &&
+ (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL) &&
+ (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FAST) &&
+ (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_HIGH_SPEED) &&
+ (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FASTEST))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_ENC_SPEED_PRESET;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_GOP_PARAMS:
+ {
+ isvce_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_gop_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_gop_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_gop_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_i_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) ||
+ (ps_ip->s_ive_ip.u4_i_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INTRA_FRAME_INTERVAL;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_idr_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) ||
+ (ps_ip->s_ive_ip.u4_idr_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_IDR_FRAME_INTERVAL;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS:
+ {
+ isvce_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_deblock_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_deblock_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_0) &&
+ (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_2) &&
+ (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_3) &&
+ (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_4))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_DEBLOCKING_TYPE_INPUT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_QP:
+ {
+ isvce_ctl_set_qp_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_qp_op_t *ps_op = pv_api_op;
+
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_handle->pv_codec_handle);
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_qp_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_qp_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ if((ps_ip->pu4_i_qp_max[i] > MAX_H264_QP) ||
+ (ps_ip->pu4_p_qp_max[i] > MAX_H264_QP) ||
+ (ps_ip->pu4_b_qp_max[i] > MAX_H264_QP))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_MAX_FRAME_QP;
+ return IV_FAIL;
+ }
+
+ /* We donot support QP < 4 */
+ if((((WORD32) ps_ip->pu4_i_qp_min[i]) < MIN_H264_QP) ||
+ ((WORD32) ps_ip->pu4_p_qp_min[i] < MIN_H264_QP) ||
+ (((WORD32) ps_ip->pu4_b_qp_min[i]) < MIN_H264_QP) ||
+ (ps_ip->pu4_i_qp_min[i] > ps_ip->pu4_i_qp_max[i]) ||
+ (ps_ip->pu4_p_qp_min[i] > ps_ip->pu4_p_qp_max[i]) ||
+ (ps_ip->pu4_b_qp_min[i] > ps_ip->pu4_b_qp_max[i]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_MIN_FRAME_QP;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->pu4_i_qp[i] > ps_ip->pu4_i_qp_max[i]) ||
+ (ps_ip->pu4_p_qp[i] > ps_ip->pu4_p_qp_max[i]) ||
+ (ps_ip->pu4_b_qp[i] > ps_ip->pu4_b_qp_max[i]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->pu4_i_qp[i] < ps_ip->pu4_i_qp_min[i]) ||
+ (ps_ip->pu4_p_qp[i] < ps_ip->pu4_p_qp_min[i]) ||
+ (ps_ip->pu4_b_qp[i] < ps_ip->pu4_b_qp_min[i]))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_VUI_PARAMS:
+ {
+ isvce_vui_ip_t *ps_ip = pv_api_ip;
+ isvce_vui_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvce_vui_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_VUI_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvce_vui_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_VUI_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS:
+ {
+ isvce_ctl_set_sei_mdcv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_mdcv_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvce_ctl_set_sei_mdcv_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_SEI_MDCV_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvce_ctl_set_sei_mdcv_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_SEI_MDCV_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u1_sei_mdcv_params_present_flag != 0) &&
+ (ps_ip->u1_sei_mdcv_params_present_flag) != 1)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(1 == ps_ip->u1_sei_mdcv_params_present_flag)
+ {
+ /* Check values for u2_display_primaries_x and
+ * u2_display_primaries_y */
+ for(i = 0; i < 3; i++)
+ {
+ if((ps_ip->au2_display_primaries_x[i] >
+ DISPLAY_PRIMARIES_X_UPPER_LIMIT) ||
+ (ps_ip->au2_display_primaries_x[i] <
+ DISPLAY_PRIMARIES_X_LOWER_LIMIT) ||
+ ((ps_ip->au2_display_primaries_x[i] %
+ DISPLAY_PRIMARIES_X_DIVISION_FACTOR) != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->au2_display_primaries_y[i] >
+ DISPLAY_PRIMARIES_Y_UPPER_LIMIT) ||
+ (ps_ip->au2_display_primaries_y[i] <
+ DISPLAY_PRIMARIES_Y_LOWER_LIMIT) ||
+ ((ps_ip->au2_display_primaries_y[i] %
+ DISPLAY_PRIMARIES_Y_DIVISION_FACTOR) != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+
+ if((ps_ip->u2_white_point_x > WHITE_POINT_X_UPPER_LIMIT) ||
+ (ps_ip->u2_white_point_x < WHITE_POINT_X_LOWER_LIMIT) ||
+ ((ps_ip->u2_white_point_x % WHITE_POINT_X_DIVISION_FACTOR) != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u2_white_point_y > WHITE_POINT_Y_UPPER_LIMIT) ||
+ (ps_ip->u2_white_point_y < WHITE_POINT_Y_LOWER_LIMIT) ||
+ ((ps_ip->u2_white_point_y % WHITE_POINT_Y_DIVISION_FACTOR) != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u4_max_display_mastering_luminance >
+ MAX_DISPLAY_MASTERING_LUMINANCE_UPPER_LIMIT) ||
+ (ps_ip->u4_max_display_mastering_luminance <
+ MAX_DISPLAY_MASTERING_LUMINANCE_LOWER_LIMIT) ||
+ ((ps_ip->u4_max_display_mastering_luminance %
+ MAX_DISPLAY_MASTERING_LUMINANCE_DIVISION_FACTOR) != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u4_min_display_mastering_luminance >
+ MIN_DISPLAY_MASTERING_LUMINANCE_UPPER_LIMIT) ||
+ (ps_ip->u4_min_display_mastering_luminance <
+ MIN_DISPLAY_MASTERING_LUMINANCE_LOWER_LIMIT))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u4_max_display_mastering_luminance <=
+ ps_ip->u4_min_display_mastering_luminance)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_MDCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS:
+ {
+ isvce_ctl_set_sei_cll_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_cll_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvce_ctl_set_sei_cll_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_SEI_CLL_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvce_ctl_set_sei_cll_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_SEI_CLL_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u1_sei_cll_params_present_flag != 0) &&
+ (ps_ip->u1_sei_cll_params_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CLL_PARAMS;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS:
+ {
+ isvce_ctl_set_sei_ave_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_ave_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvce_ctl_set_sei_ave_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_SEI_AVE_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvce_ctl_set_sei_ave_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_SEI_AVE_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u1_sei_ave_params_present_flag != 0) &&
+ (ps_ip->u1_sei_ave_params_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_AVE_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(1 == ps_ip->u1_sei_ave_params_present_flag)
+ {
+ if((0 == ps_ip->u4_ambient_illuminance))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_AVE_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u2_ambient_light_x > AMBIENT_LIGHT_X_UPPER_LIMIT)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_AVE_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->u2_ambient_light_y > AMBIENT_LIGHT_Y_UPPER_LIMIT)
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_AVE_PARAMS;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS:
+ {
+ isvce_ctl_set_sei_ccv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_ccv_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->u4_size != sizeof(isvce_ctl_set_sei_ccv_params_ip_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_IP_CTL_SET_SEI_CCV_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->u4_size != sizeof(isvce_ctl_set_sei_ccv_params_op_t))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IVE_ERR_OP_CTL_SET_SEI_CCV_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u1_sei_ccv_params_present_flag != 0) &&
+ (ps_ip->u1_sei_ccv_params_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(1 == ps_ip->u1_sei_ccv_params_present_flag)
+ {
+ if((ps_ip->u1_ccv_cancel_flag != 0) && (ps_ip->u1_ccv_cancel_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(0 == ps_ip->u1_ccv_cancel_flag)
+ {
+ if((ps_ip->u1_ccv_persistence_flag != 0) &&
+ (ps_ip->u1_ccv_persistence_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ if((ps_ip->u1_ccv_primaries_present_flag != 0) &&
+ (ps_ip->u1_ccv_primaries_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ if((ps_ip->u1_ccv_min_luminance_value_present_flag != 0) &&
+ (ps_ip->u1_ccv_min_luminance_value_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ if((ps_ip->u1_ccv_max_luminance_value_present_flag != 0) &&
+ (ps_ip->u1_ccv_max_luminance_value_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ if((ps_ip->u1_ccv_avg_luminance_value_present_flag != 0) &&
+ (ps_ip->u1_ccv_avg_luminance_value_present_flag != 1))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ if((ps_ip->u1_ccv_primaries_present_flag == 0) &&
+ (ps_ip->u1_ccv_min_luminance_value_present_flag == 0) &&
+ (ps_ip->u1_ccv_max_luminance_value_present_flag == 0) &&
+ (ps_ip->u1_ccv_avg_luminance_value_present_flag == 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->u1_ccv_reserved_zero_2bits != 0))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if(1 == ps_ip->u1_ccv_primaries_present_flag)
+ {
+ for(i = 0; i < 3; i++)
+ {
+ if((ps_ip->ai4_ccv_primaries_x[i] >
+ CCV_PRIMARIES_X_UPPER_LIMIT) ||
+ (ps_ip->ai4_ccv_primaries_x[i] <
+ CCV_PRIMARIES_X_LOWER_LIMIT))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->ai4_ccv_primaries_y[i] >
+ CCV_PRIMARIES_Y_UPPER_LIMIT) ||
+ (ps_ip->ai4_ccv_primaries_y[i] <
+ CCV_PRIMARIES_Y_LOWER_LIMIT))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+ }
+
+ if((1 == ps_ip->u1_ccv_min_luminance_value_present_flag) &&
+ (1 == ps_ip->u1_ccv_avg_luminance_value_present_flag))
+ {
+ if((ps_ip->u4_ccv_avg_luminance_value <
+ ps_ip->u4_ccv_min_luminance_value))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+
+ if((1 == ps_ip->u1_ccv_min_luminance_value_present_flag) &&
+ (1 == ps_ip->u1_ccv_max_luminance_value_present_flag))
+ {
+ if((ps_ip->u4_ccv_max_luminance_value <
+ ps_ip->u4_ccv_min_luminance_value))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+ if((1 == ps_ip->u1_ccv_avg_luminance_value_present_flag) &&
+ (1 == ps_ip->u1_ccv_max_luminance_value_present_flag))
+ {
+ if((ps_ip->u4_ccv_max_luminance_value <
+ ps_ip->u4_ccv_avg_luminance_value))
+ {
+ ps_op->u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->u4_error_code |= IH264E_INVALID_SEI_CCV_PARAMS;
+ return IV_FAIL;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_ENC_MODE:
+ {
+ isvce_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_enc_mode_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_enc_mode_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_HEADER) &&
+ (ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_PICTURE))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_ENC_OPERATION_MODE;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_VBV_PARAMS:
+ {
+ isvce_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
+
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_handle->pv_codec_handle);
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_vbv_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_vbv_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ if((ps_ip->pu4_vbv_buffer_delay[i] < DEFAULT_MIN_BUFFER_DELAY) ||
+ (ps_ip->pu4_vbv_buffer_delay[i] > DEFAULT_MAX_BUFFER_DELAY))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_BUFFER_DELAY;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_AIR_PARAMS:
+ {
+ isvce_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_air_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_air_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_air_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if((ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE) &&
+ (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_CYCLIC) &&
+ (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_RANDOM))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_AIR_MODE;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_air_refresh_period == 0)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_AIR_REFRESH_PERIOD;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_PROFILE_PARAMS:
+ {
+ isvce_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_profile_params_op_t *ps_op = pv_api_op;
+
+ if(ps_ip->s_ive_ip.u4_size != sizeof(isvce_ctl_set_profile_params_ip_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_IP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_op->s_ive_op.u4_size != sizeof(isvce_ctl_set_profile_params_op_t))
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |=
+ IVE_ERR_OP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.e_profile != IV_PROFILE_BASE &&
+ ps_ip->s_ive_ip.e_profile != IV_PROFILE_MAIN)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_PROFILE_NOT_SUPPORTED;
+ return IV_FAIL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_entropy_coding_mode > 1)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_ENTROPY_CODING_MODE;
+ return IV_FAIL;
+ }
+
+ break;
+ }
+ default:
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_SUB_CMD;
+ return IV_FAIL;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
+ *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD;
+ return IV_FAIL;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets default encoder config parameters
+*
+* @par Description:
+* Sets default dynamic parameters. Will be called in isvce_init() to ensure
+* that even if set_params is not called, codec continues to work
+*
+* @param[in] ps_cfg
+* Pointer to encoder config params
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_set_default_params(isvce_cfg_params_t *ps_cfg)
+{
+ WORD32 ret = IV_SUCCESS;
+ WORD32 i;
+
+ ps_cfg->u4_max_wd = MAX_WD;
+ ps_cfg->u4_max_ht = MAX_HT;
+ ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
+ ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
+ ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
+ ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV;
+ ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE;
+ ps_cfg->e_recon_color_fmt = IV_YUV_420P;
+ ps_cfg->u4_enc_speed_preset = IVE_FASTEST;
+ ps_cfg->e_rc_mode = DEFAULT_RC;
+ ps_cfg->u4_max_framerate = DEFAULT_MAX_FRAMERATE;
+ ps_cfg->u4_num_bframes = DEFAULT_MAX_NUM_BFRAMES;
+ ps_cfg->e_content_type = IV_PROGRESSIVE;
+ ps_cfg->u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
+ ps_cfg->u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
+ ps_cfg->e_slice_mode = IVE_SLICE_MODE_NONE;
+ ps_cfg->u4_slice_param = DEFAULT_SLICE_PARAM;
+ ps_cfg->e_arch = isvce_default_arch();
+ ps_cfg->e_soc = SOC_GENERIC;
+ ps_cfg->u4_disp_wd = MAX_WD;
+ ps_cfg->u4_disp_ht = MAX_HT;
+ ps_cfg->u4_wd = MAX_WD;
+ ps_cfg->u4_ht = MAX_HT;
+ ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
+ ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
+ ps_cfg->e_frame_type = IV_NA_FRAME;
+ ps_cfg->e_enc_mode = IVE_ENC_MODE_DEFAULT;
+ ps_cfg->e_air_mode = DEFAULT_AIR_MODE;
+ ps_cfg->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD;
+ ps_cfg->u4_num_cores = DEFAULT_NUM_CORES;
+ ps_cfg->u4_me_speed_preset = DEFAULT_ME_SPEED_PRESET;
+ ps_cfg->u4_enable_hpel = DEFAULT_HPEL;
+ ps_cfg->u4_enable_qpel = DEFAULT_QPEL;
+ ps_cfg->u4_enable_intra_4x4 = DEFAULT_I4;
+ ps_cfg->u4_enable_intra_8x8 = DEFAULT_I8;
+ ps_cfg->u4_enable_intra_16x16 = DEFAULT_I16;
+ ps_cfg->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD;
+ ps_cfg->u4_enable_satqd = DEFAULT_ENABLE_SATQD;
+ ps_cfg->i4_min_sad = (ps_cfg->u4_enable_satqd == DEFAULT_ENABLE_SATQD)
+ ? DEFAULT_MIN_SAD_ENABLE
+ : DEFAULT_MIN_SAD_DISABLE;
+ ps_cfg->u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
+ ps_cfg->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
+ ps_cfg->u4_i_frm_interval = DEFAULT_I_INTERVAL;
+ ps_cfg->u4_idr_frm_interval = DEFAULT_IDR_INTERVAL;
+ ps_cfg->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL;
+ ps_cfg->e_profile = DEFAULT_PROFILE;
+ ps_cfg->u4_timestamp_low = 0;
+ ps_cfg->u4_timestamp_high = 0;
+ ps_cfg->u4_is_valid = 1;
+ ps_cfg->e_cmd = ISVCE_CMD_CT_NA;
+ ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
+ ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
+ ps_cfg->u4_entropy_coding_mode = CAVLC;
+ ps_cfg->u4_weighted_prediction = 0;
+ ps_cfg->u4_pic_info_type = 0;
+ ps_cfg->u4_isvce_mb_info_type = 0;
+ ps_cfg->s_vui.u1_video_signal_type_present_flag = 1;
+ ps_cfg->s_vui.u1_colour_description_present_flag = 1;
+
+ ps_cfg->b_nalu_info_export_enable = false;
+
+ for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
+ {
+ ps_cfg->au4_i_qp_max[i] = MAX_H264_QP;
+ ps_cfg->au4_i_qp_min[i] = MIN_H264_QP;
+ ps_cfg->au4_i_qp[i] = DEFAULT_I_QP;
+ ps_cfg->au4_p_qp_max[i] = MAX_H264_QP;
+ ps_cfg->au4_p_qp_min[i] = MIN_H264_QP;
+ ps_cfg->au4_p_qp[i] = DEFAULT_P_QP;
+ ps_cfg->au4_b_qp_max[i] = MAX_H264_QP;
+ ps_cfg->au4_b_qp_min[i] = MIN_H264_QP;
+ ps_cfg->au4_b_qp[i] = DEFAULT_B_QP;
+ }
+
+ ps_cfg->s_svc_params.d_spatial_res_ratio = 2.0;
+ ps_cfg->s_svc_params.u1_num_spatial_layers = 1;
+ ps_cfg->s_svc_params.u1_num_temporal_layers = 1;
+
+ return ret;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Initialize encoder context. This will be called by init_mem_rec and during
+* codec reset
+*
+* @par Description:
+* Initializes the context
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_init(isvce_codec_t *ps_codec)
+{
+ /* enc config param set */
+ isvce_cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
+
+ UWORD32 i;
+
+ /* coded pic count */
+ ps_codec->i4_poc = 0;
+
+ /* Number of API calls to encode are made */
+ ps_codec->i4_encode_api_call_cnt = -1;
+
+ /* Indicates no header has been generated yet */
+ ps_codec->u4_header_generated = 0;
+
+ /* Number of pictures encoded */
+ ps_codec->i4_pic_cnt = -1;
+
+ /* Number of threads created */
+ ps_codec->i4_proc_thread_cnt = 0;
+
+ /* ctl mutex init */
+ ithread_mutex_init(ps_codec->pv_ctl_mutex);
+
+ /* Set encoder chroma format */
+ ps_codec->e_codec_color_format =
+ (ps_cfg->e_inp_color_fmt == IV_YUV_420SP_VU) ? IV_YUV_420SP_VU : IV_YUV_420SP_UV;
+
+ /* Number of continuous frames where deblocking was disabled */
+ ps_codec->u4_disable_deblock_level_cnt = 0;
+
+ /* frame num */
+ ps_codec->i4_frame_num = 0;
+
+ /* set the current frame type to I frame, since we are going to start
+ * encoding*/
+ ps_codec->force_curr_frame_type = IV_NA_FRAME;
+
+ /* idr_pic_id */
+ ps_codec->i4_idr_pic_id = -1;
+
+ /* Flush mode */
+ ps_codec->i4_flush_mode = 0;
+
+ /* Encode header mode */
+ ps_codec->i4_header_mode = 0;
+
+ /* Encode generate header */
+ ps_codec->i4_gen_header = 0;
+
+ /* To signal successful completion of init */
+ ps_codec->i4_init_done = 1;
+
+ /* To signal that at least one picture was decoded */
+ ps_codec->i4_first_pic_done = 0;
+
+ /* Reset Codec */
+ ps_codec->i4_reset_flag = 0;
+
+ /* Current error code */
+ ps_codec->i4_error_code = IH264E_SUCCESS;
+
+ /* threshold residue */
+ ps_codec->u4_thres_resi = 1;
+
+ /* inter gating enable */
+ ps_codec->u4_inter_gate = 0;
+
+ /* entropy mutex init */
+ ithread_mutex_init(ps_codec->pv_entropy_mutex);
+
+ /* Process thread created status */
+ memset(ps_codec->ai4_process_thread_created, 0, sizeof(ps_codec->ai4_process_thread_created));
+
+ /* Number of MBs processed together */
+ ps_codec->i4_proc_nmb = 8;
+
+ /* Previous POC msb */
+ ps_codec->i4_prev_poc_msb = 0;
+
+ /* Previous POC lsb */
+ ps_codec->i4_prev_poc_lsb = -1;
+
+ /* max Previous POC lsb */
+ ps_codec->i4_max_prev_poc_lsb = -1;
+
+ /* sps, pps status */
+ {
+ sps_t *ps_sps = ps_codec->ps_sps_base;
+ pps_t *ps_pps = ps_codec->ps_pps_base;
+
+ for(i = 0; i < MAX_SPS_CNT; i++)
+ {
+ ps_sps->i1_sps_valid = 0;
+ ps_sps++;
+ }
+
+ for(i = 0; i < MAX_PPS_CNT; i++)
+ {
+ ps_pps->i1_pps_valid = 0;
+ ps_pps++;
+ }
+ }
+
+ {
+ WORD32 max_mb_rows;
+ UWORD32 u4_ht, u4_wd;
+
+ isvce_get_svc_compliant_dimensions(ps_cfg->s_svc_params.u1_num_spatial_layers,
+ ps_cfg->s_svc_params.d_spatial_res_ratio, ps_cfg->u4_wd,
+ ps_cfg->u4_ht, &u4_wd, &u4_ht);
+
+ /* frame dimensions */
+ u4_ht = ALIGN16(u4_ht);
+ max_mb_rows = u4_ht / MB_SIZE;
+
+ {
+ WORD32 clz;
+
+ WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
+
+ /* Use next power of two number of entries*/
+ clz = CLZ(num_jobs);
+ num_jobs = 1 << (32 - clz);
+
+ /* init process jobq */
+ ps_codec->pv_proc_jobq =
+ ih264_list_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size,
+ num_jobs, sizeof(job_t), 10);
+ RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
+ ih264_list_reset(ps_codec->pv_proc_jobq);
+
+ /* init entropy jobq */
+ ps_codec->pv_entropy_jobq =
+ ih264_list_init(ps_codec->pv_entropy_jobq_buf, ps_codec->i4_entropy_jobq_buf_size,
+ num_jobs, sizeof(job_t), 10);
+ RETURN_IF((ps_codec->pv_entropy_jobq == NULL), IV_FAIL);
+ ih264_list_reset(ps_codec->pv_entropy_jobq);
+ }
+ }
+
+ /* Update the jobq context to all the threads */
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
+ ps_codec->as_process[i].pv_entropy_jobq = ps_codec->pv_entropy_jobq;
+
+ /* i4_id always stays between 0 and MAX_PROCESS_THREADS */
+ ps_codec->as_process[i].i4_id = i % MAX_PROCESS_THREADS;
+ ps_codec->as_process[i].ps_codec = ps_codec;
+
+ ps_codec->as_process[i].s_entropy.pv_proc_jobq = ps_codec->pv_proc_jobq;
+ ps_codec->as_process[i].s_entropy.pv_entropy_jobq = ps_codec->pv_entropy_jobq;
+ ps_codec->as_process[i].s_entropy.i4_abs_pic_order_cnt = -1;
+ }
+
+ /* Initialize MV Bank buffer manager */
+ ps_codec->pv_svc_au_data_store_mgr =
+ ih264_buf_mgr_init(ps_codec->pv_svc_au_data_store_mgr_base);
+
+ /* Initialize Picture buffer manager for reference buffers*/
+ ps_codec->pv_ref_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_ref_buf_mgr_base);
+
+ /* Initialize Picture buffer manager for input buffers*/
+ ps_codec->pv_inp_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_inp_buf_mgr_base);
+
+ /* Initialize buffer manager for output buffers*/
+ ps_codec->pv_out_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_out_buf_mgr_base);
+
+ /* buffer cnt in buffer manager */
+ ps_codec->i4_inp_buf_cnt = 0;
+ ps_codec->i4_out_buf_cnt = 0;
+ ps_codec->i4_ref_buf_cnt = 0;
+
+ ps_codec->ps_pic_buf = ps_codec->ps_pic_buf_base;
+ memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(svc_au_buf_t));
+
+ for(i = 0; i < BUF_MGR_MAX_CNT; i++)
+ {
+ isvce_svc_au_buf_init(&((svc_au_buf_t *) ps_codec->ps_pic_buf)[i], &ps_cfg->s_svc_params);
+ }
+
+ /* Initialize dpb manager */
+ ih264_dpb_mgr_init((dpb_mgr_t *) ps_codec->pv_dpb_mgr);
+
+ memset(ps_codec->as_ref_set, 0, sizeof(ps_codec->as_ref_set));
+ for(i = 0; i < (sizeof(ps_codec->as_ref_set) / sizeof(ps_codec->as_ref_set[0])); i++)
+ {
+ ps_codec->as_ref_set[i].i4_pic_cnt = -1;
+ }
+
+ /* fn ptr init */
+ isvce_init_function_ptr(ps_codec);
+
+ /* reset status flags */
+ for(i = 0; i < MAX_CTXT_SETS; i++)
+ {
+ ps_codec->au4_entropy_thread_active[i] = 0;
+ ps_codec->ai4_pic_cnt[i] = -1;
+
+ ps_codec->s_rate_control.pre_encode_skip[i] = 0;
+ ps_codec->s_rate_control.post_encode_skip[i] = 0;
+ }
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_codec->s_rate_control.ai4_num_intra_in_prev_frame[i] = 0;
+ ps_codec->s_rate_control.ai4_avg_activity[i] = 0;
+ }
+
+ ps_codec->i4_max_num_reference_frames =
+ MIN((gas_ih264_lvl_tbl[ih264e_get_lvl_idx(ps_codec->s_cfg.u4_max_level)].u4_max_dpb_size /
+ (ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs)),
+ 16);
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Gets number of memory records required by the codec
+*
+* @par Description:
+* Gets codec memory requirements
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns status
+*
+* @remarks
+*
+*******************************************************************************
+*/
+static WORD32 isvce_get_num_rec(void *pv_api_ip, void *pv_api_op)
+{
+ /* api call I/O structures */
+ isvce_num_mem_rec_op_t *ps_op = pv_api_op;
+
+ UNUSED(pv_api_ip);
+
+ ps_op->s_ive_op.u4_num_mem_rec = ISVCE_MEM_REC_CNT;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Fills memory records of the codec
+*
+* @par Description:
+* Fills codec memory requirements
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
+{
+ isvce_fill_mem_rec_ip_t *ps_ip = pv_api_ip;
+ isvce_fill_mem_rec_op_t *ps_op = pv_api_op;
+
+ WORD32 level;
+ WORD32 num_reorder_frames;
+ WORD32 num_ref_frames;
+
+ WORD32 no_of_mem_rec;
+ iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
+
+ WORD32 max_wd_luma, max_ht_luma;
+ WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
+ UWORD32 u4_wd, u4_ht;
+
+ WORD32 i;
+
+ IV_STATUS_T status = IV_SUCCESS;
+
+ num_reorder_frames = ps_ip->s_ive_ip.u4_max_reorder_cnt;
+ num_ref_frames = ps_ip->s_ive_ip.u4_max_ref_cnt;
+
+ ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
+ no_of_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec;
+
+ isvce_get_svc_compliant_dimensions(ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, ps_ip->u4_wd,
+ ps_ip->u4_ht, &u4_wd, &u4_ht);
+
+ /* frame dimensions */
+ max_ht_luma = ALIGN16(u4_ht);
+ max_wd_luma = ALIGN16(u4_wd);
+ max_mb_rows = max_ht_luma / MB_SIZE;
+ max_mb_cols = max_wd_luma / MB_SIZE;
+ max_mb_cnt = max_mb_rows * max_mb_cols;
+
+ /* profile / level info */
+ level = ih264e_get_min_level(max_ht_luma, max_wd_luma);
+
+ /* Validate params */
+ ps_op->s_ive_op.u4_error_code |= isvce_svc_au_props_validate(
+ &ps_ip->s_svc_inp_params, ps_ip->u4_wd, ps_ip->u4_ht, u4_wd, u4_ht);
+
+ if(ps_op->s_ive_op.u4_error_code != IV_SUCCESS)
+ {
+ return IV_FAIL;
+ }
+
+ if((level < MIN_LEVEL) || (level > MAX_LEVEL))
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
+ level = MAX_LEVEL;
+ }
+
+ if(num_ref_frames > MAX_REF_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
+ num_ref_frames = MAX_REF_CNT;
+ }
+
+ if(num_reorder_frames > MAX_REF_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
+ num_reorder_frames = MAX_REF_CNT;
+ }
+
+ /* Set all memory records as persistent and alignment as 128 by default */
+ ps_mem_rec = ps_mem_rec_base;
+ for(i = 0; i < no_of_mem_rec; i++)
+ {
+ ps_mem_rec->u4_mem_alignment = 128;
+ ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
+ ps_mem_rec++;
+ }
+
+ /************************************************************************
+ * Request memory for h264 encoder handle *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_IV_OBJ];
+ {
+ ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_IV_OBJ, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for h264 encoder context *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CODEC];
+ {
+ ps_mem_rec->u4_mem_size = sizeof(isvce_codec_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_CODEC, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for CABAC context *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CABAC];
+ {
+ ps_mem_rec->u4_mem_size = sizeof(isvce_cabac_ctxt_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_CABAC, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for CABAC MB info *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CABAC_MB_INFO];
+ {
+ ps_mem_rec->u4_mem_size = ((max_mb_cols + 1) + 1) * sizeof(isvce_mb_info_ctxt_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_CABAC_MB_INFO, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for entropy context *
+ * In multi core encoding, each row is assumed to be launched on a *
+ * thread. The rows below can only start after its neighbors are coded *
+ * The status of an mb coded/uncoded is signaled via entropy map. *
+ * 1. One word32 to store skip run cnt *
+ * 2. mb entropy map (mb status entropy coded/uncoded). The size*
+ * of the entropy map is max mb cols. Further allocate one *
+ * more additional row to evade checking for row -1. *
+ * 3. size of bit stream buffer to store bit stream ctxt. *
+ * 4. Entropy coding is dependent on nnz coefficient count for *
+ * the neighbor blocks. It is sufficient to maintain one row *
+ * worth of nnz as entropy for lower row waits on entropy map*
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size of skip mb run */
+ total_size += sizeof(WORD32);
+ total_size = ALIGN8(total_size);
+
+ /* size in bytes to store entropy status of an entire frame */
+ total_size += (max_mb_cols * max_mb_rows);
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+ total_size = ALIGN128(total_size);
+
+ /* size of bit stream buffer */
+ total_size += sizeof(bitstrm_t);
+ total_size = ALIGN128(total_size);
+
+#if ENABLE_RE_ENC_AS_SKIP
+ total_size += sizeof(bitstrm_t);
+ total_size = ALIGN128(total_size);
+#endif
+
+ /* top nnz luma */
+ total_size += (max_mb_cols * 4 * sizeof(UWORD8));
+ total_size = ALIGN128(total_size);
+
+ /* top nnz cbcr */
+ total_size += (max_mb_cols * 4 * sizeof(UWORD8));
+ total_size = ALIGN128(total_size);
+
+ /* ps_mb_qp_ctxt */
+ total_size += ALIGN128(sizeof(mb_qp_ctxt_t));
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_ENTROPY, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * The residue coefficients that needs to be entropy coded are packed *
+ * at a buffer space by the proc threads. The entropy thread shall *
+ * read from the buffer space, unpack them and encode the same. The *
+ * buffer space required to pack a row of mbs are as follows. *
+ * Assuming transform_8x8_flag is disabled, *
+ * In the worst case, 1 mb contains 1 dc 4x4 luma sub block, followed *
+ * by 16 ac 4x4 luma sub blocks, 2 dc chroma 2x2 sub blocks, followed *
+ * by 8 ac 4x4 chroma sub blocks. *
+ * For the sake of simplicity we assume that all sub blocks are of *
+ * type 4x4. The packing of each 4x4 is depicted by the structure *
+ * tu_sblk_coeff_data_t *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_COEFF_DATA];
+ {
+ /* temp var */
+ WORD32 size = 0;
+
+ /* size of coeff data of 1 mb */
+ size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
+
+ /* size of coeff data of 1 row of mb's */
+ size *= max_mb_cols;
+
+ /* align to avoid any false sharing across threads */
+ size = ALIGN64(size);
+
+ /* size for one full frame */
+ size *= max_mb_rows;
+
+ /* size of each proc buffer set (ping, pong) */
+ size *= MAX_CTXT_SETS;
+
+ ps_mem_rec->u4_mem_size = size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_MB_COEFF_DATA, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * while encoding an mb, the mb header data is signaled to the entropy*
+ * thread by writing to a buffer space. the size of header data per mb *
+ * is assumed to be 40 bytes *
+ * TODO: revisit this inference *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_HEADER_DATA];
+ {
+ /* temp var */
+ WORD32 size;
+
+ /* size per MB */
+ size = sizeof(isvce_mb_hdr_t);
+
+ /* size for 1 row of mbs */
+ size = size * max_mb_cols;
+
+ /* align to avoid any false sharing across threads */
+ size = ALIGN64(size);
+
+ /* size for one full frame */
+ size *= max_mb_rows;
+
+ /* size of each proc buffer set (ping, pong) */
+ size *= MAX_CTXT_SETS;
+
+ ps_mem_rec->u4_mem_size = size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_MB_HEADER_DATA, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * While encoding inter slices, to compute the cost of encoding an mb *
+ * with the mv's at hand, we employ the expression cost = sad + lambda *
+ * x mv_bits. Here mv_bits is the total number of bits taken to represe*
+ * nt the mv in the stream. The mv bits for all the possible mv are *
+ * stored in the look up table. The mem record for this look up table *
+ * is given below. *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MVBITS];
+ {
+ /* max srch range x */
+ UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
+
+ /* max srch range y */
+ UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
+
+ /* max srch range */
+ UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
+
+ /* due to subpel */
+ u4_max_srch_range <<= 2;
+
+ /* due to mv on either direction */
+ u4_max_srch_range = (u4_max_srch_range << 1);
+
+ /* due to pred mv + zero */
+ u4_max_srch_range = (u4_max_srch_range << 1) + 1;
+
+ u4_max_srch_range = ALIGN128(u4_max_srch_range);
+
+ ps_mem_rec->u4_mem_size = u4_max_srch_range;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_MVBITS, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for SPS *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SPS];
+ {
+ ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SPS, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for PPS *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PPS];
+ {
+ ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_PPS, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for SVC NALU Extension *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SVC_NALU_EXT];
+ {
+ /* 2 implies allocation for NAL_PREFIX and NAL_CODED_SLICE_EXTENSION */
+ ps_mem_rec->u4_mem_size =
+ 2 * MAX_CTXT_SETS * SVC_MAX_SLICE_HDR_CNT * sizeof(svc_nalu_ext_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SVC_NALU_EXT, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for subset SPS *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SUBSET_SPS];
+ {
+ ps_mem_rec->u4_mem_size =
+ MAX_SPS_CNT * ps_ip->s_svc_inp_params.u1_num_spatial_layers * sizeof(subset_sps_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SUBSET_SPS, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for Slice Header *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SLICE_HDR];
+ {
+ ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * SVC_MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SLICE_HDR, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for SVC Slice Header *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SVC_SLICE_HDR];
+ {
+ ps_mem_rec->u4_mem_size =
+ MAX_CTXT_SETS * SVC_MAX_SLICE_HDR_CNT * sizeof(svc_slice_header_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SVC_SLICE_HDR, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory for Adaptive Intra Refresh *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_AIR_MAP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* intra coded map */
+ total_size += max_mb_cnt;
+ total_size *= MAX_CTXT_SETS;
+
+ /* mb refresh map */
+ total_size += sizeof(UWORD16) * max_mb_cnt;
+
+ /* alignment */
+ total_size = ALIGN128(total_size);
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_AIR_MAP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * In multi slice encoding, this memory record helps tracking the start*
+ * of slice with reference to mb. *
+ * MEM RECORD for holding *
+ * 1. mb slice map *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SLICE_MAP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to slice index of all mbs of a frame */
+ total_size = ALIGN64(max_mb_cnt);
+
+ /* isvce_update_proc_ctxt can overread by 1 at the end */
+ total_size += 1;
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_SLICE_MAP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold thread handles for each processing thread *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_THREAD_HANDLE];
+ {
+ WORD32 handle_size = ithread_get_handle_size();
+
+ ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * handle_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_THREAD_HANDLE, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold mutex for control calls *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CTL_MUTEX];
+ {
+ ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_CTL_MUTEX, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold mutex for entropy calls *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY_MUTEX];
+ {
+ ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_ENTROPY_MUTEX, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold process jobs *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_JOBQ];
+ {
+ /* One process job per row of MBs */
+ /* Allocate for two pictures, so that wrap around can be handled easily */
+ WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
+
+ WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
+
+ ps_mem_rec->u4_mem_size = job_queue_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_PROC_JOBQ, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold entropy jobs *
+ ***********************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY_JOBQ];
+ {
+ /* One process job per row of MBs */
+ /* Allocate for two pictures, so that wrap around can be handled easily */
+ WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
+
+ WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
+
+ ps_mem_rec->u4_mem_size = job_queue_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_ENTROPY_JOBQ, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * In multi core encoding, each row is assumed to be launched on a *
+ * thread. The rows below can only start after its neighbors are coded *
+ * The status of an mb coded/uncoded is signaled via proc map. *
+ * MEM RECORD for holding *
+ * 1. mb proc map (mb status core coded/uncoded) *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_MAP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_PROC_MAP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * mem record for holding a particular MB is deblocked or not *
+ * 1. mb deblk map (mb status deblocked/not deblocked) *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_DBLK_MAP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ total_size = ALIGN64(total_size);
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_DBLK_MAP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * mem record for holding a particular MB's me is done or not *
+ * 1. mb me map *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ME_MAP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_ME_MAP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * size for holding dpb manager context *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_DPB_MGR];
+ {
+ ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_DPB_MGR, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * luma or chroma core coding involves mb estimation, error computation*
+ * between the estimated singnal and the actual signal, transform the *
+ * error, quantize the error, then inverse transform and inverse quant *
+ * ize the residue and add the result back to estimated signal. *
+ * To perform all these, a set of temporary buffers are needed. *
+ * MEM RECORD for holding scratch buffers *
+ * 1. prediction buffer used during mb mode analysis *
+ * 2 temp. reference buffer when intra 4x4 with rdopt on is *
+ * enabled *
+ * - when intra 4x4 is enabled, rdopt is on, to store the *
+ * reconstructed values and use them later this temp. buffer *
+ * is used. *
+ * 3. prediction buffer used during intra mode analysis *
+ * 4. prediction buffer used during intra 16x16 plane mode *
+ * analysis
+ * 5. prediction buffer used during intra chroma mode analysis *
+ * 6. prediction buffer used during intra chroma 16x16 plane *
+ * mode analysis
+ * 7. forward transform output buffer *
+ * - to store the error between estimated and the actual inp *
+ * ut and to store the fwd transformed quantized output *
+ * 8. forward transform output buffer *
+ * - when intra 4x4 is enabled, rdopt is on, to store the *
+ * fwd transform values and use them later this temp. buffer *
+ * is used. *
+ * 9. temporary buffer for inverse transform *
+ * - temporary buffer used in inverse transform and inverse *
+ * quantization *
+ * A. Buffers for holding half_x , half_y and half_xy planes *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_SCRATCH];
+ {
+ WORD32 total_size = 0;
+ WORD32 i4_tmp_size;
+
+ /* size to hold prediction buffer */
+ total_size += sizeof(UWORD8) * 16 * 16;
+ total_size = ALIGN64(total_size);
+
+ /* size to hold recon for intra 4x4 buffer */
+ total_size += sizeof(UWORD8) * 16 * 16;
+ total_size = ALIGN64(total_size);
+
+ /* prediction buffer intra 16x16 */
+ total_size += sizeof(UWORD8) * 16 * 16;
+ total_size = ALIGN64(total_size);
+
+ /* prediction buffer intra 16x16 plane*/
+ total_size += sizeof(UWORD8) * 16 * 16;
+ total_size = ALIGN64(total_size);
+
+ /* prediction buffer intra chroma*/
+ total_size += sizeof(UWORD8) * 16 * 8;
+ total_size = ALIGN64(total_size);
+
+ /* prediction buffer intra chroma plane*/
+ total_size += sizeof(UWORD8) * 16 * 8;
+ total_size = ALIGN64(total_size);
+
+ /* size to hold fwd transform output */
+ total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
+ total_size = ALIGN64(total_size);
+
+ /* size to hold fwd transform output */
+ total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
+ total_size = ALIGN64(total_size);
+
+ /* size to hold temporary data during inverse transform */
+ total_size += sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
+ total_size = ALIGN64(total_size);
+
+ /* Buffers for holding half_x , half_y and half_xy planes */
+ i4_tmp_size = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
+ total_size += (ALIGN64(i4_tmp_size) * SUBPEL_BUFF_CNT);
+
+ /* Allocate for each process thread */
+ total_size *= MAX_PROCESS_CTXT;
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_PROC_SCRATCH, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * When transform_8x8_flag is disabled, the size of a sub block is *
+ * 4x4 and when the transform_8x8_flag is enabled the size of the sub *
+ * block is 8x8. The threshold matrix and the forward scaling list *
+ * is of the size of the sub block. *
+ * MEM RECORD for holding *
+ * 1. quantization parameters for plane y, cb, cr *
+ * - threshold matrix for quantization *
+ * - forward weight matrix *
+ * - satqd threshold matrix *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_QUANT_PARAM];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* quantization parameter list for planes y,cb and cr */
+ total_size += ALIGN64(sizeof(quant_params_t)) * 3;
+
+ /* size of threshold matrix for quantization
+ * (assuming the transform_8x8_flag is disabled).
+ * for all 3 planes */
+ total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
+
+ /* size of forward weight matrix for quantization
+ * (assuming the transform_8x8_flag is disabled).
+ * for all 3 planes */
+ total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
+
+ /* Size for SATDQ threshold matrix for palnes y, cb and cr */
+ total_size += ALIGN64(sizeof(UWORD16) * 9) * 3;
+
+ total_size = ALIGN128(total_size);
+
+ /* total size per each proc thread */
+ total_size *= MAX_PROCESS_CTXT;
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_QUANT_PARAM, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * While computing blocking strength for the current mb, the csbp, mb *
+ * type for the neighboring mbs are necessary. memtab for storing top *
+ * row mbtype and csbp is evaluated here. *
+ * *
+ * when encoding intra 4x4 or intra 8x8 the submb types are estimated *
+ * and sent. The estimation is dependent on neighbor mbs. For this *
+ * store the top row sub mb types for intra mbs *
+ * *
+ * During motion vector prediction, the curr mb mv is predicted from *
+ * neigbors left, top, top right and sometimes top left depending on *
+ * the availability. The top and top right content is accessed from *
+ * the memtab specified below. *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_TOP_ROW_SYN_INFO];
+ {
+ UWORD32 total_size = isvce_get_svc_nbr_info_buf_size(
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ total_size = ALIGN128(total_size);
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_TOP_ROW_SYN_INFO, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * When transform_8x8_flag is disabled, the mb is partitioned into *
+ * 4 sub blocks. This corresponds to 1 vertical left edge and 1 *
+ * vertical inner edge, 1 horizontal top edge and 1 horizontal *
+ * inner edge per mb. Further, When transform_8x8_flag is enabled, *
+ * the mb is partitioned in to 16 sub blocks. This corresponds to *
+ * 1 vertical left edge and 3 vertical inner edges, 1 horizontal top *
+ * edge and 3 horizontal inner edges per mb. *
+ * MEM RECORD for holding *
+ * 1. vertical edge blocking strength *
+ * 2. horizontal edge blocking strength *
+ * 3. mb qp *
+ * all are frame level *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_BS_QP];
+ {
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to store vertical edge bs, horizontal edge bs and qp of
+ * every mb*/
+ WORD32 vert_bs_size, horz_bs_size, qp_size;
+
+ /* vertical edge bs = total number of vertical edges * number of bytes per
+ * each edge */
+ /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
+ * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing
+ * bs */
+ vert_bs_size = 2 * ALIGN64(max_mb_cnt * 4 * 4);
+
+ /* horizontal edge bs = total number of horizontal edges * number of bytes
+ * per each edge */
+ /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
+ * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing
+ * bs */
+ horz_bs_size = 2 * ALIGN64(max_mb_cnt * 4 * 4);
+
+ /* qp of each mb requires 1 byte */
+ qp_size = ALIGN64(max_mb_cnt);
+
+ /* total size */
+ total_size = vert_bs_size + horz_bs_size + qp_size;
+
+ /* total size per each proc ctxt */
+ total_size *= MAX_CTXT_SETS;
+
+ ps_mem_rec->u4_mem_size = total_size;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_BS_QP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * size for holding input pic buf *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_INP_PIC];
+ {
+ ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_INP_PIC, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * size for holding putput pic buf *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_OUT];
+ {
+ ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_OUT, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Size for color space conversion *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CSC];
+ {
+ /* We need a total a memory for a single frame of 420 sp, ie
+ * (wd * ht) for luma and (wd * ht / 2) for chroma*/
+ ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * ((3 * max_ht_luma * max_wd_luma) >> 1);
+ /* Allocate an extra row, since inverse transform functions for
+ * chroma access(only read, not used) few extra bytes due to
+ * interleaved input
+ */
+ ps_mem_rec->u4_mem_size += max_wd_luma;
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_CSC, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Size for holding pic_buf_t for each reference picture *
+ * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
+ * MAX_DPB_SIZE or max_dpb_size for following reasons *
+ * max_dpb_size will be based on max_wd and max_ht *
+ * For higher max_wd and max_ht this number will be smaller than *
+ * MAX_DPB_SIZE But during actual initialization number of buffers *
+ * allocated can be more. *
+ * *
+ * Also to handle display depth application can allocate more than *
+ * what codec asks for in case of non-shared mode *
+ * Since this is only a structure allocation and not actual buffer *
+ * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_REF_PIC];
+ {
+ ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
+ ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(svc_au_buf_t);
+
+ /************************************************************************
+ * Note: Number of luma samples is not max_wd * max_ht here, instead it *
+ * is set to maximum number of luma samples allowed at the given level. *
+ * This is done to ensure that any stream with width and height lesser *
+ * than max_wd and max_ht is supported. Number of buffers required can *
+ * be greater for lower width and heights at a given level and this *
+ * increased number of buffers might require more memory than what *
+ * max_wd and max_ht buffer would have required. Number of buffers is *
+ * doubled in order to return one frame at a time instead of sending *
+ * multiple outputs during dpb full case. Also note one extra buffer is *
+ * allocted to store current picture. *
+ * *
+ * Half-pel planes for each reference buffer are allocated along with *
+ * the reference buffer. So each reference buffer is 4 times the *
+ * required size. This way buffer management for the half-pel planes is *
+ * easier and while using the half-pel planes in MC, an offset can be *
+ * used from a single pointer *
+ ***********************************************************************/
+ ps_mem_rec->u4_mem_size +=
+ HPEL_PLANES_CNT * isvce_get_total_svc_au_buf_size(&ps_ip->s_svc_inp_params,
+ u4_wd * u4_ht, level, PAD_WD, PAD_HT,
+ num_ref_frames, num_reorder_frames);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_REF_PIC, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Size for holding svc_au_data_t for each MV Bank. *
+ * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
+ * MAX_DPB_SIZE or max_dpb_size for following reasons *
+ * max_dpb_size will be based on max_wd and max_ht *
+ * For higher max_wd and max_ht this number will be smaller than *
+ * MAX_DPB_SIZE But during actual initialization number of buffers *
+ * allocated can be more. *
+ * *
+ * One extra MV Bank is needed to hold current pics MV bank. *
+ * Since this is only a structure allocation and not actual buffer *
+ * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MVBANK];
+ {
+ ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
+
+ /************************************************************************
+ * Allocate for pu_map, isvce_enc_pu_t and pic_pu_idx for each MV bank *
+ * Note: Number of luma samples is not max_wd * max_ht here, instead it *
+ * is set to maximum number of luma samples allowed at the given level. *
+ * This is done to ensure that any stream with width and height lesser *
+ * than max_wd and max_ht is supported. Number of buffers required can *
+ * be greater for lower width and heights at a given level and this *
+ * increased number of buffers might require more memory than what *
+ * max_wd and max_ht buffer would have required Also note one extra *
+ * buffer is allocated to store current pictures MV bank. *
+ ***********************************************************************/
+
+ ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(svc_au_data_t);
+
+ ps_mem_rec->u4_mem_size +=
+ (num_ref_frames + num_reorder_frames + ps_ip->s_svc_inp_params.u1_num_temporal_layers +
+ MAX_CTXT_SETS) *
+ isvce_get_total_svc_au_data_size(u4_wd * u4_ht,
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_MVBANK, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * Request memory to hold mem recs to be returned during retrieve call *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_BACKUP];
+ {
+ ps_mem_rec->u4_mem_size = ISVCE_MEM_REC_CNT * sizeof(iv_mem_rec_t);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_BACKUP, ps_mem_rec->u4_mem_size);
+
+ /************************************************************************
+ * size for memory required by NMB info structs and buffer for storing *
+ * half pel plane *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_INFO_NMB];
+ {
+ /* Additional 4 bytes to allow use of '_mm_loadl_epi64' */
+ ps_mem_rec->u4_mem_size =
+ MAX_PROCESS_CTXT * max_mb_cols *
+ (sizeof(isvce_mb_info_nmb_t) + (MB_SIZE * MB_SIZE + 4) * sizeof(UWORD8));
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_MB_INFO_NMB, ps_mem_rec->u4_mem_size);
+
+ /* Buffers for storing SVC Spatial data */
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_SPAT_INP];
+
+ ps_mem_rec->u4_mem_size =
+ isvce_get_svc_inp_buf_size(ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_SPAT_INP, ps_mem_rec->u4_mem_size);
+ }
+
+ /* Buffer for storing Downscaler data */
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_DOWN_SCALER];
+
+ ps_mem_rec->u4_mem_size = isvce_get_downscaler_data_size(
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_DOWN_SCALER, ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_ILP_DATA];
+
+ ps_mem_rec->u4_mem_size =
+ isvce_get_svc_ilp_buf_size(ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_ILP_DATA, ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_ILP_MV_CTXT];
+
+ ps_mem_rec->u4_mem_size =
+ isvce_get_ilp_mv_ctxt_size(ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_ILP_MV_CTXT, ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_RES_PRED_CTXT];
+
+ ps_mem_rec->u4_mem_size = isvce_get_svc_res_pred_ctxt_size(
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_RES_PRED_CTXT,
+ ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_INTRA_PRED_CTXT];
+
+ ps_mem_rec->u4_mem_size = isvce_get_svc_intra_pred_ctxt_size(
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_INTRA_PRED_CTXT,
+ ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_RC_UTILS_CTXT];
+
+ ps_mem_rec->u4_mem_size = isvce_get_rc_utils_data_size();
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_RC_UTILS_CTXT,
+ ps_mem_rec->u4_mem_size);
+ }
+
+ {
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_SVC_SUB_PIC_RC_CTXT];
+
+ ps_mem_rec->u4_mem_size = isvce_get_sub_pic_rc_ctxt_size(
+ ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_SVC_SUB_PIC_RC_CTXT,
+ ps_mem_rec->u4_mem_size);
+ }
+
+#if ENABLE_MODE_STAT_VISUALISER
+ {
+ ps_mem_rec = &ps_mem_rec_base[MEM_MODE_STAT_VISUALISER_BUF];
+
+ ps_mem_rec->u4_mem_size = isvce_get_msv_ctxt_size(u4_wd, u4_ht);
+
+ DEBUG("\nMemory record Id %d = %d \n", MEM_MODE_STAT_VISUALISER_BUF,
+ ps_mem_rec->u4_mem_size);
+ }
+#endif
+
+ /************************************************************************
+ * RC mem records *
+ ************************************************************************/
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_RC];
+ {
+ isvce_get_rate_control_mem_tab(NULL, ps_mem_rec, FILL_MEMTAB);
+ }
+ DEBUG("\nMemory record Id %d = %d \n", ISVCE_MEM_REC_RC, ps_mem_rec->u4_mem_size);
+
+ /* Each memtab size is aligned to next multiple of 128 bytes */
+ /* This is to ensure all the memtabs start at different cache lines */
+ ps_mem_rec = ps_mem_rec_base;
+ for(i = 0; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
+ ps_mem_rec++;
+ }
+
+ ps_op->s_ive_op.u4_num_mem_rec = ISVCE_MEM_REC_CNT;
+
+ DEBUG("Num mem recs in fill call : %d\n", ps_op->s_ive_op.u4_num_mem_rec);
+
+ return (status);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Initializes from mem records passed to the codec
+*
+* @par Description:
+* Initializes pointers based on mem records passed
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_init_mem_rec(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ /* api call I/O structures */
+ isvce_init_ip_t *ps_ip = pv_api_ip;
+ isvce_init_op_t *ps_op = pv_api_op;
+
+ /* mem records */
+ iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
+
+ /* codec variables */
+ isvce_codec_t *ps_codec;
+ isvce_cabac_ctxt_t *ps_cabac;
+ isvce_mb_info_ctxt_t *ps_mb_map_ctxt_inc;
+
+ isvce_cfg_params_t *ps_cfg;
+
+ /* frame dimensions */
+ WORD32 max_wd_luma, max_ht_luma;
+ WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
+
+ /* temp var */
+ WORD32 i, j;
+ WORD32 status = IV_SUCCESS;
+
+ /* mem records */
+ ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
+
+ /* memset all allocated memory, except the first one. First buffer (i.e. i == MEM_REC_IV_OBJ)
+ is initialized by application before calling this init function */
+ for(i = ISVCE_MEM_REC_CODEC; i < ISVCE_MEM_REC_CNT; i++)
+ {
+ ps_mem_rec = &ps_mem_rec_base[i];
+ memset(ps_mem_rec->pv_base, 0, ps_mem_rec->u4_mem_size);
+ }
+
+ /* Init mem records */
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CODEC];
+ {
+ ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
+ ps_codec = (isvce_codec_t *) (ps_codec_obj->pv_codec_handle);
+ }
+ /* Init mem records_cabac ctxt */
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CABAC];
+ {
+ ps_cabac = (isvce_cabac_ctxt_t *) (ps_mem_rec->pv_base);
+ }
+
+ /* Init mem records mb info array for CABAC */
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CABAC_MB_INFO];
+ {
+ ps_mb_map_ctxt_inc = (isvce_mb_info_ctxt_t *) (ps_mem_rec->pv_base);
+ }
+
+ /* Note this memset can not be done in init() call, since init will called
+ during reset as well. And calling this during reset will mean all pointers
+ need to reinitialized */
+ memset(ps_codec, 0, sizeof(isvce_codec_t));
+ memset(ps_cabac, 0, sizeof(isvce_cabac_ctxt_t));
+
+ /* Set default Config Params */
+ ps_cfg = &ps_codec->s_cfg;
+ isvce_set_default_params(ps_cfg);
+
+ /* get new input dimensions that satisfy the SVC and libavc constraints
+ constraint 1) All layers of SVC should have dimensions that are a multiple of
+ 16 constraint 2) Dimension of Li layer = dimension of Li-1 layer * scaling
+ factor*/
+
+ isvce_get_svc_compliant_dimensions(ps_ip->s_svc_inp_params.u1_num_spatial_layers,
+ ps_ip->s_svc_inp_params.d_spatial_res_ratio, ps_ip->u4_wd,
+ ps_ip->u4_ht, &ps_cfg->u4_wd, &ps_cfg->u4_ht);
+
+ /* Update config params as per input */
+ ps_cfg->u4_max_wd = ps_cfg->u4_disp_wd = ALIGN16(ps_cfg->u4_wd);
+ ps_cfg->u4_max_ht = ps_cfg->u4_disp_ht = ALIGN16(ps_cfg->u4_ht);
+ ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
+ ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
+ ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;
+ ps_cfg->u4_max_reorder_cnt = ps_ip->s_ive_ip.u4_max_reorder_cnt;
+ ps_cfg->u4_max_level = ps_ip->s_ive_ip.u4_max_level;
+ ps_cfg->e_inp_color_fmt = ps_ip->s_ive_ip.e_inp_color_fmt;
+ ps_cfg->e_recon_color_fmt = ps_ip->s_ive_ip.e_recon_color_fmt;
+ ps_cfg->u4_max_framerate = ps_ip->s_ive_ip.u4_max_framerate;
+ for(i = 0; i < ps_ip->s_svc_inp_params.u1_num_spatial_layers; i++)
+ {
+ ps_cfg->au4_max_bitrate[i] = ps_ip->pu4_max_bitrate[i];
+ }
+ ps_cfg->u4_num_bframes = ps_ip->s_ive_ip.u4_num_bframes;
+ ps_cfg->e_content_type = ps_ip->s_ive_ip.e_content_type;
+ ps_cfg->u4_max_srch_rng_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
+ ps_cfg->u4_max_srch_rng_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
+ ps_cfg->e_slice_mode = ps_ip->s_ive_ip.e_slice_mode;
+ ps_cfg->u4_slice_param = ps_ip->s_ive_ip.u4_slice_param;
+ ps_cfg->e_arch = ps_ip->s_ive_ip.e_arch;
+ ps_cfg->e_soc = ps_ip->s_ive_ip.e_soc;
+ ps_cfg->u4_enable_recon = ps_ip->s_ive_ip.u4_enable_recon;
+ ps_cfg->e_rc_mode = ps_ip->s_ive_ip.e_rc_mode;
+ ps_cfg->u4_disable_vui = ps_ip->b_use_default_vui;
+
+ ps_cfg->s_svc_params.u1_num_temporal_layers = ps_ip->s_svc_inp_params.u1_num_temporal_layers;
+
+ ps_cfg->s_svc_params.u1_num_spatial_layers = ps_ip->s_svc_inp_params.u1_num_spatial_layers;
+
+ ps_cfg->s_svc_params.d_spatial_res_ratio = ps_ip->s_svc_inp_params.d_spatial_res_ratio;
+
+ ps_cfg->b_nalu_info_export_enable = ps_ip->b_nalu_info_export_enable;
+
+ /* frame dimensions */
+ max_ht_luma = ALIGN16(ps_cfg->u4_ht);
+ max_wd_luma = ALIGN16(ps_cfg->u4_wd);
+ max_mb_rows = max_ht_luma / MB_SIZE;
+ max_mb_cols = max_wd_luma / MB_SIZE;
+ max_mb_cnt = max_mb_rows * max_mb_cols;
+
+ /* Validate params */
+ ps_op->s_ive_op.u4_error_code |= isvce_svc_inp_params_validate(ps_ip, ps_cfg);
+
+ if(ps_op->s_ive_op.u4_error_code != IV_SUCCESS)
+ {
+ return IV_FAIL;
+ }
+
+#if defined(X86)
+ if((ps_cfg->e_arch != ARCH_X86_GENERIC) && (ps_cfg->e_arch != ARCH_X86_SSSE3) &&
+ (ps_cfg->e_arch != ARCH_X86_SSE42))
+ {
+ ps_cfg->e_arch = ARCH_X86_SSE42;
+ }
+#else
+ if((ps_cfg->e_arch == ARCH_X86_GENERIC) || (ps_cfg->e_arch == ARCH_X86_SSSE3) ||
+ (ps_cfg->e_arch == ARCH_X86_SSE42))
+ {
+#if defined(DISABLE_NEON)
+ ps_cfg->e_arch = ARCH_ARM_NONEON;
+#elif defined(ARMV8)
+ ps_cfg->e_arch = ARCH_ARM_V8_NEON;
+#else
+ ps_cfg->e_arch = ARCH_ARM_A7;
+#endif
+ }
+#endif
+
+ if((ps_ip->s_ive_ip.u4_max_level < MIN_LEVEL) || (ps_ip->s_ive_ip.u4_max_level > MAX_LEVEL))
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
+ ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
+ ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
+ }
+
+ if(ps_ip->s_ive_ip.u4_max_reorder_cnt > MAX_REF_CNT)
+ {
+ ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
+ ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_BACKUP];
+ {
+ ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *) ps_mem_rec->pv_base;
+
+ memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
+ ISVCE_MEM_REC_CNT * sizeof(iv_mem_rec_t));
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY];
+ {
+ /* temp var */
+ WORD32 size = 0, offset;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ /* base ptr */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* reset size */
+ size = 0;
+
+ /* skip mb run */
+ ps_codec->as_process[i].s_entropy.pi4_mb_skip_run = (WORD32 *) (pu1_buf + size);
+ size += sizeof(WORD32);
+ size = ALIGN8(size);
+
+ /* entropy map */
+ ps_codec->as_process[i].s_entropy.pu1_entropy_map =
+ (UWORD8 *) (pu1_buf + size + max_mb_cols);
+ /* size in bytes to store entropy status of an entire frame */
+ size += (max_mb_cols * max_mb_rows);
+ /* add an additional 1 row of bytes to evade the special case of row 0
+ */
+ size += max_mb_cols;
+ size = ALIGN128(size);
+
+ /* bit stream ptr */
+ ps_codec->as_process[i].s_entropy.ps_bitstrm = (bitstrm_t *) (pu1_buf + size);
+ size += sizeof(ps_codec->as_process[i].s_entropy.ps_bitstrm[0]);
+ size = ALIGN128(size);
+
+#if ENABLE_RE_ENC_AS_SKIP
+ ps_codec->as_process[i].s_entropy.ps_bitstrm_after_slice_hdr =
+ (bitstrm_t *) (pu1_buf + size);
+ size += sizeof(ps_codec->as_process[i].s_entropy.ps_bitstrm_after_slice_hdr[0]);
+ size = ALIGN128(size);
+#endif
+
+ /* nnz luma */
+ ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma = (UWORD8(*)[4])(pu1_buf + size);
+ size += (max_mb_cols * 4 * sizeof(UWORD8));
+ size = ALIGN128(size);
+
+ /* nnz chroma */
+ ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr = (UWORD8(*)[4])(pu1_buf + size);
+ size += (max_mb_cols * 4 * sizeof(UWORD8));
+ size = ALIGN128(size);
+
+ /* ps_mb_qp_ctxt */
+ ps_codec->as_process[i].s_entropy.ps_mb_qp_ctxt = (mb_qp_ctxt_t *) (pu1_buf + size);
+ size += ALIGN128(sizeof(ps_codec->as_process[i].s_entropy.ps_mb_qp_ctxt[0]));
+
+ offset = size;
+
+ /* cabac Context */
+ ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
+ }
+ else
+ {
+ /* base ptr */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* reset size */
+ size = offset;
+
+ /* skip mb run */
+ ps_codec->as_process[i].s_entropy.pi4_mb_skip_run = (WORD32 *) (pu1_buf + size);
+ size += sizeof(WORD32);
+ size = ALIGN8(size);
+
+ /* entropy map */
+ ps_codec->as_process[i].s_entropy.pu1_entropy_map =
+ (UWORD8 *) (pu1_buf + size + max_mb_cols);
+ /* size in bytes to store entropy status of an entire frame */
+ size += (max_mb_cols * max_mb_rows);
+ /* add an additional 1 row of bytes to evade the special case of row 0
+ */
+ size += max_mb_cols;
+ size = ALIGN128(size);
+
+ /* bit stream ptr */
+ ps_codec->as_process[i].s_entropy.ps_bitstrm = (bitstrm_t *) (pu1_buf + size);
+ size += sizeof(ps_codec->as_process[i].s_entropy.ps_bitstrm[0]);
+ size = ALIGN128(size);
+
+#if ENABLE_RE_ENC_AS_SKIP
+ ps_codec->as_process[i].s_entropy.ps_bitstrm_after_slice_hdr =
+ (bitstrm_t *) (pu1_buf + size);
+ size += sizeof(ps_codec->as_process[i].s_entropy.ps_bitstrm_after_slice_hdr[0]);
+ size = ALIGN128(size);
+#endif
+
+ /* nnz luma */
+ ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma =
+ (UWORD8(*)[4])(UWORD8(*)[4])(pu1_buf + size);
+ size += (max_mb_cols * 4 * sizeof(UWORD8));
+ size = ALIGN128(size);
+
+ /* nnz chroma */
+ ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr = (UWORD8(*)[4])(pu1_buf + size);
+ size += (max_mb_cols * 4 * sizeof(UWORD8));
+ size = ALIGN128(size);
+
+ /* ps_mb_qp_ctxt */
+ ps_codec->as_process[i].s_entropy.ps_mb_qp_ctxt = (mb_qp_ctxt_t *) (pu1_buf + size);
+ size = ALIGN128(sizeof(ps_codec->as_process[i].s_entropy.ps_mb_qp_ctxt[0]));
+
+ /* cabac Context */
+ ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
+ }
+ }
+ ps_codec->as_process[0].s_entropy.ps_cabac->ps_mb_map_ctxt_inc_base = ps_mb_map_ctxt_inc;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_COEFF_DATA];
+ {
+ /* temp var */
+ WORD32 size = 0, size_of_row;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* size of coeff data of 1 mb */
+ size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
+
+ /* size of coeff data of 1 row of mb's */
+ size *= max_mb_cols;
+
+ /* align to avoid false sharing */
+ size = ALIGN64(size);
+ size_of_row = size;
+
+ /* size for one full frame */
+ size *= max_mb_rows;
+
+ ps_codec->u4_size_coeff_data = size_of_row;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf;
+ ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = pu1_buf;
+ }
+ else
+ {
+ ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf + size;
+ ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = pu1_buf + size;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_HEADER_DATA];
+ {
+ /* temp var */
+ WORD32 size, size_of_row;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* size of header data of 1 mb */
+ size = sizeof(isvce_mb_hdr_t);
+
+ /* size for 1 row of mbs */
+ size = size * max_mb_cols;
+
+ /* align to avoid any false sharing across threads */
+ size = ALIGN64(size);
+ size_of_row = size;
+
+ /* size for one full frame */
+ size *= max_mb_rows;
+
+ ps_codec->u4_size_header_data = size_of_row;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf;
+ ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data = pu1_buf;
+ }
+ else
+ {
+ ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf + size;
+ ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data = pu1_buf + size;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MVBITS];
+ {
+ /* max srch range x */
+ UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
+
+ /* max srch range y */
+ UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
+
+ /* max srch range */
+ UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
+
+ /* temp var */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* due to subpel */
+ u4_max_srch_range <<= 2;
+
+ // /* due to mv on either direction */
+ // u4_max_srch_range = (u4_max_srch_range << 1);
+
+ /* due to pred mv + zero */
+ u4_max_srch_range = (u4_max_srch_range << 1) + 1;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ /* me ctxt */
+ isvce_me_ctxt_t *ps_mem_ctxt = &(ps_codec->as_process[i].s_me_ctxt);
+
+ /* init at zero mv */
+ ps_mem_ctxt->pu1_mv_bits = pu1_buf + u4_max_srch_range;
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SPS];
+ {
+ ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PPS];
+ {
+ ps_codec->ps_pps_base = (pps_t *) ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SVC_NALU_EXT];
+ {
+ ps_codec->ps_svc_nalu_ext_base = ps_mem_rec->pv_base;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].ps_svc_nalu_ext_base = ps_mem_rec->pv_base;
+ }
+ else
+ {
+ WORD32 size = SVC_MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
+ void *pv_buf = (UWORD8 *) ps_mem_rec->pv_base + size;
+
+ ps_codec->as_process[i].ps_svc_nalu_ext_base = pv_buf;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SUBSET_SPS];
+ {
+ ps_codec->ps_subset_sps_base = ps_mem_rec->pv_base;
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ ps_codec->as_process[i].ps_subset_sps_base = ps_mem_rec->pv_base;
+ }
+ }
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SLICE_HDR];
+ {
+ ps_codec->ps_slice_hdr_base = ps_mem_rec->pv_base;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].ps_slice_hdr_base = ps_mem_rec->pv_base;
+ }
+ else
+ {
+ /* temp var */
+ WORD32 size = SVC_MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
+ void *pv_buf = (UWORD8 *) ps_mem_rec->pv_base + size;
+
+ ps_codec->as_process[i].ps_slice_hdr_base = pv_buf;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SVC_SLICE_HDR];
+ {
+ ps_codec->ps_svc_slice_hdr_base = ps_mem_rec->pv_base;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ ps_codec->as_process[i].ps_svc_slice_hdr_base = ps_mem_rec->pv_base;
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_AIR_MAP];
+ {
+ /* temp var */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf;
+ }
+ else
+ {
+ ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf + max_mb_cnt;
+ }
+ }
+
+ ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * MAX_CTXT_SETS);
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_SLICE_MAP];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf_ping, *pu1_buf_pong;
+
+ /* init pointer */
+ pu1_buf_ping = ps_mem_rec->pv_base;
+ pu1_buf_pong = pu1_buf_ping + ALIGN64(max_mb_cnt);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pu1_slice_idx = pu1_buf_ping;
+ }
+ else
+ {
+ ps_codec->as_process[i].pu1_slice_idx = pu1_buf_pong;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_THREAD_HANDLE];
+ {
+ WORD32 handle_size = ithread_get_handle_size();
+
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
+ {
+ ps_codec->apv_proc_thread_handle[i] =
+ (UWORD8 *) ps_mem_rec->pv_base + (i * handle_size);
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CTL_MUTEX];
+ {
+ ps_codec->pv_ctl_mutex = ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY_MUTEX];
+ {
+ ps_codec->pv_entropy_mutex = ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_JOBQ];
+ {
+ ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
+ ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ENTROPY_JOBQ];
+ {
+ ps_codec->pv_entropy_jobq_buf = ps_mem_rec->pv_base;
+ ps_codec->i4_entropy_jobq_buf_size = ps_mem_rec->u4_mem_size;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_MAP];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pu1_proc_map = pu1_buf + max_mb_cols;
+ }
+ else
+ {
+ ps_codec->as_process[i].pu1_proc_map = pu1_buf + total_size + max_mb_cols;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_DBLK_MAP];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ /*Align the memory offsets*/
+ total_size = ALIGN64(total_size);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pu1_deblk_map = pu1_buf + max_mb_cols;
+ }
+ else
+ {
+ ps_codec->as_process[i].pu1_deblk_map = pu1_buf + total_size + max_mb_cols;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_ME_MAP];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
+
+ /* total size of the mem record */
+ WORD32 total_size = 0;
+
+ /* size in bytes to mb core coding status of an entire frame */
+ total_size = max_mb_cnt;
+
+ /* add an additional 1 row of bytes to evade the special case of row 0 */
+ total_size += max_mb_cols;
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ if(i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
+ {
+ ps_codec->as_process[i].pu1_me_map = pu1_buf + max_mb_cols;
+ }
+ else
+ {
+ ps_codec->as_process[i].pu1_me_map = pu1_buf + total_size + max_mb_cols;
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_DPB_MGR];
+ {
+ ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_PROC_SCRATCH];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
+
+ /* size of pred buffer, fwd transform output, temp buffer for inv tra */
+ WORD32 size_pred_luma, size_pred_chroma, size_fwd, size_inv, size_hp;
+
+ /* temp var */
+ WORD32 size = 0;
+
+ /* size to hold intra/inter prediction buffer */
+ size_pred_luma = sizeof(UWORD8) * 16 * 16;
+ size_pred_chroma = sizeof(UWORD8) * 8 * 16;
+
+ /* size to hold fwd transform output */
+ size_fwd = sizeof(WORD16) * SIZE_TRANS_BUFF;
+
+ /* size to hold temporary data during inverse transform */
+ size_inv = sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
+
+ /* size to hold half pel plane buffers */
+ size_hp = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ /* prediction buffer */
+ ps_codec->as_process[i].pu1_pred_mb = (void *) (pu1_buf + size);
+ ps_codec->as_process[i].i4_pred_strd = 16;
+ size += size_pred_luma;
+ size = ALIGN64(size);
+
+ /* prediction buffer */
+ ps_codec->as_process[i].pu1_ref_mb_intra_4x4 = (void *) (pu1_buf + size);
+ size += size_pred_luma;
+ size = ALIGN64(size);
+
+ /* prediction buffer intra 16x16 */
+ ps_codec->as_process[i].pu1_pred_mb_intra_16x16 = (void *) (pu1_buf + size);
+ size += size_pred_luma;
+ size = ALIGN64(size);
+
+ /* prediction buffer intra 16x16 plane*/
+ ps_codec->as_process[i].pu1_pred_mb_intra_16x16_plane = (void *) (pu1_buf + size);
+ size += size_pred_luma;
+ size = ALIGN64(size);
+
+ /* prediction buffer intra chroma*/
+ ps_codec->as_process[i].pu1_pred_mb_intra_chroma = (void *) (pu1_buf + size);
+ size += size_pred_chroma;
+ size = ALIGN64(size);
+
+ /* prediction buffer intra chroma plane*/
+ ps_codec->as_process[i].pu1_pred_mb_intra_chroma_plane = (void *) (pu1_buf + size);
+ size += size_pred_chroma;
+ size = ALIGN64(size);
+
+ /* Fwd transform output */
+ ps_codec->as_process[i].pi2_res_buf = (void *) (pu1_buf + size);
+ ps_codec->as_process[i].i4_res_strd = 16;
+ size += size_fwd;
+ size = ALIGN64(size);
+
+ /* Fwd transform output */
+ ps_codec->as_process[i].pi2_res_buf_intra_4x4 = (void *) (pu1_buf + size);
+ size += size_fwd;
+ size = ALIGN64(size);
+
+ /* scratch buffer used during inverse transform */
+ ps_codec->as_process[i].pv_scratch_buff = (void *) (pu1_buf + size);
+ size += size_inv;
+ size = ALIGN64(size);
+
+ for(j = 0; j < SUBPEL_BUFF_CNT; j++)
+ {
+ ps_codec->as_process[i].apu1_subpel_buffs[j] = (pu1_buf + size);
+ size += ALIGN64(size_hp);
+ }
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_QUANT_PARAM];
+ {
+ /* pointer to storage space */
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
+
+ /* size of qp, threshold matrix, fwd scaling list for one plane */
+ WORD32 size_quant_param, size_thres_mat, size_fwd_weight_mat, size_satqd_weight_mat;
+
+ /* temp var */
+ WORD32 total_size = 0;
+
+ /* size of quantization parameter list of 1 plane */
+ size_quant_param = ALIGN64(sizeof(quant_params_t));
+
+ /* size of threshold matrix for quantization
+ * (assuming the transform_8x8_flag is disabled).
+ * for 1 plane */
+ size_thres_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
+
+ /* size of forward weight matrix for quantization
+ * (assuming the transform_8x8_flag is disabled).
+ * for 1 plane */
+ size_fwd_weight_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
+
+ /* size of SATQD matrix*/
+ size_satqd_weight_mat = ALIGN64(sizeof(UWORD16) * 9);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ quant_params_t **ps_qp_params = ps_codec->as_process[i].ps_qp_params;
+
+ /* quantization param structure */
+ ps_qp_params[0] = (quant_params_t *) (pu1_buf + total_size);
+ total_size = total_size + size_quant_param;
+ ps_qp_params[1] = (quant_params_t *) (pu1_buf + total_size);
+ total_size = total_size + size_quant_param;
+ ps_qp_params[2] = (quant_params_t *) (pu1_buf + total_size);
+ total_size = total_size + size_quant_param;
+
+ /* threshold matrix for quantization */
+ ps_qp_params[0]->pu2_thres_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_thres_mat;
+ ps_qp_params[1]->pu2_thres_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_thres_mat;
+ ps_qp_params[2]->pu2_thres_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_thres_mat;
+
+ /* fwd weight matrix */
+ ps_qp_params[0]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_fwd_weight_mat;
+ ps_qp_params[1]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_fwd_weight_mat;
+ ps_qp_params[2]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_fwd_weight_mat;
+
+ /* threshold matrix for SATQD */
+ ps_qp_params[0]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_satqd_weight_mat;
+ ps_qp_params[1]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_satqd_weight_mat;
+ ps_qp_params[2]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
+ total_size = total_size + size_satqd_weight_mat;
+
+ total_size = ALIGN128(total_size);
+ }
+ }
+
+ isvce_svc_nbr_info_buf_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_REC_TOP_ROW_SYN_INFO]);
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_BS_QP];
+ {
+ UWORD8 *pu1_buf_ping;
+
+ /* size in bytes to store vertical edge bs, horizontal edge bs and qp of
+ * every mb*/
+ WORD32 vert_bs_size, horz_bs_size, qp_size;
+
+ /* vertical edge bs = total number of vertical edges * number of bytes per
+ * each edge */
+ /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
+ * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing
+ * bs */
+ vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
+
+ /* horizontal edge bs = total number of horizontal edges * number of bytes
+ * per each edge */
+ /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
+ * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing
+ * bs */
+ horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
+
+ /* qp of each mb requires 1 byte */
+ qp_size = ALIGN64(max_mb_cnt);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ pu1_buf_ping = (UWORD8 *) ps_mem_rec->pv_base;
+
+ /* vertical edge bs storage space */
+ ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs =
+ (UWORD32 *) pu1_buf_ping;
+ pu1_buf_ping += vert_bs_size;
+
+ ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_intra_base_vert_bs =
+ (UWORD32 *) pu1_buf_ping;
+ pu1_buf_ping += vert_bs_size;
+
+ /* horizontal edge bs storage space */
+ ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs =
+ (UWORD32 *) pu1_buf_ping;
+ pu1_buf_ping += horz_bs_size;
+
+ ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_intra_base_horz_bs =
+ (UWORD32 *) pu1_buf_ping;
+ pu1_buf_ping += horz_bs_size;
+
+ /* qp */
+ ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *) pu1_buf_ping;
+ pu1_buf_ping += qp_size;
+ }
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_INP_PIC];
+ {
+ ps_codec->pv_inp_buf_mgr_base = ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_OUT];
+ {
+ ps_codec->pv_out_buf_mgr_base = ps_mem_rec->pv_base;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_CSC];
+ {
+ ps_codec->pu1_y_csc_buf_base = ps_mem_rec->pv_base;
+ ps_codec->pu1_uv_csc_buf_base =
+ (UWORD8 *) ps_mem_rec->pv_base + (max_ht_luma * max_wd_luma);
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_REF_PIC];
+ {
+ /* size of buf mgr struct */
+ WORD32 size = ih264_buf_mgr_size();
+
+ /* temp var */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* pic buffer mgr */
+ ps_codec->pv_ref_buf_mgr_base = pu1_buf;
+
+ /* picture bank */
+ ps_codec->ps_pic_buf_base = (svc_au_buf_t *) (pu1_buf + size);
+ ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - size;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MVBANK];
+ {
+ /* size of buf mgr struct */
+ WORD32 size = ih264_buf_mgr_size();
+
+ /* temp var */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* mv buffer mgr */
+ ps_codec->pv_svc_au_data_store_mgr_base = pu1_buf;
+
+ /* mv bank */
+ ps_codec->ps_svc_au_data_base = (svc_au_data_t *) (pu1_buf + size);
+ ps_codec->i4_svc_au_data_size = ps_mem_rec->u4_mem_size - size;
+ }
+
+ ps_mem_rec = &ps_mem_rec_base[ISVCE_MEM_REC_MB_INFO_NMB];
+ {
+ /* temp var */
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+
+ /* size of nmb ctxt */
+ WORD32 size = max_mb_cols * sizeof(isvce_mb_info_nmb_t);
+
+ WORD32 nmb_cntr, subpel_buf_size;
+
+ /* init nmb info structure pointer in all proc ctxts */
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ ps_codec->as_process[i].ps_nmb_info = (isvce_mb_info_nmb_t *) (pu1_buf);
+
+ pu1_buf += size;
+ }
+
+ /* Additional 4 bytes to allow use of '_mm_loadl_epi64' */
+ subpel_buf_size = (MB_SIZE * MB_SIZE + 4) * sizeof(UWORD8);
+
+ /* adjusting pointers for nmb halfpel buffer */
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ isvce_mb_info_nmb_t *ps_mb_info_nmb = &ps_codec->as_process[i].ps_nmb_info[0];
+
+ for(nmb_cntr = 0; nmb_cntr < max_mb_cols; nmb_cntr++)
+ {
+ ps_mb_info_nmb[nmb_cntr].pu1_best_sub_pel_buf = pu1_buf;
+
+ pu1_buf = pu1_buf + subpel_buf_size;
+
+ ps_mb_info_nmb[nmb_cntr].u4_bst_spel_buf_strd = MB_SIZE;
+ }
+ }
+ }
+
+ isvce_svc_inp_buf_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_SPAT_INP]);
+
+ isvce_initialize_downscaler(&ps_codec->s_scaler, &ps_mem_rec_base[ISVCE_MEM_DOWN_SCALER],
+ ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio,
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers,
+ ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht,
+ ps_codec->s_cfg.e_arch);
+
+ isvce_svc_ilp_buf_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_ILP_DATA]);
+
+ isvce_ilp_mv_ctxt_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_ILP_MV_CTXT]);
+
+ isvce_svc_res_pred_ctxt_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_RES_PRED_CTXT]);
+
+ isvce_intra_pred_ctxt_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_INTRA_PRED_CTXT]);
+
+ isvce_rc_utils_init(&ps_codec->s_rate_control.s_rc_utils,
+ &ps_mem_rec_base[ISVCE_MEM_SVC_RC_UTILS_CTXT], ps_codec->s_cfg.e_arch);
+
+#if ENABLE_MODE_STAT_VISUALISER
+ isvce_msv_ctxt_init(ps_codec, &ps_mem_rec_base[MEM_MODE_STAT_VISUALISER_BUF]);
+#endif
+
+ isvce_get_rate_control_mem_tab(&ps_codec->s_rate_control, &ps_mem_rec_base[ISVCE_MEM_REC_RC],
+ USE_BASE);
+
+ isvce_sub_pic_rc_ctxt_init(ps_codec, &ps_mem_rec_base[ISVCE_MEM_SVC_SUB_PIC_RC_CTXT]);
+
+ status = isvce_init(ps_codec);
+
+ return status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Retrieves mem records passed to the codec
+*
+* @par Description:
+* Retrieves mem recs passed during init
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_retrieve_memrec(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ isvce_codec_t *ps_codec = (isvce_codec_t *) ps_codec_obj->pv_codec_handle;
+
+ /* ctrl call I/O structures */
+ isvce_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip;
+ isvce_retrieve_mem_rec_op_t *ps_op = pv_api_op;
+
+ if(ps_codec->i4_init_done != 1)
+ {
+ ps_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
+ ps_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
+ return IV_FAIL;
+ }
+
+ /* join threads upon at end of sequence */
+ isvce_join_threads(ps_codec);
+
+ /* collect list of memory records used by the encoder library */
+ memcpy(ps_ip->s_ive_ip.ps_mem_rec, ps_codec->ps_mem_rec_backup,
+ ISVCE_MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
+ ps_op->s_ive_op.u4_num_mem_rec_filled = ISVCE_MEM_REC_CNT;
+
+ /* clean up mutex memory */
+ ih264_list_free(ps_codec->pv_entropy_jobq);
+ ih264_list_free(ps_codec->pv_proc_jobq);
+ ithread_mutex_destroy(ps_codec->pv_ctl_mutex);
+ ithread_mutex_destroy(ps_codec->pv_entropy_mutex);
+
+ ih264_buf_mgr_free((buf_mgr_t *) ps_codec->pv_svc_au_data_store_mgr);
+ ih264_buf_mgr_free((buf_mgr_t *) ps_codec->pv_ref_buf_mgr);
+ ih264_buf_mgr_free((buf_mgr_t *) ps_codec->pv_inp_buf_mgr);
+ ih264_buf_mgr_free((buf_mgr_t *) ps_codec->pv_out_buf_mgr);
+
+#if ENABLE_MODE_STAT_VISUALISER
+ isvce_msv_ctxt_delete(ps_codec->ps_mode_stat_visualiser);
+#endif
+
+ isvce_sub_pic_rc_ctxt_delete(ps_codec->as_process->ps_sub_pic_rc_ctxt);
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets the encoder in flush mode.
+*
+* @par Description:
+* Sets the encoder in flush mode
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks This call has no real effect on encoder
+*
+*******************************************************************************
+*/
+static WORD32 isvce_set_flush_mode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ /* codec ctxt */
+ isvce_codec_t *ps_codec = (isvce_codec_t *) ps_codec_obj->pv_codec_handle;
+
+ /* ctrl call I/O structures */
+ isvce_ctl_flush_op_t *ps_ctl_op = pv_api_op;
+
+ UNUSED(pv_api_ip);
+
+ ps_ctl_op->s_ive_op.u4_error_code = 0;
+
+ /* signal flush frame control call */
+ ps_codec->i4_flush_mode = 1;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Gets encoder buffer requirements
+*
+* @par Description:
+* Gets the encoder buffer requirements. Basing on max width and max height
+* configuration settings, this routine, computes the sizes of necessary input,
+* output buffers returns this info to callee.
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_get_buf_info(void *pv_codec_handle, void *pv_api_ip, void *pv_api_op)
+{
+ WORD32 i;
+ UWORD32 wd, ht;
+
+ isvce_codec_t *ps_codec = (isvce_codec_t *) pv_codec_handle;
+ isvce_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_getbufinfo_op_t *ps_op = pv_api_op;
+
+ isvce_get_svc_compliant_dimensions(ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers,
+ ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio,
+ ALIGN16(ps_ip->s_ive_ip.u4_max_wd),
+ ALIGN16(ps_ip->s_ive_ip.u4_max_ht), &wd, &ht);
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ /* Number of components in input buffers required for codec &
+ * Minimum sizes of each component in input buffer required */
+ if(ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420P)
+ {
+ ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420_COMP;
+
+ ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
+ ps_op->s_ive_op.au4_min_in_buf_size[1] = (wd >> 1) * (ht >> 1);
+ ps_op->s_ive_op.au4_min_in_buf_size[2] = (wd >> 1) * (ht >> 1);
+ }
+ else if(ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_422ILE)
+ {
+ ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_422ILE_COMP;
+
+ ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
+ ps_op->s_ive_op.au4_min_in_buf_size[1] = ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
+ }
+ else if(ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGB_565)
+ {
+ ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGB565_COMP;
+
+ ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
+ ps_op->s_ive_op.au4_min_in_buf_size[1] = ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
+ }
+ else if(ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGBA_8888)
+ {
+ ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGBA8888_COMP;
+
+ ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 4;
+ ps_op->s_ive_op.au4_min_in_buf_size[1] = ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
+ }
+ else if((ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_UV) ||
+ (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_VU))
+ {
+ ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420SP_COMP;
+
+ ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
+ ps_op->s_ive_op.au4_min_in_buf_size[1] = wd * (ht >> 1);
+ ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
+ }
+
+ /* Number of components in output buffers required for codec &
+ * Minimum sizes of each component in output buffer required */
+ ps_op->s_ive_op.u4_out_comp_cnt = MIN_BITS_BUFS_COMP;
+
+ for(i = 0; i < (WORD32) ps_op->s_ive_op.u4_out_comp_cnt; i++)
+ {
+ ps_op->s_ive_op.au4_min_out_buf_size[i] =
+ isvce_get_min_outbuf_size(wd, ht, ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
+ }
+
+ ps_op->u4_rec_comp_cnt = MIN_RAW_BUFS_420_COMP;
+ ps_op->au4_min_rec_buf_size[0] = wd * ht;
+ ps_op->au4_min_rec_buf_size[1] = (wd >> 1) * (ht >> 1);
+ ps_op->au4_min_rec_buf_size[2] = (wd >> 1) * (ht >> 1);
+
+ if(ps_codec->s_cfg.b_nalu_info_export_enable)
+ {
+ ps_op->u4_min_nalu_info_buf_size =
+ isvce_get_nalu_info_buf_size(ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
+ }
+ else
+ {
+ ps_op->u4_min_nalu_info_buf_size = 0;
+ }
+
+ ps_op->s_ive_op.u4_min_inp_bufs = MIN_INP_BUFS;
+ ps_op->s_ive_op.u4_min_out_bufs = MIN_OUT_BUFS;
+ ps_op->u4_min_rec_bufs = MIN_OUT_BUFS;
+ ps_op->u4_min_nalu_info_bufs = MIN_OUT_BUFS;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets the picture dimensions
+*
+* @par Description:
+* Sets width, height, display width, display height and strides
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_dimensions(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ isvce_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_dimensions_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ isvce_get_svc_compliant_dimensions(
+ ps_cfg->s_svc_params.u1_num_spatial_layers, ps_cfg->s_svc_params.d_spatial_res_ratio,
+ ps_ip->s_ive_ip.u4_wd, ps_ip->s_ive_ip.u4_ht, &ps_cfg->u4_wd, &ps_cfg->u4_ht);
+
+ ASSERT(0 == (ps_cfg->u4_wd % MB_SIZE));
+ ASSERT(0 == (ps_cfg->u4_ht % MB_SIZE));
+
+ ps_cfg->i4_wd_mbs = ps_cfg->u4_wd / MB_SIZE;
+ ps_cfg->i4_ht_mbs = ps_cfg->u4_ht / MB_SIZE;
+ ps_cfg->u4_disp_wd = ps_cfg->u4_wd;
+ ps_cfg->u4_disp_ht = ps_cfg->u4_ht;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Provide dimensions used for encoding
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_get_enc_frame_dimensions(isvce_ctl_get_enc_dimensions_ip_t *ps_ip,
+ isvce_ctl_get_enc_dimensions_op_t *ps_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ ps_op->u4_error_code = IVE_ERR_NONE;
+
+ isvce_get_svc_compliant_dimensions(ps_cfg->s_svc_params.u1_num_spatial_layers,
+ ps_cfg->s_svc_params.d_spatial_res_ratio,
+ ps_ip->u4_inp_frame_wd, ps_ip->u4_inp_frame_ht,
+ &ps_op->u4_enc_frame_wd, &ps_op->u4_enc_frame_ht);
+
+ ASSERT(ps_cfg->u4_wd == ps_op->u4_enc_frame_wd);
+ ASSERT(ps_cfg->u4_ht == ps_op->u4_enc_frame_ht);
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets source and target frame rates
+*
+* @par Description:
+* Sets source and target frame rates
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_frame_rate(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_frame_rate_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_src_frame_rate = ps_ip->s_ive_ip.u4_src_frame_rate;
+ ps_cfg->u4_tgt_frame_rate = ps_ip->s_ive_ip.u4_tgt_frame_rate;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets target bit rate
+*
+* @par Description:
+* Sets target bit rate
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_bit_rate(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_bitrate_op_t *ps_op = pv_api_op;
+ WORD8 i;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_cfg->au4_target_bitrate[i] = ps_ip->pu4_target_bitrate[i];
+ }
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets frame type
+*
+* @par Description:
+* Sets frame type
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks not a sticky tag
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_frame_type(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_frame_type_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->e_frame_type = ps_ip->s_ive_ip.e_frame_type;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets quantization params
+*
+* @par Description:
+* Sets the max, min and default qp for I frame, P frame and B frame
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_qp(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_qp_ip_t *ps_set_qp_ip = pv_api_ip;
+ isvce_ctl_set_qp_op_t *ps_set_qp_op = pv_api_op;
+ WORD8 i;
+
+ ps_set_qp_op->s_ive_op.u4_error_code = 0;
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_cfg->au4_i_qp_max[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_max[i]);
+ ps_cfg->au4_i_qp_min[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_min[i]);
+ ps_cfg->au4_i_qp[i] = CLIP3(ps_set_qp_ip->pu4_i_qp_min[i], ps_set_qp_ip->pu4_i_qp_max[i],
+ ps_set_qp_ip->pu4_i_qp[i]);
+ ps_cfg->au4_i_qp_max[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_max[i]);
+ ps_cfg->au4_i_qp_min[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_min[i]);
+ ps_cfg->au4_i_qp[i] = CLIP3(ps_set_qp_ip->pu4_i_qp_min[i], ps_set_qp_ip->pu4_i_qp_max[i],
+ ps_set_qp_ip->pu4_i_qp[i]);
+ ps_cfg->au4_i_qp_max[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_max[i]);
+ ps_cfg->au4_i_qp_min[i] =
+ CLIP3(MIN_H264_QP, MAX_H264_QP, (WORD32) ps_set_qp_ip->pu4_i_qp_min[i]);
+ ps_cfg->au4_i_qp[i] = CLIP3(ps_set_qp_ip->pu4_i_qp_min[i], ps_set_qp_ip->pu4_i_qp_max[i],
+ ps_set_qp_ip->pu4_i_qp[i]);
+ }
+
+ ps_cfg->u4_timestamp_high = ps_set_qp_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_set_qp_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets encoding mode
+*
+* @par Description:
+* Sets encoding mode
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_enc_mode(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->e_enc_mode = ps_ip->s_ive_ip.e_enc_mode;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets vbv parameters
+*
+* @par Description:
+* Sets vbv parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvce_set_vbv_params(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
+ WORD8 i;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_cfg->au4_vbv_buffer_delay[i] = ps_ip->pu4_vbv_buffer_delay[i];
+ }
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets AIR parameters
+*
+* @par Description:
+* Sets AIR parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvc_set_air_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_air_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->e_air_mode = ps_ip->s_ive_ip.e_air_mode;
+ ps_cfg->u4_air_refresh_period = ps_ip->s_ive_ip.u4_air_refresh_period;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets motion estimation parameters
+*
+* @par Description:
+* Sets motion estimation parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvc_set_me_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_me_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_me_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_enable_hpel = ps_ip->s_ive_ip.u4_enable_hpel;
+ ps_cfg->u4_enable_qpel = ps_ip->s_ive_ip.u4_enable_qpel;
+ ps_cfg->u4_enable_fast_sad = ps_ip->s_ive_ip.u4_enable_fast_sad;
+ ps_cfg->u4_enable_alt_ref = ps_ip->s_ive_ip.u4_enable_alt_ref;
+ ps_cfg->u4_srch_rng_x = ps_ip->s_ive_ip.u4_srch_rng_x;
+ ps_cfg->u4_srch_rng_y = ps_ip->s_ive_ip.u4_srch_rng_y;
+ ps_cfg->u4_me_speed_preset = ps_ip->s_ive_ip.u4_me_speed_preset;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets Intra/Inter Prediction estimation parameters
+*
+* @par Description:
+* Sets Intra/Inter Prediction estimation parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvc_set_ipe_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_ipe_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4;
+ ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets GOP parameters
+*
+* @par Description:
+* Sets GOP parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvc_set_gop_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_gop_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_i_frm_interval = ps_ip->s_ive_ip.u4_i_frm_interval;
+ ps_cfg->u4_idr_frm_interval = ps_ip->s_ive_ip.u4_idr_frm_interval;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets profile parameters
+*
+* @par Description:
+* Sets profile parameters
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @param[out] ps_cfg
+* Pointer to config structure to be updated
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IV_STATUS_T isvc_set_profile_params(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_profile_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->e_profile = ps_ip->s_ive_ip.e_profile;
+
+ ps_cfg->u4_entropy_coding_mode = ps_ip->s_ive_ip.u4_entropy_coding_mode;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets disable deblock level
+*
+* @par Description:
+* Sets disable deblock level. Level 0 means no disabling and level 4 means
+* disable completely. 1, 2, 3 are intermediate levels that control amount
+* of deblocking done.
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvc_set_deblock_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_disable_deblock_level = ps_ip->s_ive_ip.u4_disable_deblock_level;
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets vui params
+ *
+ * @par Description:
+ * Video usability information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @returns error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 isvce_set_vui_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_vui_ip_t *ps_ip = pv_api_ip;
+ isvce_vui_op_t *ps_op = pv_api_op;
+ vui_t *ps_vui = &ps_cfg->s_vui;
+
+ ps_op->u4_error_code = 0;
+
+ ps_vui->u1_aspect_ratio_info_present_flag = ps_ip->u1_aspect_ratio_info_present_flag;
+ ps_vui->u1_aspect_ratio_idc = ps_ip->u1_aspect_ratio_idc;
+ ps_vui->u2_sar_width = ps_ip->u2_sar_width;
+ ps_vui->u2_sar_height = ps_ip->u2_sar_height;
+ ps_vui->u1_overscan_info_present_flag = ps_ip->u1_overscan_info_present_flag;
+ ps_vui->u1_overscan_appropriate_flag = ps_ip->u1_overscan_appropriate_flag;
+ ps_vui->u1_video_signal_type_present_flag = ps_ip->u1_video_signal_type_present_flag;
+ ps_vui->u1_video_format = ps_ip->u1_video_format;
+ ps_vui->u1_video_full_range_flag = ps_ip->u1_video_full_range_flag;
+ ps_vui->u1_colour_description_present_flag = ps_ip->u1_colour_description_present_flag;
+ ps_vui->u1_colour_primaries = ps_ip->u1_colour_primaries;
+ ps_vui->u1_transfer_characteristics = ps_ip->u1_transfer_characteristics;
+ ps_vui->u1_matrix_coefficients = ps_ip->u1_matrix_coefficients;
+ ps_vui->u1_chroma_loc_info_present_flag = ps_ip->u1_chroma_loc_info_present_flag;
+ ps_vui->u1_chroma_sample_loc_type_top_field = ps_ip->u1_chroma_sample_loc_type_top_field;
+ ps_vui->u1_chroma_sample_loc_type_bottom_field = ps_ip->u1_chroma_sample_loc_type_bottom_field;
+ ps_vui->u1_vui_timing_info_present_flag = ps_ip->u1_vui_timing_info_present_flag;
+ ps_vui->u4_vui_num_units_in_tick = ps_ip->u4_vui_num_units_in_tick;
+ ps_vui->u4_vui_time_scale = ps_ip->u4_vui_time_scale;
+ ps_vui->u1_fixed_frame_rate_flag = ps_ip->u1_fixed_frame_rate_flag;
+ ps_vui->u1_nal_hrd_parameters_present_flag = ps_ip->u1_nal_hrd_parameters_present_flag;
+ ps_vui->u1_vcl_hrd_parameters_present_flag = ps_ip->u1_vcl_hrd_parameters_present_flag;
+ ps_vui->u1_low_delay_hrd_flag = ps_ip->u1_low_delay_hrd_flag;
+ ps_vui->u1_pic_struct_present_flag = ps_ip->u1_pic_struct_present_flag;
+ ps_vui->u1_bitstream_restriction_flag = ps_ip->u1_bitstream_restriction_flag;
+ ps_vui->u1_motion_vectors_over_pic_boundaries_flag =
+ ps_ip->u1_motion_vectors_over_pic_boundaries_flag;
+ ps_vui->u1_max_bytes_per_pic_denom = ps_ip->u1_max_bytes_per_pic_denom;
+ ps_vui->u1_max_bits_per_mb_denom = ps_ip->u1_max_bits_per_mb_denom;
+ ps_vui->u1_log2_max_mv_length_horizontal = ps_ip->u1_log2_max_mv_length_horizontal;
+ ps_vui->u1_log2_max_mv_length_vertical = ps_ip->u1_log2_max_mv_length_vertical;
+ ps_vui->u1_num_reorder_frames = ps_ip->u1_num_reorder_frames;
+ ps_vui->u1_max_dec_frame_buffering = ps_ip->u1_max_dec_frame_buffering;
+
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets Mastering display color volume sei params
+ *
+ * @par Description:
+ * Supplemental enhancement information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @return error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 isvce_set_sei_mdcv_params(void *pv_api_ip, void *pv_api_op,
+ isvce_cfg_params_t *ps_cfg)
+{
+ WORD32 i4_count;
+ /* ctrl call I/O structures */
+ isvce_ctl_set_sei_mdcv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_mdcv_params_op_t *ps_op = pv_api_op;
+ sei_params_t *ps_sei = &ps_cfg->s_sei;
+
+ ps_op->u4_error_code = 0;
+
+ ps_sei->u1_sei_mdcv_params_present_flag = ps_ip->u1_sei_mdcv_params_present_flag;
+ for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
+ {
+ ps_sei->s_sei_mdcv_params.au2_display_primaries_x[i4_count] =
+ ps_ip->au2_display_primaries_x[i4_count];
+ ps_sei->s_sei_mdcv_params.au2_display_primaries_y[i4_count] =
+ ps_ip->au2_display_primaries_y[i4_count];
+ }
+
+ ps_sei->s_sei_mdcv_params.u2_white_point_x = ps_ip->u2_white_point_x;
+ ps_sei->s_sei_mdcv_params.u2_white_point_y = ps_ip->u2_white_point_y;
+ ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance =
+ ps_ip->u4_max_display_mastering_luminance;
+ ps_sei->s_sei_mdcv_params.u4_min_display_mastering_luminance =
+ ps_ip->u4_min_display_mastering_luminance;
+
+ ps_cfg->u4_timestamp_high = ps_ip->u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets content light level sei params
+ *
+ * @par Description:
+ * Supplemental enhancement information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @return error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 isvce_set_sei_cll_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_sei_cll_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_cll_params_op_t *ps_op = pv_api_op;
+ sei_params_t *ps_sei = &ps_cfg->s_sei;
+
+ ps_op->u4_error_code = 0;
+
+ ps_sei->u1_sei_cll_params_present_flag = ps_ip->u1_sei_cll_params_present_flag;
+
+ ps_sei->s_sei_cll_params.u2_max_content_light_level = ps_ip->u2_max_content_light_level;
+ ps_sei->s_sei_cll_params.u2_max_pic_average_light_level = ps_ip->u2_max_pic_average_light_level;
+
+ ps_cfg->u4_timestamp_high = ps_ip->u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets ambient viewing environment sei params
+ *
+ * @par Description:
+ * Supplemental enhancement information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @return error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 isvce_set_sei_ave_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_sei_ave_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_ave_params_op_t *ps_op = pv_api_op;
+ sei_params_t *ps_sei = &ps_cfg->s_sei;
+
+ ps_op->u4_error_code = 0;
+
+ ps_sei->u1_sei_ave_params_present_flag = ps_ip->u1_sei_ave_params_present_flag;
+
+ ps_sei->s_sei_ave_params.u4_ambient_illuminance = ps_ip->u4_ambient_illuminance;
+ ps_sei->s_sei_ave_params.u2_ambient_light_x = ps_ip->u2_ambient_light_x;
+ ps_sei->s_sei_ave_params.u2_ambient_light_y = ps_ip->u2_ambient_light_y;
+
+ ps_cfg->u4_timestamp_high = ps_ip->u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Sets content color volume sei params
+ *
+ * @par Description:
+ * Supplemental enhancement information
+ *
+ * @param[in] pv_api_ip
+ * Pointer to input argument structure
+ *
+ * @param[out] pv_api_op
+ * Pointer to output argument structure
+ *
+ * @param[out] ps_cfg
+ * Pointer to config structure to be updated
+ *
+ * @return error status
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+static WORD32 isvce_set_sei_ccv_params(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ WORD32 i4_count;
+ /* ctrl call I/O structures */
+ isvce_ctl_set_sei_ccv_params_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_sei_ccv_params_op_t *ps_op = pv_api_op;
+ sei_params_t *ps_sei = &ps_cfg->s_sei;
+
+ ps_op->u4_error_code = 0;
+
+ ps_sei->u1_sei_ccv_params_present_flag = ps_ip->u1_sei_ccv_params_present_flag;
+
+ ps_sei->s_sei_ccv_params.u1_ccv_cancel_flag = ps_ip->u1_ccv_cancel_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_persistence_flag = ps_ip->u1_ccv_persistence_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_primaries_present_flag = ps_ip->u1_ccv_primaries_present_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag =
+ ps_ip->u1_ccv_min_luminance_value_present_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag =
+ ps_ip->u1_ccv_max_luminance_value_present_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_avg_luminance_value_present_flag =
+ ps_ip->u1_ccv_avg_luminance_value_present_flag;
+ ps_sei->s_sei_ccv_params.u1_ccv_reserved_zero_2bits = ps_ip->u1_ccv_reserved_zero_2bits;
+
+ for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
+ {
+ ps_sei->s_sei_ccv_params.ai4_ccv_primaries_x[i4_count] =
+ ps_ip->ai4_ccv_primaries_x[i4_count];
+ ps_sei->s_sei_ccv_params.ai4_ccv_primaries_y[i4_count] =
+ ps_ip->ai4_ccv_primaries_y[i4_count];
+ }
+
+ ps_sei->s_sei_ccv_params.u4_ccv_min_luminance_value = ps_ip->u4_ccv_min_luminance_value;
+ ps_sei->s_sei_ccv_params.u4_ccv_max_luminance_value = ps_ip->u4_ccv_max_luminance_value;
+ ps_sei->s_sei_ccv_params.u4_ccv_avg_luminance_value = ps_ip->u4_ccv_avg_luminance_value;
+
+ ps_cfg->u4_timestamp_high = ps_ip->u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Sets number of cores
+*
+* @par Description:
+* Sets number of cores
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks The number of encoder threads is limited to MAX_PROCESS_THREADS
+*
+*******************************************************************************
+*/
+static WORD32 isvce_set_num_cores(void *pv_api_ip, void *pv_api_op, isvce_cfg_params_t *ps_cfg)
+{
+ /* ctrl call I/O structures */
+ isvce_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_set_num_cores_op_t *ps_op = pv_api_op;
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ ps_cfg->u4_num_cores = MIN(ps_ip->s_ive_ip.u4_num_cores, MAX_PROCESS_THREADS);
+
+ ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
+ ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
+
+ return IV_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Resets encoder state
+*
+* @par Description:
+* Resets encoder state by calling isvce_init()
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ /* codec ctxt */
+ isvce_codec_t *ps_codec = (isvce_codec_t *) (ps_codec_obj->pv_codec_handle);
+
+ /* ctrl call I/O structures */
+ isvce_ctl_reset_op_t *ps_op = pv_api_op;
+
+ UNUSED(pv_api_ip);
+
+ ps_op->s_ive_op.u4_error_code = 0;
+
+ if(ps_codec != NULL)
+ {
+ isvce_init(ps_codec);
+ }
+ else
+ {
+ ps_op->s_ive_op.u4_error_code = IH264E_INIT_NOT_DONE;
+ }
+
+ return IV_SUCCESS;
+}
+
+static void isvce_ctl_set_error_code(void *pv_api_op, ISVCE_CONTROL_API_COMMAND_TYPE_T e_sub_cmd)
+{
+ switch(e_sub_cmd)
+ {
+ case ISVCE_CMD_CTL_SET_DIMENSIONS:
+ {
+ ((isvce_ctl_set_dimensions_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_dimensions_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_FRAMERATE:
+ {
+ ((isvce_ctl_set_frame_rate_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_frame_rate_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_BITRATE:
+ {
+ ((isvce_ctl_set_bitrate_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1
+ << IVE_FATALERROR;
+ ((isvce_ctl_set_bitrate_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_FRAMETYPE:
+ {
+ ((isvce_ctl_set_frame_type_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_frame_type_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_QP:
+ {
+ ((isvce_ctl_set_qp_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_qp_op_t *) pv_api_op)->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_ENC_MODE:
+ {
+ ((isvce_ctl_set_enc_mode_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_enc_mode_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_VBV_PARAMS:
+ {
+ ((isvce_ctl_set_vbv_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_vbv_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_AIR_PARAMS:
+ {
+ ((isvce_ctl_set_air_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_air_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_ME_PARAMS:
+ {
+ ((isvce_ctl_set_me_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_me_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_IPE_PARAMS:
+ {
+ ((isvce_ctl_set_ipe_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_ipe_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_GOP_PARAMS:
+ {
+ ((isvce_ctl_set_gop_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_gop_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_PROFILE_PARAMS:
+ {
+ ((isvce_ctl_set_profile_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_profile_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS:
+ {
+ ((isvce_ctl_set_deblock_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_deblock_params_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_VUI_PARAMS:
+ {
+ ((isvce_vui_op_t *) pv_api_op)->u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_vui_op_t *) pv_api_op)->u4_error_code |= IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS:
+ {
+ ((isvce_ctl_set_sei_mdcv_params_op_t *) pv_api_op)->u4_error_code |= 1
+ << IVE_FATALERROR;
+ ((isvce_ctl_set_sei_mdcv_params_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS:
+ {
+ ((isvce_ctl_set_sei_cll_params_op_t *) pv_api_op)->u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_sei_cll_params_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS:
+ {
+ ((isvce_ctl_set_sei_ave_params_op_t *) pv_api_op)->u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_sei_ave_params_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS:
+ {
+ ((isvce_ctl_set_sei_ccv_params_op_t *) pv_api_op)->u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_sei_ccv_params_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_RESET:
+ {
+ ((isvce_ctl_reset_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_reset_op_t *) pv_api_op)->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SETDEFAULT:
+ {
+ ((isvce_ctl_setdefault_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1
+ << IVE_FATALERROR;
+ ((isvce_ctl_setdefault_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_FLUSH:
+ {
+ ((isvce_ctl_flush_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_flush_op_t *) pv_api_op)->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_GETBUFINFO:
+ {
+ ((isvce_ctl_getbufinfo_op_t *) pv_api_op)->s_ive_op.u4_error_code |= 1
+ << IVE_FATALERROR;
+ ((isvce_ctl_getbufinfo_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_GETVERSION:
+ {
+ ((isvce_ctl_getversioninfo_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_getversioninfo_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_SET_NUM_CORES:
+ {
+ ((isvce_ctl_set_num_cores_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_set_num_cores_op_t *) pv_api_op)->s_ive_op.u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ case ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS:
+ {
+ ((isvce_ctl_get_enc_dimensions_op_t *) pv_api_op)->u4_error_code |= 1 << IVE_FATALERROR;
+ ((isvce_ctl_get_enc_dimensions_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_INIT_NOT_DONE;
+
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Codec control call
+*
+* @par Description:
+* Codec control call which in turn calls appropriate calls based on
+*sub-command
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static WORD32 isvce_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op,
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_ctl_cmd)
+{
+ WORD32 i;
+
+ isvce_codec_t *ps_codec = (isvce_codec_t *) ps_codec_obj->pv_codec_handle;
+ isvce_cfg_params_t *ps_cfg = NULL;
+
+ IV_STATUS_T ret = IV_SUCCESS;
+
+ /* control call is for configuring encoding params, this is not to be called
+ * before a successful init call */
+ if(ps_codec->i4_init_done != 1)
+ {
+ isvce_ctl_set_error_code(pv_api_op, e_ctl_cmd);
+
+ return IV_FAIL;
+ }
+
+ /* make it thread safe */
+ ithread_mutex_lock(ps_codec->pv_ctl_mutex);
+
+ /* find a free config param set to hold current parameters */
+ if(e_ctl_cmd != ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS)
+ {
+ for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
+ {
+ if(0 == ps_codec->as_cfg[i].u4_is_valid)
+ {
+ ps_cfg = &ps_codec->as_cfg[i];
+ break;
+ }
+ }
+
+ /* If all are invalid, then start overwriting from the head config params */
+ if(NULL == ps_cfg)
+ {
+ ps_cfg = &ps_codec->as_cfg[0];
+ }
+
+ ps_cfg->u4_is_valid = 1;
+
+ ps_cfg->s_svc_params = ps_codec->s_cfg.s_svc_params;
+ ps_cfg->e_cmd = e_ctl_cmd;
+ }
+
+ switch(e_ctl_cmd)
+ {
+ case ISVCE_CMD_CTL_SET_DIMENSIONS:
+ ret = isvce_set_dimensions(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_FRAMERATE:
+ ret = isvce_set_frame_rate(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_BITRATE:
+ ret = isvce_set_bit_rate(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_FRAMETYPE:
+ ret = isvce_set_frame_type(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_QP:
+ ret = isvce_set_qp(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_ENC_MODE:
+ ret = isvce_set_enc_mode(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_VBV_PARAMS:
+ ret = isvce_set_vbv_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_AIR_PARAMS:
+ ret = isvc_set_air_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_ME_PARAMS:
+ ret = isvc_set_me_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_IPE_PARAMS:
+ ret = isvc_set_ipe_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_GOP_PARAMS:
+ ret = isvc_set_gop_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_PROFILE_PARAMS:
+ ret = isvc_set_profile_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS:
+ ret = isvc_set_deblock_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_VUI_PARAMS:
+ ret = isvce_set_vui_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS:
+ ret = isvce_set_sei_mdcv_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS:
+ ret = isvce_set_sei_cll_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS:
+ ret = isvce_set_sei_ave_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS:
+ ret = isvce_set_sei_ccv_params(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_RESET:
+
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ ret = isvce_reset(ps_codec_obj, pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_CTL_SETDEFAULT:
+ {
+ /* ctrl call I/O structures */
+ isvce_ctl_setdefault_op_t *ps_op = pv_api_op;
+
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ /* error status */
+ ret = isvce_set_default_params(ps_cfg);
+
+ ps_op->s_ive_op.u4_error_code = ret;
+
+ break;
+ }
+
+ case ISVCE_CMD_CTL_FLUSH:
+
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ ret = isvce_set_flush_mode(ps_codec_obj, pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_CTL_GETBUFINFO:
+
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ ret = isvce_get_buf_info(ps_codec_obj->pv_codec_handle, pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_CTL_GETVERSION:
+ {
+ /* ctrl call I/O structures */
+ isvce_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip;
+ isvce_ctl_getversioninfo_op_t *ps_op = pv_api_op;
+
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ /* error status */
+ ps_op->s_ive_op.u4_error_code = IV_SUCCESS;
+
+ if(ps_ip->s_ive_ip.u4_version_bufsize <= 0)
+ {
+ ps_op->s_ive_op.u4_error_code = IH264E_CXA_VERS_BUF_INSUFFICIENT;
+ ret = IV_FAIL;
+ }
+ else
+ {
+ ret = ih264e_get_version((CHAR *) ps_ip->s_ive_ip.pu1_version,
+ ps_ip->s_ive_ip.u4_version_bufsize);
+
+ if(ret != IV_SUCCESS)
+ {
+ ps_op->s_ive_op.u4_error_code = IH264E_CXA_VERS_BUF_INSUFFICIENT;
+ ret = IV_FAIL;
+ }
+ }
+ break;
+ }
+
+ case ISVCE_CMD_CTL_SET_NUM_CORES:
+ ret = isvce_set_num_cores(pv_api_ip, pv_api_op, ps_cfg);
+ break;
+
+ case ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS:
+ {
+ ps_cfg = NULL;
+
+ for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
+ {
+ if(ps_codec->as_cfg[i].u4_is_valid &&
+ (ps_codec->as_cfg[i].e_cmd == ISVCE_CMD_CTL_SET_DIMENSIONS))
+ {
+ ps_cfg = &ps_codec->as_cfg[i];
+
+ break;
+ }
+ }
+
+ if(NULL == ps_cfg)
+ {
+ ((isvce_ctl_get_enc_dimensions_op_t *) pv_api_op)->u4_error_code |=
+ 1 << IVE_FATALERROR;
+ ((isvce_ctl_get_enc_dimensions_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_WIDTH_NOT_SUPPORTED;
+ ((isvce_ctl_get_enc_dimensions_op_t *) pv_api_op)->u4_error_code |=
+ IH264E_HEIGHT_NOT_SUPPORTED;
+
+ return IV_FAIL;
+ }
+
+ ret = isvce_get_enc_frame_dimensions((isvce_ctl_get_enc_dimensions_ip_t *) pv_api_ip,
+ (isvce_ctl_get_enc_dimensions_op_t *) pv_api_op,
+ ps_cfg);
+
+ break;
+ }
+
+ default:
+ /* invalidate config param struct as it is being served right away */
+ ps_codec->as_cfg[i].u4_is_valid = 0;
+
+ DEBUG("Warning !! unrecognized control api command \n");
+ break;
+ }
+
+ ithread_mutex_unlock(ps_codec->pv_ctl_mutex);
+
+ return ret;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Codec entry point function. All the function calls to the codec are done
+* using this function with different values specified in command
+*
+* @par Description:
+* Arguments are tested for validity and then based on the command
+* appropriate function is called
+*
+* @param[in] ps_handle
+* API level handle for codec
+*
+* @param[in] pv_api_ip
+* Input argument structure
+*
+* @param[out] pv_api_op
+* Output argument structure
+*
+* @returns error_status
+*
+* @remarks
+*
+*******************************************************************************
+*/
+IV_STATUS_T isvce_api_function(iv_obj_t *ps_handle, void *pv_api_ip, void *pv_api_op,
+ isvce_api_cmds_t *ps_iv_api_cmds)
+{
+ IV_STATUS_T e_status;
+ WORD32 ret;
+
+ ISVCE_API_COMMAND_TYPE_T e_cmd = ps_iv_api_cmds->e_cmd;
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_ctl_cmd = ps_iv_api_cmds->e_ctl_cmd;
+
+ /* validate input / output structures */
+ e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op, ps_iv_api_cmds);
+
+ if(e_status != IV_SUCCESS)
+ {
+ DEBUG("error code = %d\n", *((UWORD32 *) pv_api_op + 1));
+ return IV_FAIL;
+ }
+
+ switch(e_cmd)
+ {
+ case ISVCE_CMD_GET_NUM_MEM_REC:
+ ret = isvce_get_num_rec(pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_FILL_NUM_MEM_REC:
+ ret = isvce_fill_num_mem_rec(pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_INIT:
+ ret = isvce_init_mem_rec(ps_handle, pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_RETRIEVE_MEMREC:
+ ret = isvce_retrieve_memrec(ps_handle, pv_api_ip, pv_api_op);
+ break;
+
+ case ISVCE_CMD_VIDEO_CTL:
+ ret = isvce_ctl(ps_handle, pv_api_ip, pv_api_op, e_ctl_cmd);
+ break;
+
+ case ISVCE_CMD_VIDEO_ENCODE:
+ ret = isvce_encode(ps_handle, pv_api_ip, pv_api_op);
+ break;
+
+ default:
+ ret = IV_FAIL;
+ break;
+ }
+
+ return (IV_STATUS_T) ret;
+}
diff --git a/encoder/svc/isvce_cabac.c b/encoder/svc/isvce_cabac.c
new file mode 100644
index 0000000..95f5111
--- /dev/null
+++ b/encoder/svc/isvce_cabac.c
@@ -0,0 +1,759 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_cabac.c
+*
+* @brief
+* Contains all leaf level functions for CABAC entropy coding.
+*
+*
+* @author
+* Doney Alex
+*
+* @par List of Functions:
+*
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+/* User include files */
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_debug.h"
+#include "ih264_macros.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvc_macros.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_platform_macros.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "isvce_encode_header.h"
+#include "ih264_cavlc_tables.h"
+#include "ih264e_statistics.h"
+#include "ih264e_trace.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated
+ * unary/ k-th order Exp-Golomb (UEGk) binarization process,
+ * where k = 0 as defined in 9.3.2.3 of ITU_T_H264-201402
+ *
+ * @param[in] i2_sufs
+ * Suffix bit string
+ *
+ * @param[in] pi1_bins_len
+ * Pointer to length of tthe string
+ *
+ * @returns Binarized value
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+UWORD32 isvce_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len)
+{
+ WORD32 unary_length;
+ UWORD32 u4_sufs_shiftk_plus1, u4_egk, u4_unary_bins;
+
+ u4_sufs_shiftk_plus1 = i2_sufs + 1;
+
+ unary_length = (32 - CLZ(u4_sufs_shiftk_plus1) + (0 == u4_sufs_shiftk_plus1));
+
+ /* unary code with (unary_length-1) '1's and terminating '0' bin */
+ u4_unary_bins = (1 << unary_length) - 2;
+
+ /* insert the symbol prefix of (unary length - 1) bins */
+ u4_egk = (u4_unary_bins << (unary_length - 1)) |
+ (u4_sufs_shiftk_plus1 & ((1 << (unary_length - 1)) - 1));
+
+ /* length of the code = 2 *(unary_length - 1) + 1 + k */
+ *pi1_bins_len = (2 * unary_length) - 1;
+
+ return (u4_egk);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Get cabac context for the MB :calculates the pointers to Top and left
+ * cabac neighbor context depending upon neighbor availability.
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @param[in] u4_mb_type
+ * Type of MB
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_get_cabac_context(isvce_entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type)
+{
+ /* CABAC context */
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ isvce_mb_info_ctxt_t *ps_ctx_inc_mb_map;
+ cab_csbp_t *ps_lft_csbp;
+
+ WORD32 i4_lft_avail, i4_top_avail, i4_is_intra;
+ WORD32 i4_mb_x, i4_mb_y;
+ UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
+
+ i4_is_intra = ((u4_mb_type == I16x16) || (u4_mb_type == I8x8) || (u4_mb_type == I4x4));
+
+ /* derive neighbor availability */
+ i4_mb_x = ps_ent_ctxt->i4_mb_x;
+ i4_mb_y = ps_ent_ctxt->i4_mb_y;
+ pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
+ /* left macroblock availability */
+ i4_lft_avail = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
+ /* top macroblock availability */
+ i4_top_avail = (i4_mb_y == 0 ||
+ (pu1_slice_idx[i4_mb_x - ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
+ ? 0
+ : 1;
+ i4_mb_x = ps_ent_ctxt->i4_mb_x;
+ ps_ctx_inc_mb_map = ps_cabac_ctxt->ps_mb_map_ctxt_inc;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info = ps_ctx_inc_mb_map + i4_mb_x;
+ ps_cabac_ctxt->ps_left_ctxt_mb_info = ps_cabac_ctxt->ps_def_ctxt_mb_info;
+ ps_cabac_ctxt->ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_def_ctxt_mb_info;
+ ps_lft_csbp = ps_cabac_ctxt->ps_lft_csbp;
+ ps_cabac_ctxt->pu1_left_y_ac_csbp = &ps_lft_csbp->u1_y_ac_csbp_top_mb;
+ ps_cabac_ctxt->pu1_left_uv_ac_csbp = &ps_lft_csbp->u1_uv_ac_csbp_top_mb;
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp = &ps_lft_csbp->u1_yuv_dc_csbp_top_mb;
+ ps_cabac_ctxt->pi1_left_ref_idx_ctxt_inc = &ps_cabac_ctxt->i1_left_ref_idx_ctx_inc_arr[0][0];
+ ps_cabac_ctxt->pu1_left_mv_ctxt_inc = ps_cabac_ctxt->u1_left_mv_ctxt_inc_arr[0];
+
+ if(i4_lft_avail) ps_cabac_ctxt->ps_left_ctxt_mb_info = ps_cabac_ctxt->ps_curr_ctxt_mb_info - 1;
+ if(i4_top_avail) ps_cabac_ctxt->ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ if(!i4_lft_avail)
+ {
+ UWORD8 u1_def_csbp = i4_is_intra ? 0xf : 0;
+ *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = u1_def_csbp;
+ *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = u1_def_csbp;
+ *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = u1_def_csbp;
+ *((UWORD32 *) ps_cabac_ctxt->pi1_left_ref_idx_ctxt_inc) = 0;
+ memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
+ }
+ if(!i4_top_avail)
+ {
+ UWORD8 u1_def_csbp = i4_is_intra ? 0xff : 0;
+ ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_yuv_ac_csbp = u1_def_csbp;
+ ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_yuv_dc_csbp = u1_def_csbp;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[0] =
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[1] =
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[2] =
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[3] = 0;
+ memset(ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv, 0, 16);
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402).
+ *
+ * @param[in] ps_cabac_ctxt
+ * pointer to cabac context (handle)
+ *
+ * @returns none
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_cabac_flush(isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ /* bit stream ptr */
+ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm;
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
+ UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
+ UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen;
+ UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer;
+ UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset;
+ WORD32 zero_run = ps_stream->i4_zero_bytes_run;
+ UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes;
+
+ /************************************************************************/
+ /* Insert the carry (propogated in previous byte) along with */
+ /* outstanding bytes (if any) and flush remaining bits */
+ /************************************************************************/
+ {
+ /* carry = 1 => putbit(1); carry propogated due to L renorm */
+ WORD32 carry = (u4_low >> (u4_bits_gen + CABAC_BITS)) & 0x1;
+ WORD32 last_byte;
+ WORD32 bits_left;
+ WORD32 rem_bits;
+
+ /* carry exists only if pu1_strm_buf has at least 1 byte of data */
+ carry = carry && (u4_strm_buf_offset > 0);
+
+ if(carry)
+ {
+ /* CORNER CASE: if the previous data is 0x000003, then EPB will be
+ inserted and the data will become 0x00000303 and if the carry is present,
+ it will be added with the last byte and it will become 0x00000304 which
+ is not correct as per standard */
+ /* so check for previous four bytes and if it is equal to 0x00000303
+ then subtract u4_strm_buf_offset by 1 */
+ if((u4_strm_buf_offset >= 4) && pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 &&
+ pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 &&
+ pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 &&
+ pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00)
+ {
+ u4_strm_buf_offset -= 1;
+ }
+ /* previous byte carry add will not result in overflow to */
+ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */
+ pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
+ zero_run = 0;
+ }
+
+ /* Insert outstanding bytes (if any) */
+ while(u4_out_standing_bytes)
+ {
+ UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
+
+ PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
+ u4_out_standing_bytes--;
+ }
+
+ /* clear the carry in low */
+ if(carry)
+ {
+ u4_low &= ((1 << (u4_bits_gen + CABAC_BITS)) - 1);
+ }
+
+ /* extract the remaining bits; */
+ /* includes additional msb bit of low as per Figure 9-12 */
+ bits_left = u4_bits_gen + 1;
+ rem_bits = (u4_low >> (u4_bits_gen + CABAC_BITS - bits_left));
+
+ if(bits_left >= 8)
+ {
+ last_byte = (rem_bits >> (bits_left - 8)) & 0xFF;
+ PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
+ bits_left -= 8;
+ }
+
+ /* insert last byte along with rbsp stop bit(1) and 0's in the end */
+ last_byte =
+ (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left) | (1 << (7 - bits_left - 1)));
+ last_byte &= 0xFF;
+ PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
+
+ /* update the state variables and return success */
+ ps_stream->u4_strm_buf_offset = u4_strm_buf_offset;
+ ps_stream->i4_zero_bytes_run = 0;
+ /* Default init values for scratch variables of bitstream context */
+ ps_stream->u4_cur_word = 0;
+ ps_stream->i4_bits_left_in_cw = WORD_SIZE;
+ }
+}
+
+/**
+ ******************************************************************************
+ *
+ * @brief Puts new byte (and outstanding bytes) into bitstream after cabac
+ * renormalization
+ *
+ * @par Description
+ * 1. Extract the leading byte of low(L)
+ * 2. If leading byte=0xff increment outstanding bytes and return
+ * (as the actual bits depend on carry propogation later)
+ * 3. If leading byte is not 0xff check for any carry propogation
+ * 4. Insert the carry (propogated in previous byte) along with outstanding
+ * bytes (if any) and leading byte
+ *
+ *
+ * @param[in] ps_cabac_ctxt
+ * pointer to cabac context (handle)
+ *
+ * @return
+ *
+ ******************************************************************************
+ */
+void isvce_cabac_put_byte(isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ /* bit stream ptr */
+ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm;
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
+ UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
+ UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen;
+ WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8);
+
+ /* Sanity checks */
+ ASSERT((ps_cab_enc_env->u4_code_int_range >= 256) && (ps_cab_enc_env->u4_code_int_range < 512));
+ ASSERT((u4_bits_gen >= 8));
+
+ /* update bits generated and low after extracting leading byte */
+ u4_bits_gen -= 8;
+ ps_cab_enc_env->u4_code_int_low &= ((1 << (CABAC_BITS + u4_bits_gen)) - 1);
+ ps_cab_enc_env->u4_bits_gen = u4_bits_gen;
+
+ /************************************************************************/
+ /* 1. Extract the leading byte of low(L) */
+ /* 2. If leading byte=0xff increment outstanding bytes and return */
+ /* (as the actual bits depend on carry propogation later) */
+ /* 3. If leading byte is not 0xff check for any carry propogation */
+ /* 4. Insert the carry (propogated in previous byte) along with */
+ /* outstanding bytes (if any) and leading byte */
+ /************************************************************************/
+ if(lead_byte == 0xff)
+ {
+ /* actual bits depend on carry propogration */
+ ps_cab_enc_env->u4_out_standing_bytes++;
+ return;
+ }
+ else
+ {
+ UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer;
+ UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset;
+ /* carry = 1 => putbit(1); carry propogated due to L renorm */
+ WORD32 carry = (lead_byte >> 8) & 0x1;
+ WORD32 zero_run = ps_stream->i4_zero_bytes_run;
+ UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes;
+
+ /*********************************************************************/
+ /* Insert the carry propogated in previous byte */
+ /* */
+ /* Note : Do not worry about corruption into slice header align byte */
+ /* This is because the first bin cannot result in overflow */
+ /*********************************************************************/
+ if(carry)
+ {
+ /* CORNER CASE: if the previous data is 0x000003, then EPB will be
+ inserted and the data will become 0x00000303 and if the carry is present,
+ it will be added with the last byte and it will become 0x00000304 which
+ is not correct as per standard */
+ /* so check for previous four bytes and if it is equal to 0x00000303
+ then subtract u4_strm_buf_offset by 1 */
+ if((u4_strm_buf_offset > 3) && (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03) &&
+ (pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03) &&
+ (pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00) &&
+ (pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00))
+ {
+ u4_strm_buf_offset -= 1;
+ }
+
+ /* previous byte carry add will not result in overflow to */
+ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */
+ if(u4_strm_buf_offset > 0)
+ {
+ pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
+ zero_run = 0;
+ }
+ }
+
+ /* Insert outstanding bytes (if any) */
+ while(u4_out_standing_bytes)
+ {
+ UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
+
+ PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
+
+ u4_out_standing_bytes--;
+ }
+ ps_cab_enc_env->u4_out_standing_bytes = 0;
+
+ /* Insert the leading byte */
+ lead_byte &= 0xFF;
+ PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run);
+
+ /* update the state variables and return success */
+ ps_stream->u4_strm_buf_offset = u4_strm_buf_offset;
+ ps_stream->i4_zero_bytes_run = zero_run;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief Codes a bin based on probablilty and mps packed context model
+*
+* @par Description
+* 1. Apart from encoding bin, context model is updated as per state transition
+* 2. Range and Low renormalization is done based on bin and original state
+* 3. After renorm bistream is updated (if required)
+*
+* @param[in] ps_cabac
+* pointer to cabac context (handle)
+*
+* @param[in] bin
+* bin(boolean) to be encoded
+*
+* @param[in] pu1_bin_ctxts
+* index of cabac context model containing pState[bits 5-0] | MPS[bit6]
+*
+* @return
+*
+******************************************************************************
+*/
+void isvce_cabac_encode_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin, bin_ctxt_model *pu1_bin_ctxts)
+{
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
+ UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
+ UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
+ UWORD32 u4_rlps;
+ UWORD8 state_mps = (*pu1_bin_ctxts) & 0x3F;
+ UWORD8 u1_mps = !!((*pu1_bin_ctxts) & (0x40));
+ WORD32 shift;
+ UWORD32 u4_table_val;
+ /* Sanity checks */
+ ASSERT((bin == 0) || (bin == 1));
+ ASSERT((u4_range >= 256) && (u4_range < 512));
+
+ /* Get the lps range from LUT based on quantized range and state */
+ u4_table_val = gau4_isvc_cabac_table[state_mps][(u4_range >> 6) & 0x3];
+ u4_rlps = u4_table_val & 0xFF;
+ u4_range -= u4_rlps;
+
+ /* check if bin is mps or lps */
+ if(u1_mps ^ bin)
+ {
+ /* lps path; L= L + R; R = RLPS */
+ u4_low += u4_range;
+ u4_range = u4_rlps;
+ if(state_mps == 0)
+ {
+ /* MPS(CtxIdx) = 1 - MPS(CtxIdx) */
+ u1_mps = 1 - u1_mps;
+ } /* update the context model from state transition LUT */
+
+ state_mps = (u4_table_val >> 15) & 0x3F;
+ }
+ else
+ { /* update the context model from state transition LUT */
+ state_mps = (u4_table_val >> 8) & 0x3F;
+ }
+
+ (*pu1_bin_ctxts) = (u1_mps << 6) | state_mps;
+
+ /*****************************************************************/
+ /* Renormalization; calculate bits generated based on range(R) */
+ /* Note : 6 <= R < 512; R is 2 only for terminating encode */
+ /*****************************************************************/
+ GETRANGE(shift, u4_range);
+ shift = 9 - shift;
+ u4_low <<= shift;
+ u4_range <<= shift;
+
+ /* bits to be inserted in the bitstream */
+ ps_cab_enc_env->u4_bits_gen += shift;
+ ps_cab_enc_env->u4_code_int_range = u4_range;
+ ps_cab_enc_env->u4_code_int_low = u4_low;
+
+ /* generate stream when a byte is ready */
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ isvce_cabac_put_byte(ps_cabac);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Encoding process for a binary decision :implements encoding process of a
+decision
+* as defined in 9.3.4.2 . This function encodes multiple bins, of a symbol.
+Implements
+* flowchart Figure 9-7( ITU_T_H264-201402)
+*
+* @param[in] u4_bins
+* array of bin values
+*
+* @param[in] i1_bins_len
+* Length of bins, maximum 32
+*
+* @param[in] u4_ctx_inc
+* CtxInc, byte0- bin0, byte1-bin1 ..
+*
+* @param[in] i1_valid_len
+* valid length of bins, after that CtxInc is constant
+*
+* @param[in] pu1_bin_ctxt_type
+* Pointer to binary contexts
+
+* @param[in] ps_cabac
+* Pointer to cabac_context_structure
+*
+* @returns
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+void isvce_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, UWORD32 u4_ctx_inc,
+ WORD8 i1_valid_len, bin_ctxt_model *pu1_bin_ctxt_type,
+ isvce_cabac_ctxt_t *ps_cabac)
+{
+ WORD8 i;
+ UWORD8 u1_ctx_inc, u1_bin;
+
+ for(i = 0; i < i1_bins_len; i++)
+ {
+ u1_bin = (u4_bins & 0x01);
+ u4_bins = u4_bins >> 1;
+ u1_ctx_inc = u4_ctx_inc & 0x0f;
+ if(i < i1_valid_len) u4_ctx_inc = u4_ctx_inc >> 4;
+ /* Encode the bin */
+ isvce_cabac_encode_bin(ps_cabac, u1_bin, pu1_bin_ctxt_type + u1_ctx_inc);
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encoding process for a binary decision before termination:Encoding process
+ * of a termination(9.3.4.5 :ITU_T_H264-201402) . Explained in flowchart 9-11.
+ *
+ * @param[in] ps_cabac
+ * Pointer to cabac structure
+ *
+ * @param[in] term_bin
+ * Symbol value, end of slice or not, term_bin is binary
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_cabac_encode_terminate(isvce_cabac_ctxt_t *ps_cabac, WORD32 term_bin)
+{
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
+
+ UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
+ UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
+ UWORD32 u4_rlps;
+ WORD32 shift;
+
+ /* Sanity checks */
+ ASSERT((u4_range >= 256) && (u4_range < 512));
+ ASSERT((term_bin == 0) || (term_bin == 1));
+
+ /* term_bin = 1 has lps range = 2 */
+ u4_rlps = 2;
+ u4_range -= u4_rlps;
+
+ /* if terminate L is incremented by curR and R=2 */
+ if(term_bin)
+ {
+ /* lps path; L= L + R; R = RLPS */
+ u4_low += u4_range;
+ u4_range = u4_rlps;
+ }
+
+ /*****************************************************************/
+ /* Renormalization; calculate bits generated based on range(R) */
+ /* Note : 6 <= R < 512; R is 2 only for terminating encode */
+ /*****************************************************************/
+ GETRANGE(shift, u4_range);
+ shift = 9 - shift;
+ u4_low <<= shift;
+ u4_range <<= shift;
+
+ /* bits to be inserted in the bitstream */
+ ps_cab_enc_env->u4_bits_gen += shift;
+ ps_cab_enc_env->u4_code_int_range = u4_range;
+ ps_cab_enc_env->u4_code_int_low = u4_low;
+
+ /* generate stream when a byte is ready */
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ isvce_cabac_put_byte(ps_cabac);
+ }
+
+ if(term_bin)
+ {
+ isvce_cabac_flush(ps_cabac);
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Bypass encoding process for binary decisions: Explained (9.3.4.4
+ *:ITU_T_H264-201402) , flowchart 9-10.
+ *
+ * @param[ino] ps_cabac : pointer to cabac context (handle)
+ *
+ * @param[in] bin : bypass bin(0/1) to be encoded
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+void isvce_cabac_encode_bypass_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin)
+{
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
+
+ UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
+ UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
+
+ /* Sanity checks */
+ ASSERT((u4_range >= 256) && (u4_range < 512));
+ ASSERT((bin == 0) || (bin == 1));
+
+ u4_low <<= 1;
+ /* add range if bin is 1 */
+ if(bin)
+ {
+ u4_low += u4_range;
+ }
+
+ /* 1 bit to be inserted in the bitstream */
+ ps_cab_enc_env->u4_bits_gen++;
+ ps_cab_enc_env->u4_code_int_low = u4_low;
+
+ /* generate stream when a byte is ready */
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ isvce_cabac_put_byte(ps_cabac);
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief Encodes a series of bypass bins (FLC bypass bins)
+*
+* @par Description
+* This function is more optimal than calling isvce_cabac_encode_bypass_bin()
+* in a loop as cabac low, renorm and generating the stream (8bins at a time)
+* can be done in one operation
+*
+* @param[inout]ps_cabac
+* pointer to cabac context (handle)
+*
+* @param[in] u4_bins
+* syntax element to be coded (as FLC bins)
+*
+* @param[in] num_bins
+* This is the FLC length for u4_sym
+*
+* @return
+*
+******************************************************************************
+*/
+
+void isvce_cabac_encode_bypass_bins(isvce_cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, WORD32 num_bins)
+{
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
+
+ UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
+ WORD32 next_byte;
+
+ /* Sanity checks */
+ ASSERT((num_bins < 33) && (num_bins > 0));
+ ASSERT((u4_range >= 256) && (u4_range < 512));
+
+ /* Compute bit always to populate the trace */
+ /* increment bits generated by num_bins */
+
+ /* Encode 8bins at a time and put in the bit-stream */
+ while(num_bins > 8)
+ {
+ num_bins -= 8;
+
+ next_byte = (u4_bins >> (num_bins)) & 0xff;
+
+ /* L = (L << 8) + (R * next_byte) */
+ ps_cab_enc_env->u4_code_int_low <<= 8;
+ ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
+ ps_cab_enc_env->u4_bits_gen += 8;
+
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ /* insert the leading byte of low into stream */
+ isvce_cabac_put_byte(ps_cabac);
+ }
+ }
+
+ /* Update low with remaining bins and return */
+ next_byte = (u4_bins & ((1 << num_bins) - 1));
+
+ ps_cab_enc_env->u4_code_int_low <<= num_bins;
+ ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
+ ps_cab_enc_env->u4_bits_gen += num_bins;
+
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ /* insert the leading byte of low into stream */
+ isvce_cabac_put_byte(ps_cabac);
+ }
+}
diff --git a/encoder/svc/isvce_cabac.h b/encoder/svc/isvce_cabac.h
new file mode 100644
index 0000000..57ce5d6
--- /dev/null
+++ b/encoder/svc/isvce_cabac.h
@@ -0,0 +1,380 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_cabac_structs.h
+ *
+ * @brief
+ * This file contains cabac related macros, enums, tables and function
+ *declarations.
+ *
+ * @author
+ * Doney Alex
+ *
+ * @remarks
+ * none
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCE_CABAC_H_
+#define _ISVCE_CABAC_H_
+
+#include "ih264e_cabac.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_defs.h"
+#include "isvce_structs.h"
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Initialize default context values and pointers.
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_init_cabac_table(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Initialize cabac context: Intitalize all contest with init values given in
+ *the spec. Called at the beginning of entropy coding of each slice for CABAC
+ *encoding.
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+extern void isvce_init_cabac_ctxt(isvce_entropy_ctxt_t *ps_ent_ctxt, slice_header_t *ps_slice_hdr);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated
+ * unary/ k-th order Exp-Golomb (UEGk) binarization process,
+ * where k = 0 as defined in 9.3.2.3 of ITU_T_H264-201402
+ *
+ * @param[in] i2_sufs
+ * Suffix bit string
+ *
+ * @param[in] pi1_bins_len
+ * Pointer to length of the string
+ *
+ * @returns Binarized value
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+UWORD32 isvce_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Get cabac context for the MB :calculates the pointers to Top and left
+ * cabac neighbor context depending upon neighbor availability.
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @param[in] u4_mb_type
+ * Type of MB
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_get_cabac_context(isvce_entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type);
+
+/**
+ *******************************************************************************
+ * @brief
+ * flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402).
+ *
+ * @param[in] ps_cabac_ctxt
+ * pointer to cabac context (handle)
+ *
+ * @returns none
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_cabac_flush(isvce_cabac_ctxt_t *ps_cabac_ctxt);
+
+/**
+ ******************************************************************************
+ *
+ * @brief Puts new byte (and outstanding bytes) into bitstream after cabac
+ * renormalization
+ *
+ * @par Description
+ * 1. Extract the leading byte of low(L)
+ * 2. If leading byte=0xff increment outstanding bytes and return
+ * (as the actual bits depend on carry propogation later)
+ * 3. If leading byte is not 0xff check for any carry propogation
+ * 4. Insert the carry (propogated in previous byte) along with outstanding
+ * bytes (if any) and leading byte
+ *
+ *
+ * @param[inout] ps_cabac_ctxt
+ * pointer to cabac context (handle)
+ *
+ * @return
+ *
+ ******************************************************************************
+ */
+void isvce_cabac_put_byte(isvce_cabac_ctxt_t *ps_cabac_ctxt);
+
+/**
+ ******************************************************************************
+ *
+ * @brief Codes a bin based on probablilty and mps packed context model
+ *
+ * @par Description
+ * 1. Apart from encoding bin, context model is updated as per state transition
+ * 2. Range and Low renormalization is done based on bin and original state
+ * 3. After renorm bistream is updated (if required)
+ *
+ * @param[inout] ps_cabac
+ * pointer to cabac context (handle)
+ *
+ * @param[in] bin
+ * bin(boolean) to be encoded
+ *
+ * @param[in] pu1_bin_ctxts
+ * index of cabac context model containing pState[bits 5-0] | MPS[bit6]
+ *
+ * @return
+ *
+ ******************************************************************************
+ */
+void isvce_cabac_encode_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin,
+ bin_ctxt_model *pu1_bin_ctxts);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encoding process for a binary decision :implements encoding process of a
+ decision
+ * as defined in 9.3.4.2 . This function encodes multiple bins, of a symbol.
+ Implements
+ * flowchart Figure 9-7( ITU_T_H264-201402)
+ *
+ * @param[in] u4_bins
+ * array of bin values
+ *
+ * @param[in] i1_bins_len
+ * Length of bins, maximum 32
+ *
+ * @param[in] u4_ctx_inc
+ * CtxInc, byte0- bin0, byte1-bin1 ..
+ *
+ * @param[in] i1_valid_len
+ * valid length of bins, after that CtxInc is constant
+ *
+ * @param[in] pu1_bin_ctxt_type
+ * Pointer to binary contexts
+
+ * @param[in] ps_cabac
+ * Pointer to cabac_context_structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, UWORD32 u4_ctx_inc,
+ WORD8 i1_valid_len, bin_ctxt_model *pu1_bin_ctxt_type,
+ isvce_cabac_ctxt_t *ps_cabac);
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encoding process for a binary decision before termination:Encoding process
+ * of a termination(9.3.4.5 :ITU_T_H264-201402) . Explained in flowchart 9-11.
+ *
+ * @param[in] ps_cabac
+ * Pointer to cabac structure
+ *
+ * @param[in] term_bin
+ * Symbol value, end of slice or not, term_bin is binary
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_cabac_encode_terminate(isvce_cabac_ctxt_t *ps_cabac, WORD32 term_bin);
+
+/**
+ *******************************************************************************
+ * @brief
+ * Bypass encoding process for binary decisions: Explained (9.3.4.4
+ *:ITU_T_H264-201402) , flowchart 9-10.
+ *
+ * @param[in] ps_cabac : pointer to cabac context (handle)
+ *
+ * @param[in] bin : bypass bin(0/1) to be encoded
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+void isvce_cabac_encode_bypass_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin);
+
+/**
+ ******************************************************************************
+ *
+ * @brief Encodes a series of bypass bins (FLC bypass bins)
+ *
+ * @par Description
+ * This function is more optimal than calling isvce_cabac_encode_bypass_bin()
+ * in a loop as cabac low, renorm and generating the stream (8bins at a time)
+ * can be done in one operation
+ *
+ * @param[inout]ps_cabac
+ * pointer to cabac context (handle)
+ *
+ * @param[in] u4_bins
+ * syntax element to be coded (as FLC bins)
+ *
+ * @param[in] num_bins
+ * This is the FLC length for u4_sym
+ *
+ * @return
+ *
+ ******************************************************************************
+ */
+
+void isvce_cabac_encode_bypass_bins(isvce_cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, WORD32 num_bins);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for an Intra Slice.
+ *
+ * @description
+ * The mb syntax layer for intra slices constitutes luma mb mode, luma sub
+ *modes (if present), mb qp delta, coded block pattern, chroma mb mode and
+ * luma/chroma residue. These syntax elements are written as directed by table
+ * 7.3.5 of h264 specification.
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_islice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for Inter slices
+ *
+ * @description
+ * The mb syntax layer for inter slices constitutes luma mb mode, luma sub
+ *modes (if present), mb qp delta, coded block pattern, chroma mb mode and
+ * luma/chroma residue. These syntax elements are written as directed by table
+ * 7.3.5 of h264 specification
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_pslice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for B slices
+ *
+ * @description
+ * The mb syntax layer for inter slices constitutes luma mb mode,
+ * mb qp delta, coded block pattern, chroma mb mode and
+ * luma/chroma residue. These syntax elements are written as directed by table
+ * 7.3.5 of h264 specification
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_bslice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+#if ENABLE_RE_ENC_AS_SKIP
+IH264E_ERROR_T isvce_reencode_as_skip_frame_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt);
+#endif
+
+#endif
diff --git a/encoder/svc/isvce_cabac_encode.c b/encoder/svc/isvce_cabac_encode.c
new file mode 100644
index 0000000..d31fdd8
--- /dev/null
+++ b/encoder/svc/isvce_cabac_encode.c
@@ -0,0 +1,2374 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_cabac.c
+*
+* @brief
+* Contains all functions to encode in CABAC entropy mode
+*
+*
+* @author
+* Doney Alex
+*
+* @par List of Functions:
+*
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+/* User include files */
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvc_macros.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_platform_macros.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "isvce_encode_header.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_statistics.h"
+#include "ih264e_trace.h"
+#include "isvce_cabac_utils.h"
+#include "isvce_utils.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes mb_skip_flag using CABAC entropy coding mode.
+ *
+ * @param[in] u1_mb_skip_flag
+ * mb_skip_flag
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @param[in] u4_ctxidx_offset
+ * ctxIdxOffset for mb_skip_flag context
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_mb_skip(UWORD8 u1_mb_skip_flag, isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD32 u4_ctxidx_offset)
+{
+ UWORD8 u4_ctx_inc;
+ WORD8 a, b;
+ a = ((ps_cabac_ctxt->ps_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? 0 : 1);
+ b = ((ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ? 0 : 1);
+
+ u4_ctx_inc = a + b;
+ /* Encode the bin */
+ isvce_cabac_encode_bin(ps_cabac_ctxt, (UWORD32) u1_mb_skip_flag,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset + u4_ctx_inc);
+}
+
+/* ! < Table 9-36 – Binarization for macroblock types in I slices in
+ * ITU_T_H264-201402 Bits 0-7 : binarised value Bits 8-15: length of binary
+ * sequence
+ */
+static const UWORD32 u4_mb_type_intra[26] = {0x0100, 0x0620, 0x0621, 0x0622, 0x0623, 0x0748, 0x0749,
+ 0x074a, 0x074b, 0x074c, 0x074d, 0x074e, 0x074f, 0x0628,
+ 0x0629, 0x062a, 0x062b, 0x0758, 0x0759, 0x075a, 0x075b,
+ 0x075c, 0x075d, 0x075e, 0x075f, 0x0203};
+
+/* CtxInc for mb types */
+static const UWORD32 u4_mb_ctxinc[2][26] = {
+ /* Intra CtxInc's */
+ {0x00, 0x03467, 0x03467, 0x03467, 0x03467, 0x034567, 0x034567, 0x034567, 0x034567,
+ 0x034567, 0x034567, 0x034567, 0x034567, 0x03467, 0x03467, 0x03467, 0x03467, 0x034567,
+ 0x034567, 0x034567, 0x034567, 0x034567, 0x034567, 0x034567, 0x034567, 0x00},
+ /* Inter CtxInc's */
+ {0x00, 0x001233, 0x001233, 0x001233, 0x001233, 0x0012233, 0x0012233,
+ 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x001233,
+ 0x001233, 0x001233, 0x001233, 0x0012233, 0x0012233, 0x0012233, 0x0012233,
+ 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x00}};
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes mb_type for an intra MB.
+ *
+ * @param[in] u4_slice_type
+ * slice type
+ *
+ * @param[in] u4_intra_mb_type
+ * MB type (Table 7-11)
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ ** @param[in] u4_ctxidx_offset
+ * ctxIdxOffset for mb_type context
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+static void isvce_cabac_enc_intra_mb_type(UWORD32 u4_slice_type, UWORD32 u4_intra_mb_type,
+ isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD32 u4_ctx_idx_offset)
+{
+ encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
+ bin_ctxt_model *pu1_mb_bin_ctxt, *pu1_bin_ctxt;
+ UWORD8 u1_bin;
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ UWORD32 u4_bins;
+ UWORD32 u4_ctx_inc;
+ WORD8 i1_bins_len;
+ UWORD32 u4_code_int_range;
+ UWORD32 u4_code_int_low;
+ UWORD16 u2_quant_code_int_range;
+ UWORD16 u4_code_int_range_lps;
+ WORD8 i;
+ UWORD8 u1_ctx_inc;
+ UWORD32 u4_table_val;
+
+ pu1_mb_bin_ctxt = ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset;
+
+ u4_bins = u4_mb_type_intra[u4_intra_mb_type];
+ i1_bins_len = (WORD8) ((u4_bins >> 8) & 0x0f);
+ u4_ctx_inc = u4_mb_ctxinc[(u4_slice_type != ISLICE)][u4_intra_mb_type];
+ u1_ctx_inc = 0;
+ if(u4_slice_type == ISLICE)
+ {
+ if(ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ u1_ctx_inc += ((ps_left_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0);
+ if(ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ u1_ctx_inc += ((ps_top_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0);
+
+ u4_ctx_inc = (u4_ctx_inc | (u1_ctx_inc << ((i1_bins_len - 1) << 2)));
+ }
+ else
+ {
+ pu1_mb_bin_ctxt += 3;
+ if(u4_slice_type == BSLICE) pu1_mb_bin_ctxt += 2;
+ }
+
+ u4_code_int_range = ps_cab_enc_env->u4_code_int_range;
+ u4_code_int_low = ps_cab_enc_env->u4_code_int_low;
+
+ for(i = (i1_bins_len - 1); i >= 0; i--)
+ {
+ WORD32 shift;
+
+ u1_ctx_inc = ((u4_ctx_inc >> (i << 2)) & 0x0f);
+ u1_bin = ((u4_bins >> i) & 0x01);
+ /* Encode the bin */
+ pu1_bin_ctxt = pu1_mb_bin_ctxt + u1_ctx_inc;
+ if(i != (i1_bins_len - 2))
+ {
+ WORD8 i1_mps = !!((*pu1_bin_ctxt) & (0x40));
+ WORD8 i1_state = (*pu1_bin_ctxt) & 0x3F;
+
+ u2_quant_code_int_range = ((u4_code_int_range >> 6) & 0x03);
+ u4_table_val = gau4_isvc_cabac_table[i1_state][u2_quant_code_int_range];
+ u4_code_int_range_lps = u4_table_val & 0xFF;
+
+ u4_code_int_range -= u4_code_int_range_lps;
+ if(u1_bin != i1_mps)
+ {
+ u4_code_int_low += u4_code_int_range;
+ u4_code_int_range = u4_code_int_range_lps;
+ if(i1_state == 0)
+ {
+ /* MPS(CtxIdx) = 1 - MPS(CtxIdx) */
+ i1_mps = 1 - i1_mps;
+ }
+
+ i1_state = (u4_table_val >> 15) & 0x3F;
+ }
+ else
+ {
+ i1_state = (u4_table_val >> 8) & 0x3F;
+ }
+
+ (*pu1_bin_ctxt) = (i1_mps << 6) | i1_state;
+ }
+ else
+ {
+ u4_code_int_range -= 2;
+ }
+
+ /* Renormalize */
+ /*****************************************************************/
+ /* Renormalization; calculate bits generated based on range(R) */
+ /* Note : 6 <= R < 512; R is 2 only for terminating encode */
+ /*****************************************************************/
+ GETRANGE(shift, u4_code_int_range);
+ shift = 9 - shift;
+ u4_code_int_low <<= shift;
+ u4_code_int_range <<= shift;
+
+ /* bits to be inserted in the bitstream */
+ ps_cab_enc_env->u4_bits_gen += shift;
+ ps_cab_enc_env->u4_code_int_range = u4_code_int_range;
+ ps_cab_enc_env->u4_code_int_low = u4_code_int_low;
+
+ /* generate stream when a byte is ready */
+ if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
+ {
+ isvce_cabac_put_byte(ps_cabac_ctxt);
+ u4_code_int_range = ps_cab_enc_env->u4_code_int_range;
+ u4_code_int_low = ps_cab_enc_env->u4_code_int_low;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes prev_intra4x4_pred_mode_flag and
+ * rem_intra4x4_pred_mode using CABAC entropy coding mode
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @param[in] pu1_intra_4x4_modes
+ * Pointer to array containing prev_intra4x4_pred_mode_flag and
+ * rem_intra4x4_pred_mode
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_4x4mb_modes(isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD8 *pu1_intra_4x4_modes)
+{
+ WORD32 i;
+ WORD8 byte;
+ for(i = 0; i < 16; i += 2)
+ {
+ /* sub blk idx 1 */
+ byte = pu1_intra_4x4_modes[i >> 1];
+ if(byte & 0x1)
+ {
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + PREV_INTRA4X4_PRED_MODE_FLAG);
+ }
+ else
+ {
+ /* Binarization is FL and Cmax=7 */
+ isvce_encode_decision_bins(
+ byte & 0xF, 4, 0x05554, 4,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + REM_INTRA4X4_PRED_MODE - 5, ps_cabac_ctxt);
+ }
+ /* sub blk idx 2 */
+ byte >>= 4;
+ if(byte & 0x1)
+ {
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + PREV_INTRA4X4_PRED_MODE_FLAG);
+ }
+ else
+ {
+ isvce_encode_decision_bins(
+ byte & 0xF, 4, 0x05554, 4,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + REM_INTRA4X4_PRED_MODE - 5, ps_cabac_ctxt);
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes chroma intrapred mode for the MB.
+ *
+ * @param[in] u1_chroma_pred_mode
+ * Chroma intr prediction mode
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_chroma_predmode(UWORD8 u1_chroma_pred_mode,
+ isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ WORD8 i1_temp;
+ isvce_mb_info_ctxt_t *ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ UWORD32 u4_bins = 0;
+ WORD8 i1_bins_len = 1;
+ UWORD32 u4_ctx_inc = 0;
+ UWORD8 a, b;
+ a = ((ps_left_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0);
+ b = ((ps_top_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0);
+
+ /* Binarization is TU and Cmax=3 */
+ ps_curr_ctxt->u1_intrapred_chroma_mode = u1_chroma_pred_mode;
+
+ u4_ctx_inc = a + b;
+ u4_ctx_inc = (u4_ctx_inc | 0x330);
+ if(u1_chroma_pred_mode)
+ {
+ u4_bins = 1;
+ i1_temp = u1_chroma_pred_mode;
+ i1_temp--;
+ /* Put a stream of 1's of length Chromaps_pred_mode_ctxt value */
+ while(i1_temp)
+ {
+ u4_bins = (u4_bins | (1 << i1_bins_len));
+ i1_bins_len++;
+ i1_temp--;
+ }
+ /* If Chromaps_pred_mode_ctxt < Cmax i.e 3. Terminate put a zero */
+ if(u1_chroma_pred_mode < 3)
+ {
+ i1_bins_len++;
+ }
+ }
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 3,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + INTRA_CHROMA_PRED_MODE,
+ ps_cabac_ctxt);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes CBP for the MB.
+ *
+ * @param[in] u1_cbp
+ * CBP for the MB
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_cbp(UWORD32 u4_cbp, isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ WORD8 i2_cbp_chroma, i, j;
+ UWORD8 u1_ctxt_inc, u1_bin;
+ UWORD8 a, b;
+ UWORD32 u4_ctx_inc;
+ UWORD32 u4_bins;
+ WORD8 i1_bins_len;
+
+ /* CBP Luma, FL, Cmax = 15, L = 4 */
+ u4_ctx_inc = 0;
+ u4_bins = 0;
+ i1_bins_len = 5;
+ for(i = 0; i < 4; i++)
+ {
+ /* calulate ctxtInc, depending on neighbour availability */
+ /* u1_ctxt_inc = CondTerm(A) + 2 * CondTerm(B);
+ A: Left block and B: Top block */
+
+ /* Check for Top availability */
+ if(i >> 1)
+ {
+ j = i - 2;
+ /* Top is available always and it's current MB */
+ b = (((u4_cbp >> j) & 0x01) != 0 ? 0 : 1);
+ }
+ else
+ {
+ /* for blocks whose top reference is in another MB */
+ {
+ j = i + 2;
+ b = ((ps_top_ctxt->u1_cbp >> j) & 0x01) ? 0 : 1;
+ }
+ }
+
+ /* Check for Left availability */
+ if(i & 0x01)
+ {
+ /* Left is available always and it's current MB */
+ j = i - 1;
+ a = (((u4_cbp >> j) & 0x01) != 0 ? 0 : 1);
+ }
+ else
+ {
+ {
+ j = i + 1;
+ a = ((ps_left_ctxt->u1_cbp >> j) & 0x01) ? 0 : 1;
+ }
+ }
+ u1_ctxt_inc = a + 2 * b;
+ u1_bin = ((u4_cbp >> i) & 0x01);
+ u4_ctx_inc = (u4_ctx_inc | (u1_ctxt_inc << (i << 2)));
+ u4_bins = (u4_bins | (u1_bin << i));
+ }
+
+ /* CBP Chroma, TU, Cmax = 2 */
+ i2_cbp_chroma = u4_cbp >> 4;
+ /* calulate ctxtInc, depending on neighbour availability */
+ a = (ps_left_ctxt->u1_cbp > 15) ? 1 : 0;
+ b = (ps_top_ctxt->u1_cbp > 15) ? 1 : 0;
+
+ u1_ctxt_inc = a + 2 * b;
+ if(i2_cbp_chroma)
+ {
+ u4_ctx_inc = u4_ctx_inc | ((4 + u1_ctxt_inc) << 16);
+ u4_bins = (u4_bins | 0x10);
+ /* calulate ctxtInc, depending on neighbour availability */
+ a = (ps_left_ctxt->u1_cbp > 31) ? 1 : 0;
+ b = (ps_top_ctxt->u1_cbp > 31) ? 1 : 0;
+ u1_ctxt_inc = a + 2 * b;
+ u4_ctx_inc = u4_ctx_inc | ((8 + u1_ctxt_inc) << 20);
+ u4_bins = (u4_bins | (((i2_cbp_chroma >> 1) & 0x01) << i1_bins_len));
+ i1_bins_len++;
+ }
+ else
+ {
+ u4_ctx_inc = (u4_ctx_inc | ((4 + u1_ctxt_inc) << 16));
+ }
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 8,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + CBP_LUMA, ps_cabac_ctxt);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Encodes mb_qp_delta for the MB.
+ *
+ * @param[in] i1_mb_qp_delta
+ * mb_qp_delta
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_mb_qp_delta(WORD8 i1_mb_qp_delta, isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ UWORD8 u1_code_num;
+ UWORD8 u1_ctxt_inc;
+
+ UWORD32 u4_bins;
+ WORD8 i1_bins_len;
+
+ /* Range of ps_mb_qp_delta_ctxt= -26 to +25 inclusive */
+ ASSERT((i1_mb_qp_delta < 26) && (i1_mb_qp_delta > -27));
+
+ /* if ps_mb_qp_delta_ctxt=0, then codeNum=0 */
+ u1_code_num = 0;
+ if(i1_mb_qp_delta > 0)
+ {
+ u1_code_num = (i1_mb_qp_delta << 1) - 1;
+ }
+ else if(i1_mb_qp_delta < 0)
+ {
+ u1_code_num = (ABS(i1_mb_qp_delta)) << 1;
+ }
+
+ u4_bins = 0;
+ i1_bins_len = 1;
+
+ u1_ctxt_inc = !!ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt;
+
+ if(u1_code_num == 0)
+ {
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u1_ctxt_inc, 3,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
+ ps_cabac_ctxt);
+ }
+ else
+ {
+ u4_bins = 1;
+ u1_code_num--;
+
+ if(u1_code_num == 0)
+ {
+ i1_bins_len++;
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u1_ctxt_inc | 0x20, 3,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
+ ps_cabac_ctxt);
+ }
+ else
+ {
+ u4_bins = (u4_bins | (1 << i1_bins_len));
+ i1_bins_len++;
+ u1_code_num--;
+
+ /* BinIdx from b2 onwards */
+ if(u1_code_num < 30)
+ {
+ /* maximum i1_bins_len = 31 */
+ while(u1_code_num)
+ {
+ u4_bins = (u4_bins | (1 << i1_bins_len));
+ i1_bins_len++;
+ u1_code_num--;
+ };
+
+ i1_bins_len++;
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u1_ctxt_inc | 0x320, 2,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
+ ps_cabac_ctxt);
+ }
+ else
+ {
+ /* maximum i1_bins_len = 53 */
+ u4_bins = 0xffffffff;
+ i1_bins_len = 32;
+ u1_code_num -= 30;
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u1_ctxt_inc | 0x320, 2,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
+ ps_cabac_ctxt);
+
+ u4_bins = 0;
+ i1_bins_len = 0;
+
+ while(u1_code_num)
+ {
+ u4_bins = (u4_bins | (1 << i1_bins_len));
+ i1_bins_len++;
+ u1_code_num--;
+ };
+
+ i1_bins_len++;
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, 0x333, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
+ ps_cabac_ctxt);
+ }
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encodes 4residual_block_cabac as defined in 7.3.5.3.3.
+ *
+ * @param[in] pi2_res_block
+ * pointer to the array of residues
+ *
+ * @param[in] u1_nnz
+ * Number of non zero coeffs in the block
+ *
+ * @param[in] u1_max_num_coeffs
+ * Max number of coeffs that can be there in the block
+ *
+ * @param[in] u2_sig_coeff_map
+ * Significant coeff map
+ *
+ * @param[in] u4_ctx_cat_offset
+ * ctxIdxOffset for absolute value contexts
+ *
+ * @param[in] pu1_ctxt_sig_coeff
+ * Pointer to residual state variables
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_write_coeff4x4(WORD16 *pi2_res_block, UWORD8 u1_nnz,
+ UWORD8 u1_max_num_coeffs, UWORD16 u2_sig_coeff_map,
+ UWORD32 u4_ctx_cat_offset,
+ bin_ctxt_model *pu1_ctxt_sig_coeff,
+ isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ WORD8 i;
+ WORD16 *pi16_coeffs;
+ UWORD32 u4_sig_coeff, u4_bins;
+ UWORD32 u4_ctx_inc;
+ UWORD8 u1_last_sig_coef_index = (31 - CLZ(u2_sig_coeff_map));
+
+ /* Always put Coded Block Flag as 1 */
+
+ pi16_coeffs = pi2_res_block;
+ {
+ bin_ctxt_model *pu1_bin_ctxt;
+ UWORD8 u1_bin, uc_last;
+
+ i = 0;
+ pu1_bin_ctxt = pu1_ctxt_sig_coeff;
+ u4_sig_coeff = 0;
+ u1_bin = 1;
+ if((u1_last_sig_coef_index))
+ {
+ u1_bin = !!(u2_sig_coeff_map & 01);
+ }
+ uc_last = 1;
+
+ do
+ {
+ /* Encode Decision */
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_bin, pu1_bin_ctxt);
+
+ if(u1_bin & uc_last)
+ {
+ u4_sig_coeff = (u4_sig_coeff | (1 << i));
+ pu1_bin_ctxt = pu1_ctxt_sig_coeff + i + LAST_SIGNIFICANT_COEFF_FLAG_FRAME -
+ SIGNIFICANT_COEFF_FLAG_FRAME;
+ u1_bin = (i == u1_last_sig_coef_index);
+ uc_last = 0;
+ }
+ else
+ {
+ i = i + 1;
+ pu1_bin_ctxt = pu1_ctxt_sig_coeff + i;
+ u1_bin = (i == u1_last_sig_coef_index);
+ uc_last = 1;
+ if((i != u1_last_sig_coef_index))
+ {
+ u1_bin = !!((u2_sig_coeff_map >> i) & 01);
+ }
+ }
+ } while(!((i > u1_last_sig_coef_index) || (i > (u1_max_num_coeffs - 1))));
+ }
+
+ /* Encode coeff_abs_level_minus1 and coeff_sign_flag */
+ {
+ UWORD8 u1_sign;
+ UWORD16 u2_abs_level;
+ UWORD8 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0;
+ UWORD8 u1_ctx_inc;
+ UWORD8 u1_coff;
+ WORD16 i2_sufs;
+ WORD8 i1_bins_len;
+ i = u1_last_sig_coef_index;
+ pi16_coeffs = pi2_res_block + u1_nnz - 1;
+ do
+ {
+ {
+ u4_sig_coeff = u4_sig_coeff & ((1 << i) - 1);
+ u4_bins = 0;
+ u4_ctx_inc = 0;
+ i1_bins_len = 1;
+ /* Encode the AbsLevelMinus1 */
+ u2_abs_level = ABS(*(pi16_coeffs)) - 1;
+ /* CtxInc for bin0 */
+ u4_ctx_inc = MIN(u1_abs_level_equal1, 4);
+ /* CtxInc for remaining */
+ u1_ctx_inc = 5 + MIN(u1_abs_level_gt1, 4);
+ u4_ctx_inc = u4_ctx_inc + (u1_ctx_inc << 4);
+ if(u2_abs_level)
+ {
+ u1_abs_level_gt1++;
+ u1_abs_level_equal1 = 0;
+ }
+ if(!u1_abs_level_gt1) u1_abs_level_equal1++;
+
+ u1_coff = 14;
+ if(u2_abs_level >= u1_coff)
+ {
+ /* Prefix TU i.e string of 14 1's */
+ u4_bins = 0x3fff;
+ i1_bins_len = 14;
+ isvce_encode_decision_bins(
+ u4_bins, i1_bins_len, u4_ctx_inc, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_cat_offset, ps_cabac_ctxt);
+
+ /* Suffix, uses EncodeBypass */
+ i2_sufs = u2_abs_level - u1_coff;
+
+ u4_bins = isvce_cabac_UEGk0_binarization(i2_sufs, &i1_bins_len);
+
+ isvce_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins, i1_bins_len);
+ }
+ else
+ {
+ /* Prefix only */
+ u4_bins = (1 << u2_abs_level) - 1;
+ i1_bins_len = u2_abs_level + 1;
+ /* Encode Terminating bit */
+ isvce_encode_decision_bins(
+ u4_bins, i1_bins_len, u4_ctx_inc, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_cat_offset, ps_cabac_ctxt);
+ }
+ }
+ /* encode coeff_sign_flag[i] */
+ u1_sign = ((*pi16_coeffs) < 0) ? 1 : 0;
+ isvce_cabac_encode_bypass_bin(ps_cabac_ctxt, u1_sign);
+ i = CLZ(u4_sig_coeff);
+ i = 31 - i;
+ pi16_coeffs--;
+ } while(u4_sig_coeff);
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Write DC coeffs for intra predicted luma block
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_encode_residue_luma_dc(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ /* CABAC context */
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ tu_sblk_coeff_data_t *ps_mb_coeff_data;
+
+ /* packed residue */
+ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
+ UWORD16 u2_sig_coeff_map;
+ WORD16 *pi2_res_block;
+ UWORD8 u1_nnz;
+ UWORD8 u1_cbf;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *p_CurCtxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u1_nnz, u2_sig_coeff_map,
+ pi2_res_block);
+
+ u1_cbf = !!(u1_nnz);
+
+ {
+ UWORD32 u4_ctx_inc;
+ UWORD8 u1_a, u1_b;
+
+ u1_a = ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] & 0x1;
+ u1_b = ps_top_ctxt->u1_yuv_dc_csbp & 0x1;
+ u4_ctx_inc = u1_a + (u1_b << 1);
+
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, u1_cbf,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + CBF + (LUMA_DC_CTXCAT << 2) + u4_ctx_inc);
+ }
+
+ /* Write coded_block_flag */
+ if(u1_cbf)
+ {
+ isvce_cabac_write_coeff4x4(pi2_res_block, u1_nnz, 15, u2_sig_coeff_map,
+ COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_0_OFFSET,
+ ps_cabac_ctxt->au1_cabac_ctxt_table +
+ SIGNIFICANT_COEFF_FLAG_FRAME + SIG_COEFF_CTXT_CAT_0_OFFSET,
+ ps_cabac_ctxt);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] |= 0x1;
+ p_CurCtxt->u1_yuv_dc_csbp |= 0x1;
+ }
+ else
+ {
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ p_CurCtxt->u1_yuv_dc_csbp &= 0x6;
+ }
+
+ ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Write chroma residues to the bitstream
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @param[in] u1_chroma_cbp
+ * coded block pattern, chroma
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_write_chroma_residue(isvce_entropy_ctxt_t *ps_ent_ctxt,
+ UWORD8 u1_chroma_cbp)
+{
+ /* CABAC context */
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ tu_sblk_coeff_data_t *ps_mb_coeff_data;
+ /* packed residue */
+ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
+ UWORD16 u2_sig_coeff_map;
+ UWORD8 u1_nnz;
+ isvce_mb_info_ctxt_t *ps_top_ctxt_mb_info, *ps_curr_ctxt;
+
+ ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ /********************/
+ /* Write Chroma DC */
+ /********************/
+ {
+ WORD16 *pi2_res_block;
+ UWORD8 u1_left_dc_csbp, u1_top_dc_csbp, u1_uv, u1_cbf;
+
+ u1_left_dc_csbp = (ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0]) >> 1;
+ u1_top_dc_csbp = (ps_top_ctxt_mb_info->u1_yuv_dc_csbp) >> 1;
+
+ for(u1_uv = 0; u1_uv < 2; u1_uv++)
+ {
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u1_nnz, u2_sig_coeff_map,
+ pi2_res_block);
+ u1_cbf = !!(u1_nnz);
+ {
+ UWORD8 u1_a, u1_b;
+ UWORD32 u4_ctx_inc;
+ u1_a = (u1_left_dc_csbp >> u1_uv) & 0x01;
+ u1_b = (u1_top_dc_csbp >> u1_uv) & 0x01;
+ u4_ctx_inc = (u1_a + (u1_b << 1));
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_cbf,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + CBF +
+ (CHROMA_DC_CTXCAT << 2) + u4_ctx_inc);
+ }
+
+ if(u1_cbf)
+ {
+ isvce_cabac_write_coeff4x4(pi2_res_block, u1_nnz, 3, u2_sig_coeff_map,
+ COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_3_OFFSET,
+ ps_cabac_ctxt->au1_cabac_ctxt_table +
+ SIGNIFICANT_COEFF_FLAG_FRAME +
+ SIG_COEFF_CTXT_CAT_3_OFFSET,
+ ps_cabac_ctxt);
+
+ SETBIT(u1_top_dc_csbp, u1_uv);
+ SETBIT(u1_left_dc_csbp, u1_uv);
+ }
+ else
+ {
+ CLEARBIT(u1_top_dc_csbp, u1_uv);
+ CLEARBIT(u1_left_dc_csbp, u1_uv);
+ }
+ }
+ /*************************************************************/
+ /* Update the DC csbp */
+ /*************************************************************/
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x1;
+ ps_curr_ctxt->u1_yuv_dc_csbp &= 0x1;
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] |= (u1_left_dc_csbp << 1);
+ ps_curr_ctxt->u1_yuv_dc_csbp |= (u1_top_dc_csbp << 1);
+ }
+ /*******************/
+ /* Write Chroma AC */
+ /*******************/
+ {
+ if(u1_chroma_cbp == 2)
+ {
+ UWORD8 u1_uv_blkno, u1_left_ac_csbp, u1_top_ac_csbp;
+ WORD16 *pi2_res_block;
+ u1_left_ac_csbp = ps_cabac_ctxt->pu1_left_uv_ac_csbp[0];
+ u1_top_ac_csbp = ps_top_ctxt_mb_info->u1_yuv_ac_csbp >> 4;
+
+ for(u1_uv_blkno = 0; u1_uv_blkno < 8; u1_uv_blkno++)
+ {
+ UWORD8 u1_cbf;
+ UWORD8 u1_b2b0, u1_b2b1;
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u1_nnz,
+ u2_sig_coeff_map, pi2_res_block);
+
+ u1_cbf = !!(u1_nnz);
+ u1_b2b0 = ((u1_uv_blkno & 0x4) >> 1) | (u1_uv_blkno & 0x1);
+ u1_b2b1 = ((u1_uv_blkno & 0x4) >> 1) | ((u1_uv_blkno & 0x2) >> 1);
+
+ {
+ UWORD8 u1_a, u1_b;
+ UWORD32 u4_ctx_inc;
+ /* write coded_block_flag */
+ u1_a = (u1_left_ac_csbp >> u1_b2b1) & 0x1;
+ u1_b = (u1_top_ac_csbp >> u1_b2b0) & 0x1;
+ u4_ctx_inc = u1_a + (u1_b << 1);
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_cbf,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + CBF +
+ (CHROMA_AC_CTXCAT << 2) + u4_ctx_inc);
+ }
+ if(u1_cbf)
+ {
+ isvce_cabac_write_coeff4x4(
+ pi2_res_block, u1_nnz, 14, u2_sig_coeff_map,
+ COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_4_OFFSET,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + +SIGNIFICANT_COEFF_FLAG_FRAME +
+ SIG_COEFF_CTXT_CAT_4_OFFSET,
+ ps_cabac_ctxt);
+
+ SETBIT(u1_left_ac_csbp, u1_b2b1);
+ SETBIT(u1_top_ac_csbp, u1_b2b0);
+ }
+ else
+ {
+ CLEARBIT(u1_left_ac_csbp, u1_b2b1);
+ CLEARBIT(u1_top_ac_csbp, u1_b2b0);
+ }
+ }
+ /*************************************************************/
+ /* Update the AC csbp */
+ /*************************************************************/
+ ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = u1_left_ac_csbp;
+ ps_curr_ctxt->u1_yuv_ac_csbp &= 0x0f;
+ ps_curr_ctxt->u1_yuv_ac_csbp |= (u1_top_ac_csbp << 4);
+ }
+ else
+ {
+ ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = 0;
+ ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf;
+ }
+ }
+ ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encodes Residues for the MB as defined in 7.3.5.3
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @param[in] u1_cbp
+ * coded block pattern
+ *
+ * @param[in] u1_ctx_cat
+ * Context category, LUMA_AC_CTXCAT or LUMA_4x4_CTXCAT
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_encode_residue(isvce_entropy_ctxt_t *ps_ent_ctxt, UWORD32 u4_cbp,
+ UWORD8 u1_ctx_cat)
+{
+ /* CABAC context */
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+
+ tu_sblk_coeff_data_t *ps_mb_coeff_data;
+ /* packed residue */
+ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
+ UWORD16 u2_sig_coeff_map;
+ UWORD8 u1_nnz;
+ isvce_mb_info_ctxt_t *ps_curr_ctxt;
+ isvce_mb_info_ctxt_t *ps_top_ctxt;
+ UWORD8 u1_left_ac_csbp;
+ UWORD8 u1_top_ac_csbp;
+ UWORD32 u4_ctx_idx_offset_sig_coef, u4_ctx_idx_offset_abs_lvl;
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+ ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ u1_left_ac_csbp = ps_cabac_ctxt->pu1_left_y_ac_csbp[0];
+ u1_top_ac_csbp = ps_top_ctxt->u1_yuv_ac_csbp;
+
+ if(u4_cbp & 0xf)
+ {
+ /* Write luma residue */
+ UWORD8 u1_offset;
+ WORD16 *pi2_res_block;
+ UWORD8 u1_subblk_num;
+ if(u1_ctx_cat == LUMA_AC_CTXCAT)
+ {
+ u1_offset = 1;
+ u4_ctx_idx_offset_sig_coef = SIG_COEFF_CTXT_CAT_1_OFFSET;
+ u4_ctx_idx_offset_abs_lvl = COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_1_OFFSET;
+ }
+ else
+ {
+ u1_offset = 0;
+ u4_ctx_idx_offset_sig_coef = SIG_COEFF_CTXT_CAT_2_OFFSET;
+ u4_ctx_idx_offset_abs_lvl = COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_2_OFFSET;
+ }
+
+ for(u1_subblk_num = 0; u1_subblk_num < 16; u1_subblk_num++)
+ {
+ UWORD8 u1_b0, u1_b1, u1_b2, u1_b3, u1_b2b0, u1_b3b1, u1_b3b2;
+ u1_b0 = (u1_subblk_num & 0x1);
+ u1_b1 = (u1_subblk_num & 0x2) >> 1;
+ u1_b2 = (u1_subblk_num & 0x4) >> 2;
+ u1_b3 = (u1_subblk_num & 0x8) >> 3;
+ u1_b2b0 = (u1_b2 << 1) | (u1_b0);
+ u1_b3b1 = (u1_b3 << 1) | (u1_b1);
+ u1_b3b2 = (u1_b3 << 1) | (u1_b2);
+
+ if(!((u4_cbp >> u1_b3b2) & 0x1))
+ {
+ /* ---------------------------------------------------------- */
+ /* The current block is not coded so skip all the sub block */
+ /* and set the pointer of scan level, csbp accrodingly */
+ /* ---------------------------------------------------------- */
+ CLEARBIT(u1_top_ac_csbp, u1_b2b0);
+ CLEARBIT(u1_top_ac_csbp, (u1_b2b0 + 1));
+ CLEARBIT(u1_left_ac_csbp, u1_b3b1);
+ CLEARBIT(u1_left_ac_csbp, (u1_b3b1 + 1));
+
+ u1_subblk_num += 3;
+ }
+ else
+ {
+ UWORD8 u1_csbf;
+
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u1_nnz,
+ u2_sig_coeff_map, pi2_res_block);
+
+ u1_csbf = !!(u1_nnz);
+ {
+ UWORD8 u1_a, u1_b;
+ UWORD32 u4_ctx_inc;
+ u1_b = (u1_top_ac_csbp >> u1_b2b0) & 0x01;
+ u1_a = (u1_left_ac_csbp >> u1_b3b1) & 0x01;
+ u4_ctx_inc = u1_a + (u1_b << 1);
+
+ /* Encode the bin */
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, u1_csbf,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + CBF + (u1_ctx_cat << 2) + u4_ctx_inc);
+ }
+ /**************************/
+ /* Write coded_block_flag */
+ /**************************/
+ if(u1_csbf)
+ {
+ isvce_cabac_write_coeff4x4(pi2_res_block, u1_nnz, (UWORD8) (15 - u1_offset),
+ u2_sig_coeff_map, u4_ctx_idx_offset_abs_lvl,
+ ps_cabac_ctxt->au1_cabac_ctxt_table +
+ SIGNIFICANT_COEFF_FLAG_FRAME +
+ u4_ctx_idx_offset_sig_coef,
+ ps_cabac_ctxt);
+
+ SETBIT(u1_top_ac_csbp, u1_b2b0);
+ SETBIT(u1_left_ac_csbp, u1_b3b1);
+ }
+ else
+ {
+ CLEARBIT(u1_top_ac_csbp, u1_b2b0);
+ CLEARBIT(u1_left_ac_csbp, u1_b3b1);
+ }
+ }
+ }
+ /**************************************************************************/
+ /* Update the AC csbp */
+ /**************************************************************************/
+ ps_cabac_ctxt->pu1_left_y_ac_csbp[0] = u1_left_ac_csbp & 0xf;
+ u1_top_ac_csbp &= 0x0f;
+ ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf0;
+ ps_curr_ctxt->u1_yuv_ac_csbp |= u1_top_ac_csbp;
+ }
+ else
+ {
+ ps_cabac_ctxt->pu1_left_y_ac_csbp[0] = 0;
+ ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf0;
+ }
+
+ /* Write chroma residue */
+
+ ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
+ {
+ UWORD8 u1_cbp_chroma;
+ u1_cbp_chroma = u4_cbp >> 4;
+ if(u1_cbp_chroma)
+ {
+ isvce_cabac_write_chroma_residue(ps_ent_ctxt, u1_cbp_chroma);
+ }
+ else
+ {
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x1;
+ ps_curr_ctxt->u1_yuv_dc_csbp &= 0x1;
+ ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = 0;
+ ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf;
+ }
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encodes a Motion vector (9.3.3.1.1.7 )
+ *
+ * @param[in] u1_mvd
+ * Motion vector to be encoded
+ *
+ * @param[in] u4_ctx_idx_offset
+ * * ctxIdxOffset for MV_X or MV_Ycontext
+ *
+ * @param[in] ui2_abs_mvd
+ * sum of absolute value of corresponding neighboring motion vectors
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_ctx_mvd(WORD16 u1_mvd, UWORD32 u4_ctx_idx_offset, UWORD16 ui2_abs_mvd,
+ isvce_cabac_ctxt_t *ps_cabac_ctxt)
+{
+ UWORD8 u1_bin, u1_ctxt_inc;
+ WORD8 k = 3, u1_coff = 9;
+ WORD16 i2_abs_mvd, i2_sufs;
+ UWORD32 u4_ctx_inc;
+ UWORD32 u4_bins;
+ WORD8 i1_bins_len;
+
+ /* if mvd < u1_coff
+ only Prefix
+ else
+ Prefix + Suffix
+
+ encode sign bit
+
+ Prefix TU encoding Cmax =u1_coff and Suffix 3rd order Exp-Golomb
+ */
+
+ if(ui2_abs_mvd < 3)
+ u4_ctx_inc = 0;
+ else if(ui2_abs_mvd > 32)
+ u4_ctx_inc = 2;
+ else
+ u4_ctx_inc = 1;
+
+ u4_bins = 0;
+ i1_bins_len = 1;
+
+ if(u1_mvd == 0)
+ {
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, 0, ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset + u4_ctx_inc);
+ }
+ else
+ {
+ i2_abs_mvd = ABS(u1_mvd);
+ if(i2_abs_mvd >= u1_coff)
+ {
+ /* Prefix TU i.e string of 9 1's */
+ u4_bins = 0x1ff;
+ i1_bins_len = 9;
+ u4_ctx_inc = (u4_ctx_inc | 0x065430);
+
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 4,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset,
+ ps_cabac_ctxt);
+
+ /* Suffix, uses EncodeBypass */
+ u4_bins = 0;
+ i1_bins_len = 0;
+ i2_sufs = i2_abs_mvd - u1_coff;
+ while(1)
+ {
+ if(i2_sufs >= (1 << k))
+ {
+ u4_bins = (u4_bins | (1 << (31 - i1_bins_len)));
+ i1_bins_len++;
+ i2_sufs = i2_sufs - (1 << k);
+ k++;
+ }
+ else
+ {
+ i1_bins_len++;
+ while(k--)
+ {
+ u1_bin = ((i2_sufs >> k) & 0x01);
+ u4_bins = (u4_bins | (u1_bin << (31 - i1_bins_len)));
+ i1_bins_len++;
+ }
+ break;
+ }
+ }
+ u4_bins >>= (32 - i1_bins_len);
+ isvce_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins, i1_bins_len);
+ }
+ else
+ {
+ /* Prefix only */
+ /* b0 */
+ u4_bins = 1;
+ i2_abs_mvd--;
+ u1_ctxt_inc = 3;
+ while(i2_abs_mvd)
+ {
+ i2_abs_mvd--;
+ u4_bins = (u4_bins | (1 << i1_bins_len));
+ if(u1_ctxt_inc <= 6)
+ {
+ u4_ctx_inc = (u4_ctx_inc | (u1_ctxt_inc << (i1_bins_len << 2)));
+ u1_ctxt_inc++;
+ }
+ i1_bins_len++;
+ }
+ /* Encode Terminating bit */
+ if(i1_bins_len <= 4) u4_ctx_inc = (u4_ctx_inc | (u1_ctxt_inc << (i1_bins_len << 2)));
+ i1_bins_len++;
+ isvce_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 4,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset,
+ ps_cabac_ctxt);
+ }
+ /* sign bit, uses EncodeBypass */
+ if(u1_mvd > 0)
+ isvce_cabac_encode_bypass_bin(ps_cabac_ctxt, 0);
+ else
+ isvce_cabac_encode_bypass_bin(ps_cabac_ctxt, 1);
+ }
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encodes all motion vectors for a P16x16 MB
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @param[in] pi2_mv_ptr
+ * Pointer to array of motion vectors
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_mvds_p16x16(isvce_cabac_ctxt_t *ps_cabac_ctxt, WORD16 *pi2_mv_ptr)
+{
+ UWORD8 u1_abs_mvd_x, u1_abs_mvd_y;
+ UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt;
+ WORD16 u2_mv;
+ u1_abs_mvd_x = 0;
+ u1_abs_mvd_y = 0;
+ pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0];
+ pu1_lft_mv_ctxt = ps_cabac_ctxt->pu1_left_mv_ctxt_inc[0];
+ {
+ UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a, u2_abs_mvd_y_b;
+ u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[0];
+ u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[1];
+ u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[0];
+ u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[1];
+ u2_mv = *(pi2_mv_ptr++);
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_X, (UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
+ u2_mv = *(pi2_mv_ptr++);
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_Y, (UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
+ }
+ /***************************************************************/
+ /* Store abs_mvd_values cabac contexts */
+ /***************************************************************/
+ pu1_top_mv_ctxt[0] = pu1_lft_mv_ctxt[0] = u1_abs_mvd_x;
+ pu1_top_mv_ctxt[1] = pu1_lft_mv_ctxt[1] = u1_abs_mvd_y;
+}
+
+/**
+ *******************************************************************************
+ * @brief
+ * Encodes all motion vectors for a B MB (Assues that mbype is B_L0_16x16,
+ *B_L1_16x16 or B_Bi_16x16
+ *
+ * @param[in] ps_cabac_ctxt
+ * Pointer to cabac context structure
+ *
+ * @param[in] pi2_mv_ptr
+ * Pointer to array of motion vectors
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_cabac_enc_mvds_b16x16(isvce_cabac_ctxt_t *ps_cabac_ctxt, WORD16 *pi2_mv_ptr,
+ WORD32 i4_mb_part_pred_mode)
+{
+ /* Encode the differential component of the motion vectors */
+
+ {
+ UWORD8 u1_abs_mvd_x, u1_abs_mvd_y;
+ UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt;
+ WORD16 u2_mv;
+ u1_abs_mvd_x = 0;
+ u1_abs_mvd_y = 0;
+ pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0];
+ pu1_lft_mv_ctxt = ps_cabac_ctxt->pu1_left_mv_ctxt_inc[0];
+ if(i4_mb_part_pred_mode != L1)
+ {
+ UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a, u2_abs_mvd_y_b;
+ u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[0];
+ u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[1];
+ u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[0];
+ u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[1];
+ u2_mv = pi2_mv_ptr[0];
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_X, (UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
+ u2_mv = pi2_mv_ptr[1];
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_Y, (UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
+ }
+
+ /***************************************************************/
+ /* Store abs_mvd_values cabac contexts */
+ /***************************************************************/
+ pu1_top_mv_ctxt[0] = pu1_lft_mv_ctxt[0] = u1_abs_mvd_x;
+ pu1_top_mv_ctxt[1] = pu1_lft_mv_ctxt[1] = u1_abs_mvd_y;
+
+ u1_abs_mvd_x = 0;
+ u1_abs_mvd_y = 0;
+ if(i4_mb_part_pred_mode != L0)
+ {
+ UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a, u2_abs_mvd_y_b;
+ u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[2];
+ u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[3];
+ u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[2];
+ u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[3];
+ u2_mv = pi2_mv_ptr[2];
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_X, (UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
+ u2_mv = pi2_mv_ptr[3];
+
+ isvce_cabac_enc_ctx_mvd(u2_mv, MVD_Y, (UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
+ ps_cabac_ctxt);
+
+ u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
+ }
+ /***************************************************************/
+ /* Store abs_mvd_values cabac contexts */
+ /***************************************************************/
+ pu1_top_mv_ctxt[2] = pu1_lft_mv_ctxt[2] = u1_abs_mvd_x;
+ pu1_top_mv_ctxt[3] = pu1_lft_mv_ctxt[3] = u1_abs_mvd_y;
+ }
+}
+
+static FORCEINLINE void isvce_mb_ctxt_update(isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ isvce_mb_info_ctxt_t *ps_curr_ctxt,
+ WORD8 i1_mb_qp_delta, UWORD8 u1_cbp,
+ UWORD8 u1_base_mode_flag, MBTYPES_T e_mb_type)
+{
+ UWORD8 u1_is_intra_mb = (e_mb_type == I16x16) || (e_mb_type == I8x8) || (e_mb_type == I4x4);
+ UWORD8 u1_is_skip_mb = (e_mb_type == PSKIP) || (e_mb_type == BSKIP);
+ UWORD8 u1_is_direct_mb = (e_mb_type == BDIRECT);
+
+ ps_curr_ctxt->u1_cbp = u1_cbp;
+ ps_curr_ctxt->u1_base_mode_flag = u1_base_mode_flag;
+
+ if(u1_is_intra_mb || u1_is_skip_mb || u1_is_direct_mb || u1_base_mode_flag)
+ {
+ memset(ps_curr_ctxt->u1_mv, 0, 16);
+ memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
+ }
+
+ if((0 == u1_cbp) && (e_mb_type != I16x16))
+ {
+ ps_curr_ctxt->u1_yuv_ac_csbp = 0;
+ ps_curr_ctxt->u1_yuv_dc_csbp = 0;
+
+ ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = 0;
+ ps_cabac_ctxt->pu1_left_y_ac_csbp[0] = 0;
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] = 0;
+ }
+
+ if(u1_is_skip_mb)
+ {
+ ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 0;
+ }
+ else if((I16x16 != e_mb_type) && (0 == u1_cbp))
+ {
+ ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 0;
+ }
+ else if(0 == i1_mb_qp_delta)
+ {
+ ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 0;
+ }
+ else
+ {
+ ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 1;
+ }
+
+ if(!u1_is_intra_mb || u1_base_mode_flag)
+ {
+ ps_curr_ctxt->u1_intrapred_chroma_mode = 0;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for an Intra Slice.
+ *
+ * @description
+ * The mb syntax layer for intra slices constitutes luma mb mode, mb qp delta,
+ *coded block pattern, chroma mb mode and luma/chroma residue. These syntax
+ *elements are written as directed by table 7.3.5 of h264 specification.
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_islice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ isvce_mb_info_ctxt_t *ps_curr_ctxt;
+
+ WORD32 mb_tpm, mb_type, chroma_intra_mode, luma_intra_mode;
+ UWORD8 u1_cbp, u1_cbp_l, u1_cbp_c;
+ WORD8 mb_qp_delta;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+ UWORD8 u1_base_mode_flag;
+
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+
+ if((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB) >= ps_bitstream->u4_max_strm_size)
+ {
+ /* return without corrupting the buffer beyond its size */
+ return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
+ }
+
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+ u1_base_mode_flag = ps_mb_hdr->u1_base_mode_flag;
+ u1_cbp = ps_mb_hdr->u1_cbp;
+ u1_cbp_c = (u1_cbp >> 4);
+ u1_cbp_l = (u1_cbp & 0xF);
+ mb_type = mb_tpm & 0xF;
+
+ isvce_get_cabac_context(ps_ent_ctxt, mb_type);
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ if(mb_type == I16x16)
+ {
+ luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u1_cbp_c << 2) + (u1_cbp_l == 15) * 12;
+ }
+ else
+ {
+ luma_intra_mode = 0;
+ }
+
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ isvce_cabac_enc_base_mode_flag(ps_cabac_ctxt, u1_base_mode_flag);
+ }
+
+ if(!u1_base_mode_flag)
+ {
+ isvce_cabac_enc_intra_mb_type(ISLICE, luma_intra_mode, ps_cabac_ctxt, MB_TYPE_I_SLICE);
+
+ if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ isvce_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
+ }
+
+ isvce_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
+ }
+
+ if(u1_base_mode_flag || (mb_type != I16x16))
+ {
+ isvce_cabac_enc_cbp(u1_cbp, ps_cabac_ctxt);
+ }
+
+ if((u1_cbp > 0) || (mb_type == I16x16))
+ {
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ isvce_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
+ bitstream_start_offset = bitstream_end_offset;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ isvce_cabac_encode_residue_luma_dc(ps_ent_ctxt);
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_AC_CTXCAT);
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == BASE_MODE)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_P | CAB_NON_BD16x16;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
+ }
+ else
+ {
+ mb_qp_delta = 0;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == BASE_MODE)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_P | CAB_NON_BD16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
+ }
+
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, mb_qp_delta, u1_cbp, u1_base_mode_flag,
+ mb_type);
+
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return IH264E_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for Inter slices
+ *
+ * @description
+ * The mb syntax layer for inter slices constitutes luma mb mode, mb qp delta,
+ *coded block pattern, chroma mb mode and luma/chroma residue. These syntax
+ *elements are written as directed by table 7.3.5 of h264 specification
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_pslice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ isvce_mb_info_ctxt_t *ps_curr_ctxt;
+
+ WORD32 mb_tpm, mb_type, chroma_intra_mode, luma_intra_mode;
+ UWORD8 u1_cbp, u1_cbp_l, u1_cbp_c;
+ WORD8 mb_qp_delta;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+ UWORD8 u1_base_mode_flag;
+ UWORD8 u1_is_intra_mb;
+
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+
+ if((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB) >= ps_bitstream->u4_max_strm_size)
+ {
+ /* return without corrupting the buffer beyond its size */
+ return IH264E_BITSTREAM_BUFFER_OVERFLOW;
+ }
+
+ /* mb header info */
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+ u1_base_mode_flag = ps_mb_hdr->u1_base_mode_flag;
+ u1_cbp = ps_mb_hdr->u1_cbp;
+ u1_cbp_c = (u1_cbp >> 4);
+ u1_cbp_l = (u1_cbp & 0xF);
+
+ /* mb type */
+ mb_type = mb_tpm & 0xF;
+ u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
+
+ /* CABAC contexts for the MB */
+ isvce_get_cabac_context(ps_ent_ctxt, mb_type);
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ /* Encode mb_skip_flag */
+ isvce_cabac_enc_mb_skip(mb_type == PSKIP, ps_cabac_ctxt, MB_SKIP_FLAG_P_SLICE);
+
+ if(mb_type == PSKIP)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_P_SKIP;
+
+ ps_ent_ctxt->pi4_mb_skip_run[0]++;
+
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, 0, 0, 0, PSKIP);
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+
+ pu1_byte += sizeof(isvce_mb_hdr_pskip_t);
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return IH264E_SUCCESS;
+ }
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ isvce_cabac_enc_base_mode_flag(ps_cabac_ctxt, u1_base_mode_flag);
+ }
+
+ if(!u1_base_mode_flag)
+ {
+ if(u1_is_intra_mb)
+ {
+ if(mb_type == I16x16)
+ {
+ luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u1_cbp_c << 2) + (u1_cbp_l == 15) * 12;
+ }
+ else
+ {
+ luma_intra_mode = 0;
+ }
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, 1,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_TYPE_P_SLICE);
+
+ isvce_cabac_enc_intra_mb_type(PSLICE, (UWORD8) luma_intra_mode, ps_cabac_ctxt,
+ MB_TYPE_P_SLICE);
+
+ if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ isvce_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
+ }
+
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ isvce_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
+ }
+ else
+ {
+ UWORD32 u4_ctx_inc_p;
+
+ isvce_mb_hdr_p16x16_t *ps_mb_hdr_p16x16 =
+ (isvce_mb_hdr_p16x16_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_p16x16->ai2_mvd;
+
+ /* Encoding mb_type as P16x16 */
+ u4_ctx_inc_p = (0x010 + ((2) << 8));
+
+ isvce_encode_decision_bins(0, 3, u4_ctx_inc_p, 3,
+ &(ps_cabac_ctxt->au1_cabac_ctxt_table[MB_TYPE_P_SLICE]),
+ ps_cabac_ctxt);
+
+ if(ps_ent_ctxt->u1_spatial_layer_id &&
+ ps_svc_slice_header->i1_adaptive_motion_prediction_flag)
+ {
+ isvce_cabac_enc_motion_prediction_flag(ps_cabac_ctxt, ps_mb_hdr_p16x16->u1_mvp_idx,
+ 1);
+ }
+
+ isvce_cabac_enc_mvds_p16x16(ps_cabac_ctxt, pi2_mv_ptr);
+ }
+ }
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && (u1_base_mode_flag || !u1_is_intra_mb) &&
+ ps_svc_slice_header->i1_adaptive_residual_prediction_flag)
+ {
+ isvce_cabac_enc_residual_prediction_flag(ps_cabac_ctxt, u1_base_mode_flag,
+ ps_mb_hdr->u1_residual_prediction_flag);
+ }
+
+ if(u1_base_mode_flag || (mb_type != I16x16))
+ {
+ isvce_cabac_enc_cbp(u1_cbp, ps_cabac_ctxt);
+ }
+
+ if((u1_cbp > 0) || (mb_type == I16x16))
+ {
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ isvce_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+
+ bitstream_start_offset = bitstream_end_offset;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ isvce_cabac_encode_residue_luma_dc(ps_ent_ctxt);
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_AC_CTXCAT);
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == P16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = (CAB_P | CAB_NON_BD16x16);
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_p16x16_t);
+ }
+ else if(mb_type == BASE_MODE)
+ {
+ ps_curr_ctxt->u1_mb_type = (CAB_P | CAB_NON_BD16x16);
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_residue_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+ }
+ else
+ {
+ mb_qp_delta = 0;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == P16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = (CAB_P | CAB_NON_BD16x16);
+
+ pu1_byte += sizeof(isvce_mb_hdr_p16x16_t);
+ }
+ else if(mb_type == BASE_MODE)
+ {
+ ps_curr_ctxt->u1_mb_type = (CAB_P | CAB_NON_BD16x16);
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+ }
+
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, mb_qp_delta, u1_cbp, u1_base_mode_flag,
+ mb_type);
+
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return IH264E_SUCCESS;
+}
+
+/* ! < Table 9-37 – Binarization for macroblock types in B slices in
+ * ITU_T_H264-201402 Bits 0-7 : binarised value Bits 8-15: length of binary
+ * sequence */
+
+static const UWORD32 u4_b_mb_type[27] = {
+ 0x0100, 0x0301, 0x0305, 0x0603, 0x0623, 0x0613, 0x0633, 0x060b, 0x062b, 0x061b, 0x063b, 0x061f,
+ 0x0707, 0x0747, 0x0727, 0x0767, 0x0717, 0x0757, 0x0737, 0x0777, 0x070f, 0x074f, 0x063f};
+/* CtxInc for mb types in B slices */
+static const UWORD32 ui_b_mb_type_ctx_inc[27] = {
+ 0x00, 0x0530, 0x0530, 0x0555430, 0x0555430, 0x0555430, 0x0555430, 0x0555430,
+ 0x0555430, 0x0555430, 0x0555430, 0x0555430, 0x05555430, 0x05555430, 0x05555430, 0x05555430,
+ 0x05555430, 0x05555430, 0x05555430, 0x05555430, 0x05555430, 0x05555430, 0x0555430};
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function generates CABAC coded bit stream for B slices
+ *
+ * @description
+ * The mb syntax layer for inter slices constitutes luma mb mode,
+ * mb qp delta, coded block pattern, chroma mb mode and
+ * luma/chroma residue. These syntax elements are written as directed by table
+ * 7.3.5 of h264 specification
+ *
+ * @param[in] ps_ent_ctxt
+ * pointer to entropy context
+ *
+ * @returns error code
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+IH264E_ERROR_T isvce_write_bslice_mb_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ isvce_mb_info_ctxt_t *ps_curr_ctxt;
+
+ WORD32 mb_tpm, mb_type, chroma_intra_mode, luma_intra_mode;
+ UWORD8 u1_cbp, u1_cbp_l, u1_cbp_c;
+ WORD8 mb_qp_delta;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+ UWORD8 u1_base_mode_flag;
+ UWORD8 u1_is_intra_mb;
+
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+
+ if((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB) >= ps_bitstream->u4_max_strm_size)
+ {
+ /* return without corrupting the buffer beyond its size */
+ return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
+ }
+
+ /* mb header info */
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+ u1_base_mode_flag = ps_mb_hdr->u1_base_mode_flag;
+ u1_cbp = ps_mb_hdr->u1_cbp;
+ u1_cbp_c = (u1_cbp >> 4);
+ u1_cbp_l = (u1_cbp & 0xF);
+
+ /* mb type */
+ mb_type = mb_tpm & 0xF;
+ u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
+
+ /* CABAC contexts for the MB */
+ isvce_get_cabac_context(ps_ent_ctxt, mb_type);
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ /* Encode mb_skip_flag */
+ isvce_cabac_enc_mb_skip(mb_type == BSKIP, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE);
+
+ if(mb_type == BSKIP)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_B_SKIP;
+
+ ps_ent_ctxt->pi4_mb_skip_run[0]++;
+
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, 0, 0, 0, BSKIP);
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+
+ pu1_byte += sizeof(isvce_mb_hdr_bskip_t);
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return IH264E_SUCCESS;
+ }
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ isvce_cabac_enc_base_mode_flag(ps_cabac_ctxt, u1_base_mode_flag);
+ }
+
+ if(!u1_base_mode_flag)
+ {
+ if(u1_is_intra_mb)
+ {
+ if(mb_type == I16x16)
+ {
+ luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u1_cbp_c << 2) + (u1_cbp_l == 15) * 12;
+ }
+ else
+ {
+ luma_intra_mode = 0;
+ }
+
+ {
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+
+ UWORD32 u4_ctx_inc = 0;
+
+ if(ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ {
+ u4_ctx_inc +=
+ ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+ }
+
+ if(ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ {
+ u4_ctx_inc +=
+ ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+ }
+
+ /* Intra Prefix Only "111101" */
+ u4_ctx_inc = (u4_ctx_inc | 0x05555430);
+ isvce_encode_decision_bins(0x2f, 6, u4_ctx_inc, 3,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_TYPE_B_SLICE,
+ ps_cabac_ctxt);
+
+ isvce_cabac_enc_intra_mb_type(BSLICE, (UWORD8) luma_intra_mode, ps_cabac_ctxt,
+ MB_TYPE_B_SLICE);
+ }
+
+ if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ isvce_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
+ }
+
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ isvce_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
+ }
+ else if(mb_type == BDIRECT)
+ {
+ /* Encoding mb_type as B_Direct_16x16 */
+ {
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+
+ UWORD32 u4_ctx_inc = 0;
+
+ if(ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ {
+ u4_ctx_inc +=
+ ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+ }
+
+ if(ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ {
+ u4_ctx_inc +=
+ ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+ }
+
+ /* Encode the bin */
+ isvce_cabac_encode_bin(
+ ps_cabac_ctxt, 0,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + MB_TYPE_B_SLICE + u4_ctx_inc);
+ }
+ }
+ else
+ {
+ WORD32 i;
+
+ isvce_mb_hdr_b16x16_t *ps_mb_hdr_b16x16 =
+ (isvce_mb_hdr_b16x16_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_b16x16->ai2_mvd;
+ WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
+ UWORD32 u4_mb_type = mb_type - B16x16 + B_L0_16x16 + i4_mb_part_pred_mode;
+
+ /* Encoding mb_type as B16x16 */
+ {
+ isvce_mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
+ isvce_mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
+ UWORD32 u4_ctx_inc = 0;
+
+ UWORD32 u4_mb_type_bins = u4_b_mb_type[u4_mb_type];
+ UWORD32 u4_bin_len = (u4_mb_type_bins >> 8) & 0x0F;
+ u4_mb_type_bins = u4_mb_type_bins & 0xFF;
+
+ if(ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ u4_ctx_inc +=
+ ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+ if(ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
+ u4_ctx_inc +=
+ ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16) ? 1 : 0;
+
+ u4_ctx_inc = u4_ctx_inc | ui_b_mb_type_ctx_inc[u4_mb_type];
+
+ isvce_encode_decision_bins(u4_mb_type_bins, u4_bin_len, u4_ctx_inc, u4_bin_len,
+ &(ps_cabac_ctxt->au1_cabac_ctxt_table[MB_TYPE_B_SLICE]),
+ ps_cabac_ctxt);
+ }
+
+ for(i = 0; i < NUM_PRED_DIRS; i++)
+ {
+ PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
+ PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
+
+ if(((PRED_MODE_T) i4_mb_part_pred_mode) != e_pred_mode)
+ {
+ if(ps_svc_slice_header->i1_adaptive_motion_prediction_flag &&
+ ps_ent_ctxt->u1_spatial_layer_id)
+ {
+ isvce_cabac_enc_motion_prediction_flag(
+ ps_cabac_ctxt, ps_mb_hdr_b16x16->au1_mvp_idx[e_cmpl_pred_mode],
+ e_cmpl_pred_mode == L0);
+ }
+ }
+ }
+
+ isvce_cabac_enc_mvds_b16x16(ps_cabac_ctxt, pi2_mv_ptr, i4_mb_part_pred_mode);
+ }
+ }
+
+ if(ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
+ ps_ent_ctxt->u1_spatial_layer_id && (u1_base_mode_flag || !u1_is_intra_mb))
+ {
+ isvce_cabac_enc_residual_prediction_flag(ps_cabac_ctxt, u1_base_mode_flag,
+ ps_mb_hdr->u1_residual_prediction_flag);
+ }
+
+ if(u1_base_mode_flag || (mb_type != I16x16))
+ {
+ isvce_cabac_enc_cbp(u1_cbp, ps_cabac_ctxt);
+ }
+
+ if((u1_cbp > 0) || (mb_type == I16x16))
+ {
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ isvce_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+ bitstream_start_offset = bitstream_end_offset;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ isvce_cabac_encode_residue_luma_dc(ps_ent_ctxt);
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_AC_CTXCAT);
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == B16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
+ }
+ else if(mb_type == BDIRECT)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_BD16x16;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
+ }
+ else if(mb_type == BASE_MODE)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
+
+ isvce_cabac_encode_residue(ps_ent_ctxt, u1_cbp, LUMA_4X4_CTXCAT);
+
+ ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
+ ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_residue_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+ }
+ else
+ {
+ mb_qp_delta = 0;
+
+ if(mb_type == I16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_I4x4;
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == B16x16)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
+ }
+ else if(mb_type == BDIRECT)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_BD16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
+ }
+ else if(mb_type == BDIRECT)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
+
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_header_bits[!u1_is_intra_mb] +=
+ bitstream_end_offset - bitstream_start_offset;
+ }
+
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, mb_qp_delta, u1_cbp, u1_base_mode_flag,
+ mb_type);
+
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return IH264E_SUCCESS;
+}
+
+#if ENABLE_RE_ENC_AS_SKIP
+IH264E_ERROR_T isvce_reencode_as_skip_frame_cabac(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ bitstrm_t *ps_bitstrm = ps_ent_ctxt->ps_bitstrm;
+ bitstrm_t *ps_bitstrm_after_slice_hdr = ps_ent_ctxt->ps_bitstrm_after_slice_hdr;
+
+ isvce_mb_info_ctxt_t *ps_curr_ctxt;
+
+ slice_header_t *ps_slice_header =
+ (ps_ent_ctxt->u1_spatial_layer_id == 0)
+ ? &ps_ent_ctxt->ps_slice_hdr_base[ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT]
+ : &ps_ent_ctxt
+ ->ps_svc_slice_hdr_base[ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT]
+ .s_slice_header;
+
+ /* total mb cnt */
+ UWORD32 i4_wd_mbs = ps_ent_ctxt->i4_wd_mbs;
+ UWORD32 i4_ht_mbs = ps_ent_ctxt->i4_ht_mbs;
+ UWORD8 i, j;
+
+ isvce_init_cabac_ctxt(ps_ent_ctxt, ps_slice_header);
+
+ ps_bitstrm->i4_bits_left_in_cw = ps_bitstrm_after_slice_hdr->i4_bits_left_in_cw;
+ ps_bitstrm->u4_cur_word = ps_bitstrm_after_slice_hdr->u4_cur_word;
+ ps_bitstrm->u4_strm_buf_offset = ps_bitstrm_after_slice_hdr->u4_strm_buf_offset;
+ ps_bitstrm->i4_zero_bytes_run = ps_bitstrm_after_slice_hdr->i4_zero_bytes_run;
+
+ for(i = 0; i < i4_ht_mbs; i++)
+ {
+ for(j = 0; j < i4_wd_mbs; j++)
+ {
+ MBTYPES_T mb_type = PSKIP;
+
+ ps_ent_ctxt->i4_mb_x = j;
+ ps_ent_ctxt->i4_mb_y = i;
+
+ isvce_get_cabac_context(ps_ent_ctxt, mb_type);
+ ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
+
+ isvce_cabac_enc_mb_skip(mb_type == PSKIP, ps_cabac_ctxt, MB_SKIP_FLAG_P_SLICE);
+
+ if(mb_type == PSKIP)
+ {
+ ps_curr_ctxt->u1_mb_type = CAB_P_SKIP;
+ isvce_mb_ctxt_update(ps_cabac_ctxt, ps_curr_ctxt, 0, 0, 0, PSKIP);
+ }
+
+ if(j == i4_wd_mbs - 1 && i == i4_ht_mbs - 1)
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
+ }
+ else
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
+ }
+ }
+ }
+ return IH264E_SUCCESS;
+}
+#endif
diff --git a/encoder/svc/isvce_cabac_init.c b/encoder/svc/isvce_cabac_init.c
new file mode 100644
index 0000000..ea8695b
--- /dev/null
+++ b/encoder/svc/isvce_cabac_init.c
@@ -0,0 +1,215 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_cabac_init.c
+*
+* @brief
+* Contains all initialization functions for cabac contexts
+*
+* @author
+* Doney Alex
+*
+* @par List of Functions:
+*
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_debug.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_platform_macros.h"
+#include "isvc_macros.h"
+#include "ih264_buf_mgr.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "isvc_common_tables.h"
+#include "isvc_cabac_tables.h"
+#include "ih264_list.h"
+#include "isvce_defs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "isvce_process.h"
+#include "ithread.h"
+#include "isvce_encode_header.h"
+#include "isvce_globals.h"
+#include "ih264e_config.h"
+#include "ih264e_trace.h"
+#include "ih264e_statistics.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_deblk.h"
+#include "isvce_me.h"
+#include "ih264e_debug.h"
+#include "ih264e_master.h"
+#include "isvce_utils.h"
+#include "irc_mem_req_and_acq.h"
+#include "irc_rate_control_api.h"
+#include "ih264e_platform_macros.h"
+#include "ime_statistics.h"
+
+/*****************************************************************************/
+/* Function definitions . */
+/*****************************************************************************/
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Initialize cabac encoding environment
+ *
+ * @param[in] ps_cab_enc_env
+ * Pointer to encoding_envirnoment_t structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+static void isvce_init_cabac_enc_envirnoment(encoding_envirnoment_t *ps_cab_enc_env)
+{
+ ps_cab_enc_env->u4_code_int_low = 0;
+ ps_cab_enc_env->u4_code_int_range = 0x1fe;
+ ps_cab_enc_env->u4_out_standing_bytes = 0;
+ ps_cab_enc_env->u4_bits_gen = 0;
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Initialize default context values and pointers (Called once at the beginning
+ *of encoding).
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_init_cabac_table(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ /* CABAC context */
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+ ps_cabac_ctxt->ps_mb_map_ctxt_inc = ps_cabac_ctxt->ps_mb_map_ctxt_inc_base + 1;
+ ps_cabac_ctxt->ps_lft_csbp = &ps_cabac_ctxt->s_lft_csbp;
+ ps_cabac_ctxt->ps_bitstrm = ps_ent_ctxt->ps_bitstrm;
+
+ {
+ /* 0th entry of mb_map_ctxt_inc will be always be containing default values
+ */
+ /* for CABAC context representing MB not available */
+ isvce_mb_info_ctxt_t *ps_def_ctxt = ps_cabac_ctxt->ps_mb_map_ctxt_inc - 1;
+
+ ps_def_ctxt->u1_mb_type = CAB_SKIP;
+ ps_def_ctxt->u1_cbp = 0x0f;
+ ps_def_ctxt->u1_intrapred_chroma_mode = 0;
+ ps_def_ctxt->u1_base_mode_flag = 0;
+
+ memset(ps_def_ctxt->i1_ref_idx, 0, sizeof(ps_def_ctxt->i1_ref_idx));
+ memset(ps_def_ctxt->u1_mv, 0, sizeof(ps_def_ctxt->u1_mv));
+ ps_cabac_ctxt->ps_def_ctxt_mb_info = ps_def_ctxt;
+ }
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Initialize cabac context: Initialize all contest with init values given in
+ *the spec. Called at the beginning of entropy coding of each slice for CABAC
+ *encoding.
+ *
+ * @param[in] ps_ent_ctxt
+ * Pointer to entropy context structure
+ *
+ * @returns
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+void isvce_init_cabac_ctxt(isvce_entropy_ctxt_t *ps_ent_ctxt, slice_header_t *ps_slice_hdr)
+{
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
+
+ const UWORD8 u1_slice_type = ps_slice_hdr->u1_slice_type;
+ WORD8 i1_cabac_init_idc = 0;
+ bin_ctxt_model *au1_cabac_ctxt_table = ps_cabac_ctxt->au1_cabac_ctxt_table;
+ UWORD8 u1_qp_y = ps_slice_hdr->i1_slice_qp;
+
+ isvce_init_cabac_enc_envirnoment(&ps_cabac_ctxt->s_cab_enc_env);
+
+ ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = 0;
+
+ if(ISLICE != u1_slice_type)
+ {
+ i1_cabac_init_idc = ps_slice_hdr->i1_cabac_init_idc;
+ }
+ else
+ {
+ i1_cabac_init_idc = 3;
+ }
+
+ memcpy(au1_cabac_ctxt_table, gau1_isvc_cabac_ctxt_init_table[i1_cabac_init_idc][u1_qp_y],
+ NUM_SVC_CABAC_CTXTS * sizeof(bin_ctxt_model));
+}
diff --git a/encoder/svc/isvce_cabac_structs.h b/encoder/svc/isvce_cabac_structs.h
new file mode 100644
index 0000000..4c7d208
--- /dev/null
+++ b/encoder/svc/isvce_cabac_structs.h
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_cabac_structs.h
+ *
+ * @brief
+ * This file contains cabac related structure definitions.
+ *
+ * @author
+ * Doney Alex
+ *
+ * @remarks
+ * none
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCE_CABAC_STRUCTS_H_
+#define _ISVCE_CABAC_STRUCTS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_cabac_tables.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+
+/**
+ ******************************************************************************
+ * @brief MB info for cabac
+ ******************************************************************************
+ */
+typedef struct isvce_mb_info_ctxt_t
+{
+ /* Neighbour availability Variables needed to get CtxtInc, for CABAC */
+ UWORD8 u1_mb_type; /* !< macroblock type: I/P/B/SI/SP */
+
+ UWORD8 u1_cbp; /* !< Coded Block Pattern */
+ UWORD8 u1_intrapred_chroma_mode;
+
+ /*************************************************************************/
+ /* Arrangnment of AC CSBP */
+ /* bits: b7 b6 b5 b4 b3 b2 b1 b0 */
+ /* CSBP: V1 V0 U1 U0 Y3 Y2 Y1 Y0 */
+ /*************************************************************************/
+ UWORD8 u1_yuv_ac_csbp;
+ /*************************************************************************/
+ /* Arrangnment of DC CSBP */
+ /* bits: b7 b6 b5 b4 b3 b2 b1 b0 */
+ /* CSBP: x x x x x Vdc Udc Ydc */
+ /*************************************************************************/
+ UWORD8 u1_yuv_dc_csbp;
+
+ WORD8 i1_ref_idx[4];
+ UWORD8 u1_mv[4][4];
+
+ UWORD8 u1_base_mode_flag;
+} isvce_mb_info_ctxt_t;
+
+/**
+ ******************************************************************************
+ * @brief CABAC Context structure : Variables to handle Cabac
+ ******************************************************************************
+ */
+typedef struct isvce_cabac_ctxt_t
+{
+ /* Base pointer to all the cabac contexts */
+ bin_ctxt_model au1_cabac_ctxt_table[NUM_SVC_CABAC_CTXTS];
+
+ cab_csbp_t s_lft_csbp;
+
+ /**
+ * pointer to Bitstream structure
+ */
+ bitstrm_t *ps_bitstrm;
+
+ /* Pointer to mb_info_ctxt_t map_base */
+ isvce_mb_info_ctxt_t *ps_mb_map_ctxt_inc_base;
+
+ /* Pointer to encoding_envirnoment_t */
+ encoding_envirnoment_t s_cab_enc_env;
+
+ /* These things need to be updated at each MbLevel */
+
+ /* Prev ps_mb_qp_delta_ctxt */
+ WORD8 i1_prevps_mb_qp_delta_ctxt;
+
+ /* Pointer to mb_info_ctxt_t map */
+ isvce_mb_info_ctxt_t *ps_mb_map_ctxt_inc;
+
+ /* Pointer to default mb_info_ctxt_t */
+ isvce_mb_info_ctxt_t *ps_def_ctxt_mb_info;
+
+ /* Pointer to current mb_info_ctxt_t */
+ isvce_mb_info_ctxt_t *ps_curr_ctxt_mb_info;
+
+ /* Pointer to left mb_info_ctxt_t */
+ isvce_mb_info_ctxt_t *ps_left_ctxt_mb_info;
+
+ /* Pointer to top mb_info_ctxt_t */
+ isvce_mb_info_ctxt_t *ps_top_ctxt_mb_info;
+
+ /* Poniter to left csbp structure */
+ cab_csbp_t *ps_lft_csbp;
+ UWORD8 *pu1_left_y_ac_csbp;
+ UWORD8 *pu1_left_uv_ac_csbp;
+ UWORD8 *pu1_left_yuv_dc_csbp;
+
+ /***************************************************************************/
+ /* Ref_idx contexts are stored in the following way */
+ /* Array Idx 0,1 for reference indices in Forward direction */
+ /* Array Idx 2,3 for reference indices in backward direction */
+ /***************************************************************************/
+ /* Dimensions for u1_left_ref_ctxt_inc_arr is [2][4] for Mbaff:Top and Bot */
+ WORD8 i1_left_ref_idx_ctx_inc_arr[2][4];
+ WORD8 *pi1_left_ref_idx_ctxt_inc;
+
+ /* Dimensions for u1_left_mv_ctxt_inc_arr is [2][4][4] for Mbaff case */
+ UWORD8 u1_left_mv_ctxt_inc_arr[2][4][4];
+ UWORD8 (*pu1_left_mv_ctxt_inc)[4];
+
+} isvce_cabac_ctxt_t;
+
+#endif
diff --git a/encoder/svc/isvce_cabac_utils.h b/encoder/svc/isvce_cabac_utils.h
new file mode 100644
index 0000000..ffd05ed
--- /dev/null
+++ b/encoder/svc/isvce_cabac_utils.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_cabac_utils.h
+*
+* @brief
+* Contains function declarations for function declared in
+* isvce_svc_cabac_utils.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_CABAC_UTILS_H_
+#define _ISVCE_CABAC_UTILS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "isvc_defs.h"
+#include "isvc_cabac_tables.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_cabac.h"
+
+static FORCEINLINE void isvce_cabac_enc_base_mode_flag(isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD8 u1_base_mode_flag)
+{
+ UWORD8 u1_ctx_inc;
+ UWORD8 u1_a, u1_b;
+
+ const UWORD32 u4_ctxidx_offset = BASE_MODE_FLAG;
+
+ u1_a = !ps_cabac_ctxt->ps_left_ctxt_mb_info->u1_base_mode_flag;
+ u1_b = !ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_base_mode_flag;
+
+ u1_ctx_inc = u1_a + u1_b;
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_base_mode_flag,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset + u1_ctx_inc);
+}
+
+static FORCEINLINE void isvce_cabac_enc_residual_prediction_flag(isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD8 u1_base_mode_flag,
+ UWORD8 u1_residual_prediction_flag)
+{
+ const UWORD32 u4_ctxidx_offset = RESIDUAL_PREDICTION_FLAG;
+ UWORD8 u1_ctx_inc = !u1_base_mode_flag;
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_residual_prediction_flag,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset + u1_ctx_inc);
+}
+
+static FORCEINLINE void isvce_cabac_enc_motion_prediction_flag(isvce_cabac_ctxt_t *ps_cabac_ctxt,
+ UWORD8 u1_motion_prediction_flag,
+ UWORD8 u1_is_l0_mvp)
+{
+ const UWORD32 u4_ctxidx_offset =
+ u1_is_l0_mvp ? MOTION_PREDICTION_FLAG_L0 : MOTION_PREDICTION_FLAG_L1;
+
+ isvce_cabac_encode_bin(ps_cabac_ctxt, u1_motion_prediction_flag,
+ ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset);
+}
+
+#endif
diff --git a/encoder/svc/isvce_cavlc.c b/encoder/svc/isvce_cavlc.c
new file mode 100644
index 0000000..71122ed
--- /dev/null
+++ b/encoder/svc/isvce_cavlc.c
@@ -0,0 +1,2021 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_cavlc.c
+*
+* @brief
+* Contains all the routines to code syntax elements and residuals when entropy
+* coding chosen is CAVLC
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_compute_zeroruns_and_trailingones()
+* - isvce_write_coeff4x4_cavlc()
+* - isvce_write_coeff8x8_cavlc()
+* - isvce_encode_residue()
+* - isvce_write_islice_mb_cavlc()
+* - isvce_write_pslice_mb_cavlc()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+
+/* User include files */
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_debug.h"
+#include "isvc_macros.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_encode_header.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_statistics.h"
+#include "ih264e_trace.h"
+#include "isvce_encode_header.h"
+#include "isvce_utils.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function computes run of zero, number of trailing ones and sign of
+* trailing ones basing on the significant coeff map, residual block and
+* total nnz.
+*
+* @param[in] pi2_res_block
+* Pointer to residual block containing levels in scan order
+*
+* @param[in] u4_total_coeff
+* Total non-zero coefficients in that sub block
+*
+* @param[in] pu1_zero_run
+* Pointer to array to store run of zeros
+*
+* @param[in] u4_sig_coeff_map
+* significant coefficient map
+*
+* @returns u4_totzero_sign_trailone
+* Bits 0-8 contains number of trailing ones.
+* Bits 8-16 contains bitwise sign information of trailing one
+* Bits 16-24 contains total number of zeros.
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+static UWORD32 isvce_compute_zeroruns_and_trailingones(WORD16 *pi2_res_block,
+ UWORD32 u4_total_coeff, UWORD8 *pu1_zero_run,
+ UWORD32 u4_sig_coeff_map)
+{
+ UWORD32 i = 0;
+ UWORD32 u4_nnz_coeff = 0;
+ WORD32 i4_run = -1;
+ UWORD32 u4_sign = 0;
+ UWORD32 u4_tot_zero = 0;
+ UWORD32 u4_trailing1 = 0;
+ WORD32 i4_val;
+ UWORD32 u4_totzero_sign_trailone;
+ UWORD32 *pu4_zero_run;
+
+ pu4_zero_run = (void *) pu1_zero_run;
+ pu4_zero_run[0] = 0;
+ pu4_zero_run[1] = 0;
+ pu4_zero_run[2] = 0;
+ pu4_zero_run[3] = 0;
+
+ /* Compute Runs of zeros for all nnz coefficients except the last 3 */
+ if(u4_total_coeff > 3)
+ {
+ for(i = 0; u4_nnz_coeff < (u4_total_coeff - 3); i++)
+ {
+ i4_run++;
+
+ i4_val = (u4_sig_coeff_map & 0x1);
+ u4_sig_coeff_map >>= 1;
+
+ if(i4_val != 0)
+ {
+ pu1_zero_run[u4_nnz_coeff++] = i4_run;
+ i4_run = -1;
+ }
+ }
+ }
+
+ /* Compute T1's, Signof(T1's) and Runs of zeros for the last 3 */
+ while(u4_nnz_coeff != u4_total_coeff)
+ {
+ i4_run++;
+
+ i4_val = (u4_sig_coeff_map & 0x1);
+ u4_sig_coeff_map >>= 1;
+
+ if(i4_val != 0)
+ {
+ if(pi2_res_block[u4_nnz_coeff] == 1)
+ {
+ pu1_zero_run[u4_nnz_coeff] = i4_run;
+ u4_trailing1++;
+ }
+ else
+ {
+ if(pi2_res_block[u4_nnz_coeff] == -1)
+ {
+ pu1_zero_run[u4_nnz_coeff] = i4_run;
+ u4_sign |= 1 << u4_trailing1;
+ u4_trailing1++;
+ }
+ else
+ {
+ pu1_zero_run[u4_nnz_coeff] = i4_run;
+ u4_trailing1 = 0;
+ u4_sign = 0;
+ }
+ }
+ i4_run = -1;
+ u4_nnz_coeff++;
+ }
+ i++;
+ }
+
+ u4_tot_zero = i - u4_total_coeff;
+ u4_totzero_sign_trailone = (u4_tot_zero << 16) | (u4_sign << 8) | u4_trailing1;
+
+ return (u4_totzero_sign_trailone);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for the given residual block
+*
+* @param[in] pi2_res_block
+* Pointer to residual block containing levels in scan order
+*
+* @param[in] u4_total_coeff
+* Total non-zero coefficients in the sub block
+*
+* @param[in] u4_block_type
+* block type
+*
+* @param[in] pu1_zero_run
+* Pointer to array to store run of zeros
+*
+* @param[in] u4_nc
+* average of non zero coeff from top and left blocks (when available)
+*
+* @param[in, out] ps_bit_stream
+* structure pointing to a buffer holding output bit stream
+*
+* @param[in] u4_sig_coeff_map
+* significant coefficient map of the residual block
+*
+* @returns
+* error code
+*
+* @remarks
+* If the block type is CAVLC_CHROMA_4x4_DC, then u4_nc is non-significant
+*
+*******************************************************************************
+*/
+static IH264E_ERROR_T isvce_write_coeff4x4_cavlc(WORD16 *pi2_res_block, UWORD32 u4_total_coeff,
+ ENTROPY_BLK_TYPE u4_block_type,
+ UWORD8 *pu1_zero_run, UWORD32 u4_nc,
+ bitstrm_t *ps_bit_stream, UWORD32 u4_sig_coeff_map)
+{
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+ UWORD32 u4_totzero_sign_trailone = 0;
+ UWORD32 u4_trailing_ones = 0;
+ UWORD32 u4_tot_zeros = 0;
+ UWORD32 u4_remaining_coeff = 0;
+ UWORD32 u4_sign1 = 0;
+ UWORD32 u4_max_num_coeff = 0;
+ const UWORD32 au4_max_num_nnz_coeff[] = {16, 15, 16, 4, 15};
+
+ /* validate inputs */
+ ASSERT(u4_block_type <= CAVLC_CHROMA_4x4_AC);
+
+ u4_max_num_coeff = au4_max_num_nnz_coeff[u4_block_type];
+
+ ASSERT(u4_total_coeff <= u4_max_num_coeff);
+
+ if(!u4_total_coeff)
+ {
+ UWORD32 u4_codeword = 15;
+ UWORD32 u4_codesize = 1;
+ if(u4_block_type == CAVLC_CHROMA_4x4_DC)
+ {
+ u4_codeword = 1;
+ u4_codesize = 2;
+ DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, 0);
+ ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
+ ENTROPY_TRACE("\tnumber of trailing ones ", 0);
+ }
+ else
+ {
+ UWORD32 u4_vlcnum = u4_nc >> 1;
+
+ /* write coeff_token */
+ if(u4_vlcnum > 3)
+ {
+ /* Num-FLC */
+ u4_codeword = 3;
+ u4_codesize = 6;
+ }
+ else
+ {
+ /* Num-VLC 0, 1, 2 */
+ if(u4_vlcnum > 1)
+ {
+ u4_vlcnum = 2;
+ }
+ u4_codesize <<= u4_vlcnum;
+ u4_codeword >>= (4 - u4_codesize);
+ }
+
+ DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff, 0, u4_nc);
+ ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
+ ENTROPY_TRACE("\tnC ", u4_nc);
+ }
+
+ DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
+ ENTROPY_TRACE("\tcodeword ", u4_codeword);
+ ENTROPY_TRACE("\tcodesize ", u4_codesize);
+
+ error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
+
+ return error_status;
+ }
+ else
+ {
+ /* Compute zero run, number of trailing ones and their sign. */
+ u4_totzero_sign_trailone = isvce_compute_zeroruns_and_trailingones(
+ pi2_res_block, u4_total_coeff, pu1_zero_run, u4_sig_coeff_map);
+ u4_trailing_ones = u4_totzero_sign_trailone & 0xFF;
+ u4_sign1 = (u4_totzero_sign_trailone >> 8) & 0xFF;
+ u4_tot_zeros = (u4_totzero_sign_trailone >> 16) & 0xFF;
+ u4_remaining_coeff = u4_total_coeff - u4_trailing_ones;
+
+ /* write coeff_token */
+ {
+ UWORD32 u4_codeword;
+ UWORD32 u4_codesize;
+ if(u4_block_type == CAVLC_CHROMA_4x4_DC)
+ {
+ u4_codeword =
+ gu1_code_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
+ u4_codesize =
+ gu1_size_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
+
+ DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, u4_trailing_ones);
+ ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
+ ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
+ }
+ else
+ {
+ UWORD32 u4_vlcnum = u4_nc >> 1;
+
+ if(u4_vlcnum > 3)
+ {
+ /* Num-FLC */
+ u4_codeword = ((u4_total_coeff - 1) << 2) + u4_trailing_ones;
+ u4_codesize = 6;
+ }
+ else
+ {
+ /* Num-VLC 0, 1, 2 */
+ if(u4_vlcnum > 1)
+ {
+ u4_vlcnum = 2;
+ }
+ u4_codeword =
+ gu1_code_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
+ u4_codesize =
+ gu1_size_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
+ }
+
+ DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff,
+ u4_trailing_ones, u4_nc);
+ ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
+ ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
+ ENTROPY_TRACE("\tnC ", u4_nc);
+ }
+
+ DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
+ ENTROPY_TRACE("\tcodeword ", u4_codeword);
+ ENTROPY_TRACE("\tcodesize ", u4_codesize);
+
+ error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
+ }
+
+ /* write sign of trailing ones */
+ if(u4_trailing_ones)
+ {
+ DEBUG("\nT1's: %d u4_codeword, %d u4_codesize", u4_sign1, u4_trailing_ones);
+ error_status = ih264e_put_bits(ps_bit_stream, u4_sign1, u4_trailing_ones);
+ ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
+ ENTROPY_TRACE("\tsign of trailing ones ", u4_sign1);
+ }
+
+ /* write level codes */
+ if(u4_remaining_coeff)
+ {
+ WORD32 i4_level = pi2_res_block[u4_remaining_coeff - 1];
+ UWORD32 u4_escape;
+ UWORD32 u4_suffix_length = 0; // Level-VLC[N]
+ UWORD32 u4_abs_level, u4_abs_level_actual = 0;
+ WORD32 i4_sign;
+ const UWORD32 u4_rndfactor[] = {0, 0, 1, 3, 7, 15, 31};
+
+ DEBUG("\n \t%d coeff,", i4_level);
+ ENTROPY_TRACE("\tcoeff ", i4_level);
+
+ if(u4_trailing_ones < 3)
+ {
+ /* If there are less than 3 T1s, then the first non-T1 level is
+ * incremented if negative (decremented if positive)*/
+ if(i4_level < 0)
+ {
+ i4_level += 1;
+ }
+ else
+ {
+ i4_level -= 1;
+ }
+
+ u4_abs_level_actual = 1;
+
+ /* Initialize VLC table (Suffix Length) to encode the level */
+ if(u4_total_coeff > 10)
+ {
+ u4_suffix_length = 1;
+ }
+ }
+
+ i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
+ u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
+
+ u4_abs_level_actual += u4_abs_level;
+
+ u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
+
+ while(1)
+ {
+ UWORD32 u4_codesize;
+ UWORD32 u4_codeword;
+ UWORD32 u4_codeval;
+
+ u4_remaining_coeff--;
+
+ GATHER_CAVLC_STATS1();
+
+ {
+ u4_codeval = u4_abs_level << 1;
+ u4_codeval = u4_codeval - 2 - i4_sign;
+
+ if((!u4_suffix_length) && (u4_escape > 7) && (u4_abs_level < 16))
+ {
+ u4_codeword = (1 << 4) + (u4_codeval - 14);
+ u4_codesize = 19;
+ }
+ else if(u4_escape > 7)
+ {
+ u4_codeword = (1 << 12) + (u4_codeval - (15 << u4_suffix_length));
+ u4_codesize = 28;
+ if(!u4_suffix_length)
+ {
+ u4_codeword -= 15;
+ }
+ }
+ else
+ {
+ u4_codeword =
+ (1 << u4_suffix_length) + (u4_codeval & ((1 << u4_suffix_length) - 1));
+ u4_codesize = (u4_codeval >> u4_suffix_length) + 1 + u4_suffix_length;
+ }
+ }
+
+ /*put the level code in bitstream*/
+ DEBUG("\nLEVEL: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
+ ENTROPY_TRACE("\tcodeword ", u4_codeword);
+ ENTROPY_TRACE("\tcodesize ", u4_codesize);
+ error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
+
+ if(u4_remaining_coeff == 0) break;
+
+ /*update suffix length for next level*/
+ if(u4_suffix_length == 0)
+ {
+ u4_suffix_length++;
+ }
+ if(u4_suffix_length < 6)
+ {
+ if(u4_abs_level_actual > gu1_threshold_vlc_level[u4_suffix_length])
+ {
+ u4_suffix_length++;
+ }
+ }
+
+ /* next level */
+ i4_level = pi2_res_block[u4_remaining_coeff - 1];
+
+ DEBUG("\n \t%d coeff,", i4_level);
+ ENTROPY_TRACE("\tcoeff ", i4_level);
+
+ i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
+ u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
+
+ u4_abs_level_actual = u4_abs_level;
+
+ u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
+ }
+ }
+
+ DEBUG("\n \t %d totalzeros", u4_tot_zeros);
+ ENTROPY_TRACE("\ttotal zeros ", u4_tot_zeros);
+
+ /* Write Total Zeros */
+ if(u4_total_coeff < u4_max_num_coeff)
+ {
+ WORD32 index;
+ UWORD32 u4_codeword;
+ UWORD32 u4_codesize;
+
+ if(u4_block_type == CAVLC_CHROMA_4x4_DC)
+ {
+ UWORD8 gu1_index_zero_table_chroma[] = {0, 4, 7};
+ index = gu1_index_zero_table_chroma[u4_total_coeff - 1] + u4_tot_zeros;
+ u4_codesize = gu1_size_zero_table_chroma[index];
+ u4_codeword = gu1_code_zero_table_chroma[index];
+ }
+ else
+ {
+ index = gu1_index_zero_table[u4_total_coeff - 1] + u4_tot_zeros;
+ u4_codesize = gu1_size_zero_table[index];
+ u4_codeword = gu1_code_zero_table[index];
+ }
+
+ DEBUG("\nTOTAL ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
+ ENTROPY_TRACE("\tcodeword ", u4_codeword);
+ ENTROPY_TRACE("\tcodesize ", u4_codesize);
+ error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
+ }
+
+ /* Write Run Before */
+ if(u4_tot_zeros)
+ {
+ UWORD32 u4_max_num_coef = u4_total_coeff - 1;
+ UWORD32 u4_codeword;
+ UWORD32 u4_codesize;
+ UWORD32 u4_zeros_left = u4_tot_zeros;
+
+ while(u4_max_num_coef)
+ {
+ UWORD32 u4_run_before = pu1_zero_run[u4_max_num_coef];
+ UWORD32 u4_index;
+
+ if(u4_zeros_left > MAX_ZERO_LEFT)
+ {
+ u4_index = gu1_index_run_table[MAX_ZERO_LEFT];
+ }
+ else
+ {
+ u4_index = gu1_index_run_table[u4_zeros_left - 1];
+ }
+
+ u4_codesize = gu1_size_run_table[u4_index + u4_run_before];
+ u4_codeword = gu1_code_run_table[u4_index + u4_run_before];
+
+ DEBUG("\nRUN BEFORE ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword,
+ u4_codesize);
+ ENTROPY_TRACE("\tcodeword ", u4_codeword);
+ ENTROPY_TRACE("\tcodesize ", u4_codesize);
+ error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
+
+ u4_zeros_left -= u4_run_before;
+ if(!u4_zeros_left)
+ {
+ break;
+ }
+ u4_max_num_coef--;
+ }
+ }
+ }
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for the given subblock
+*
+* @param[in] ps_ent_ctxt
+* Pointer to entropy context
+*
+* @param[in] pi2_res_block
+* Pointers to residual blocks of all the partitions for the current subblk
+* (containing levels in scan order)
+*
+* @param[in] pu1_nnz
+* Total non-zero coefficients of all the partitions for the current subblk
+*
+* @param[in] pu2_sig_coeff_map
+* Significant coefficient map of all the partitions for the current subblk
+*
+* @param[in] u4_block_type
+* entropy coding block type
+*
+* @param[in] u4_ngbr_avbl
+* top and left availability of all the partitions for the current subblk
+* (packed)
+*
+* @param[in] pu1_top_nnz
+* pointer to the buffer containing nnz of all the subblks to the top
+*
+* @param[in] pu1_left_nnz
+* pointer to the buffer containing nnz of all the subblks to the left
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IH264E_ERROR_T isvce_write_coeff8x8_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt,
+ WORD16 **pi2_res_block, UWORD8 *pu1_nnz,
+ UWORD16 *pu2_sig_coeff_map,
+ ENTROPY_BLK_TYPE u4_block_type,
+ UWORD32 u4_ngbr_avlb, UWORD8 *pu1_top_nnz,
+ UWORD8 *pu1_left_nnz)
+{
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run, *pu1_ngbr_avbl;
+ UWORD32 u4_nC;
+ UWORD8 u1_mb_a, u1_mb_b;
+
+ pu1_ngbr_avbl = (void *) (&u4_ngbr_avlb);
+
+ /* encode ac block index 4x4 = 0*/
+ u1_mb_a = pu1_ngbr_avbl[0] & 0x0F;
+ u1_mb_b = pu1_ngbr_avbl[0] & 0xF0;
+ u4_nC = 0;
+ if(u1_mb_a) u4_nC += pu1_left_nnz[0];
+ if(u1_mb_b) u4_nC += pu1_top_nnz[0];
+ if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
+ pu1_left_nnz[0] = pu1_top_nnz[0] = pu1_nnz[0];
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[0], pu1_nnz[0], u4_block_type, pu1_zero_run, u4_nC,
+ ps_bitstream, pu2_sig_coeff_map[0]);
+
+ /* encode ac block index 4x4 = 1*/
+ u1_mb_a = pu1_ngbr_avbl[1] & 0x0F;
+ u1_mb_b = pu1_ngbr_avbl[1] & 0xF0;
+ u4_nC = 0;
+ if(u1_mb_a) u4_nC += pu1_left_nnz[0];
+ if(u1_mb_b) u4_nC += pu1_top_nnz[1];
+ if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
+ pu1_left_nnz[0] = pu1_top_nnz[1] = pu1_nnz[1];
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[1], pu1_nnz[1], u4_block_type, pu1_zero_run, u4_nC,
+ ps_bitstream, pu2_sig_coeff_map[1]);
+
+ /* encode ac block index 4x4 = 2*/
+ u1_mb_a = pu1_ngbr_avbl[2] & 0x0F;
+ u1_mb_b = pu1_ngbr_avbl[2] & 0xF0;
+ u4_nC = 0;
+ if(u1_mb_a) u4_nC += pu1_left_nnz[1];
+ if(u1_mb_b) u4_nC += pu1_top_nnz[0];
+ if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
+ pu1_left_nnz[1] = pu1_top_nnz[0] = pu1_nnz[2];
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[2], pu1_nnz[2], u4_block_type, pu1_zero_run, u4_nC,
+ ps_bitstream, pu2_sig_coeff_map[2]);
+
+ /* encode ac block index 4x4 = 0*/
+ u1_mb_a = pu1_ngbr_avbl[3] & 0x0F;
+ u1_mb_b = pu1_ngbr_avbl[3] & 0xF0;
+ u4_nC = 0;
+ if(u1_mb_a) u4_nC += pu1_left_nnz[1];
+ if(u1_mb_b) u4_nC += pu1_top_nnz[1];
+ if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
+ pu1_left_nnz[1] = pu1_top_nnz[1] = pu1_nnz[3];
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[3], pu1_nnz[3], u4_block_type, pu1_zero_run, u4_nC,
+ ps_bitstream, pu2_sig_coeff_map[3]);
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function encodes luma and chroma residues of a macro block when
+* the entropy coding mode chosen is cavlc.
+*
+* @param[in] ps_ent_ctxt
+* Pointer to entropy context
+*
+* @param[in] u4_mb_type
+* current mb type
+*
+* @param[in] u4_cbp
+* coded block pattern for the current mb
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IH264E_ERROR_T isvce_encode_residue(isvce_entropy_ctxt_t *ps_ent_ctxt, UWORD32 u4_mb_type,
+ UWORD32 u4_cbp)
+{
+ /* error status */
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+
+ /* packed residue */
+ void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
+
+ /* bit stream buffer */
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+
+ /* zero run */
+ UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run;
+
+ /* temp var */
+ UWORD32 u4_nC, u4_ngbr_avlb;
+ UWORD8 au1_nnz[4], *pu1_ngbr_avlb, *pu1_top_nnz, *pu1_left_nnz;
+ UWORD16 au2_sig_coeff_map[4] = {0};
+ WORD16 *pi2_res_block[4] = {NULL};
+ UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
+ tu_sblk_coeff_data_t *ps_mb_coeff_data;
+ ENTROPY_BLK_TYPE e_entropy_blk_type = CAVLC_LUMA_4x4;
+
+ /* ngbr availability */
+ UWORD8 u1_mb_a, u1_mb_b;
+
+ /* cbp */
+ UWORD32 u4_cbp_luma = u4_cbp & 0xF, u4_cbp_chroma = u4_cbp >> 4;
+
+ /* mb indices */
+ WORD32 i4_mb_x, i4_mb_y;
+
+ /* derive neighbor availability */
+ i4_mb_x = ps_ent_ctxt->i4_mb_x;
+ i4_mb_y = ps_ent_ctxt->i4_mb_y;
+ pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
+ /* left macroblock availability */
+ u1_mb_a = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
+ /* top macroblock availability */
+ u1_mb_b = (i4_mb_y == 0 ||
+ (pu1_slice_idx[i4_mb_x - ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
+ ? 0
+ : 1;
+
+ pu1_ngbr_avlb = (void *) (&u4_ngbr_avlb);
+ pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
+ pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_luma;
+
+ /* encode luma residue */
+
+ /* mb type intra 16x16 */
+ if(u4_mb_type == I16x16)
+ {
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ /* estimate nnz for the current mb */
+ u4_nC = 0;
+ if(u1_mb_a) u4_nC += pu1_left_nnz[0];
+ if(u1_mb_b) u4_nC += pu1_top_nnz[0];
+ if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
+
+ /* encode dc block */
+ ENTROPY_TRACE("Luma DC blk idx %d", 0);
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_LUMA_4x4_DC,
+ pu1_zero_run, u4_nC, ps_bitstream, au2_sig_coeff_map[0]);
+
+ e_entropy_blk_type = CAVLC_LUMA_4x4_AC;
+ }
+
+ if(u4_cbp_luma & 1)
+ {
+ /* encode ac block index 8x8 = 0*/
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+ /* derive sub block neighbor availability */
+
+ pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
+ pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
+ pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
+ pu1_ngbr_avlb[3] = 0x11;
+ /* encode sub blk */
+ ENTROPY_TRACE("Luma blk idx %d", 0);
+ error_status =
+ isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz, au2_sig_coeff_map,
+ e_entropy_blk_type, u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
+ }
+ else
+ {
+ pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
+ pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
+ }
+
+ if(u4_cbp_luma & 2)
+ {
+ /* encode ac block index 8x8 = 1*/
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+
+ /* derive sub block neighbor availability */
+ pu1_ngbr_avlb[1] = pu1_ngbr_avlb[0] = (u1_mb_b << 4) | 1;
+ pu1_ngbr_avlb[3] = pu1_ngbr_avlb[2] = 0x11;
+ /* encode sub blk */
+ ENTROPY_TRACE("Luma blk idx %d", 1);
+ error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
+ au2_sig_coeff_map, e_entropy_blk_type,
+ u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz);
+ }
+ else
+ {
+ (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
+ pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
+ }
+
+ if(u4_cbp_luma & 0x4)
+ {
+ /* encode ac block index 8x8 = 2*/
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+
+ /* derive sub block neighbor availability */
+ pu1_ngbr_avlb[2] = pu1_ngbr_avlb[0] = (1 << 4) | u1_mb_a;
+ pu1_ngbr_avlb[1] = pu1_ngbr_avlb[3] = 0x11;
+ /* encode sub blk */
+ ENTROPY_TRACE("Luma blk idx %d", 2);
+ error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
+ au2_sig_coeff_map, e_entropy_blk_type,
+ u4_ngbr_avlb, pu1_top_nnz, (pu1_left_nnz + 2));
+ }
+ else
+ {
+ pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
+ (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
+ }
+
+ if(u4_cbp_luma & 0x8)
+ {
+ /* encode ac block index 8x8 = 3*/
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+
+ /* derive sub block neighbor availability */
+ u4_ngbr_avlb = 0x11111111;
+ /* encode sub blk */
+ ENTROPY_TRACE("Luma blk idx %d", 3);
+ error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
+ au2_sig_coeff_map, e_entropy_blk_type,
+ u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz + 2);
+ }
+ else
+ {
+ (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
+ (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
+ }
+
+ /* encode chroma residue */
+ if(u4_cbp_chroma & 3)
+ {
+ /* parse packed coeff data structure for residual data */
+ /* cb, cr */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+
+ /* encode dc block */
+ /* cb, cr */
+ ENTROPY_TRACE("Chroma DC blk idx %d", 0);
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_CHROMA_4x4_DC,
+ pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[0]);
+ ENTROPY_TRACE("Chroma DC blk idx %d", 1);
+ error_status =
+ isvce_write_coeff4x4_cavlc(pi2_res_block[1], au1_nnz[1], CAVLC_CHROMA_4x4_DC,
+ pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[1]);
+ }
+
+ pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
+ pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_cbcr;
+
+ /* encode sub blk */
+ if(u4_cbp_chroma & 0x2)
+ {
+ /* encode ac block index 8x8 = 0*/
+ /* derive sub block neighbor availability */
+ pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
+ pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
+ pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
+ pu1_ngbr_avlb[3] = 0x11;
+
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+
+ ENTROPY_TRACE("Chroma AC blk idx %d", 0);
+ error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
+ au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
+ u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
+ }
+ else
+ {
+ pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
+ pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
+ }
+
+ pu1_top_nnz += 2;
+ pu1_left_nnz += 2;
+
+ /* encode sub blk */
+ if(u4_cbp_chroma & 0x2)
+ {
+ /* parse packed coeff data structure for residual data */
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
+ au2_sig_coeff_map[0], pi2_res_block[0]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
+ au2_sig_coeff_map[1], pi2_res_block[1]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
+ au2_sig_coeff_map[2], pi2_res_block[2]);
+ PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
+ au2_sig_coeff_map[3], pi2_res_block[3]);
+
+ ENTROPY_TRACE("Chroma AC blk idx %d", 1);
+ error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
+ au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
+ u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
+ }
+ else
+ {
+ pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
+ pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
+ }
+
+ /* store the index of the next mb coeff data */
+ ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for an Intra Slice.
+*
+* @description
+* The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification.
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ /* error status */
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+
+ /* bit stream ptr */
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+
+ /* packed header data */
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* mb header info */
+ /*
+ * mb_tpm : mb type plus mode
+ * mb_type : luma mb type and chroma mb type are packed
+ * cbp : coded block pattern
+ * mb_qp_delta : mb qp delta
+ * chroma_intra_mode : chroma intra mode
+ * luma_intra_mode : luma intra mode
+ */
+ WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
+ WORD8 mb_qp_delta;
+
+ /* temp var */
+ WORD32 i, mb_type_stream;
+
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ /********************************************************************/
+ /* BEGIN HEADER GENERATION */
+ /********************************************************************/
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ /* write base_mode_flag */
+ PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
+ }
+ else
+ {
+ ps_mb_hdr->u1_base_mode_flag = 0;
+ }
+
+ /* mb header info */
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+ cbp = ps_mb_hdr->u1_cbp;
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ /* mb type */
+ mb_type = mb_tpm & 0xF;
+ /* is intra ? */
+ if(!ps_mb_hdr->u1_base_mode_flag)
+ {
+ if(mb_type == I16x16)
+ {
+ UWORD32 u4_cbp_l, u4_cbp_c;
+
+ u4_cbp_c = (cbp >> 4);
+ u4_cbp_l = (cbp & 0xF);
+ luma_intra_mode = (mb_tpm >> 4) & 3;
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
+
+ for(i = 0; i < 16; i += 2)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == I8x8)
+ {
+ /* transform 8x8 flag */
+ UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
+ isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
+ (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ ASSERT(0);
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
+
+ /* u4_transform_size_8x8_flag */
+ PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
+ "u4_transform_size_8x8_flag");
+
+ /* write sub block modes */
+ for(i = 0; i < 4; i++)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+
+ pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
+ }
+ }
+ else
+ {
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ /* coded_block_pattern */
+ if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
+ {
+ PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][ps_mb_hdr->u1_base_mode_flag],
+ error_status, "coded_block_pattern");
+
+ if(cbp % 16 > 0 && ps_ent_ctxt->i1_transform_8x8_mode_flag &&
+ (ps_mb_hdr->u1_base_mode_flag || (mb_type == I8x8 || mb_type == I4x4)))
+ {
+ PUT_BITS(ps_bitstream, ps_ent_ctxt->i1_transform_8x8_mode_flag, 1, error_status,
+ "u4_transform_size_8x8_flag");
+ }
+ }
+
+ if((cbp > 0) || (mb_type == I16x16))
+ {
+ /* mb_qp_delta */
+ PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+ }
+
+ /* Ending bitstream offset for header in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
+
+ /* Starting bitstream offset for residue */
+ bitstream_start_offset = bitstream_end_offset;
+
+ /* residual */
+ error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
+
+ /* Ending bitstream offset for reside in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+ ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
+
+ /* store the index of the next mb syntax layer */
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for Inter slices
+*
+* @description
+* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ /* mb header info */
+ /*
+ * mb_tpm : mb type plus mode
+ * mb_type : luma mb type and chroma mb type are packed
+ * cbp : coded block pattern
+ * mb_qp_delta : mb qp delta
+ * chroma_intra_mode : chroma intra mode
+ * luma_intra_mode : luma intra mode
+ * ps_pu : Pointer to the array of structures having motion vectors, size
+ * and position of sub partitions
+ */
+ WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
+ WORD8 mb_qp_delta;
+ WORD32 i, mb_type_stream;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+ UWORD8 u1_is_intra_mb;
+
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+ WORD32 cbptable = 1;
+ WORD32 is_inter = 0;
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ /********************************************************************/
+ /* BEGIN HEADER GENERATION */
+ /********************************************************************/
+
+ /* mb header info */
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+
+ /* mb type */
+ mb_type = mb_tpm & 0xF;
+ u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
+
+ /* check for skip */
+ if(mb_type == PSKIP)
+ {
+ UWORD32 *nnz;
+
+ is_inter = 1;
+
+ /* increment skip counter */
+ (*ps_ent_ctxt->pi4_mb_skip_run)++;
+
+ /* store the index of the next mb syntax layer */
+ pu1_byte += sizeof(isvce_mb_hdr_pskip_t);
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ /* set nnz to zero */
+ ps_ent_ctxt->u4_left_nnz_luma = 0;
+ nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
+ *nnz = 0;
+ ps_ent_ctxt->u4_left_nnz_cbcr = 0;
+ nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
+ *nnz = 0;
+
+ /* residual */
+ error_status = isvce_encode_residue(ps_ent_ctxt, P16x16, 0);
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ return error_status;
+ }
+
+ /* remaining mb header info */
+ cbp = ps_mb_hdr->u1_cbp;
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ /* mb skip run */
+ PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
+
+ /* reset skip counter */
+ *ps_ent_ctxt->pi4_mb_skip_run = 0;
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ /* write base_mode_flag */
+ PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
+ }
+ else
+ {
+ ps_mb_hdr->u1_base_mode_flag = 0;
+ }
+
+ if(!ps_mb_hdr->u1_base_mode_flag)
+ {
+ /* is intra ? */
+ if(mb_type == I16x16)
+ {
+ UWORD32 u4_cbp_l, u4_cbp_c;
+
+ is_inter = 0;
+
+ u4_cbp_c = (cbp >> 4);
+ u4_cbp_l = (cbp & 0xF);
+ luma_intra_mode = (mb_tpm >> 4) & 3;
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
+
+ mb_type_stream += 5;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ is_inter = 0;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+ cbptable = 0;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
+
+ for(i = 0; i < 16; i += 2)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == I8x8)
+ {
+ isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
+ (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* transform 8x8 flag */
+ UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ is_inter = 0;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+ cbptable = 0;
+
+ ASSERT(0);
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
+
+ /* u4_transform_size_8x8_flag */
+ PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
+ "u4_transform_size_8x8_flag");
+
+ /* write sub block modes */
+ for(i = 0; i < 4; i++)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+
+ pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
+ }
+ else
+ {
+ isvce_mb_hdr_p16x16_t *ps_mb_hdr_p16x16 =
+ (isvce_mb_hdr_p16x16_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* inter macro block partition cnt */
+ const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
+
+ /* mv ptr */
+ WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_p16x16->ai2_mvd;
+
+ /* number of partitions for the current mb */
+ UWORD32 u4_part_cnt = au1_part_cnt[mb_type - 3];
+
+ is_inter = 1;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, mb_type - 3, error_status, "mb type");
+
+ for(i = 0; i < (WORD32) u4_part_cnt; i++)
+ {
+ if(ps_ent_ctxt->u1_spatial_layer_id &&
+ ps_svc_slice_header->i1_adaptive_motion_prediction_flag)
+ {
+ PUT_BITS(ps_bitstream, ps_mb_hdr_p16x16->u1_mvp_idx, 1, error_status,
+ "motion_prediction_flag_l0");
+ }
+ }
+
+ for(i = 0; i < (WORD32) u4_part_cnt; i++)
+ {
+ PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i], error_status, "mv x");
+ PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i + 1], error_status, "mv y");
+ }
+
+ pu1_byte += sizeof(isvce_mb_hdr_p16x16_t);
+ }
+ }
+ else
+ {
+ pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
+ }
+
+ if(ps_ent_ctxt->u1_spatial_layer_id &&
+ ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
+ !ps_ent_ctxt
+ ->ps_svc_nalu_ext_base[1 + (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT)]
+ .u1_idr_flag &&
+ (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
+ {
+ PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
+ "residual_prediction_flag");
+ }
+
+ /* coded_block_pattern */
+ if(ps_mb_hdr->u1_base_mode_flag || (mb_type != I16x16))
+ {
+ PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
+ "coded_block_pattern");
+ }
+
+ if((cbp > 0) || (mb_type == I16x16))
+ {
+ /* mb_qp_delta */
+ PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+ }
+
+ /* Ending bitstream offset for header in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ /* start bitstream offset for residue in bits */
+ bitstream_start_offset = bitstream_end_offset;
+
+ /* residual */
+ error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
+
+ /* Ending bitstream offset for residue in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ /* store the index of the next mb syntax layer */
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for B slices
+*
+* @description
+* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
+{
+ /* mb header info */
+ /*
+ * mb_tpm : mb type plus mode
+ * mb_type : luma mb type and chroma mb type are packed
+ * cbp : coded block pattern
+ * mb_qp_delta : mb qp delta
+ * chroma_intra_mode : chroma intra mode
+ * luma_intra_mode : luma intra mode
+ * ps_pu : Pointer to the array of structures having motion vectors, size
+ * and position of sub partitions
+ */
+ WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
+ WORD8 mb_qp_delta;
+ WORD32 i, j;
+ WORD32 mb_type_stream;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+ UWORD8 u1_is_intra_mb;
+
+ bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
+ isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
+ svc_slice_header_t *ps_svc_slice_header =
+ ps_ent_ctxt->ps_svc_slice_hdr_base +
+ (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+
+ UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
+ WORD32 cbptable = 1;
+ WORD32 is_inter = 0;
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
+
+ /********************************************************************/
+ /* BEGIN HEADER GENERATION */
+ /********************************************************************/
+
+ mb_tpm = ps_mb_hdr->u1_mb_type_mode;
+
+ /* mb type */
+ mb_type = mb_tpm & 0xF;
+ u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
+
+ /* check for skip */
+ if(mb_type == BSKIP)
+ {
+ UWORD32 *nnz;
+
+ is_inter = 1;
+
+ /* increment skip counter */
+ (*ps_ent_ctxt->pi4_mb_skip_run)++;
+
+ /* store the index of the next mb syntax layer */
+ pu1_byte += sizeof(isvce_mb_hdr_bskip_t);
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ /* set nnz to zero */
+ ps_ent_ctxt->u4_left_nnz_luma = 0;
+ nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
+ *nnz = 0;
+ ps_ent_ctxt->u4_left_nnz_cbcr = 0;
+ nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
+ *nnz = 0;
+
+ /* residual */
+ error_status = isvce_encode_residue(ps_ent_ctxt, B16x16, 0);
+
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ return error_status;
+ }
+
+ /* remaining mb header info */
+ cbp = ps_mb_hdr->u1_cbp;
+ mb_qp_delta =
+ ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
+
+ /* mb skip run */
+ PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
+
+ /* reset skip counter */
+ *ps_ent_ctxt->pi4_mb_skip_run = 0;
+
+ if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
+ {
+ /* write base_mode_flag */
+ PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
+ }
+ else
+ {
+ ps_mb_hdr->u1_base_mode_flag = 0;
+ }
+
+ if(!ps_mb_hdr->u1_base_mode_flag)
+ {
+ /* is intra ? */
+ if(mb_type == I16x16)
+ {
+ UWORD32 u4_cbp_l, u4_cbp_c;
+
+ is_inter = 0;
+
+ u4_cbp_c = (cbp >> 4);
+ u4_cbp_l = (cbp & 0xF);
+ luma_intra_mode = (mb_tpm >> 4) & 3;
+ chroma_intra_mode = (mb_tpm >> 6);
+
+ mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
+
+ mb_type_stream += 23;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+ pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
+ }
+ else if(mb_type == I4x4)
+ {
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
+ (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ is_inter = 0;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+ cbptable = 0;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
+
+ for(i = 0; i < 16; i += 2)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+ pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
+ }
+ else if(mb_type == I8x8)
+ {
+ isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
+ (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* transform 8x8 flag */
+ UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
+
+ /* mb sub blk modes */
+ WORD32 intra_pred_mode_flag, rem_intra_mode;
+ WORD32 byte;
+
+ is_inter = 0;
+
+ chroma_intra_mode = (mb_tpm >> 6);
+ cbptable = 0;
+
+ ASSERT(0);
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
+
+ /* u4_transform_size_8x8_flag */
+ PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
+ "u4_transform_size_8x8_flag");
+
+ /* write sub block modes */
+ for(i = 0; i < 4; i++)
+ {
+ /* sub blk idx 1 */
+ byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+
+ /* sub blk idx 2 */
+ byte >>= 4;
+
+ intra_pred_mode_flag = byte & 0x1;
+
+ /* prev_intra4x4_pred_mode_flag */
+ PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
+ "prev_intra4x4_pred_mode_flag");
+
+ /* rem_intra4x4_pred_mode */
+ if(!intra_pred_mode_flag)
+ {
+ rem_intra_mode = (byte & 0xF) >> 1;
+ PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
+ "rem_intra4x4_pred_mode");
+ }
+ }
+
+ /* intra_chroma_pred_mode */
+ PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
+ pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
+ }
+ else if(mb_type == BDIRECT)
+ {
+ is_inter = 1;
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, B_DIRECT_16x16, error_status, "mb type");
+ pu1_byte += sizeof(isvce_mb_hdr_bdirect_t);
+ }
+ else
+ {
+ isvce_mb_hdr_b16x16_t *ps_mb_hdr_b16x16 =
+ (isvce_mb_hdr_b16x16_t *) ps_ent_ctxt->pv_mb_header_data;
+
+ /* inter macro block partition cnt for 16x16 16x8 8x16 8x8 */
+ const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
+
+ /* number of partitions for the current mb */
+ UWORD32 u4_part_cnt = au1_part_cnt[mb_type - B16x16];
+
+ /* Get the pred modes */
+ WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
+
+ ASSERT(mb_type == B16x16);
+
+ is_inter = 1;
+
+ mb_type_stream = mb_type - B16x16 + B_L0_16x16 + i4_mb_part_pred_mode;
+
+ /* write mb type */
+ PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
+
+ for(i = 0; i < (WORD32) u4_part_cnt; i++)
+ {
+ for(j = 0; j < NUM_PRED_DIRS; j++)
+ {
+ PRED_MODE_T e_pred_mode = (PRED_MODE_T) j;
+ PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
+
+ if(((PRED_MODE_T) i4_mb_part_pred_mode) != e_pred_mode)
+ {
+ if(ps_svc_slice_header->i1_adaptive_motion_prediction_flag &&
+ ps_ent_ctxt->u1_spatial_layer_id)
+ {
+ PUT_BITS(ps_bitstream, ps_mb_hdr_b16x16->au1_mvp_idx[e_cmpl_pred_mode],
+ 1, error_status, "motion_prediction_flag_l0");
+ }
+ }
+ }
+ }
+
+ for(i = 0; i < (WORD32) u4_part_cnt; i++)
+ {
+ if(i4_mb_part_pred_mode != L1)
+ {
+ PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][0], error_status,
+ "mv l0 x");
+ PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][1], error_status,
+ "mv l0 y");
+ }
+ if(i4_mb_part_pred_mode != L0)
+ {
+ PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][0], error_status,
+ "mv l1 x");
+ PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][1], error_status,
+ "mv l1 y");
+ }
+ }
+
+ pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
+ }
+ }
+
+ if(ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
+ ps_ent_ctxt->u1_spatial_layer_id && (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
+ {
+ PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
+ "residual_prediction_flag");
+ }
+
+ /* coded_block_pattern */
+ if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
+ {
+ PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
+ "coded_block_pattern");
+ }
+
+ if((cbp > 0) || (mb_type == I16x16))
+ {
+ /* mb_qp_delta */
+ PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
+ ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
+ }
+
+ /* Ending bitstream offset for header in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ /* start bitstream offset for residue in bits */
+ bitstream_start_offset = bitstream_end_offset;
+
+ /* residual */
+ error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
+
+ /* Ending bitstream offset for residue in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
+
+ ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
+
+ /* store the index of the next mb syntax layer */
+ ps_ent_ctxt->pv_mb_header_data = pu1_byte;
+
+ return error_status;
+}
+
+#if ENABLE_RE_ENC_AS_SKIP
+/**
+******************************************************************************
+*
+* @brief re-encode frame as all skip MBs
+*
+* @par Description
+* The frame is encoded as all skip MBs to comply with VBV restrictions
+*
+* @param[in] ps_entropy
+* pointer to entropy context (handle)
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t *ps_entropy)
+{
+ WORD32 i4_mb_skip_run;
+
+ bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
+ bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
+
+ ps_bitstrm->i4_bits_left_in_cw = ps_bitstrm_after_slice_hdr->i4_bits_left_in_cw;
+ ps_bitstrm->u4_cur_word = ps_bitstrm_after_slice_hdr->u4_cur_word;
+ ps_bitstrm->u4_strm_buf_offset = ps_bitstrm_after_slice_hdr->u4_strm_buf_offset;
+ ps_bitstrm->i4_zero_bytes_run = ps_bitstrm_after_slice_hdr->i4_zero_bytes_run;
+
+ /* mb skip run */
+ i4_mb_skip_run = ps_entropy->i4_wd_mbs * ps_entropy->i4_ht_mbs;
+ PUT_BITS_UEV(ps_bitstrm, i4_mb_skip_run, ps_entropy->i4_error_code, "mb skip run");
+
+ /* put rbsp trailing bits */
+ ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return ps_entropy->i4_error_code;
+}
+#endif
diff --git a/encoder/svc/isvce_cavlc.h b/encoder/svc/isvce_cavlc.h
new file mode 100644
index 0000000..4a1952c
--- /dev/null
+++ b/encoder/svc/isvce_cavlc.h
@@ -0,0 +1,126 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_cavlc.h
+*
+* @brief
+* This file contains enumerations, macros and extern declarations of H264
+* cavlc tables
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+******************************************************************************
+*/
+
+#ifndef _ISVCE_CAVLC_H_
+#define _ISVCE_CAVLC_H_
+
+#include "ih264_typedefs.h"
+#include "isvce_defs.h"
+#include "isvce_structs.h"
+
+/*****************************************************************************/
+/* Function macro definitions */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for an Intra Slice.
+*
+* @description
+* The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification.
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for Inter slices
+*
+* @description
+* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function generates CAVLC coded bit stream for Inter(B) slices
+*
+* @description
+* The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
+* (if present), mb qp delta, coded block pattern, chroma mb mode and
+* luma/chroma residue. These syntax elements are written as directed by table
+* 7.3.5 of h264 specification
+*
+* @param[in] ps_ent_ctxt
+* pointer to entropy context
+*
+* @returns error code
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+#if ENABLE_RE_ENC_AS_SKIP
+IH264E_ERROR_T isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t *ps_entropy);
+#endif
+
+#endif
diff --git a/encoder/svc/isvce_core_coding.c b/encoder/svc/isvce_core_coding.c
new file mode 100644
index 0000000..ecb453f
--- /dev/null
+++ b/encoder/svc/isvce_core_coding.c
@@ -0,0 +1,2367 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_core_coding.c
+ *
+ * @brief
+ * This file contains routines that perform luma and chroma core coding for
+ * intra macroblocks
+ *
+ * @author
+ * ittiam
+ *
+ * @par List of Functions:
+ * - isvce_pack_l_mb_i16()
+ * - isvce_pack_c_mb_i8()
+ * - isvce_code_luma_intra_macroblock_16x16()
+ * - isvce_code_luma_intra_macroblock_4x4()
+ * - isvce_code_chroma_intra_macroblock_8x8()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "ih264_platform_macros.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_macros.h"
+#include "isvc_defs.h"
+#include "ih264e_config.h"
+#include "isvce_defs.h"
+#include "ih264_trans_data.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_globals.h"
+#include "isvce_core_coding.h"
+#include "isvce_mc.h"
+#include "isvce_ibl_eval.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function performs does the DCT transform then Hadamard transform
+* and quantization for a macroblock when the mb mode is intra 16x16 mode
+*
+* @par Description:
+* First cf4 is done on all 16 4x4 blocks of the 16x16 input block.
+* Then hadamard transform is done on the DC coefficients
+* Quantization is then performed on the 16x16 block, 4x4 wise
+*
+* @param[in] pu1_src
+* Pointer to source sub-block
+*
+* @param[in] pu1_pred
+* Pointer to prediction sub-block
+*
+* @param[in] pi2_out
+* Pointer to residual sub-block
+* The output will be in linear format
+* The first 16 continuous locations will contain the values of Dc block
+* After DC block and a stride 1st AC block will follow
+* After one more stride next AC block will follow
+* The blocks will be in raster scan order
+*
+* @param[in] i4_src_stride
+* Source stride
+*
+* @param[in] i4_pred_stride
+* Prediction stride
+*
+* @param[in] dst_strd
+* Destination stride
+*
+* @param[in] pu2_scale_matrix
+* The quantization matrix for 4x4 transform
+*
+* @param[in] pu2_threshold_matrix
+* Threshold matrix
+*
+* @param[in] u4_qbits
+* 15+QP/6
+*
+* @param[in] u4_round_factor
+* Round factor for quant
+*
+* @param[out] pu1_nnz
+* Memory to store the non-zeros after transform
+* The first byte will be the nnz of DC block
+* From the next byte the AC nnzs will be stored in raster scan order
+*
+* @param u4_dc_flag
+* Signals if Dc transform is to be done or not
+* 1 -> Dc transform will be done
+* 0 -> Dc transform will not be done
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_luma_16x16_resi_trans_dctrans_quant(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_quant_coeffs,
+ buffer_container_t *ps_upsampled_res, isa_dependent_fxns_t *ps_isa_dependent_fxns,
+ const UWORD16 *pu2_scale_matrix, const UWORD16 *pu2_threshold_matrix, UWORD8 *pu1_nnz,
+ UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD32 u4_dc_flag, UWORD8 u1_use_upsampled_res)
+{
+ WORD32 blk_cntr;
+ WORD32 i4_offsetx, i4_offsety;
+
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ buffer_container_t s_src = ps_src[0];
+ buffer_container_t s_pred = ps_pred[0];
+ buffer_container_t s_quant_coeffs = ps_quant_coeffs[0];
+ buffer_container_t s_upsampled_res = {0};
+ resi_trans_quant_constants_t s_resi_trans_quant_constants = {
+ .pu2_scale_matrix = pu2_scale_matrix,
+ .pu2_threshold_matrix = pu2_threshold_matrix,
+ .u4_qbits = u4_qbits,
+ .u4_round_factor = u4_round_factor};
+
+ UWORD8 u1_resi_trans_fxn_idx = isvc_get_resi_trans_quant_variant_idx(u1_use_upsampled_res);
+
+ /* Move to the ac addresses */
+ pu1_nnz++;
+ s_quant_coeffs.pv_data = ((WORD16 *) s_quant_coeffs.pv_data) + s_quant_coeffs.i4_data_stride;
+
+ if(u1_use_upsampled_res)
+ {
+ s_upsampled_res = ps_upsampled_res[0];
+ }
+
+ for(blk_cntr = 0; blk_cntr < NUM_LUMA4x4_BLOCKS_IN_MB; blk_cntr++)
+ {
+ IND2SUB_LUMA_MB(blk_cntr, i4_offsetx, i4_offsety);
+
+ s_src.pv_data =
+ ((UWORD8 *) ps_src[0].pv_data) + i4_offsetx + i4_offsety * ps_src[0].i4_data_stride;
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred[0].pv_data) + i4_offsetx + i4_offsety * ps_pred[0].i4_data_stride;
+ s_quant_coeffs.pv_data =
+ ((WORD16 *) ps_quant_coeffs[0].pv_data) + blk_cntr * ps_quant_coeffs[0].i4_data_stride;
+
+ if(u1_use_upsampled_res)
+ {
+ s_upsampled_res.pv_data = ((WORD16 *) ps_upsampled_res[0].pv_data) + i4_offsetx +
+ i4_offsety * ps_upsampled_res[0].i4_data_stride;
+ }
+
+ /* Move to the ac addresses */
+ s_quant_coeffs.pv_data =
+ ((WORD16 *) s_quant_coeffs.pv_data) + ps_quant_coeffs[0].i4_data_stride;
+
+ s_quant_coeffs.i4_data_stride = 4;
+
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[u1_resi_trans_fxn_idx](
+ &s_src, &s_pred, &s_quant_coeffs, &s_upsampled_res, &s_resi_trans_quant_constants,
+ &pu1_nnz[blk_cntr], ((WORD16 *) ps_quant_coeffs->pv_data) + blk_cntr,
+ u1_use_upsampled_res);
+ }
+
+ if(!u4_dc_flag)
+ {
+ return;
+ }
+
+ /*
+ * In case of i16x16, we need to remove the contribution of dc coeffs into
+ * nnz of each block. We are doing that in the packing function
+ */
+
+ /* Adjust pointers to point to dc values */
+ s_quant_coeffs = ps_quant_coeffs[0];
+ pu1_nnz--;
+
+ u4_qbits++;
+ u4_round_factor <<= 1;
+
+ ps_enc_loop_fxns->pf_hadamard_quant_4x4(((WORD16 *) s_quant_coeffs.pv_data),
+ ((WORD16 *) s_quant_coeffs.pv_data),
+ &s_resi_trans_quant_constants, &pu1_nnz[0]);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function performs the intra 16x16 inverse transform process for H264
+* it includes inverse Dc transform, inverse quant and then inverse transform
+*
+* @par Description:
+*
+* @param[in] pi2_src
+* Input data, 16x16 size
+* First 16 mem locations will have the Dc coffs in rater scan order in linear
+*fashion after a stride 1st AC clock will be present again in raster can order
+* Then each AC block of the 16x16 block will follow in raster scan order
+*
+* @param[in] pu1_pred
+* The predicted data, 16x16 size
+* Block by block form
+*
+* @param[in] pu1_out
+* Output 16x16
+* In block by block form
+*
+* @param[in] i4_src_stride
+* Source stride
+*
+* @param[in] i4_pred_stride
+* input stride for prediction buffer
+*
+* @param[in] i4_out_stride
+* input stride for output buffer
+*
+* @param[in] pu2_iscale_mat
+* Inverse quantization matrix for 4x4 transform
+*
+* @param[in] pu2_weigh_mat
+* weight matrix of 4x4 transform
+*
+* @param[in] u4_qp_div_6
+* QP/6
+*
+* @param[in] pi4_tmp
+* Input temporary buffer
+* needs to be at least 20 in size
+*
+* @param[in] pu4_cntrl
+* Controls the transform path
+* total Last 17 bits are used
+* the 16th th bit will correspond to DC block
+* and 32-17 will correspond to the ac blocks in raster scan order
+* bit equaling zero indicates that the entire 4x4 block is zero for DC
+* For AC blocks a bit equaling zero will mean that all 15 AC coffs of the block
+*is nonzero
+*
+* @param[in] pi4_tmp
+* Input temporary buffer
+* needs to be at least COFF_CNT_SUB_BLK_4x4+COFF_CNT_SUB_BLK_4x4 size
+*
+* @returns
+* none
+*
+* @remarks
+* The all zero case must be taken care outside
+*
+*******************************************************************************
+*/
+void isvce_luma_16x16_idctrans_iquant_itrans_recon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_recon,
+ buffer_container_t *ps_res, buffer_container_t *ps_res_pred,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ isa_dependent_fxns_t *ps_isa_dependent_fxns, WORD32 *pi4_tmp, UWORD32 u4_cntrl,
+ UWORD32 u4_dc_trans_flag, UWORD8 u1_res_accumulate)
+{
+ /* Cntrl bits for 4x4 transforms
+ * u4_blk_cntrl : controls if a 4x4 block should be processed in ac path
+ * u4_dc_cntrl : controls is a 4x4 block is to be processed in dc path
+ * : dc block must contain only single dc coefficient
+ * u4_empty_blk_cntrl : control fot 4x4 block with no coeffs, ie no dc and ac
+ * : ie not (ac or dc)
+ */
+ UWORD32 u4_blk_cntrl, u4_dc_cntrl, u4_empty_blk_cntrl;
+ UWORD32 u4_blk_id;
+ WORD32 i4_offset_x, i4_offset_y;
+ UWORD32 u4_dc_inc;
+ WORD16 *pi2_dc_src;
+
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ buffer_container_t s_src = ps_src[0];
+ buffer_container_t s_pred = ps_pred[0];
+ buffer_container_t s_recon = ps_recon[0];
+ buffer_container_t s_res = ps_res[0];
+ buffer_container_t s_res_pred = ps_res_pred[0];
+
+ /* Start index for inverse quant in a 4x4 block */
+ WORD32 i4_iq_start_idx = (u4_dc_trans_flag == 0) ? 0 : 1;
+ const UWORD16 *pu2_iscale_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD8 u1_iq_it_recon_fxn_idx =
+ isvc_get_iq_it_recon_variant_idx(!!u4_dc_trans_flag, u1_res_accumulate);
+
+ /*
+ * For intra blocks we need to do inverse dc transform
+ * In case if intra blocks, its here that we populate the dc bits in cntrl
+ * as they cannot be populated any earlier
+ */
+ if(u4_dc_trans_flag)
+ {
+ UWORD32 cntr, u4_dc_cntrl;
+
+ /* Do inv hadamard and place the results at the start of each AC block */
+ ps_enc_loop_fxns->pf_ihadamard_scaling_4x4(ps_src->pv_data, ps_src->pv_data, pu2_iscale_mat,
+ pu2_weigh_mat, u4_qp_div_6, pi4_tmp);
+
+ /* Update the cntrl flag */
+ u4_dc_cntrl = 0;
+
+ for(cntr = 0; cntr < DC_COEFF_CNT_LUMA_MB; cntr++)
+ {
+ u4_dc_cntrl |= ((((WORD16 *) ps_src->pv_data)[cntr] != 0) << (15 - cntr));
+ }
+
+ /* Mark dc bits as 1 if corresponding ac bit is 0 */
+ u4_dc_cntrl = (~(u4_cntrl >> 16) & u4_dc_cntrl);
+
+ /* Combine both ac and dc bits */
+ u4_cntrl = (u4_cntrl & CNTRL_FLAG_AC_MASK_LUMA) | (u4_dc_cntrl & CNTRL_FLAG_DC_MASK_LUMA);
+ }
+
+ /* Source for dc coeffs
+ * If the block is intra, we have to read dc values from first row of src
+ * then stride for each block is 1, other wise its src stride
+ */
+ pi2_dc_src = ((WORD16 *) ps_src->pv_data) + (i4_iq_start_idx == 0) * ps_src->i4_data_stride;
+ u4_dc_inc = (i4_iq_start_idx == 0) ? ps_src->i4_data_stride : 1;
+
+ /* Get the block bits */
+ u4_blk_cntrl = (u4_cntrl & CNTRL_FLAG_AC_MASK_LUMA);
+ u4_dc_cntrl = (u4_cntrl & CNTRL_FLAG_DC_MASK_LUMA) << 16;
+ u4_empty_blk_cntrl = (~(u4_dc_cntrl | u4_blk_cntrl)) & 0xFFFF0000;
+
+ /* Get first block to process */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_dc_cntrl, u4_blk_id);
+
+ while(u4_blk_id < NUM_LUMA4x4_BLOCKS_IN_MB)
+ {
+ /* Compute address of src blocks */
+ WORD32 i4_src_offset = u4_dc_inc * u4_blk_id;
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ s_src.pv_data = pi2_dc_src + i4_src_offset;
+
+ IND2SUB_LUMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ /* Compute address of out and pred blocks */
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[u1_iq_it_recon_fxn_idx](
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants, NULL,
+ pi2_dc_src + i4_src_offset, i4_iq_start_idx, u1_res_accumulate);
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_dc_cntrl, u4_blk_id);
+ }
+
+ /* now process ac/mixed blocks */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_blk_cntrl, u4_blk_id);
+ while(u4_blk_id < NUM_LUMA4x4_BLOCKS_IN_MB)
+ {
+ IND2SUB_LUMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ /* The AC blocks starts from 2nd row */
+ s_src.pv_data = ((WORD16 *) ps_src->pv_data) + (u4_blk_id + 1) * ps_src->i4_data_stride;
+
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[u1_iq_it_recon_fxn_idx](
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants,
+ (WORD16 *) pi4_tmp, pi2_dc_src + u4_blk_id, i4_iq_start_idx, u1_res_accumulate);
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_blk_cntrl, u4_blk_id);
+ }
+
+ /* Now process empty blocks */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_empty_blk_cntrl, u4_blk_id);
+ while(u4_blk_id < NUM_LUMA4x4_BLOCKS_IN_MB)
+ {
+ IND2SUB_LUMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ /* The AC blocks starts from 2nd row */
+ s_src.pv_data = ((WORD16 *) ps_src->pv_data) + (u4_blk_id + 1) * ps_src->i4_data_stride;
+
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->pf_zcbf_iquant_itrans_recon_4x4(
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants, NULL,
+ pi2_dc_src + u4_blk_id, i4_iq_start_idx, u1_res_accumulate);
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_empty_blk_cntrl, u4_blk_id);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function performs does the DCT transform then Hadamard transform
+* and quantization for a chroma macroblock
+*
+* @par Description:
+* First cf4 is done on all 16 4x4 blocks of the 8x8input block
+* Then hadamard transform is done on the DC coefficients
+* Quantization is then performed on the 8x8 block, 4x4 wise
+*
+* @param[in] pu1_src
+* Pointer to source sub-block
+* The input is in interleaved format for two chroma planes
+*
+* @param[in] pu1_pred
+* Pointer to prediction sub-block
+* Prediction is in inter leaved format
+*
+* @param[in] pi2_out
+* Pointer to residual sub-block
+* The output will be in linear format
+* The first 4 continuous locations will contain the values of DC block for U
+* and then next 4 will contain for V.
+* After DC block and a stride 1st AC block of U plane will follow
+* After one more stride next AC block of V plane will follow
+* The blocks will be in raster scan order
+*
+* After all the AC blocks of U plane AC blocks of V plane will follow in exact
+* same way
+*
+* @param[in] i4_src_stride
+* Source stride
+*
+* @param[in] i4_pred_stride
+* Prediction stride
+*
+* @param[in] dst_strd
+* Destination stride
+*
+* @param[in] pu2_scale_matrix
+* The quantization matrix for 4x4 transform
+*
+* @param[in] pu2_threshold_matrix
+* Threshold matrix
+*
+* @param[in] u4_qbits
+* 15+QP/6
+*
+* @param[in] u4_round_factor
+* Round factor for quant
+*
+* @param[out] pu1_nnz
+* Memory to store the non-zeros after transform
+* The first byte will be the nnz od DC block for U plane
+* From the next byte the AC nnzs will be storerd in raster scan order
+* The fifth byte will be nnz of Dc block of V plane
+* Then Ac blocks will follow
+*
+* @param u4_dc_flag
+* Signals if Dc transform is to be done or not
+* 1 -> Dc transform will be done
+* 0 -> Dc transform will not be done
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_chroma_8x8_resi_trans_dctrans_quant(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_quant_coeffs,
+ buffer_container_t *ps_upsampled_res, isa_dependent_fxns_t *ps_isa_dependent_fxns,
+ const UWORD16 *pu2_scale_matrix, const UWORD16 *pu2_threshold_matrix, UWORD8 *pu1_nnz,
+ UWORD32 u4_qbits, UWORD32 u4_round_factor, UWORD8 u1_use_upsampled_res)
+{
+ WORD32 blk_cntr;
+ WORD32 i4_offsetx, i4_offsety;
+ UWORD8 au1_dcnnz[2];
+
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ buffer_container_t s_src = ps_src[0];
+ buffer_container_t s_pred = ps_pred[0];
+ buffer_container_t s_quant_coeffs = ps_quant_coeffs[0];
+ buffer_container_t s_upsampled_res = {0};
+ resi_trans_quant_constants_t s_resi_trans_quant_constants = {
+ .pu2_scale_matrix = pu2_scale_matrix,
+ .pu2_threshold_matrix = pu2_threshold_matrix,
+ .u4_qbits = u4_qbits,
+ .u4_round_factor = u4_round_factor};
+
+ UWORD8 u1_resi_trans_fxn_idx = isvc_get_resi_trans_quant_variant_idx(u1_use_upsampled_res);
+
+ if(u1_use_upsampled_res)
+ {
+ s_upsampled_res = ps_upsampled_res[0];
+ }
+
+ /* Move to the ac addresses */
+ pu1_nnz++;
+
+ for(blk_cntr = 0; blk_cntr < NUM_CHROMA4x4_BLOCKS_IN_MB; blk_cntr++)
+ {
+ IND2SUB_CHROMA_MB(blk_cntr, i4_offsetx, i4_offsety);
+
+ s_src.pv_data =
+ ((UWORD8 *) ps_src[0].pv_data) + i4_offsetx + i4_offsety * ps_src[0].i4_data_stride;
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred[0].pv_data) + i4_offsetx + i4_offsety * ps_pred[0].i4_data_stride;
+ s_quant_coeffs.pv_data =
+ ((WORD16 *) ps_quant_coeffs[0].pv_data) + blk_cntr * ps_quant_coeffs[0].i4_data_stride;
+
+ if(u1_use_upsampled_res)
+ {
+ s_upsampled_res.pv_data = ((WORD16 *) ps_upsampled_res[0].pv_data) + i4_offsetx +
+ i4_offsety * ps_upsampled_res[0].i4_data_stride;
+ }
+
+ /* Move to the ac addresses */
+ s_quant_coeffs.pv_data =
+ ((WORD16 *) s_quant_coeffs.pv_data) + ps_quant_coeffs[0].i4_data_stride;
+
+ s_quant_coeffs.i4_data_stride = 4;
+
+ /* For chroma, v plane nnz is populated from position 5 */
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[u1_resi_trans_fxn_idx](
+ &s_src, &s_pred, &s_quant_coeffs, &s_upsampled_res, &s_resi_trans_quant_constants,
+ &pu1_nnz[blk_cntr + (blk_cntr > 3)], ((WORD16 *) ps_quant_coeffs->pv_data) + blk_cntr,
+ u1_use_upsampled_res);
+ }
+
+ /* Adjust pointers to point to dc values */
+ s_quant_coeffs = ps_quant_coeffs[0];
+ pu1_nnz--;
+
+ s_resi_trans_quant_constants.u4_qbits++;
+ s_resi_trans_quant_constants.u4_round_factor <<= 1;
+
+ ps_enc_loop_fxns->pf_hadamard_quant_2x2_uv(((WORD16 *) ps_quant_coeffs->pv_data),
+ ((WORD16 *) ps_quant_coeffs->pv_data),
+ &s_resi_trans_quant_constants, au1_dcnnz);
+
+ /* Copy the dc nnzs */
+ pu1_nnz[0] = au1_dcnnz[0];
+ pu1_nnz[5] = au1_dcnnz[1];
+}
+
+/**
+*******************************************************************************
+* @brief
+* This function performs the inverse transform with process for chroma MB of
+*H264
+*
+* @par Description:
+* Does inverse DC transform ,inverse quantization inverse transform
+*
+* @param[in] pi2_src
+* Input data, 16x16 size
+* The input is in the form of, first 4 locations will contain DC coeffs of
+* U plane, next 4 will contain DC coeffs of V plane, then AC blocks of U plane
+* in raster scan order will follow, each block as linear array in raster scan
+*order. After a stride next AC block will follow. After all AC blocks of U plane
+* V plane AC blocks will follow in exact same order.
+*
+* @param[in] pu1_pred
+* The predicted data, 8x16 size, U and V interleaved
+*
+* @param[in] pu1_out
+* Output 8x16, U and V interleaved
+*
+* @param[in] i4_src_stride
+* Source stride
+*
+* @param[in] i4_pred_stride
+* input stride for prediction buffer
+*
+* @param[in] i4_out_stride
+* input stride for output buffer
+*
+* @param[in] pu2_iscale_mat
+* Inverse quantization martix for 4x4 transform
+*
+* @param[in] pu2_weigh_mat
+* weight matrix of 4x4 transform
+*
+* @param[in] u4_qp_div_6
+* QP/6
+*
+* @param[in] pi4_tmp
+* Input temporary buffer
+* needs to be at least COFF_CNT_SUB_BLK_4x4 + Number of Dc cofss for chroma *
+*number of planes in size
+*
+* @param[in] pu4_cntrl
+* Controls the transform path
+* the 15 th bit will correspond to DC block of U plane , 14th will indicate the
+*V plane Dc block 32-28 bits will indicate AC blocks of U plane in raster scan
+*order 27-23 bits will indicate AC blocks of V plane in rater scan order The bit
+*1 implies that there is at least one non zero coeff in a block
+*
+* @returns
+* none
+*
+* @remarks
+*******************************************************************************
+*/
+void isvce_chroma_8x8_idctrans_iquant_itrans_recon(
+ buffer_container_t *ps_src, buffer_container_t *ps_pred, buffer_container_t *ps_recon,
+ buffer_container_t *ps_res, buffer_container_t *ps_res_pred,
+ iq_it_res_rec_constants_t *ps_iq_it_res_rec_constants,
+ isa_dependent_fxns_t *ps_isa_dependent_fxns, WORD32 *pi4_tmp, UWORD32 u4_cntrl,
+ UWORD8 u1_res_accumulate)
+{
+ /* Cntrl bits for 4x4 transforms
+ * u4_blk_cntrl : controls if a 4x4 block should be processed in ac path
+ * u4_dc_cntrl : controls is a 4x4 block is to be processed in dc path
+ * : dc block must contain only single dc coefficient
+ * u4_empty_blk_cntrl : control fot 4x4 block with no coeffs, ie no dc and ac
+ * : ie not (ac or dc)
+ */
+ UWORD32 u4_blk_cntrl, u4_dc_cntrl, u4_empty_blk_cntrl;
+ WORD32 u4_blk_id;
+ WORD32 i4_offset_x, i4_offset_y;
+ WORD16 *pi2_dc_src;
+ /* Increment for dc block */
+ WORD32 i4_dc_inc;
+
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ buffer_container_t s_src = ps_src[0];
+ buffer_container_t s_pred = ps_pred[0];
+ buffer_container_t s_recon = ps_recon[0];
+ buffer_container_t s_res = ps_res[0];
+ buffer_container_t s_res_pred = ps_res_pred[0];
+
+ WORD16 i2_zero = 0;
+ const UWORD16 *pu2_iscale_mat = ps_iq_it_res_rec_constants->pu2_iscal_mat;
+ const UWORD16 *pu2_weigh_mat = ps_iq_it_res_rec_constants->pu2_weigh_mat;
+ UWORD32 u4_qp_div_6 = ps_iq_it_res_rec_constants->u4_qp_div_6;
+ UWORD8 u1_iq_it_recon_fxn_idx = isvc_get_iq_it_recon_variant_idx(0, u1_res_accumulate);
+
+ /*
+ * Lets do the inverse transform for dc coeffs in chroma
+ */
+ if(u4_cntrl & CNTRL_FLAG_DCBLK_MASK_CHROMA)
+ {
+ UWORD32 cntr, u4_dc_cntrl;
+ /* Do inv hadamard for u an v block */
+
+ ps_enc_loop_fxns->pf_ihadamard_scaling_2x2_uv(s_src.pv_data, s_src.pv_data, pu2_iscale_mat,
+ pu2_weigh_mat, u4_qp_div_6, NULL);
+ /*
+ * Update the cntrl flag
+ * Flag is updated as follows bits 15-11 -> u block dc bits
+ */
+ u4_dc_cntrl = 0;
+ for(cntr = 0; cntr < 8; cntr++)
+ {
+ u4_dc_cntrl |= ((((WORD16 *) ps_src->pv_data)[cntr] != 0) << (15 - cntr));
+ }
+
+ /* Mark dc bits as 1 if corresponding ac bit is 0 */
+ u4_dc_cntrl = (~(u4_cntrl >> 16) & u4_dc_cntrl);
+ /* Combine both ac and dc bits */
+ u4_cntrl =
+ (u4_cntrl & CNTRL_FLAG_AC_MASK_CHROMA) | (u4_dc_cntrl & CNTRL_FLAG_DC_MASK_CHROMA);
+
+ /* Since we populated the dc coffs, we have to read them from there */
+ pi2_dc_src = ((WORD16 *) ps_src->pv_data);
+ i4_dc_inc = 1;
+ }
+ else
+ {
+ u4_cntrl = u4_cntrl & CNTRL_FLAG_AC_MASK_CHROMA;
+ pi2_dc_src = &i2_zero;
+ i4_dc_inc = 0;
+ }
+
+ /* Get the block bits */
+ u4_blk_cntrl = (u4_cntrl & CNTRL_FLAG_AC_MASK_CHROMA);
+ u4_dc_cntrl = (u4_cntrl & CNTRL_FLAG_DC_MASK_CHROMA) << 16;
+ u4_empty_blk_cntrl = (~(u4_dc_cntrl | u4_blk_cntrl)) & 0xFF000000;
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_dc_cntrl, u4_blk_id);
+
+ while(u4_blk_id < 8)
+ {
+ WORD32 dc_src_offset = u4_blk_id * i4_dc_inc;
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ s_src.pv_data = pi2_dc_src + dc_src_offset;
+
+ IND2SUB_CHROMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[u1_iq_it_recon_fxn_idx](
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants, NULL,
+ s_src.pv_data, 0, u1_res_accumulate);
+
+ /* Get next DC block to process */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_dc_cntrl, u4_blk_id);
+ }
+
+ /* now process ac/mixed blocks */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_blk_cntrl, u4_blk_id);
+ while(u4_blk_id < 8)
+ {
+ WORD32 dc_src_offset = i4_dc_inc * u4_blk_id;
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ /* The AC blocks starts from 2nd row */
+ s_src.pv_data = ((WORD16 *) ps_src->pv_data) + (u4_blk_id + 1) * ps_src->i4_data_stride;
+
+ IND2SUB_CHROMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[u1_iq_it_recon_fxn_idx](
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants,
+ (WORD16 *) pi4_tmp, pi2_dc_src + dc_src_offset, 0, u1_res_accumulate);
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_blk_cntrl, u4_blk_id);
+ }
+
+ /* Now process empty blocks */
+ DEQUEUE_BLKID_FROM_CONTROL(u4_empty_blk_cntrl, u4_blk_id);
+
+ while(u4_blk_id < 8)
+ {
+ WORD32 dc_src_offset = i4_dc_inc * u4_blk_id;
+
+ IND2SUB_CHROMA_MB(u4_blk_id, i4_offset_x, i4_offset_y);
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+ /* The AC blocks starts from 2nd row */
+ s_src.pv_data = ((WORD16 *) ps_src->pv_data) + (u4_blk_id + 1) * ps_src->i4_data_stride;
+
+ s_pred.pv_data =
+ ((UWORD8 *) ps_pred->pv_data) + i4_offset_x + i4_offset_y * ps_pred->i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) ps_recon->pv_data) + i4_offset_x + i4_offset_y * ps_recon->i4_data_stride;
+ s_res.pv_data =
+ ((WORD16 *) ps_res->pv_data) + i4_offset_x + i4_offset_y * ps_res->i4_data_stride;
+ s_res_pred.pv_data = ((WORD16 *) ps_res_pred->pv_data) + i4_offset_x +
+ i4_offset_y * ps_res_pred->i4_data_stride;
+
+ ps_enc_loop_fxns->pf_chroma_zcbf_iquant_itrans_recon_4x4(
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, ps_iq_it_res_rec_constants,
+ (WORD16 *) pi4_tmp, pi2_dc_src + dc_src_offset, 0, u1_res_accumulate);
+
+ DEQUEUE_BLKID_FROM_CONTROL(u4_empty_blk_cntrl, u4_blk_id);
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief This function packs residue of an i16x16 luma mb for entropy coding
+*
+* @par Description
+* An i16 macro block contains two classes of units, dc 4x4 block and
+* 4x4 ac blocks. while packing the mb, the dc block is sent first, and
+* the 16 ac blocks are sent next in scan order. Each and every block is
+* represented by 3 parameters (nnz, significant coefficient map and the
+* residue coefficients itself). If a 4x4 unit does not have any coefficients
+* then only nnz is sent. Inside a 4x4 block the individual coefficients are
+* sent in scan order.
+*
+* The first byte of each block will be nnz of the block, if it is non zero,
+* a 2 byte significance map is sent. This is followed by nonzero coefficients.
+* This is repeated for 1 dc + 16 ac blocks.
+*
+* @param[in] pi2_res_mb
+* pointer to residue mb
+*
+* @param[in, out] pv_mb_coeff_data
+* buffer pointing to packed residue coefficients
+*
+* @param[in] u4_res_strd
+* residual block stride
+*
+* @param[out] u1_cbp_l
+* coded block pattern luma
+*
+* @param[in] pu1_nnz
+* number of non zero coefficients in each 4x4 unit
+*
+* @param[out]
+* Control signal for inverse transform of 16x16 blocks
+*
+* @return none
+*
+* @ remarks
+*
+******************************************************************************
+*/
+void isvce_pack_l_mb_i16(WORD16 *pi2_res_mb, void **pv_mb_coeff_data, WORD32 i4_res_strd,
+ UWORD8 *u1_cbp_l, UWORD8 *pu1_nnz, UWORD32 *pu4_cntrl)
+{
+ /* pointer to packed sub block buffer space */
+ tu_sblk_coeff_data_t *ps_mb_coeff_data = (*pv_mb_coeff_data), *ps_mb_coeff_data_ac;
+
+ /* no of non zero coefficients in the current sub block */
+ UWORD32 u4_nnz_cnt;
+
+ /* significant coefficient map */
+ UWORD32 u4_s_map;
+
+ /* pointer to scanning matrix */
+ const UWORD8 *pu1_scan_order;
+
+ /* number of non zeros in sub block */
+ UWORD32 u4_nnz;
+
+ /* coeff scan order */
+ const UWORD8 u1_scan_order[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+ /* temp var */
+ UWORD32 coeff_cnt, mask, b4, u4_cntrl = 0;
+
+ /*DC and AC coeff pointers*/
+ WORD16 *pi2_res_mb_ac, *pi2_res_mb_dc;
+
+ /********************************************************/
+ /* pack dc coeff data for entropy coding */
+ /********************************************************/
+
+ pi2_res_mb_dc = pi2_res_mb;
+ pu1_scan_order = gu1_luma_scan_order_dc;
+
+ u4_nnz = *pu1_nnz;
+ u4_cntrl = 0;
+
+ /* write number of non zero coefficients */
+ ps_mb_coeff_data->i4_sig_map_nnz = u4_nnz;
+
+ if(u4_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < u4_nnz; coeff_cnt++)
+ {
+ if(pi2_res_mb_dc[pu1_scan_order[coeff_cnt]])
+ {
+ /* write residue */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] =
+ pi2_res_mb_dc[pu1_scan_order[coeff_cnt]];
+ u4_s_map |= mask;
+ }
+ mask <<= 1;
+ }
+ /* write significant coeff map */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+
+ u4_cntrl = 0x00008000; // Set DC bit in ctrl code
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+
+ /********************************************************/
+ /* pack ac coeff data for entropy coding */
+ /********************************************************/
+
+ pu1_nnz++;
+ pu1_scan_order = gu1_luma_scan_order;
+ pi2_res_mb += i4_res_strd; /*Move to AC block*/
+
+ ps_mb_coeff_data_ac = (*pv_mb_coeff_data);
+
+ for(b4 = 0; b4 < 16; b4++)
+ {
+ ps_mb_coeff_data = (*pv_mb_coeff_data);
+
+ u4_nnz = pu1_nnz[u1_scan_order[b4]];
+
+ /* Jump according to the scan order */
+ pi2_res_mb_ac = pi2_res_mb + (i4_res_strd * u1_scan_order[b4]);
+
+ /*
+ * Since this is a i16x16 block, we should not count dc coeff on indi
+ * vidual 4x4 blocks to nnz. But due to the implementation of 16x16
+ * trans function, we add dc's nnz to u4_nnz too. Hence we adjust that
+ * here
+ */
+ u4_nnz -= (pi2_res_mb_ac[0] != 0);
+
+ /* write number of non zero coefficients */
+ ps_mb_coeff_data->i4_sig_map_nnz = u4_nnz;
+
+ if(u4_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 1, mask = 1, u4_s_map = 0; u4_nnz_cnt < u4_nnz;
+ coeff_cnt++)
+ {
+ if(pi2_res_mb_ac[pu1_scan_order[coeff_cnt]])
+ {
+ /* write residue */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] =
+ pi2_res_mb_ac[pu1_scan_order[coeff_cnt]];
+ u4_s_map |= mask;
+ }
+ mask <<= 1;
+ }
+ /* write significant coeff map */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+ *u1_cbp_l = 15;
+
+ u4_cntrl |= (1 << (31 - u1_scan_order[b4]));
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+ }
+
+ if(!(*u1_cbp_l))
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data_ac;
+ }
+
+ /* Store the cntrl signal */
+ (*pu4_cntrl) = u4_cntrl;
+ return;
+}
+
+/**
+******************************************************************************
+*
+* @brief This function packs residue of an p16x16 luma mb for entropy coding
+*
+* @par Description
+* A p16x16 macro block contains two classes of units 16 4x4 ac blocks.
+* while packing the mb, the dc block is sent first, and
+* the 16 ac blocks are sent next in scan order. Each and every block is
+* represented by 3 parameters (nnz, significant coefficient map and the
+* residue coefficients itself). If a 4x4 unit does not have any coefficients
+* then only nnz is sent. Inside a 4x4 block the individual coefficients are
+* sent in scan order.
+*
+* The first byte of each block will be nnz of the block, if it is non zero,
+* a 2 byte significance map is sent. This is followed by nonzero coefficients.
+* This is repeated for 1 dc + 16 ac blocks.
+*
+* @param[in] pi2_res_mb
+* pointer to residue mb
+*
+* @param[in, out] pv_mb_coeff_data
+* buffer pointing to packed residue coefficients
+*
+* @param[in] i4_res_strd
+* residual block stride
+*
+* @param[out] u1_cbp_l
+* coded block pattern luma
+*
+* @param[in] pu1_nnz
+* number of non zero coefficients in each 4x4 unit
+*
+* @param[out] pu4_cntrl
+* Control signal for inverse transform
+*
+* @return none
+*
+* @remarks Killing coffs not yet coded
+*
+******************************************************************************
+*/
+void isvce_pack_l_mb(WORD16 *pi2_res_mb, void **pv_mb_coeff_data, WORD32 i4_res_strd,
+ UWORD8 *u1_cbp_l, UWORD8 *pu1_nnz, UWORD32 u4_thres_resi, UWORD32 *pu4_cntrl)
+{
+ /* pointer to packed sub block buffer space */
+ tu_sblk_coeff_data_t *ps_mb_coeff_data, *ps_mb_coeff_data_b8, *ps_mb_coeff_data_mb;
+
+ /* no of non zero coefficients in the current sub block */
+ UWORD32 u4_nnz_cnt;
+
+ /* significant coefficient map */
+ UWORD32 u4_s_map;
+
+ /* pointer to scanning matrix */
+ const UWORD8 *pu1_scan_order = gu1_luma_scan_order;
+
+ /* number of non zeros in sub block */
+ UWORD32 u4_nnz;
+
+ /* pointer to residual sub block */
+ WORD16 *pi2_res_sb;
+
+ /* coeff scan order */
+ const UWORD8 u1_scan_order[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+ /* coeff cost */
+ const UWORD8 *pu1_coeff_cost = gu1_coeff_cost;
+
+ /* temp var */
+ UWORD32 u4_mb_coeff_cost = 0, u4_b8_coeff_cost = 0, coeff_cnt, mask, u4_cntrl = 0, b4, b8;
+
+ /* temp var */
+ WORD32 i4_res_val, i4_run = -1, dcac_block;
+
+ /* When Hadamard transform is disabled, first row values are dont care, ignore
+ * them */
+ pi2_res_mb += i4_res_strd;
+
+ /* When Hadamard transform is disabled, first unit value is dont care, ignore
+ * this */
+ pu1_nnz++;
+
+ ps_mb_coeff_data_mb = ps_mb_coeff_data_b8 = (*pv_mb_coeff_data);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+
+ for(b4 = 0; b4 < 16; b4++)
+ {
+ ps_mb_coeff_data = (*pv_mb_coeff_data);
+
+ b8 = b4 >> 2;
+
+ u4_nnz = pu1_nnz[u1_scan_order[b4]];
+
+ /* Jump according to the scan order */
+ pi2_res_sb = pi2_res_mb + (i4_res_strd * u1_scan_order[b4]);
+
+ /* write number of non zero coefficients */
+ ps_mb_coeff_data->i4_sig_map_nnz = u4_nnz;
+
+ if(u4_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < u4_nnz;
+ coeff_cnt++)
+ {
+ /* number of runs of zero before, this is used to compute coeff cost */
+ i4_run++;
+
+ i4_res_val = pi2_res_sb[pu1_scan_order[coeff_cnt]];
+
+ if(i4_res_val)
+ {
+ /* write residue */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] = i4_res_val;
+ u4_s_map |= mask;
+
+ if(u4_thres_resi)
+ {
+ /* compute coeff cost */
+ if(i4_res_val == 1 || i4_res_val == -1)
+ {
+ if(i4_run < 6) u4_b8_coeff_cost += pu1_coeff_cost[i4_run];
+ }
+ else
+ u4_b8_coeff_cost += 9;
+
+ i4_run = -1;
+ }
+ }
+
+ mask <<= 1;
+ }
+
+ /* write significant coeff map */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+
+ /* cbp */
+ *u1_cbp_l |= (1 << b8);
+
+ /* Cntrl map for inverse transform computation
+ *
+ * If coeff_cnt is zero, it means that only nonzero was a dc coeff
+ * Hence we have to set the 16 - u1_scan_order[b4]) position instead
+ * of 31 - u1_scan_order[b4]
+ */
+ dcac_block = (coeff_cnt == 0) ? 16 : 31;
+ u4_cntrl |= (1 << (dcac_block - u1_scan_order[b4]));
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+
+ /* Decide if the 8x8 unit has to be sent for entropy coding? */
+ if((b4 + 1) % 4 == 0)
+ {
+ if(u4_thres_resi && (u4_b8_coeff_cost <= LUMA_SUB_BLOCK_SKIP_THRESHOLD) &&
+ (*u1_cbp_l & (1 << b8)))
+ {
+ /*
+ * When we want to reset the full 8x8 block, we have to reset
+ * both the dc and ac coeff bits hence we have the symmetric
+ * arrangement of bits
+ */
+ const UWORD32 cntrl_mask_map[4] = {0xcc00cc00, 0x33003300, 0x00cc00cc, 0x00330033};
+
+ /* restore cbp */
+ *u1_cbp_l = (*u1_cbp_l & (~(1 << b8)));
+
+ /* correct cntrl flag */
+ u4_cntrl = u4_cntrl & (~cntrl_mask_map[(b4 >> 2)]);
+
+ /* correct nnz */
+ pu1_nnz[u1_scan_order[b4 - 3]] = 0;
+ pu1_nnz[u1_scan_order[b4 - 2]] = 0;
+ pu1_nnz[u1_scan_order[b4 - 1]] = 0;
+ pu1_nnz[u1_scan_order[b4]] = 0;
+
+ /* reset blk cost */
+ u4_b8_coeff_cost = 0;
+ }
+
+ if(!(*u1_cbp_l & (1 << b8)))
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data_b8;
+ }
+
+ u4_mb_coeff_cost += u4_b8_coeff_cost;
+
+ u4_b8_coeff_cost = 0;
+ i4_run = -1;
+ ps_mb_coeff_data_b8 = (*pv_mb_coeff_data);
+ }
+ }
+
+ if(u4_thres_resi && (u4_mb_coeff_cost <= LUMA_BLOCK_SKIP_THRESHOLD) && (*u1_cbp_l))
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data_mb;
+ *u1_cbp_l = 0;
+ u4_cntrl = 0;
+ memset(pu1_nnz, 0, 16);
+ }
+
+ (*pu4_cntrl) = u4_cntrl;
+
+ return;
+}
+
+/**
+******************************************************************************
+*
+* @brief This function packs residue of an i8x8 chroma mb for entropy coding
+*
+* @par Description
+* An i8 chroma macro block contains two classes of units, dc 2x2 block and
+* 4x4 ac blocks. while packing the mb, the dc block is sent first, and
+* the 4 ac blocks are sent next in scan order. Each and every block is
+* represented by 3 parameters (nnz, significant coefficient map and the
+* residue coefficients itself). If a 4x4 unit does not have any coefficients
+* then only nnz is sent. Inside a 4x4 block the individual coefficients are
+* sent in scan order.
+*
+* The first byte of each block will be nnz of the block, if it is non zero,
+* a 2 byte significance map is sent. This is followed by nonzero coefficients.
+* This is repeated for 1 dc + 4 ac blocks.
+*
+* @param[in] pi2_res_mb
+* pointer to residue mb
+*
+* @param[in, out] pv_mb_coeff_data
+* buffer pointing to packed residue coefficients
+*
+* @param[in] u4_res_strd
+* residual block stride
+*
+* @param[out] u1_cbp_c
+* coded block pattern chroma
+*
+* @param[in] pu1_nnz
+* number of non zero coefficients in each 4x4 unit
+*
+* @param[out] pu1_nnz
+* Control signal for inverse transform
+*
+* @param[in] u4_swap_uv
+* Swaps the order of U and V planes in entropy bitstream
+*
+* @return none
+*
+* @ remarks
+*
+******************************************************************************
+*/
+void isvce_pack_c_mb(WORD16 *pi2_res_mb, void **pv_mb_coeff_data, WORD32 i4_res_strd,
+ UWORD8 *u1_cbp_c, UWORD8 *pu1_nnz, UWORD32 u4_thres_resi, UWORD32 *pu4_cntrl,
+ UWORD32 u4_swap_uv)
+{
+ /* pointer to packed sub block buffer space */
+ tu_sblk_coeff_data_t *ps_mb_coeff_data = (*pv_mb_coeff_data);
+ tu_sblk_coeff_data_t *ps_mb_coeff_data_dc, *ps_mb_coeff_data_ac;
+
+ /* nnz pointer */
+ UWORD8 *pu1_nnz_ac, *pu1_nnz_dc;
+
+ /* nnz counter */
+ UWORD32 u4_nnz_cnt;
+
+ /* significant coefficient map */
+ UWORD32 u4_s_map;
+
+ /* pointer to scanning matrix */
+ const UWORD8 *pu1_scan_order;
+
+ /* no of non zero coefficients in the current sub block */
+ UWORD32 u4_nnz;
+
+ /* pointer to residual sub block, res val */
+ WORD16 *pi2_res_sb, i2_res_val;
+
+ /* temp var */
+ UWORD32 coeff_cnt, mask, b4, plane;
+
+ /* temp var */
+ UWORD32 u4_coeff_cost;
+ WORD32 i4_run;
+
+ /* coeff cost */
+ const UWORD8 *pu1_coeff_cost = gu1_coeff_cost;
+
+ /* pointer to packed buffer space */
+ UWORD32 *pu4_mb_coeff_data = NULL;
+
+ /* ac coded block pattern */
+ UWORD8 u1_cbp_ac;
+
+ /* Variable to store the current bit pos in cntrl variable*/
+ UWORD32 cntrl_pos = 0;
+
+ /********************************************************/
+ /* pack dc coeff data for entropy coding */
+ /********************************************************/
+ pu1_scan_order = gu1_chroma_scan_order_dc;
+ pi2_res_sb = pi2_res_mb;
+ pu1_nnz_dc = pu1_nnz;
+ (*pu4_cntrl) = 0;
+ cntrl_pos = 15;
+ ps_mb_coeff_data_dc = (*pv_mb_coeff_data);
+
+ /* Color space conversion between SP_UV and SP_VU
+ * We always assume SP_UV for all the processing
+ * Hence to get proper stream output we need to swap U and V channels here
+ *
+ * For that there are two paths we need to look for
+ * One is the path to bitstream , these variables should have the proper input
+ * configured UV or VU
+ * For the other path the inverse transform variables should have what ever
+ * ordering the input had
+ */
+
+ if(u4_swap_uv)
+ {
+ pu1_nnz_dc += 5; /* Move to NNZ of V planve */
+ pi2_res_sb += 4; /* Move to DC coff of V plane */
+
+ cntrl_pos = 14; /* Control bit for V plane */
+ }
+
+ for(plane = 0; plane < 2; plane++)
+ {
+ ps_mb_coeff_data = (*pv_mb_coeff_data);
+
+ u4_nnz = *pu1_nnz_dc;
+ /* write number of non zero coefficients U/V */
+ ps_mb_coeff_data->i4_sig_map_nnz = u4_nnz;
+
+ if(u4_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < u4_nnz;
+ coeff_cnt++)
+ {
+ i2_res_val = pi2_res_sb[pu1_scan_order[coeff_cnt]];
+ if(i2_res_val)
+ {
+ /* write residue U/V */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] = i2_res_val;
+ u4_s_map |= mask;
+ }
+ mask <<= 1;
+ }
+ /* write significant coeff map U/V */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+ *u1_cbp_c = 1;
+
+ (*pu4_cntrl) |= (1 << cntrl_pos);
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+
+ if(u4_swap_uv)
+ {
+ cntrl_pos++; /* Control bit for U plane */
+ pu1_nnz_dc -= 5; /* Move to NNZ of U plane */
+ pi2_res_sb -= 4; /* Move to DC coff of U plane */
+ }
+ else
+ {
+ cntrl_pos--; /* Control bit for U plane */
+ pu1_nnz_dc += 5; /* 4 for AC NNZ and 1 for DC */
+ pi2_res_sb += 4; /* Move to DC coff of V plane */
+ }
+ }
+
+ /********************************************************/
+ /* pack ac coeff data for entropy coding */
+ /********************************************************/
+
+ pu1_scan_order = gu1_chroma_scan_order;
+ ps_mb_coeff_data_ac = (*pv_mb_coeff_data);
+
+ if(u4_swap_uv)
+ {
+ pi2_res_sb = pi2_res_mb + i4_res_strd * 5; /* Move to V plane ,ie 1dc row+ 4 ac row */
+ cntrl_pos = 27; /* The control bits are to be added for V bloc ie 31-4 th bit */
+ pu1_nnz_ac = pu1_nnz + 6; /*Move the nnz to V block NNZ 1 dc + 1dc + 4 ac */
+ }
+ else
+ {
+ pi2_res_sb = pi2_res_mb + i4_res_strd; /* Move to U plane ,ie 1dc row */
+ cntrl_pos = 31;
+ pu1_nnz_ac = pu1_nnz + 1; /* Move the nnz to V block NNZ 1 dc */
+ }
+
+ for(plane = 0; plane < 2; plane++)
+ {
+ pu4_mb_coeff_data = (*pv_mb_coeff_data);
+
+ u4_coeff_cost = 0;
+ i4_run = -1;
+
+ /* get the current cbp, so that it automatically
+ * gets reverted in case of zero ac values */
+ u1_cbp_ac = *u1_cbp_c;
+
+ for(b4 = 0; b4 < 4; b4++)
+ {
+ ps_mb_coeff_data = (*pv_mb_coeff_data);
+
+ u4_nnz = *pu1_nnz_ac;
+
+ /*
+ * We are scanning only ac coeffs, but the nnz is for the
+ * complete 4x4 block. Hence we have to discount the nnz contributed
+ * by the dc coefficient
+ */
+ u4_nnz -= (pi2_res_sb[0] != 0);
+
+ /* write number of non zero coefficients U/V */
+ ps_mb_coeff_data->i4_sig_map_nnz = u4_nnz;
+
+ if(u4_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < u4_nnz;
+ coeff_cnt++)
+ {
+ i2_res_val = pi2_res_sb[pu1_scan_order[coeff_cnt]];
+
+ i4_run++;
+
+ if(i2_res_val)
+ {
+ /* write residue U/V */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] = i2_res_val;
+ u4_s_map |= mask;
+
+ if(u4_thres_resi && (u4_coeff_cost < CHROMA_BLOCK_SKIP_THRESHOLD))
+ {
+ /* compute coeff cost */
+ if(i2_res_val == 1 || i2_res_val == -1)
+ {
+ if(i4_run < 6) u4_coeff_cost += pu1_coeff_cost[i4_run];
+ }
+ else
+ u4_coeff_cost += 9;
+
+ i4_run = -1;
+ }
+ }
+ mask <<= 1;
+ }
+
+ /* write significant coeff map U/V */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+ u1_cbp_ac = 2;
+
+ (*pu4_cntrl) |= 1 << cntrl_pos;
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+
+ pu1_nnz_ac++;
+ pi2_res_sb += i4_res_strd;
+ cntrl_pos--;
+ }
+
+ /* reset block */
+ if(u4_thres_resi && (u4_coeff_cost < CHROMA_BLOCK_SKIP_THRESHOLD))
+ {
+ pu4_mb_coeff_data[0] = 0;
+ pu4_mb_coeff_data[1] = 0;
+ pu4_mb_coeff_data[2] = 0;
+ pu4_mb_coeff_data[3] = 0;
+ (*pv_mb_coeff_data) = pu4_mb_coeff_data + 4;
+
+ /* Generate the control signal */
+ /* Zero out the current plane's AC coefficients */
+ (*pu4_cntrl) &= ((plane == u4_swap_uv) ? 0x0FFFFFFF : 0xF0FFFFFF);
+
+ /* Similarly do for the NNZ also */
+ *(pu1_nnz_ac - 4) = 0;
+ *(pu1_nnz_ac - 3) = 0;
+ *(pu1_nnz_ac - 2) = 0;
+ *(pu1_nnz_ac - 1) = 0;
+ }
+ else
+ {
+ *u1_cbp_c = u1_cbp_ac;
+ }
+
+ if(u4_swap_uv)
+ {
+ pi2_res_sb =
+ pi2_res_mb + i4_res_strd; /* Move to V plane ,ie 1dc row+ 4 ac row + 1 dc row */
+ cntrl_pos = 31; /* The control bits are to be added for V bloc ie 31-4 th bit */
+ pu1_nnz_ac = pu1_nnz + 1; /* Move the nnz to V block NNZ 1 dc + 1dc + 4 ac */
+
+ pu1_nnz_ac = pu1_nnz + 1;
+ }
+ else
+ pu1_nnz_ac = pu1_nnz + 6; /* Go to nnz of V plane */
+ }
+
+ /* restore the ptr basing on cbp */
+ if(*u1_cbp_c == 0)
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data_dc;
+ }
+ else if(*u1_cbp_c == 1)
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data_ac;
+ }
+
+ return;
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs luma core coding when intra mode is i16x16
+*
+* @par Description:
+* If the current mb is to be coded as intra of mb type i16x16, the mb is first
+* predicted using one of i16x16 prediction filters, basing on the intra mode
+* chosen. Then, error is computed between the input blk and the estimated blk.
+* This error is transformed (hierarchical transform i.e., dct followed by hada-
+* -mard), quantized. The quantized coefficients are packed in scan order for
+* entropy coding.
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_l
+* coded block pattern luma
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+
+UWORD8 isvce_code_luma_intra_macroblock_16x16(isvce_process_ctxt_t *ps_proc)
+{
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_res;
+ buffer_container_t s_quant_coeffs;
+
+ /*Cntrol signal for itrans*/
+ UWORD32 u4_cntrl;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ UWORD8 *pu1_pred_mb = NULL;
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf_intra_4x4;
+ WORD32 i4_pred_stride = ps_proc->i4_pred_strd;
+ WORD32 i4_res_strd = ps_proc->i4_res_strd;
+ UWORD8 u1_intra_mode = ps_proc->u1_l_i16_mode;
+ UWORD32 au4_nnz[5] = {0};
+ UWORD8 u1_cbp_l = 0;
+ UWORD8 *pu1_nnz = (UWORD8 *) au4_nnz;
+ /* pointer to packed mb coeff data */
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+
+ if(u1_intra_mode == PLANE_I16x16)
+ {
+ pu1_pred_mb = ps_proc->pu1_pred_mb_intra_16x16_plane;
+ }
+ else
+ {
+ pu1_pred_mb = ps_proc->pu1_pred_mb_intra_16x16;
+ }
+
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[Y];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[Y];
+ s_pred.pv_data = pu1_pred_mb;
+ s_pred.i4_data_stride = i4_pred_stride;
+ s_quant_coeffs.pv_data = pi2_res_mb;
+ s_quant_coeffs.i4_data_stride = i4_res_strd;
+
+ s_res = ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]
+ .as_component_bufs[Y];
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * MB_SIZE * s_res.i4_data_stride;
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ isvce_luma_16x16_resi_trans_dctrans_quant(
+ &s_src, &s_pred, &s_quant_coeffs, &ps_proc->ps_mb_res_buf->as_component_bufs[Y],
+ ps_isa_dependent_fxns, ps_qp_params->pu2_scale_mat, ps_qp_params->pu2_thres_mat, pu1_nnz,
+ ps_qp_params->u1_qbits, ps_qp_params->u4_dead_zone, ENABLE_DC_TRANSFORM,
+ ps_proc->ps_mb_info->u1_residual_prediction_flag);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ isvce_pack_l_mb_i16(pi2_res_mb, pv_mb_coeff_data, i4_res_strd, &u1_cbp_l, pu1_nnz, &u4_cntrl);
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+ /*
+ *if refernce frame is not to be computed
+ *we only need the right and bottom border 4x4 blocks to predict next intra
+ *blocks, hence only compute them
+ */
+ if(!ps_proc->u4_compute_recon)
+ {
+ u4_cntrl &= 0x111F8000;
+ }
+
+ if(u4_cntrl)
+ {
+ isvce_luma_16x16_idctrans_iquant_itrans_recon(
+ &s_quant_coeffs, &s_pred, &s_recon, &s_res,
+ &ps_proc->ps_mb_res_buf->as_component_bufs[Y], &s_iq_it_res_rec_constants,
+ ps_isa_dependent_fxns, ps_proc->pv_scratch_buff, u4_cntrl, ENABLE_DC_TRANSFORM, 0);
+ }
+ else
+ {
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(pu1_pred_mb, (UWORD8 *) s_recon.pv_data,
+ i4_pred_stride, s_recon.i4_data_stride, MB_SIZE,
+ MB_SIZE, NULL, 0);
+ }
+
+ return (u1_cbp_l);
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs luma core coding when intra mode is i4x4
+*
+* @par Description:
+* If the current mb is to be coded as intra of mb type i4x4, the mb is first
+* predicted using one of i4x4 prediction filters, basing on the intra mode
+* chosen. Then, error is computed between the input blk and the estimated blk.
+* This error is dct transformed and quantized. The quantized coefficients are
+* packed in scan order for entropy coding.
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_l
+* coded block pattern luma
+*
+* @remarks
+* The traversal of 4x4 subblocks in the 16x16 macroblock is as per the scan
+*order mentioned in h.264 specification
+*
+*******************************************************************************
+*/
+UWORD8 isvce_code_luma_intra_macroblock_4x4(isvce_process_ctxt_t *ps_proc)
+{
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_res;
+ buffer_container_t s_res_pred;
+ buffer_container_t s_quant_coeffs;
+
+ /* pointer to neighbors: left, top, top-left */
+ UWORD8 *pu1_mb_a;
+ UWORD8 *pu1_mb_b;
+ UWORD8 *pu1_mb_c;
+ UWORD8 *pu1_mb_d;
+ WORD32 i4_ngbr_avbl;
+ UWORD8 u1_nnz;
+ UWORD32 u4_nnz_cnt;
+ /* significant coefficient map */
+ UWORD32 u4_s_map;
+ /*Dummy variable for 4x4 trans fucntion*/
+ WORD16 i2_dc_dummy;
+ UWORD32 i, b8, b4, u1_blk_x, u1_blk_y, u1_pix_x, u1_pix_y, coeff_cnt, mask;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ /* pointer to packed mb coeff data */
+ tu_sblk_coeff_data_t *ps_mb_coeff_data, *ps_mb_coeff_data_b8;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ resi_trans_quant_constants_t s_resi_trans_quant_constants = {
+ .pu2_scale_matrix = ps_qp_params->pu2_scale_mat,
+ .pu2_threshold_matrix = ps_qp_params->pu2_thres_mat,
+ .u4_qbits = ps_qp_params->u1_qbits,
+ .u4_round_factor = ps_qp_params->u4_dead_zone};
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf_intra_4x4;
+ WORD32 i4_pred_stride = ps_proc->i4_pred_strd;
+ UWORD8 u1_intra_mode = ps_proc->u1_l_i16_mode;
+ UWORD8 *pu1_ngbr_pels_i4 = ps_proc->au1_ngbr_pels;
+ UWORD8 u1_cbp_l = 0;
+ /* pointer to packed mb coeff data */
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+ const UWORD8 *pu1_scan_order = gu1_luma_scan_order;
+ UWORD8 u1_resi_trans_fxn_idx = isvc_get_resi_trans_quant_variant_idx(0);
+ UWORD8 u1_iq_it_recon_fxn_idx = isvc_get_iq_it_recon_variant_idx(1, 0);
+
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[Y];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[Y];
+ s_pred.pv_data = pu1_pred_mb;
+ s_pred.i4_data_stride = i4_pred_stride;
+ s_quant_coeffs.pv_data = pi2_res_mb;
+ s_quant_coeffs.i4_data_stride = 4;
+
+ /* Process 16 4x4 lum sub-blocks of the MB in scan order */
+ for(b8 = 0; b8 < 4; b8++)
+ {
+ u1_blk_x = GET_BLK_RASTER_POS_X(b8) << 3;
+ u1_blk_y = GET_BLK_RASTER_POS_Y(b8) << 3;
+
+ /* if in case cbp for the 8x8 block is zero, send no residue */
+ ps_mb_coeff_data_b8 = *pv_mb_coeff_data;
+
+ for(b4 = 0; b4 < 4; b4++)
+ {
+ /* index of pel in MB */
+ u1_pix_x = u1_blk_x + (GET_SUB_BLK_RASTER_POS_X(b4) << 2);
+ u1_pix_y = u1_blk_y + (GET_SUB_BLK_RASTER_POS_Y(b4) << 2);
+
+ /* Initialize source and reference pointers */
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[Y];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[Y];
+ s_src.pv_data = ((UWORD8 *) s_src.pv_data) + u1_pix_x + u1_pix_y * s_src.i4_data_stride;
+ s_recon.pv_data =
+ ((UWORD8 *) s_recon.pv_data) + u1_pix_x + u1_pix_y * s_recon.i4_data_stride;
+
+ s_res = ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]
+ .as_component_bufs[Y];
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * MB_SIZE * s_res.i4_data_stride;
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + u1_pix_x + u1_pix_y * s_res.i4_data_stride;
+
+ s_res_pred = ps_proc->ps_mb_res_buf->as_component_bufs[Y];
+ s_res_pred.pv_data =
+ ((WORD16 *) s_res_pred.pv_data) + u1_pix_x + u1_pix_y * s_res_pred.i4_data_stride;
+
+ /* pointer to left of ref macro block */
+ pu1_mb_a = ((UWORD8 *) s_recon.pv_data) - 1;
+ /* pointer to top of ref macro block */
+ pu1_mb_b = ((UWORD8 *) s_recon.pv_data) - s_recon.i4_data_stride;
+ /* pointer to topright of ref macro block */
+ pu1_mb_c = pu1_mb_b + 4;
+ /* pointer to topleft macro block */
+ pu1_mb_d = pu1_mb_b - 1;
+
+ /* compute neighbor availability */
+ i4_ngbr_avbl = ps_proc->au1_ngbr_avbl_4x4_subblks[(b8 << 2) + b4];
+
+ /* sub block intra mode */
+ u1_intra_mode = ps_proc->au1_intra_luma_mb_4x4_modes[(b8 << 2) + b4];
+
+ /********************************************************/
+ /* gather prediction pels from neighbors for prediction */
+ /********************************************************/
+ /* left pels */
+ if(i4_ngbr_avbl & LEFT_MB_AVAILABLE_MASK)
+ {
+ for(i = 0; i < 4; i++)
+ pu1_ngbr_pels_i4[4 - 1 - i] = pu1_mb_a[i * s_recon.i4_data_stride];
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4, 0, 4);
+ }
+
+ /* top pels */
+ if(i4_ngbr_avbl & TOP_MB_AVAILABLE_MASK)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 4 + 1, pu1_mb_b, 4);
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4 + 5, 0, 4);
+ }
+ /* top left pels */
+ if(i4_ngbr_avbl & TOP_LEFT_MB_AVAILABLE_MASK)
+ {
+ pu1_ngbr_pels_i4[4] = *pu1_mb_d;
+ }
+ else
+ {
+ pu1_ngbr_pels_i4[4] = 0;
+ }
+ /* top right pels */
+ if(i4_ngbr_avbl & TOP_RIGHT_MB_AVAILABLE_MASK)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 8 + 1, pu1_mb_c, 4);
+ }
+ else if(i4_ngbr_avbl & TOP_MB_AVAILABLE_MASK)
+ {
+ memset(pu1_ngbr_pels_i4 + 8 + 1, pu1_ngbr_pels_i4[8], 4);
+ }
+
+ /********************************************************/
+ /* prediction */
+ /********************************************************/
+ (ps_codec->apf_intra_pred_4_l)[u1_intra_mode](pu1_ngbr_pels_i4, pu1_pred_mb, 0,
+ i4_pred_stride, i4_ngbr_avbl);
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[u1_resi_trans_fxn_idx](
+ &s_src, &s_pred, &s_quant_coeffs, &s_res_pred, &s_resi_trans_quant_constants,
+ &u1_nnz, &i2_dc_dummy, 0);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ ps_mb_coeff_data = *pv_mb_coeff_data;
+
+ /* write number of non zero coefficients */
+ ps_mb_coeff_data->i4_sig_map_nnz = u1_nnz;
+
+ if(u1_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < u1_nnz;
+ coeff_cnt++)
+ {
+ if(pi2_res_mb[pu1_scan_order[coeff_cnt]])
+ {
+ /* write residue */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] =
+ pi2_res_mb[pu1_scan_order[coeff_cnt]];
+ u4_s_map |= mask;
+ }
+ mask <<= 1;
+ }
+ /* write significant coeff map */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+
+ /* update ptr to coeff data */
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+
+ /* cbp */
+ u1_cbp_l |= (1 << b8);
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+ if(u1_nnz)
+ {
+ buffer_container_t s_src = s_quant_coeffs;
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_src.i4_data_stride = 4;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[u1_iq_it_recon_fxn_idx](
+ &s_src, &s_pred, &s_res_pred, &s_res, &s_recon, &s_iq_it_res_rec_constants,
+ (WORD16 *) ps_proc->pv_scratch_buff, s_src.pv_data, 0, 0);
+ }
+ else
+ {
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(
+ (UWORD8 *) s_pred.pv_data, (UWORD8 *) s_recon.pv_data, s_pred.i4_data_stride,
+ s_recon.i4_data_stride, BLK_SIZE, BLK_SIZE, NULL, 0);
+ }
+ }
+
+ /* if the 8x8 block has no residue, nothing needs to be sent to entropy */
+ if(!(u1_cbp_l & (1 << b8)))
+ {
+ *pv_mb_coeff_data = ps_mb_coeff_data_b8;
+ }
+ }
+
+ return (u1_cbp_l);
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs luma core coding when intra mode is i4x4
+*
+* @par Description:
+* If the current mb is to be coded as intra of mb type i4x4, the mb is first
+* predicted using one of i4x4 prediction filters, basing on the intra mode
+* chosen. Then, error is computed between the input blk and the estimated blk.
+* This error is dct transformed and quantized. The quantized coefficients are
+* packed in scan order for entropy coding.
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_l
+* coded block pattern luma
+*
+* @remarks
+* The traversal of 4x4 subblocks in the 16x16 macroblock is as per the scan
+*order mentioned in h.264 specification
+*
+*******************************************************************************
+*/
+UWORD8 isvce_code_luma_intra_macroblock_4x4_rdopt_on(isvce_process_ctxt_t *ps_proc)
+{
+ /* pointer to packed mb coeff data */
+ tu_sblk_coeff_data_t *ps_mb_coeff_data, *ps_mb_coeff_data_b8;
+
+ UWORD32 u4_nnz_cnt;
+ /* significant coefficient map */
+ UWORD32 u4_s_map;
+ UWORD32 b8, b4, coeff_cnt, mask;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ UWORD8 *pu1_ref_mb_intra_4x4 = ps_proc->pu1_ref_mb_intra_4x4;
+ UWORD8 *pu1_rec_mb = ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data);
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf_intra_4x4;
+ WORD32 i4_rec_strd = ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride;
+ UWORD8 *pu1_nnz = (UWORD8 *) ps_proc->au4_nnz_intra_4x4;
+ UWORD8 u1_cbp_l = 0;
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+ const UWORD8 *pu1_scan_order = gu1_luma_scan_order;
+
+ /* Process 16 4x4 lum sub-blocks of the MB in scan order */
+ for(b8 = 0; b8 < 4; b8++)
+ {
+ /* if in case cbp for the 8x8 block is zero, send no residue */
+ ps_mb_coeff_data_b8 = *pv_mb_coeff_data;
+
+ for(b4 = 0; b4 < 4; b4++, pu1_nnz++, pi2_res_mb += MB_SIZE)
+ {
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ ps_mb_coeff_data = *pv_mb_coeff_data;
+
+ /* write number of non zero coefficients */
+ ps_mb_coeff_data->i4_sig_map_nnz = *pu1_nnz;
+
+ if(*pu1_nnz)
+ {
+ for(u4_nnz_cnt = 0, coeff_cnt = 0, mask = 1, u4_s_map = 0; u4_nnz_cnt < *pu1_nnz;
+ coeff_cnt++)
+ {
+ if(pi2_res_mb[pu1_scan_order[coeff_cnt]])
+ {
+ /* write residue */
+ ps_mb_coeff_data->ai2_residue[u4_nnz_cnt++] =
+ pi2_res_mb[pu1_scan_order[coeff_cnt]];
+ u4_s_map |= mask;
+ }
+ mask <<= 1;
+ }
+ /* write significant coeff map */
+ ps_mb_coeff_data->i4_sig_map_nnz |= (u4_s_map << 16);
+
+ /* update ptr to coeff data */
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue + ALIGN2(u4_nnz_cnt);
+
+ /* cbp */
+ u1_cbp_l |= (1 << b8);
+ }
+ else
+ {
+ (*pv_mb_coeff_data) = ps_mb_coeff_data->ai2_residue;
+ }
+ }
+
+ /* if the 8x8 block has no residue, nothing needs to be sent to entropy */
+ if(!(u1_cbp_l & (1 << b8)))
+ {
+ *pv_mb_coeff_data = ps_mb_coeff_data_b8;
+ }
+ }
+
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(pu1_ref_mb_intra_4x4, pu1_rec_mb, MB_SIZE,
+ i4_rec_strd, MB_SIZE, MB_SIZE, NULL, 0);
+
+ return (u1_cbp_l);
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs chroma core coding for intra macro blocks
+*
+* @par Description:
+* If the current MB is to be intra coded with mb type chroma I8x8, the MB is
+* first predicted using intra 8x8 prediction filters. The predicted data is
+* compared with the input for error and the error is transformed. The DC
+* coefficients of each transformed sub blocks are further transformed using
+* Hadamard transform. The resulting coefficients are quantized, packed and sent
+* for entropy coding.
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_c
+* coded block pattern chroma
+*
+* @remarks
+* The traversal of 4x4 subblocks in the 8x8 macroblock is as per the scan order
+* mentioned in h.264 specification
+*
+*******************************************************************************
+*/
+UWORD8 isvce_code_chroma_intra_macroblock_8x8(isvce_process_ctxt_t *ps_proc)
+{
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_res;
+ buffer_container_t s_res_pred;
+ buffer_container_t s_quant_coeffs;
+
+ /* Control signal for inverse transform */
+ UWORD32 u4_cntrl;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[1];
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ UWORD8 *pu1_pred_mb = NULL;
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf;
+ WORD32 i4_pred_stride = ps_proc->i4_pred_strd;
+ WORD32 i4_res_strd = ps_proc->i4_res_strd;
+ UWORD8 u1_intra_mode = ps_proc->u1_c_i8_mode;
+ UWORD8 u1_cbp_c = 0;
+ UWORD8 au1_nnz[2 * (NUM_4x4_IN_8x8 + 1)] = {0};
+ /* pointer to packed mb coeff data */
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+ /* See if we need to swap U and V plances for entropy */
+ UWORD32 u4_swap_uv = (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_VU);
+
+ if(PLANE_CH_I8x8 == u1_intra_mode)
+ {
+ pu1_pred_mb = ps_proc->pu1_pred_mb_intra_chroma_plane;
+ }
+ else
+ {
+ pu1_pred_mb = ps_proc->pu1_pred_mb_intra_chroma;
+ }
+
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[UV];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[UV];
+ s_pred.pv_data = pu1_pred_mb;
+ s_pred.i4_data_stride = i4_pred_stride;
+ s_quant_coeffs.pv_data = pi2_res_mb;
+ s_quant_coeffs.i4_data_stride = i4_res_strd;
+
+ s_res = ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]
+ .as_component_bufs[UV];
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * (MB_SIZE / 2) * s_res.i4_data_stride;
+
+ s_res_pred = ps_proc->ps_mb_res_buf->as_component_bufs[U];
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ isvce_chroma_8x8_resi_trans_dctrans_quant(
+ &s_src, &s_pred, &s_quant_coeffs, &s_res_pred, ps_isa_dependent_fxns,
+ ps_qp_params->pu2_scale_mat, ps_qp_params->pu2_thres_mat, au1_nnz, ps_qp_params->u1_qbits,
+ ps_qp_params->u4_dead_zone, 0);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ isvce_pack_c_mb(pi2_res_mb, pv_mb_coeff_data, i4_res_strd, &u1_cbp_c, au1_nnz,
+ ps_codec->u4_thres_resi, &u4_cntrl, u4_swap_uv);
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+ isvce_chroma_8x8_idctrans_iquant_itrans_recon(
+ &s_quant_coeffs, &s_pred, &s_recon, &s_res, &s_res_pred, &s_iq_it_res_rec_constants,
+ ps_isa_dependent_fxns, ps_proc->pv_scratch_buff, u4_cntrl, 0);
+
+ memcpy(ps_proc->au1_chroma_nnz, au1_nnz, sizeof(ps_proc->au1_chroma_nnz));
+
+ return (u1_cbp_c);
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs luma core coding when mode is inter
+*
+* @par Description:
+* If the current mb is to be coded as inter the mb is predicted based on the
+* sub mb partitions and corresponding motion vectors generated by ME. Then,
+* error is computed between the input blk and the estimated blk. This error is
+* transformed, quantized. The quantized coefficients are packed in scan order
+* for entropy coding
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_l
+* coded block pattern luma
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+
+UWORD8 isvce_code_luma_inter_macroblock_16x16(isvce_process_ctxt_t *ps_proc)
+{
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_res;
+ buffer_container_t s_res_pred;
+ buffer_container_t s_quant_coeffs;
+
+ /*Control signal of itrans*/
+ UWORD32 u4_cntrl;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf_intra_4x4;
+ WORD32 i4_res_strd = ps_proc->i4_res_strd;
+ UWORD8 u1_cbp_l = 0;
+ UWORD8 *pu1_nnz = (UWORD8 *) ps_proc->au4_nnz;
+ /* pointer to packed mb coeff data */
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+
+ ps_proc->au4_nnz[0] = 0;
+ ps_proc->au4_nnz[1] = 0;
+ ps_proc->au4_nnz[2] = 0;
+ ps_proc->au4_nnz[3] = 0;
+ ps_proc->au4_nnz[4] = 0;
+
+ /********************************************************/
+ /* prediction */
+ /********************************************************/
+ isvce_motion_comp_luma(ps_proc, &s_pred);
+
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[0];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[0];
+ s_quant_coeffs.pv_data = pi2_res_mb;
+ s_quant_coeffs.i4_data_stride = i4_res_strd;
+
+ s_res = ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]
+ .as_component_bufs[Y];
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * MB_SIZE * s_res.i4_data_stride;
+
+ s_res_pred = ps_proc->ps_mb_res_buf->as_component_bufs[Y];
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ if(ps_proc->u4_min_sad_reached == 0 || ps_proc->u4_min_sad != 0)
+ {
+ isvce_luma_16x16_resi_trans_dctrans_quant(
+ &s_src, &s_pred, &s_quant_coeffs, &s_res_pred, ps_isa_dependent_fxns,
+ ps_qp_params->pu2_scale_mat, ps_qp_params->pu2_thres_mat, pu1_nnz,
+ ps_qp_params->u1_qbits, ps_qp_params->u4_dead_zone, DISABLE_DC_TRANSFORM,
+ ps_proc->ps_mb_info->u1_residual_prediction_flag);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ isvce_pack_l_mb(pi2_res_mb, pv_mb_coeff_data, i4_res_strd, &u1_cbp_l, pu1_nnz,
+ ps_codec->u4_thres_resi, &u4_cntrl);
+ }
+ else
+ {
+ u1_cbp_l = 0;
+ u4_cntrl = 0;
+ }
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+
+ /*If the frame is not to be used for P frame reference or dumping recon
+ * we only will use the reocn for only predicting intra Mbs
+ * THis will need only right and bottom edge 4x4 blocks recon
+ * Hence we selectively enable them using control signal(including DC)
+ */
+ if(ps_proc->u4_compute_recon != 1)
+ {
+ u4_cntrl &= 0x111F0000;
+ }
+
+ isvce_luma_16x16_idctrans_iquant_itrans_recon(
+ &s_quant_coeffs, &s_pred, &s_recon, &s_res, &s_res_pred, &s_iq_it_res_rec_constants,
+ ps_isa_dependent_fxns, ps_proc->pv_scratch_buff, u4_cntrl, DISABLE_DC_TRANSFORM,
+ ps_proc->ps_mb_info->u1_residual_prediction_flag);
+
+ return (u1_cbp_l);
+}
+
+/**
+*******************************************************************************
+*
+* @brief performs chroma core coding for inter macro blocks
+*
+* @par Description:
+* If the current mb is to be coded as inter predicted mb,based on the sub mb
+*partitions and corresponding motion vectors generated by ME ,prediction is
+*done. Then, error is computed between the input blk and the estimated blk. This
+*error is transformed , quantized. The quantized coefficients are packed in scan
+*order for entropy coding.
+*
+* @param[in] ps_proc_ctxt
+* pointer to the current macro block context
+*
+* @returns u1_cbp_l
+* coded block pattern chroma
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+UWORD8 isvce_code_chroma_inter_macroblock_8x8(isvce_process_ctxt_t *ps_proc)
+{
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_res;
+ buffer_container_t s_res_pred;
+ buffer_container_t s_quant_coeffs;
+
+ /*Control signal for inverse transform*/
+ UWORD32 u4_cntrl;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[1];
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ WORD16 *pi2_res_mb = ps_proc->pi2_res_buf;
+ WORD32 i4_res_strd = ps_proc->i4_res_strd;
+ UWORD8 u1_cbp_c = 0;
+ UWORD8 au1_nnz[2 * (NUM_4x4_IN_8x8 + 1)] = {0};
+ /* pointer to packed mb coeff data */
+ void **pv_mb_coeff_data = &(ps_proc->pv_mb_coeff_data);
+ /*See if we need to swap U and V plances for entropy*/
+ UWORD32 u4_swap_uv = ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_VU;
+
+ isvce_motion_comp_chroma(ps_proc, &s_pred);
+
+ s_src = ps_proc->s_src_buf_props.as_component_bufs[UV];
+ s_recon = ps_proc->s_rec_buf_props.as_component_bufs[UV];
+ s_quant_coeffs.pv_data = pi2_res_mb;
+ s_quant_coeffs.i4_data_stride = i4_res_strd;
+
+ s_res = ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]
+ .as_component_bufs[UV];
+ s_res.pv_data = ((WORD16 *) s_res.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * (MB_SIZE / 2) * s_res.i4_data_stride;
+
+ s_res_pred = ps_proc->ps_mb_res_buf->as_component_bufs[UV];
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ isvce_chroma_8x8_resi_trans_dctrans_quant(
+ &s_src, &s_pred, &s_quant_coeffs, &s_res_pred, ps_isa_dependent_fxns,
+ ps_qp_params->pu2_scale_mat, ps_qp_params->pu2_thres_mat, au1_nnz, ps_qp_params->u1_qbits,
+ ps_qp_params->u4_dead_zone, ps_proc->ps_mb_info->u1_residual_prediction_flag);
+
+ /********************************************************/
+ /* pack coeff data for entropy coding */
+ /********************************************************/
+ isvce_pack_c_mb(pi2_res_mb, pv_mb_coeff_data, i4_res_strd, &u1_cbp_c, au1_nnz,
+ ps_codec->u4_thres_resi, &u4_cntrl, u4_swap_uv);
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+
+ /* If the frame is not to be used for P frame reference or dumping recon
+ * we only will use the reocn for only predicting intra Mbs
+ * THis will need only right and bottom edge 4x4 blocks recon
+ * Hence we selectively enable them using control signal(including DC)
+ */
+ if(!ps_proc->u4_compute_recon)
+ {
+ u4_cntrl &= 0x7700C000;
+ }
+
+ isvce_chroma_8x8_idctrans_iquant_itrans_recon(
+ &s_quant_coeffs, &s_pred, &s_recon, &s_res, &s_res_pred, &s_iq_it_res_rec_constants,
+ ps_isa_dependent_fxns, ps_proc->pv_scratch_buff, u4_cntrl,
+ ps_proc->ps_mb_info->u1_residual_prediction_flag);
+
+ memcpy(ps_proc->au1_chroma_nnz, au1_nnz, sizeof(ps_proc->au1_chroma_nnz));
+
+ return (u1_cbp_c);
+}
diff --git a/encoder/svc/isvce_core_coding.h b/encoder/svc/isvce_core_coding.h
new file mode 100644
index 0000000..0d7405a
--- /dev/null
+++ b/encoder/svc/isvce_core_coding.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_core_coding.h
+*
+* @brief
+* This file contains extern declarations of core coding routines
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+******************************************************************************
+*/
+
+#ifndef _ISVCE_CORE_CODING_H_
+#define _ISVCE_CORE_CODING_H_
+
+#include "isvce_structs.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+* @brief Enable/Disable Hadamard transform of DC Coeff's
+******************************************************************************
+*/
+#define DISABLE_DC_TRANSFORM 0
+#define ENABLE_DC_TRANSFORM 1
+
+/**
+*******************************************************************************
+* @brief bit masks for DC and AC control flags
+*******************************************************************************
+*/
+
+#define DC_COEFF_CNT_LUMA_MB 16
+#define NUM_4X4_BLKS_LUMA_MB_ROW 4
+#define NUM_LUMA4x4_BLOCKS_IN_MB 16
+#define NUM_CHROMA4x4_BLOCKS_IN_MB 8
+
+#define SIZE_4X4_BLK_HRZ TRANS_SIZE_4
+#define SIZE_4X4_BLK_VERT TRANS_SIZE_4
+
+#define CNTRL_FLAG_DC_MASK_LUMA 0x0000FFFF
+#define CNTRL_FLAG_AC_MASK_LUMA 0xFFFF0000
+
+#define CNTRL_FLAG_AC_MASK_CHROMA_U 0xF0000000
+#define CNTRL_FLAG_DC_MASK_CHROMA_U 0x0000F000
+
+#define CNTRL_FLAG_AC_MASK_CHROMA_V 0x0F000000
+#define CNTRL_FLAG_DC_MASK_CHROMA_V 0x00000F00
+
+#define CNTRL_FLAG_AC_MASK_CHROMA (CNTRL_FLAG_AC_MASK_CHROMA_U | CNTRL_FLAG_AC_MASK_CHROMA_V)
+#define CNTRL_FLAG_DC_MASK_CHROMA (CNTRL_FLAG_DC_MASK_CHROMA_U | CNTRL_FLAG_DC_MASK_CHROMA_V)
+
+#define CNTRL_FLAG_DCBLK_MASK_CHROMA 0x0000C000
+
+/**
+*******************************************************************************
+* @brief macros for transforms
+*******************************************************************************
+*/
+#define DEQUEUE_BLKID_FROM_CONTROL(u4_cntrl, blk_lin_id) \
+ { \
+ blk_lin_id = CLZ(u4_cntrl); \
+ u4_cntrl &= (0x7FFFFFFF >> blk_lin_id); \
+ };
+
+#define IND2SUB_LUMA_MB(u4_blk_id, i4_offset_x, i4_offset_y) \
+ { \
+ i4_offset_x = (u4_blk_id % 4) << 2; \
+ i4_offset_y = (u4_blk_id / 4) << 2; \
+ }
+
+#define IS_V_BLK(u4_blk_id) ((u4_blk_id) > 3)
+
+#define IND2SUB_CHROMA_MB(u4_blk_id, i4_offset_x, i4_offset_y) \
+ { \
+ i4_offset_x = ((u4_blk_id & 0x1) << 3) + IS_V_BLK(u4_blk_id); \
+ i4_offset_y = (u4_blk_id & 0x2) << 1; \
+ }
+
+/* Typedefs */
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+extern FT_CORE_CODING isvce_code_luma_intra_macroblock_16x16;
+
+extern FT_CORE_CODING isvce_code_luma_intra_macroblock_4x4;
+
+extern FT_CORE_CODING isvce_code_luma_intra_macroblock_4x4_rdopt_on;
+
+extern FT_CORE_CODING isvce_code_chroma_intra_macroblock_8x8;
+
+extern FT_CORE_CODING isvce_code_luma_inter_macroblock_16x16;
+
+extern FT_CORE_CODING isvce_code_chroma_inter_macroblock_8x8;
+
+#endif
diff --git a/encoder/svc/isvce_deblk.c b/encoder/svc/isvce_deblk.c
new file mode 100644
index 0000000..2828123
--- /dev/null
+++ b/encoder/svc/isvce_deblk.c
@@ -0,0 +1,1267 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_deblk.c
+ *
+ * @brief
+ * This file contains functions that are associated with deblocking
+ *
+ * @author
+ * ittiam
+ *
+ * @par List of Functions:
+ * - isvce_fill_bs_1mv_1ref_non_mbaff
+ * - isvce_compute_bs
+ * - isvce_filter_top_edge
+ * - isvce_filter_left_edge
+ * - isvce_deblock_mb
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+#include <stdio.h>
+#include <string.h>
+
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_macros.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "ih264_trans_data.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "ih264_deblk_tables.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_deblk.h"
+#include "isvce_globals.h"
+
+static const UWORD32 gau4_isvce_packed_bs2[(1 << MAX_TU_IN_MB_COL) * 2] = {
+ /* BS TABLES FOR NORMAL EDGES */
+ 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
+ 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
+
+ /* BS TABLES FOR XTRA LEFT MB EDGES IN MBAFF CASE */
+ 0x01010101, 0x02010101, 0x01020101, 0x02020101, 0x01010201, 0x02010201, 0x01020201, 0x02020201,
+ 0x01010102, 0x02010102, 0x01020102, 0x02020102, 0x01010202, 0x02010202, 0x01020202, 0x02020202};
+
+static const UWORD16 gau2_isvce_4x4_v2h_reorder[(1 << MAX_TU_IN_MB_COL)] = {
+ 0x0000, 0x0001, 0x0010, 0x0011, 0x0100, 0x0101, 0x0110, 0x0111,
+ 0x1000, 0x1001, 0x1010, 0x1011, 0x1100, 0x1101, 0x1110, 0x1111};
+
+static void isvce_fill_bs1_16x16mb_pslice(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
+ isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table,
+ coordinates_t *ps_mb_pos)
+{
+ WORD16 i2_q_mv0, i2_q_mv1;
+ WORD16 i2_p_mv0, i2_p_mv1;
+ UWORD32 i;
+ UWORD32 u4_bs_horz = pu4_bs_table[0];
+ UWORD32 u4_bs_vert = pu4_bs_table[4];
+
+ i2_q_mv0 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_q_mv1 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+
+ if(ps_mb_pos->i4_ordinate)
+ {
+ /* Computing Bs for the top edge */
+ for(i = 0; i < 4; i++)
+ {
+ UWORD32 u4_idx = 24 - (i << 3);
+
+ /* check if Bs is already set */
+ if(!((u4_bs_horz >> u4_idx) & 0xf))
+ {
+ /************************************************************/
+ /* If Bs is not set, use left edge and current edge mvs and */
+ /* reference pictures addresses to evaluate Bs==1 */
+ /************************************************************/
+ UWORD32 u4_bs_temp1;
+ UWORD32 u4_bs;
+
+ /*********************************************************/
+ /* If any motion vector component differs by more than 1 */
+ /* integer pel or if reference pictures are different Bs */
+ /* is set to 1. Note that this condition shall be met for*/
+ /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
+ /*********************************************************/
+ i2_p_mv0 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_p_mv1 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+
+ u4_bs_temp1 =
+ ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) || (ABS((i2_p_mv1 - i2_q_mv1)) >= 4));
+
+ u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ u4_bs_temp1);
+
+ u4_bs_horz |= (u4_bs << u4_idx);
+ }
+ }
+
+ pu4_bs_table[0] = u4_bs_horz;
+ }
+
+ if(ps_mb_pos->i4_abscissa)
+ {
+ /* Computing Bs for the left edge */
+ for(i = 0; i < 4; i++)
+ {
+ UWORD32 u4_idx = 24 - (i << 3);
+
+ /* check if Bs is already set */
+ if(!((u4_bs_vert >> u4_idx) & 0xf))
+ {
+ /* If Bs is not set, evalaute conditions for Bs=1 */
+ UWORD32 u4_bs_temp1;
+ UWORD32 u4_bs;
+ /*********************************************************/
+ /* If any motion vector component differs by more than 1 */
+ /* integer pel or if reference pictures are different Bs */
+ /* is set to 1. Note that this condition shall be met for*/
+ /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
+ /*********************************************************/
+
+ i2_p_mv0 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_p_mv1 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+
+ u4_bs_temp1 =
+ ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4));
+
+ u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ u4_bs_temp1);
+
+ u4_bs_vert |= (u4_bs << u4_idx);
+ }
+ }
+
+ pu4_bs_table[4] = u4_bs_vert;
+ }
+}
+
+static void isvce_fill_bs1_16x16mb_bslice(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
+ isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table,
+ coordinates_t *ps_mb_pos)
+{
+ WORD16 i2_q_mv0, i2_q_mv1, i2_q_mv2, i2_q_mv3;
+ WORD16 i2_p_mv0, i2_p_mv1, i2_p_mv2, i2_p_mv3;
+ UWORD32 i;
+ UWORD32 u4_bs_horz = pu4_bs_table[0];
+ UWORD32 u4_bs_vert = pu4_bs_table[4];
+
+ i2_q_mv0 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_q_mv1 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+ i2_q_mv2 = ps_cur_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
+ i2_q_mv3 = ps_cur_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
+
+ /* Computing Bs for the top edge */
+ if(ps_mb_pos->i4_ordinate)
+ {
+ for(i = 0; i < 4; i++)
+ {
+ UWORD32 u4_idx = 24 - (i << 3);
+
+ /* check if Bs is already set */
+ if(!((u4_bs_horz >> u4_idx) & 0xf))
+ {
+ /************************************************************/
+ /* If Bs is not set, use left edge and current edge mvs and */
+ /* reference pictures addresses to evaluate Bs==1 */
+ /************************************************************/
+ UWORD32 u4_bs_temp1, u4_bs_temp2;
+ UWORD32 u4_bs;
+
+ /*********************************************************/
+ /* If any motion vector component differs by more than 1 */
+ /* integer pel or if reference pictures are different Bs */
+ /* is set to 1. Note that this condition shall be met for*/
+ /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
+ /*********************************************************/
+ i2_p_mv0 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_p_mv1 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+ i2_p_mv2 = ps_top_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
+ i2_p_mv3 = ps_top_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
+
+ u4_bs_temp1 =
+ ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4) |
+ (ABS((i2_p_mv2 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv3)) >= 4));
+
+ u4_bs_temp2 =
+ ((ABS((i2_p_mv0 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv3)) >= 4) |
+ (ABS((i2_p_mv2 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv1)) >= 4));
+
+ u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
+ ps_top_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
+ u4_bs_temp1) &&
+ ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_top_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
+ (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
+ ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ u4_bs_temp2);
+
+ u4_bs_horz |= (u4_bs << u4_idx);
+ }
+ }
+
+ pu4_bs_table[0] = u4_bs_horz;
+ }
+
+ /* Computing Bs for the left edge */
+ if(ps_mb_pos->i4_abscissa)
+ {
+ for(i = 0; i < 4; i++)
+ {
+ UWORD32 u4_idx = 24 - (i << 3);
+
+ /* check if Bs is already set */
+ if(!((u4_bs_vert >> u4_idx) & 0xf))
+ {
+ /* If Bs is not set, evalaute conditions for Bs=1 */
+ UWORD32 u4_bs_temp1, u4_bs_temp2;
+ UWORD32 u4_bs;
+ /*********************************************************/
+ /* If any motion vector component differs by more than 1 */
+ /* integer pel or if reference pictures are different Bs */
+ /* is set to 1. Note that this condition shall be met for*/
+ /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
+ /*********************************************************/
+
+ i2_p_mv0 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
+ i2_p_mv1 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
+ i2_p_mv2 = ps_left_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
+ i2_p_mv3 = ps_left_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
+
+ u4_bs_temp1 =
+ ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4) |
+ (ABS((i2_p_mv2 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv3)) >= 4));
+
+ u4_bs_temp2 =
+ ((ABS((i2_p_mv0 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv3)) >= 4) |
+ (ABS((i2_p_mv2 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv1)) >= 4));
+
+ u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
+ ps_left_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
+ u4_bs_temp1) &&
+ ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
+ ps_left_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
+ (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
+ ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
+ u4_bs_temp2);
+
+ u4_bs_vert |= (u4_bs << u4_idx);
+ }
+ }
+
+ pu4_bs_table[4] = u4_bs_vert;
+ }
+}
+
+static void isvce_fill_bs2_horz_vert(UWORD32 *pu4_bs, WORD32 u4_left_mb_csbp, WORD32 u4_top_mb_csbp,
+ WORD32 u4_cur_mb_csbp, coordinates_t *ps_mb_pos,
+ const UWORD32 *pu4_packed_bs2,
+ const UWORD16 *pu2_4x4_v2h_reorder)
+{
+ UWORD32 u4_nbr_horz_csbp, u4_nbr_vert_csbp;
+ UWORD32 u4_horz_bs2_dec, u4_vert_bs2_dec;
+ UWORD32 u4_left_mb_masked_csbp, u4_cur_mb_masked_csbp;
+
+ UWORD32 u4_reordered_vert_bs2_dec, u4_temp;
+
+ WORD32 u4_cur_mb_csbp_seq = 0;
+ WORD32 u4_top_mb_csbp_seq = 0;
+ WORD32 u4_left_mb_csbp_seq = 0;
+
+ /* Convert the csbp packed data in sequential pattern from raster order */
+ u4_cur_mb_csbp_seq |= u4_cur_mb_csbp & 3; // 0 1
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 4; // 4 5
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 2; // 2 3
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 6; // 6 7
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 8; // 8 9
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 12; // 12 13
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 10; // 10 11
+ u4_cur_mb_csbp >>= 2;
+ u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 14; // 14 15
+
+ u4_left_mb_csbp_seq |= u4_left_mb_csbp & 3; // 0 1
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 4; // 4 5
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 2; // 2 3
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 6; // 6 7
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 8; // 8 9
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 12; // 12 13
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 10; // 10 11
+ u4_left_mb_csbp >>= 2;
+ u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 14; // 14 15
+
+ /* Required only the last row of top MB */
+ u4_top_mb_csbp = u4_top_mb_csbp >> 10; // 12 13
+ u4_top_mb_csbp_seq |= (u4_top_mb_csbp & 3);
+ u4_top_mb_csbp = u4_top_mb_csbp >> 4; // 14 15
+ u4_top_mb_csbp_seq |= ((u4_top_mb_csbp & 3) << 2);
+
+ /* u4_nbr_horz_csbp=11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */
+ u4_nbr_horz_csbp = (u4_cur_mb_csbp_seq << 4) | u4_top_mb_csbp_seq;
+ u4_horz_bs2_dec = u4_cur_mb_csbp_seq | u4_nbr_horz_csbp;
+
+ /* u4_left_mb_masked_csbp = 15L|0|0|0|11L|0|0|0|7L|0|0|0|3L|0|0|0 */
+ u4_left_mb_masked_csbp = u4_left_mb_csbp_seq & CSBP_RIGHT_BLOCK_MASK;
+
+ /* u4_cur_mb_masked_csbp =14C|13C|12C|x|10C|9C|8C|x|6C|5C|4C|x|2C|1C|0C|x */
+ u4_cur_mb_masked_csbp = (u4_cur_mb_csbp_seq << 1) & (~CSBP_LEFT_BLOCK_MASK);
+
+ /* u4_nbr_vert_csbp=14C|13C|12C|15L|10C|9C|8C|11L|6C|5C|4C|7L|2C|1C|0C|3L */
+ u4_nbr_vert_csbp = (u4_cur_mb_masked_csbp) | (u4_left_mb_masked_csbp >> 3);
+
+ u4_vert_bs2_dec = u4_cur_mb_csbp_seq | u4_nbr_vert_csbp;
+
+ /* Fill horz edges (0,1,2,3) boundary strengths 2 using look up table */
+ if(ps_mb_pos->i4_ordinate)
+ {
+ pu4_bs[0] = pu4_packed_bs2[u4_horz_bs2_dec & 0xF];
+ }
+
+ pu4_bs[1] = pu4_packed_bs2[(u4_horz_bs2_dec >> 4) & 0xF];
+ pu4_bs[2] = pu4_packed_bs2[(u4_horz_bs2_dec >> 8) & 0xF];
+ pu4_bs[3] = pu4_packed_bs2[(u4_horz_bs2_dec >> 12) & 0xF];
+
+ /* Do 4x4 tranpose of u4_vert_bs2_dec by using look up table for reorder */
+ u4_reordered_vert_bs2_dec = pu2_4x4_v2h_reorder[u4_vert_bs2_dec & 0xF];
+ u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 4) & 0xF];
+ u4_reordered_vert_bs2_dec |= (u4_temp << 1);
+ u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 8) & 0xF];
+ u4_reordered_vert_bs2_dec |= (u4_temp << 2);
+ u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 12) & 0xF];
+ u4_reordered_vert_bs2_dec |= (u4_temp << 3);
+
+ /* Fill vert edges (4,5,6,7) boundary strengths 2 using look up table */
+ if(ps_mb_pos->i4_abscissa)
+ {
+ pu4_bs[4] = pu4_packed_bs2[u4_reordered_vert_bs2_dec & 0xF];
+ }
+
+ pu4_bs[5] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 4) & 0xF];
+ pu4_bs[6] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 8) & 0xF];
+ pu4_bs[7] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 12) & 0xF];
+}
+
+/* brief Fills the BS for edges falling on a IBL boundary */
+static void isvce_fill_bs_ibl(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
+ isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table)
+{
+ /*! Flow of the module is as follows */
+ /*! 1. checks if MB edge is falling on IBL boundary */
+ /*! 2. if only Mb edge then it fills the BS based on INTRA or INTER
+ stauts */
+ /*! 3. if the current MB is IBL and neighbours are also neighbours
+ then it uses the current layer t_coeff flag to decide the
+ BS of a particular edge */
+ /*! 4. fills the BS for all the edges in curretn MB if IBL */
+
+ UWORD16 u2_top_horz_nnz;
+ UWORD8 u1_top_mb_ibl, u1_left_mb_ibl;
+ UWORD32 i4_i, i4_edge;
+ UWORD8 u1_bs;
+ UWORD8 u1_cnd;
+ UWORD8 u1_top_intra;
+ UWORD8 u1_left_intra;
+ UWORD8 u1_p_nnz, u1_q_nnz;
+ UWORD8 u1_curr_mb_ibl;
+ UWORD16 u2_curr_nnz;
+ UWORD8 u1_left_mb_nnz = 0, u1_left_nnz;
+ WORD32 i4_horz_start = 0;
+ WORD32 i4_vertical_start = 0;
+
+ u1_top_mb_ibl = ps_top_mb ? (ps_top_mb->u1_base_mode_flag && ps_top_mb->u1_is_intra) : 0;
+ u1_left_mb_ibl = ps_left_mb ? (ps_left_mb->u1_base_mode_flag && ps_left_mb->u1_is_intra) : 0;
+
+ u1_curr_mb_ibl = ps_cur_mb ? (ps_cur_mb->u1_base_mode_flag && ps_cur_mb->u1_is_intra) : 0;
+
+ u1_top_intra = ps_top_mb ? ps_top_mb->u1_is_intra : 0;
+ u1_left_intra = ps_left_mb ? ps_left_mb->u1_is_intra : 0;
+
+ /* return if none of the current top and left is IBL */
+ if((0 == u1_curr_mb_ibl) && (0 == u1_top_mb_ibl) && (0 == u1_left_mb_ibl))
+ {
+ return;
+ }
+
+ /* set up the vertical and horz MB edge skip flags */
+ if(0 != u1_curr_mb_ibl)
+ {
+ /* if top is not IBL */
+ if(0 == u1_top_mb_ibl)
+ {
+ i4_horz_start = 1;
+ }
+
+ /* if left in not IBL */
+ if(0 == u1_left_mb_ibl)
+ {
+ i4_vertical_start = 1;
+ }
+ }
+
+ /* Fill BS for mb egdex assuming non IBL case */
+
+ /* only the MB edges fall across IBL boundary */
+ if((0 != u1_curr_mb_ibl) || (0 != u1_top_mb_ibl) || (0 != u1_left_mb_ibl))
+ {
+ UWORD16 u2_temp, u2_i, u1_i;
+ u2_temp = ps_left_mb ? ps_left_mb->u4_res_csbp : 0;
+ for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4 + MAX_TU_IN_MB_ROW - 1];
+ u1_left_mb_nnz |= ((u2_temp & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
+ }
+
+ u2_curr_nnz = ps_cur_mb->u4_res_csbp;
+
+ u2_top_horz_nnz = 0;
+ if(ps_top_mb)
+ {
+ /* last row of top MB */
+ for(u1_i = 12; u1_i < 16; u1_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u1_i];
+ u2_top_horz_nnz |=
+ ((ps_top_mb->u4_res_csbp & (1 << u1_zscan_idx)) ? 1 << (u1_i - 12) : 0);
+ }
+ }
+ else
+ {
+ u2_top_horz_nnz = 0;
+ }
+
+ /* top is intra and not ibl */
+ if(0 != u1_top_intra)
+ {
+ pu4_bs_table[0] = 0x04040404;
+ }
+ /* left is intra and not ibl */
+ if(0 != u1_left_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ }
+
+ /* assume neighbours are inter and update bs */
+ /* Edge = 0 means Vert Edges and Edge = 1 means Horz edges */
+ for(i4_edge = 0; i4_edge < 2; i4_edge++)
+ {
+ UWORD8 u1_p_nnz = 0, u1_q_nnz = 0;
+ UWORD32 u4_bs_edge = 0;
+ WORD32 i4_bit_mask;
+ WORD32 i4_curr_intra_flag;
+ WORD32 i4_neibor_intra_flag;
+
+ if(((1 == i4_horz_start) && (i4_edge == 1))) continue;
+ if(((1 == i4_vertical_start) && (i4_edge == 0))) continue;
+
+ i4_curr_intra_flag = (0 != u1_curr_mb_ibl);
+
+ if(0 != i4_edge)
+ {
+ /* initialize for the TOP edge */
+ u1_p_nnz = (UWORD8) u2_top_horz_nnz;
+ for(i4_i = 0; i4_i < MAX_TU_IN_MB_ROW; i4_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[i4_i];
+ u1_q_nnz |= ((u2_curr_nnz & (1 << u1_zscan_idx)) ? (1 << i4_i) : 0);
+ }
+
+ i4_neibor_intra_flag = (u1_top_mb_ibl || u1_top_intra);
+ }
+ else
+ {
+ u1_p_nnz = u1_left_mb_nnz;
+ for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4];
+ u1_q_nnz |= ((u2_curr_nnz & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
+ }
+
+ i4_neibor_intra_flag = (u1_left_mb_ibl || u1_left_intra);
+ }
+
+ i4_bit_mask = 1;
+ /* find bs of 4 edges */
+ for(i4_i = 0; i4_i < 4; i4_i++)
+ {
+ UWORD8 u1_p_nnz_temp, u1_q_nnz_temp;
+
+ u1_p_nnz_temp = (u1_p_nnz & i4_bit_mask);
+ u1_q_nnz_temp = (u1_q_nnz & i4_bit_mask);
+
+ u1_cnd = ((u1_p_nnz_temp && (!i4_neibor_intra_flag)) ||
+ (u1_q_nnz_temp && (!i4_curr_intra_flag)));
+
+ u1_bs = u1_cnd ? 2 : 1;
+
+ /* update the bs of the edge */
+ u4_bs_edge = (u4_bs_edge << 8) + u1_bs;
+ i4_bit_mask <<= 1;
+
+ } /* end of loop over blk edges */
+
+ /* update the bs of edges */
+ if(i4_edge && !u1_top_intra)
+ {
+ pu4_bs_table[0] = u4_bs_edge;
+ }
+ else if(!i4_edge && !u1_left_intra)
+ {
+ pu4_bs_table[4] = u4_bs_edge;
+ }
+ } /* end of loop over v1 vetical and horizontal edge */
+ }
+
+ /* current MB is IBL */
+ if(0 != u1_curr_mb_ibl)
+ {
+ WORD32 i4_bit_mask_edge = 1;
+ UWORD16 u2_temp, u2_i, u1_i;
+
+ u1_left_mb_nnz = 0;
+ u2_temp = ps_left_mb ? ps_left_mb->u4_csbp : 0;
+ for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4 + MAX_TU_IN_MB_ROW - 1];
+ u1_left_mb_nnz |= ((u2_temp & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
+ }
+
+ u2_curr_nnz = ps_cur_mb->u4_csbp;
+
+ u2_top_horz_nnz = 0;
+ if(ps_top_mb)
+ {
+ for(u1_i = 12; u1_i < 16; u1_i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u1_i];
+ u2_top_horz_nnz |=
+ ((ps_top_mb->u4_csbp & (1 << u1_zscan_idx)) ? 1 << (u1_i - 12) : 0);
+ }
+ }
+ else
+ {
+ u2_top_horz_nnz = 0;
+ }
+
+ /* all are IBL edges then use only t_coeff of current layer */
+ /* loop over all edges */
+ for(i4_edge = 0; i4_edge < 4; i4_edge++)
+ {
+ UWORD16 u2_curr_horz_nnz = 0;
+ WORD32 i4_bit_mask = 1;
+
+ u1_left_nnz = (u1_left_mb_nnz & i4_bit_mask_edge);
+
+ for(i4_i = 0; i4_i < 4; i4_i++)
+ {
+ UWORD8 u1_curr_nnz, u1_top_nnz;
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[(4 * i4_edge) + i4_i];
+
+ u2_curr_horz_nnz |= ((ps_cur_mb->u4_csbp & (1 << u1_zscan_idx)) ? (1 << i4_i) : 0);
+ u1_curr_nnz = (u2_curr_horz_nnz & i4_bit_mask);
+ u1_top_nnz = (u2_top_horz_nnz & i4_bit_mask);
+
+ /* update bs horizontal */
+ if(!((1 == i4_horz_start) && (0 == i4_edge)))
+ {
+ u1_p_nnz = u1_top_nnz;
+ u1_q_nnz = u1_curr_nnz;
+ u1_cnd = !(u1_p_nnz || u1_q_nnz);
+ u1_bs = u1_cnd ? 0 : 1;
+ pu4_bs_table[i4_edge] = (pu4_bs_table[i4_edge] << 8) + u1_bs;
+ }
+
+ /* update bs vertical */
+ if(!((1 == i4_vertical_start) && (0 == i4_i)))
+ {
+ u1_p_nnz = u1_left_nnz;
+ u1_q_nnz = u1_curr_nnz;
+ u1_cnd = !(u1_p_nnz || u1_q_nnz);
+ u1_bs = u1_cnd ? 0 : 1;
+ pu4_bs_table[i4_i + 4] = (pu4_bs_table[i4_i + 4] << 8) + u1_bs;
+ }
+ /* store the current nnz to left nnz */
+ u1_left_nnz = u1_curr_nnz;
+ i4_bit_mask <<= 1;
+ }
+ /* store the current row nnz to top row nnz */
+ u2_top_horz_nnz = u2_curr_horz_nnz;
+ i4_bit_mask_edge <<= 1;
+ }
+ }
+}
+
+void isvce_compute_bs(isvce_process_ctxt_t *ps_proc, UWORD8 u1_inter_layer_deblk_flag)
+{
+ coordinates_t s_mb_pos;
+
+ UWORD32 *pu4_pic_vert_bs;
+ UWORD32 *pu4_pic_horz_bs;
+
+ isvce_bs_ctxt_t *ps_bs = &(ps_proc->s_deblk_ctxt.s_bs_ctxt);
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+ nbr_info_t *ps_nbr_info = &ps_proc->s_nbr_info;
+ isvce_mb_info_t *ps_left_mb = ps_ngbr_avbl->u1_mb_a ? ps_nbr_info->ps_left_mb_info : NULL;
+ isvce_mb_info_t *ps_top_mb =
+ ps_ngbr_avbl->u1_mb_b ? &ps_nbr_info->ps_top_row_mb_info[ps_bs->i4_mb_x] : NULL;
+ isvce_mb_info_t *ps_cur_mb = ps_proc->ps_mb_info;
+
+ UWORD32 u1_left_mb_intra, u1_left_mb_ibl;
+
+ UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp;
+
+ UWORD32 u4_cur_mb_intra, u1_top_mb_intra, u4_cur_mb_fld;
+ UWORD32 u4_cur_mb_ibl, u1_top_mb_ibl;
+ UWORD32 au4_bs_table[8];
+ UWORD32 *pu4_bs_table;
+
+ u4_cur_mb_intra = ps_cur_mb->u1_is_intra;
+ u4_cur_mb_ibl = ps_cur_mb->u1_base_mode_flag && ps_cur_mb->u1_is_intra;
+ u4_cur_mb_fld = 0;
+
+ u1_top_mb_intra = ps_top_mb ? ps_top_mb->u1_is_intra : 0;
+ u1_top_mb_ibl = ps_top_mb ? (ps_top_mb->u1_base_mode_flag && ps_top_mb->u1_is_intra) : 0;
+
+ u1_left_mb_intra = ps_left_mb ? ps_left_mb->u1_is_intra : 0;
+ u1_left_mb_ibl = ps_left_mb ? (ps_left_mb->u1_base_mode_flag && ps_left_mb->u1_is_intra) : 0;
+
+ pu4_bs_table = au4_bs_table;
+ memset(pu4_bs_table, 0, sizeof(pu4_bs_table[0]) * NUM_EDGES_IN_MB * 2);
+
+ s_mb_pos.i4_abscissa = ps_bs->i4_mb_x;
+ s_mb_pos.i4_ordinate = ps_bs->i4_mb_y;
+
+ if(!u1_inter_layer_deblk_flag)
+ {
+ pu4_pic_vert_bs =
+ ps_bs->pu4_pic_vert_bs +
+ ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
+ pu4_pic_horz_bs =
+ ps_bs->pu4_pic_horz_bs +
+ ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
+ }
+ else
+ {
+ pu4_pic_vert_bs =
+ ps_bs->pu4_intra_base_vert_bs +
+ ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
+ pu4_pic_horz_bs =
+ ps_bs->pu4_intra_base_horz_bs +
+ ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
+ }
+
+ if(u4_cur_mb_intra && !(u4_cur_mb_ibl))
+ {
+ pu4_bs_table[4] = ps_bs->i4_mb_x ? 0x04040404 : 0;
+ pu4_bs_table[0] = ps_bs->i4_mb_y ? 0x04040404 : 0;
+ pu4_bs_table[1] = 0x03030303;
+ pu4_bs_table[2] = 0x03030303;
+ pu4_bs_table[3] = 0x03030303;
+ pu4_bs_table[5] = 0x03030303;
+ pu4_bs_table[6] = 0x03030303;
+ pu4_bs_table[7] = 0x03030303;
+ }
+ else
+ {
+ isvce_fill_bs_ibl(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table);
+
+ if(!u4_cur_mb_ibl)
+ {
+ UWORD32 u4_bs_0, u4_bs_4;
+
+ UWORD32 u4_is_b = (ps_proc->i4_slice_type == BSLICE);
+
+ u2_cur_csbp = ps_cur_mb->u4_csbp;
+ u2_left_csbp = ps_left_mb ? ps_left_mb->u4_csbp : 0;
+ u2_top_csbp = ps_top_mb ? ps_top_mb->u4_csbp : 0;
+
+ u2_cur_csbp |= (ps_cur_mb->u4_res_csbp);
+ u2_left_csbp |= ps_left_mb ? ps_left_mb->u4_res_csbp : 0;
+ u2_top_csbp |= ps_top_mb ? ps_top_mb->u4_res_csbp : 0;
+
+ u4_bs_0 = pu4_bs_table[0];
+ u4_bs_4 = pu4_bs_table[4];
+
+ isvce_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp,
+ &s_mb_pos, (gau4_isvce_packed_bs2),
+ (gau2_isvce_4x4_v2h_reorder));
+
+ if(u1_left_mb_intra)
+ {
+ pu4_bs_table[4] = 0x04040404;
+ }
+ else if(u1_left_mb_ibl)
+ {
+ pu4_bs_table[4] = u4_bs_4;
+ }
+
+ if(u1_top_mb_intra)
+ {
+ pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
+ }
+ else if(u1_top_mb_ibl)
+ {
+ pu4_bs_table[0] = u4_bs_0;
+ }
+
+ if(!u4_is_b)
+ {
+ isvce_fill_bs1_16x16mb_pslice(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table,
+ &s_mb_pos);
+ }
+ else
+ {
+ isvce_fill_bs1_16x16mb_bslice(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table,
+ &s_mb_pos);
+ }
+ }
+ }
+
+ pu4_pic_horz_bs[0] = pu4_bs_table[0];
+ pu4_pic_horz_bs[1] = pu4_bs_table[1];
+ pu4_pic_horz_bs[2] = pu4_bs_table[2];
+ pu4_pic_horz_bs[3] = pu4_bs_table[3];
+
+ pu4_pic_vert_bs[0] = pu4_bs_table[4];
+ pu4_pic_vert_bs[1] = pu4_bs_table[5];
+ pu4_pic_vert_bs[2] = pu4_bs_table[6];
+ pu4_pic_vert_bs[3] = pu4_bs_table[7];
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs deblocking of top horizontal edge
+*
+* @par Description:
+* This function performs deblocking of top horizontal edge
+*
+* @param[in] ps_codec
+* pointer to codec context
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[in] pu1_mb_qp
+* pointer to mb quantization param
+*
+* @param[in] pu1_cur_pic_luma
+* pointer to recon buffer luma
+*
+* @param[in] pu1_cur_pic_chroma
+* pointer to recon buffer chroma
+*
+* @param[in] pu4_pic_horz_bs
+* pointer to horizontal blocking strength
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static void isvce_filter_top_edge(isvce_codec_t *ps_codec, UWORD8 u1_qp_p, UWORD8 u1_qp_q,
+ UWORD8 *pu1_cur_pic_luma, WORD32 i4_luma_stride,
+ UWORD8 *pu1_cur_pic_chroma, WORD32 i4_chroma_stride,
+ UWORD32 *pu4_pic_horz_bs)
+{
+ UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma;
+ UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
+
+ /********/
+ /* luma */
+ /********/
+ u4_qp_luma = (u1_qp_p + u1_qp_q + 1) >> 1;
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
+ u4_idx_B_luma = MIN(51, u4_qp_luma + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
+ u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
+
+ /**********/
+ /* chroma */
+ /**********/
+ u4_qp_chroma = (gu1_qpc_fqpi[u1_qp_p] + gu1_qpc_fqpi[u1_qp_q] + 1) >> 1;
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
+ u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
+ u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
+
+ /* deblk edge */
+ /* top Horizontal edge - allowed to be deblocked ? */
+ if(pu4_pic_horz_bs[0] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma);
+ ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma,
+ u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma, pu4_pic_horz_bs[0],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+
+ ps_codec->pf_deblk_chroma_horz_bslt4(
+ pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
+ u4_beta_chroma, pu4_pic_horz_bs[0], gu1_ih264_clip_table[u4_idx_A_chroma],
+ gu1_ih264_clip_table[u4_idx_A_chroma]);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs deblocking of left vertical edge
+*
+* @par Description:
+* This function performs deblocking of top horizontal edge
+*
+* @param[in] ps_codec
+* pointer to codec context
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[in] pu1_mb_qp
+* pointer to mb quantization param
+*
+* @param[in] pu1_cur_pic_luma
+* pointer to recon buffer luma
+*
+* @param[in] pu1_cur_pic_chroma
+* pointer to recon buffer chroma
+*
+* @param[in] pu4_pic_vert_bs
+* pointer to vertical blocking strength
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static void isvce_filter_left_edge(isvce_codec_t *ps_codec, UWORD8 u1_qp_p, UWORD8 u1_qp_q,
+ UWORD8 *pu1_cur_pic_luma, WORD32 i4_luma_stride,
+ UWORD8 *pu1_cur_pic_chroma, WORD32 i4_chroma_stride,
+ UWORD32 *pu4_pic_vert_bs)
+{
+ UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma;
+ UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
+
+ /********/
+ /* luma */
+ /********/
+ u4_qp_luma = (u1_qp_p + u1_qp_q + 1) >> 1;
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
+ u4_idx_B_luma = MIN(51, u4_qp_luma + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
+ u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
+
+ /**********/
+ /* chroma */
+ /**********/
+ u4_qp_chroma = (gu1_qpc_fqpi[u1_qp_p] + gu1_qpc_fqpi[u1_qp_q] + 1) >> 1;
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
+ u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
+ u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
+
+ /* deblk edge */
+ if(pu4_pic_vert_bs[0] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma);
+ ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma,
+ u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma, pu4_pic_vert_bs[0],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+
+ ps_codec->pf_deblk_chroma_vert_bslt4(
+ pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
+ u4_beta_chroma, pu4_pic_vert_bs[0], gu1_ih264_clip_table[u4_idx_A_chroma],
+ gu1_ih264_clip_table[u4_idx_A_chroma]);
+ }
+}
+
+static UWORD8 isvce_get_deblk_mb_qp(isvce_process_ctxt_t *ps_proc, coordinates_t *ps_mb_pos)
+{
+ UWORD8 u1_mb_qp;
+
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+ isvce_bs_ctxt_t *ps_bs_ctxt = &ps_deblk->s_bs_ctxt;
+ coordinates_t s_cur_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y};
+
+ UWORD32 u4_mb_idx = ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * ps_proc->i4_wd_mbs;
+
+ if((s_cur_mb_pos.i4_abscissa != ps_mb_pos->i4_abscissa) ||
+ (s_cur_mb_pos.i4_ordinate != ps_mb_pos->i4_ordinate))
+ {
+ u1_mb_qp = ps_bs_ctxt->pu1_pic_qp[u4_mb_idx];
+ }
+ else
+ {
+ isvce_mb_info_t *ps_mb_info =
+ ps_proc->ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
+ u4_mb_idx;
+
+ if((0 == ps_mb_pos->i4_abscissa) && (0 == ps_mb_pos->i4_ordinate))
+ {
+ u1_mb_qp = ps_mb_info->u1_mb_qp;
+ }
+ else
+ {
+ if((ps_mb_info->u4_cbp > 0) || (I16x16 == ps_mb_info->u2_mb_type))
+ {
+ u1_mb_qp = ps_mb_info->u1_mb_qp;
+ }
+ else
+ {
+ u1_mb_qp = ps_bs_ctxt->pu1_pic_qp[u4_mb_idx - 1];
+ }
+ }
+ }
+
+ return u1_mb_qp;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs deblocking on an mb
+*
+* @par Description:
+* This function performs deblocking on an mb
+*
+* @param[in] ps_proc
+* process context corresponding to the job
+*
+* @param[in] ps_deblk
+* pointer to deblock context
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_deblock_mb(isvce_process_ctxt_t *ps_proc, isvce_deblk_ctxt_t *ps_deblk,
+ UWORD8 u1_inter_layer_deblk_flag)
+{
+ UWORD8 u1_mb_a, u1_mb_b;
+ UWORD32 *pu4_pic_vert_bs;
+ UWORD32 *pu4_pic_horz_bs;
+ UWORD8 u1_cur_mb_qp;
+ UWORD8 u1_left_mb_qp;
+ UWORD8 u1_top_mb_qp;
+ UWORD32 u4_alpha_luma, u4_beta_luma, u4_idx_A_luma, u4_idx_B_luma;
+ UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ coordinates_t s_cur_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y};
+ coordinates_t s_left_mb_pos = {ps_deblk->i4_mb_x - 1, ps_deblk->i4_mb_y};
+ coordinates_t s_top_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y - 1};
+
+ WORD32 i4_mb_x = ps_deblk->i4_mb_x, i4_mb_y = ps_deblk->i4_mb_y;
+ WORD32 i4_luma_stride = ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].i4_data_stride;
+ UWORD8 *pu1_cur_pic_luma =
+ (UWORD8 *) (ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].pv_data) +
+ (i4_mb_x * MB_SIZE) + ((i4_mb_y * MB_SIZE) * i4_luma_stride);
+ WORD32 i4_chroma_stride = ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].i4_data_stride;
+ UWORD8 *pu1_cur_pic_chroma =
+ (UWORD8 *) (ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].pv_data) +
+ (i4_mb_x * MB_SIZE) + (i4_mb_y * (MB_SIZE / 2) * i4_chroma_stride);
+ UWORD32 push_ptr = (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x;
+
+ if(!u1_inter_layer_deblk_flag)
+ {
+ pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_pic_vert_bs;
+ pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_pic_horz_bs;
+ }
+ else
+ {
+ pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_intra_base_vert_bs;
+ pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_intra_base_horz_bs;
+ }
+
+ /* derive neighbor availability */
+ /* In slice mode the edges of mbs that lie on the slice boundary are not
+ * deblocked */
+ /* deblocking filter idc '2' */
+ if(ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
+ {
+ /* slice index */
+ UWORD8 *pu1_slice_idx = ps_deblk->pu1_slice_idx;
+
+ pu1_slice_idx += (i4_mb_y * ps_proc->i4_wd_mbs);
+ /* left macroblock availability */
+ u1_mb_a = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
+ /* top macroblock availability */
+ u1_mb_b = (i4_mb_y == 0 ||
+ (pu1_slice_idx[i4_mb_x - ps_proc->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
+ ? 0
+ : 1;
+ }
+ else
+ {
+ /* left macroblock availability */
+ u1_mb_a = (i4_mb_x == 0) ? 0 : 1;
+ /* top macroblock availability */
+ u1_mb_b = (i4_mb_y == 0) ? 0 : 1;
+ }
+
+ pu4_pic_vert_bs += push_ptr * NUM_EDGES_IN_MB;
+ pu4_pic_horz_bs += push_ptr * NUM_EDGES_IN_MB;
+
+ /********/
+ /* luma */
+ /********/
+ u1_cur_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_cur_mb_pos);
+ ps_deblk->s_bs_ctxt.pu1_pic_qp[push_ptr] = u1_cur_mb_qp;
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_luma = MIN(51, u1_cur_mb_qp + 0);
+ u4_idx_B_luma = MIN(51, u1_cur_mb_qp + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
+ u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
+
+ /**********/
+ /* chroma */
+ /**********/
+ u4_qp_chroma = gu1_qpc_fqpi[u1_cur_mb_qp];
+
+ /* filter offset A and filter offset B have to be received from slice header
+ */
+ /* TODO : for now lets set these offsets as zero */
+
+ u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
+ u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
+
+ /* alpha, beta computation */
+ u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
+ u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
+
+ /* Deblock vertical edges */
+ /* left vertical edge 0 - allowed to be deblocked ? */
+ if(u1_mb_a)
+ {
+ u1_left_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_left_mb_pos);
+
+ isvce_filter_left_edge(ps_codec, u1_left_mb_qp, u1_cur_mb_qp, pu1_cur_pic_luma,
+ i4_luma_stride, pu1_cur_pic_chroma, i4_chroma_stride,
+ pu4_pic_vert_bs);
+ }
+
+ /* vertical edge 1 */
+ if(pu4_pic_vert_bs[1] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 4, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 4, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma, pu4_pic_vert_bs[1],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+ }
+
+ /* vertical edge 2 */
+ if(pu4_pic_vert_bs[2] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 8, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma);
+ ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma + 8, i4_chroma_stride,
+ u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
+ u4_beta_chroma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 8, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma, pu4_pic_vert_bs[2],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+
+ ps_codec->pf_deblk_chroma_vert_bslt4(
+ pu1_cur_pic_chroma + 8, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma,
+ u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[2],
+ gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
+ }
+
+ /* vertical edge 3 */
+ if(pu4_pic_vert_bs[3] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 12, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 12, i4_luma_stride, u4_alpha_luma,
+ u4_beta_luma, pu4_pic_vert_bs[3],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+ }
+
+ /* Deblock Horizontal edges */
+ /* Horizontal edge 0 */
+ if(u1_mb_b)
+ {
+ u1_top_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_top_mb_pos);
+
+ isvce_filter_top_edge(ps_codec, u1_top_mb_qp, u1_cur_mb_qp, pu1_cur_pic_luma,
+ i4_luma_stride, pu1_cur_pic_chroma, i4_chroma_stride,
+ pu4_pic_horz_bs);
+ }
+
+ /* horizontal edge 1 */
+ if(pu4_pic_horz_bs[1] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 4 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 4 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[1],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+ }
+
+ /* horizontal edge 2 */
+ if(pu4_pic_horz_bs[2] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 8 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma);
+ ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma + 4 * i4_chroma_stride,
+ i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma,
+ u4_alpha_chroma, u4_beta_chroma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 8 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[2],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+
+ ps_codec->pf_deblk_chroma_horz_bslt4(
+ pu1_cur_pic_chroma + 4 * i4_chroma_stride, i4_chroma_stride, u4_alpha_chroma,
+ u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[2],
+ gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
+ }
+
+ /* horizontal edge 3 */
+ if(pu4_pic_horz_bs[3] == 0x04040404)
+ {
+ /* strong filter */
+ ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 12 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma);
+ }
+ else
+ {
+ /* normal filter */
+ ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 12 * i4_luma_stride, i4_luma_stride,
+ u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[3],
+ gu1_ih264_clip_table[u4_idx_A_luma]);
+ }
+}
diff --git a/encoder/svc/isvce_deblk.h b/encoder/svc/isvce_deblk.h
new file mode 100644
index 0000000..4772b00
--- /dev/null
+++ b/encoder/svc/isvce_deblk.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_deblk.h
+*
+* @brief
+* This file contains extern declarations of deblocking routines
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+******************************************************************************
+*/
+
+#ifndef _ISVCE_DEBLK_H_
+#define _ISVCE_DEBLK_H_
+
+#include "ih264_typedefs.h"
+#include "isvce_structs.h"
+
+#define CSBP_LEFT_BLOCK_MASK 0x1111
+#define CSBP_RIGHT_BLOCK_MASK 0x8888
+
+#define NUM_EDGES_IN_MB 4
+
+extern void isvce_compute_bs(isvce_process_ctxt_t *ps_proc, UWORD8 u1_inter_layer_deblk_flag);
+
+extern void isvce_deblock_mb(isvce_process_ctxt_t *ps_proc, isvce_deblk_ctxt_t *ps_deblk,
+ UWORD8 u1_inter_layer_deblk_flag);
+
+#endif
diff --git a/encoder/svc/isvce_defs.h b/encoder/svc/isvce_defs.h
new file mode 100644
index 0000000..c277abd
--- /dev/null
+++ b/encoder/svc/isvce_defs.h
@@ -0,0 +1,345 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_defs.h
+*
+* @brief
+* Definitions used in the encoder
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_DEFS_H_
+#define _ISVCE_DEFS_H_
+
+#include "ih264e_defs.h"
+
+#define SVC_MAX_NUM_BFRAMES 0
+
+#define DEFAULT_INIT_QP 1
+
+#define SVC_MAX_NUM_INP_FRAMES ((SVC_MAX_NUM_BFRAMES) + 2)
+
+#define LOG2_MAX_FRAME_NUM_MINUS4 12
+
+#define ENC_MAX_PU_IN_MB ((MB_SIZE / ENC_MIN_PU_SIZE) * (MB_SIZE / ENC_MIN_PU_SIZE))
+
+#define MAX_REF_FRAMES_PER_PRED_DIR 1
+
+#define SVC_MAX_SLICE_HDR_CNT 1
+
+#define MAX_LAYER_REFERENCE_PICS 1
+
+#define ENABLE_RESIDUAL_PREDICTION 1
+
+#define ENABLE_ILP_MV 1
+
+#define USE_ILP_MV_IN_ME (1 && (ENABLE_ILP_MV))
+
+#define USE_ILP_MV_AS_MVP (1 && (ENABLE_ILP_MV))
+
+#define MAX_MVP_IDX (USE_ILP_MV_AS_MVP ? 1 : 0)
+
+#define ENABLE_IBL_MODE 1
+
+#define ENABLE_INTRA_BASE_DEBLOCK (0 && (ENABLE_IBL_MODE))
+
+#define ENABLE_MODE_STAT_VISUALISER 0
+
+#define FORCE_FAST_INTRA4X4 0
+
+#define FORCE_DISTORTION_BASED_INTRA_4X4_GATING 1
+
+#define ENABLE_INTRA16X16_BASED_INTRA4X4_GATING 0
+
+#define ENABLE_ILP_BASED_INTRA4X4_GATING 0
+
+#define DISABLE_POST_ENC_SKIP 1
+
+#define ENABLE_RE_ENC_AS_SKIP 1
+
+#define MAX_ILP_MV_IN_NBR_RGN 4
+
+/* L, T, TL, TR, Zero, Skip, 'Temporal Skip', ILP */
+#define MAX_FPEL_SEARCH_CANDIDATES (7 + MAX_PU_IN_MB + MAX_ILP_MV_IN_NBR_RGN)
+
+#define NUM_SVCE_RC_MEMTABS 45
+
+#define SVCE_MAX_INP_DIM 1920
+
+#define SVCE_MAX_INP_FRAME_SIZE (1920 * 1088)
+
+/**
+ ***************************************************************************
+ * Enum to hold various mem records being request
+ ****************************************************************************
+ */
+typedef enum ISVCE_MEMREC_TYPES_T
+{
+ /**
+ * Codec Object at API level
+ */
+ ISVCE_MEM_REC_IV_OBJ,
+
+ /**
+ * Codec context
+ */
+ ISVCE_MEM_REC_CODEC,
+
+ /**
+ * Cabac context
+ */
+ ISVCE_MEM_REC_CABAC,
+
+ /**
+ * Cabac context_mb_info
+ */
+ ISVCE_MEM_REC_CABAC_MB_INFO,
+
+ /**
+ * entropy context
+ */
+ ISVCE_MEM_REC_ENTROPY,
+
+ /**
+ * Buffer to hold coeff data
+ */
+ ISVCE_MEM_REC_MB_COEFF_DATA,
+
+ /**
+ * Buffer to hold coeff data
+ */
+ ISVCE_MEM_REC_MB_HEADER_DATA,
+
+ /**
+ * Motion vector bank
+ */
+ ISVCE_MEM_REC_MVBANK,
+
+ /**
+ * Motion vector bits
+ */
+ ISVCE_MEM_REC_MVBITS,
+
+ /**
+ * Holds mem records passed to the codec.
+ */
+ ISVCE_MEM_REC_BACKUP,
+
+ /**
+ * Holds SPS
+ */
+ ISVCE_MEM_REC_SPS,
+
+ /**
+ * Holds PPS
+ */
+ ISVCE_MEM_REC_PPS,
+
+ /**
+ * Holds SVC NALU Extension data
+ */
+ ISVCE_MEM_REC_SVC_NALU_EXT,
+
+ /**
+ * Holds subset SPS data
+ */
+ ISVCE_MEM_REC_SUBSET_SPS,
+
+ /**
+ * Holds Slice Headers
+ */
+ ISVCE_MEM_REC_SLICE_HDR,
+
+ /**
+ * Holds SVC Slice Headers
+ */
+ ISVCE_MEM_REC_SVC_SLICE_HDR,
+
+ /**
+ * Contains map indicating slice index per MB basis
+ */
+ ISVCE_MEM_REC_SLICE_MAP,
+
+ /**
+ * Holds thread handles
+ */
+ ISVCE_MEM_REC_THREAD_HANDLE,
+
+ /**
+ * Holds control call mutex
+ */
+ ISVCE_MEM_REC_CTL_MUTEX,
+
+ /**
+ * Holds entropy call mutex
+ */
+ ISVCE_MEM_REC_ENTROPY_MUTEX,
+
+ /**
+ * Holds memory for Process JOB Queue
+ */
+ ISVCE_MEM_REC_PROC_JOBQ,
+
+ /**
+ * Holds memory for Entropy JOB Queue
+ */
+ ISVCE_MEM_REC_ENTROPY_JOBQ,
+
+ /**
+ * Contains status map indicating processing status per MB basis
+ */
+ ISVCE_MEM_REC_PROC_MAP,
+
+ /**
+ * Contains status map indicating deblocking status per MB basis
+ */
+ ISVCE_MEM_REC_DBLK_MAP,
+
+ /*
+ * Contains AIR map and mask
+ */
+ ISVCE_MEM_REC_AIR_MAP,
+
+ /**
+ * Contains status map indicating ME status per MB basis
+ */
+ ISVCE_MEM_REC_ME_MAP,
+
+ /**
+ * Holds dpb manager context
+ */
+ ISVCE_MEM_REC_DPB_MGR,
+
+ /**
+ * Holds intermediate buffers needed during processing stage
+ * Memory for process contexts is allocated in this memtab
+ */
+ ISVCE_MEM_REC_PROC_SCRATCH,
+
+ /**
+ * Holds buffers for vert_bs, horz_bs and QP (all frame level)
+ */
+ ISVCE_MEM_REC_QUANT_PARAM,
+
+ /**
+ * Holds top row syntax information
+ */
+ ISVCE_MEM_REC_TOP_ROW_SYN_INFO,
+
+ /**
+ * Holds buffers for vert_bs, horz_bs and QP (all frame level)
+ */
+ ISVCE_MEM_REC_BS_QP,
+
+ /**
+ * Holds input buffer manager context
+ */
+ ISVCE_MEM_REC_INP_PIC,
+
+ /**
+ * Holds output buffer manager context
+ */
+ ISVCE_MEM_REC_OUT,
+
+ /**
+ * Holds picture buffer manager context and array of pic_buf_ts
+ * Also holds reference picture buffers in non-shared mode
+ */
+ ISVCE_MEM_REC_REF_PIC,
+
+ /*
+ * Mem record for color space conversion
+ */
+ ISVCE_MEM_REC_CSC,
+
+ /**
+ * NMB info struct
+ */
+ ISVCE_MEM_REC_MB_INFO_NMB,
+
+ /**
+ * SVC Spatial layer Inputs
+ */
+ ISVCE_MEM_SVC_SPAT_INP,
+
+ /**
+ * Downscaler memory records
+ */
+ ISVCE_MEM_DOWN_SCALER,
+
+ /**
+ * SVC ILP data
+ */
+ ISVCE_MEM_SVC_ILP_DATA,
+
+ /**
+ * SVC ILP MV Context
+ */
+ ISVCE_MEM_SVC_ILP_MV_CTXT,
+
+ /**
+ * SVC ResPred Context
+ */
+ ISVCE_MEM_SVC_RES_PRED_CTXT,
+
+ /**
+ * SVC inter-layer intra pred context
+ */
+ ISVCE_MEM_SVC_INTRA_PRED_CTXT,
+
+ /**
+ * RC Utils Context
+ */
+ ISVCE_MEM_SVC_RC_UTILS_CTXT,
+
+ /**
+ * SubPic RC Context
+ */
+ ISVCE_MEM_SVC_SUB_PIC_RC_CTXT,
+
+#if ENABLE_MODE_STAT_VISUALISER
+ ISVCE_MEM_MODE_STAT_VISUALISER_BUF,
+#endif
+
+ /**
+ * Rate control of memory records.
+ */
+ ISVCE_MEM_REC_RC,
+
+ /**
+ * Place holder to compute number of memory records.
+ */
+ ISVCE_MEM_REC_CNT = ISVCE_MEM_REC_RC + NUM_SVCE_RC_MEMTABS,
+
+ /*
+ * Do not add anything below
+ */
+} ISVCE_MEMREC_TYPES_T;
+
+#endif
diff --git a/encoder/svc/isvce_downscaler.c b/encoder/svc/isvce_downscaler.c
new file mode 100644
index 0000000..3b64c8c
--- /dev/null
+++ b/encoder/svc/isvce_downscaler.c
@@ -0,0 +1,537 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_downscaler.c
+*
+* @brief
+* Contains downscaler functions required by the SVC encoder
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_get_downscaler_data_size()
+* - isvce_get_downscaler_padding_dims()
+* - isvce_get_downscaler_normalized_filtered_pixel()
+* - isvce_horizontal_downscale_and_transpose()
+* - isvce_process_downscaler()
+* - isvce_initialize_downscaler()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* system include files */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "iv2.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvc_structs.h"
+#include "isvc_structs.h"
+#include "isvce_downscaler.h"
+#include "isvce_downscaler_private_defs.h"
+
+/**
+******************************************************************************
+* @brief lanczos filter coefficients for 2x downscaling
+* @remarks Though the length of the filter is 8, the
+* same coefficients
+* are replicated so that 2 rows can be processed at one
+* go in SIMD
+******************************************************************************
+*/
+static WORD8 gai1_lanczos_coefficients_2x[NUM_SCALER_FILTER_PHASES][NUM_SCALER_FILTER_TAPS * 2] = {
+ {-7, 0, 39, 64, 39, 0, -7, 0, -7, 0, 39, 64, 39, 0, -7, 0},
+ {-6, 0, 33, 62, 41, 4, -6, 0, -6, 0, 33, 62, 41, 4, -6, 0},
+ {-5, -1, 29, 57, 45, 9, -5, -1, -5, -1, 29, 57, 45, 9, -5, -1},
+ {-4, -2, 23, 55, 48, 14, -4, -2, -4, -2, 23, 55, 48, 14, -4, -2},
+ {-3, -3, 18, 52, 52, 18, -3, -3, -3, -3, 18, 52, 52, 18, -3, -3},
+ {-2, -4, 13, 49, 54, 24, -2, -4, -2, -4, 13, 49, 54, 24, -2, -4},
+ {-1, -5, 9, 44, 58, 29, -1, -5, -1, -5, 9, 44, 58, 29, -1, -5},
+ {0, -6, 3, 42, 61, 34, 0, -6, 0, -6, 3, 42, 61, 34, 0, -6}};
+
+/**
+******************************************************************************
+* @brief lanczos filter coefficients for 1.5x downscaling
+* @remarks Though the length of the filter is 8, the same coefficients
+* are replicated so that 2 rows can be processed at one go in SIMD.
+******************************************************************************
+*/
+static WORD8 gai1_lanczos_coefficients_3by2x[NUM_SCALER_FILTER_PHASES][NUM_SCALER_FILTER_TAPS * 2] =
+ {{0, -11, 32, 86, 32, -11, 0, 0, 0, -11, 32, 86, 32, -11, 0, 0},
+ {0, -10, 26, 79, 39, -5, 0, 0, 0, -10, 26, 79, 39, -5, 0, 0},
+ {0, -8, 21, 72, 46, 0, -2, 0, 0, -8, 21, 72, 46, 0, -2, 0},
+ {0, -6, 15, 66, 52, 3, -3, 0, 0, -6, 15, 66, 52, 3, -3, 0},
+ {0, -6, 10, 60, 60, 10, -6, 0, 0, -6, 10, 60, 60, 10, -6, 0},
+ {0, -3, 3, 52, 66, 15, -6, 0, 0, -3, 3, 52, 66, 15, -6, 0},
+ {0, -2, 0, 46, 72, 21, -8, 0, 0, -2, 0, 46, 72, 21, -8, 0},
+ {0, 0, -5, 39, 79, 26, -10, 0, 0, 0, -5, 39, 79, 26, -10, 0}};
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the memory size required for downscaler
+*
+* @par Description:
+* returns the memory required by the downscaler context and state structs
+* for allocation.
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+UWORD32 isvce_get_downscaler_data_size(UWORD8 u1_num_spatial_layers, DOUBLE d_scaling_factor,
+ UWORD32 u4_width, UWORD32 u4_height)
+{
+ UWORD32 u4_size = 0;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ u4_size += sizeof(downscaler_state_t);
+
+ u4_size +=
+ (u4_height + NUM_SCALER_FILTER_TAPS * 2) * ((UWORD32) (u4_width / d_scaling_factor));
+ }
+
+ return u4_size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the padding size required for filtering
+*
+* @par Description:
+* gets the padding size required for filtering
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+void isvce_get_downscaler_padding_dims(padding_dims_t *ps_pad_dims)
+{
+ ps_pad_dims->u1_left_pad_size = ALIGN8(NUM_SCALER_FILTER_TAPS / 2);
+ ps_pad_dims->u1_right_pad_size = ALIGN8(NUM_SCALER_FILTER_TAPS / 2);
+ ps_pad_dims->u1_top_pad_size = NUM_SCALER_FILTER_TAPS / 2;
+ ps_pad_dims->u1_bottom_pad_size = NUM_SCALER_FILTER_TAPS / 2;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* processes downscaler
+*
+* @par Description:
+* calls the function for padding and scaling
+*
+* @param[in] ps_scaler
+* pointer to downdownscaler context
+*
+* @param[in] ps_src_buf_props
+* pointer to source buffer props struct
+*
+* @param[in] u4_blk_wd
+* width of the block to be processed
+*
+* @param[in] u4_blk_ht
+* height of the block to be processed
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+void isvce_process_downscaler(downscaler_ctxt_t *ps_scaler, yuv_buf_props_t *ps_src_buf_props,
+ yuv_buf_props_t *ps_dst_buf_props, UWORD32 u4_blk_wd,
+ UWORD32 u4_blk_ht)
+{
+ buffer_container_t s_src_buf;
+ buffer_container_t s_dst_buf;
+
+ UWORD32 u4_scaled_block_size_x, u4_scaled_block_size_y;
+
+ downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state;
+
+ ASSERT(ps_src_buf_props->e_color_format == IV_YUV_420SP_UV);
+
+ u4_scaled_block_size_x = (UWORD32) (u4_blk_wd / ps_scaler->d_scaling_factor);
+ u4_scaled_block_size_y = (UWORD32) (u4_blk_ht / ps_scaler->d_scaling_factor);
+
+ /* luma */
+ s_src_buf = ps_src_buf_props->as_component_bufs[Y];
+ s_src_buf.pv_data = ((UWORD8 *) s_src_buf.pv_data) - (NUM_SCALER_FILTER_TAPS / 2) -
+ (NUM_SCALER_FILTER_TAPS / 2) * s_src_buf.i4_data_stride;
+
+ s_dst_buf.pv_data = ps_scaler_state->pv_scratch_buf;
+ s_dst_buf.i4_data_stride = u4_blk_ht + NUM_SCALER_FILTER_TAPS;
+
+ ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters,
+ u4_scaled_block_size_x, u4_blk_ht + NUM_SCALER_FILTER_TAPS, 0);
+
+ s_src_buf = s_dst_buf;
+ s_dst_buf = ps_dst_buf_props->as_component_bufs[Y];
+
+ ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters,
+ u4_scaled_block_size_y, u4_scaled_block_size_x, 0);
+
+ /* chroma */
+ u4_blk_ht /= 2;
+ u4_scaled_block_size_y /= 2;
+
+ s_src_buf = ps_src_buf_props->as_component_bufs[U];
+ s_src_buf.pv_data = ((UWORD8 *) s_src_buf.pv_data) - NUM_SCALER_FILTER_TAPS -
+ (NUM_SCALER_FILTER_TAPS / 2) * s_src_buf.i4_data_stride;
+
+ s_dst_buf.pv_data = ps_scaler_state->pv_scratch_buf;
+ s_dst_buf.i4_data_stride = u4_blk_ht + NUM_SCALER_FILTER_TAPS;
+
+ ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters,
+ u4_scaled_block_size_x, u4_blk_ht + NUM_SCALER_FILTER_TAPS, 1);
+
+ s_src_buf = s_dst_buf;
+ s_dst_buf = ps_dst_buf_props->as_component_bufs[U];
+
+ ps_scaler_state->pf_downscaler(ps_scaler, &s_src_buf, &s_dst_buf, ps_scaler_state->pai1_filters,
+ u4_scaled_block_size_y, u4_scaled_block_size_x, 0);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* normalized dot product computer for downscaler
+*
+* @par Description:
+* Given the downscaler filter coefficients, source buffer, the function
+* calculates the dot product between them, adds an offset and normalizes it
+*
+* @param[in] ps_scaler
+* pointer to src buf
+*
+* @param[in] pi1_filter
+* pointer to filter coefficients
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+static UWORD8 isvce_get_downscaler_normalized_filtered_pixel(UWORD8 *pu1_src, WORD8 *pi1_filter)
+{
+ WORD32 i;
+ WORD32 i4_norm_dot_product;
+ UWORD8 u1_out_pixel;
+ WORD32 i4_dot_product_sum = 0;
+ WORD32 i4_rounding_offset = 1 << (FILTER_COEFF_Q - 1);
+ WORD32 i4_normalizing_factor = 1 << FILTER_COEFF_Q;
+
+ for(i = 0; i < NUM_SCALER_FILTER_TAPS; i++)
+ {
+ i4_dot_product_sum += (pu1_src[i] * pi1_filter[i]);
+ }
+
+ i4_norm_dot_product = ((i4_dot_product_sum + i4_rounding_offset) / i4_normalizing_factor);
+ u1_out_pixel = (UWORD8) CLIP_U8(i4_norm_dot_product);
+
+ return u1_out_pixel;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* horizontal scaler function
+*
+* @par Description:
+* Does horizontal scaling for the given block
+*
+* @param[in] ps_scaler
+* pointer to downscaler context
+*
+* @param[in] ps_src
+* pointer to source buffer container
+*
+* @param[in] ps_dst
+* pointer to destination buffer container
+*
+* @param[in] pai1_filters
+* pointer to array of downscaler filters
+*
+* @param[in] u4_blk_wd
+* width of the block after horizontal scaling (output block width)
+*
+* @param[in] u4_blk_ht
+* height of the current block (input block height)
+*
+* @param[in] u1_is_chroma
+* flag suggesting whether the buffer is luma or chroma
+*
+*
+* @returns
+*
+* @remarks
+* The same function is used for vertical scaling too as
+* the horizontally scaled input in stored in transpose fashion.
+*
+*******************************************************************************
+*/
+
+static void isvce_horizontal_downscale_and_transpose(
+ downscaler_ctxt_t *ps_scaler, buffer_container_t *ps_src, buffer_container_t *ps_dst,
+ FILTER_COEFF_ARRAY pai1_filters, UWORD32 u4_blk_wd, UWORD32 u4_blk_ht, UWORD8 u1_is_chroma)
+{
+ WORD32 i, j, k;
+ UWORD8 u1_phase;
+ UWORD8 u1_filtered_out_pixel;
+ UWORD8 *pu1_src_j, *pu1_dst_j;
+ UWORD8 u1_filtered_out_u_pixel, u1_filtered_out_v_pixel;
+ UWORD8 *pu1_in_pixel;
+ UWORD8 *pu1_out_pixel;
+ WORD8 *pi1_filter_grid;
+ UWORD16 u2_full_pixel_inc;
+ UWORD8 au1_temp_u_buff[NUM_SCALER_FILTER_TAPS];
+ UWORD8 au1_temp_v_buff[NUM_SCALER_FILTER_TAPS];
+
+ downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state;
+
+ UWORD32 u4_center_pixel_pos = ps_scaler_state->i4_init_offset;
+ UWORD32 u4_src_horz_increments = ps_scaler_state->u4_horz_increment;
+ UWORD8 *pu1_src = ps_src->pv_data;
+ UWORD32 u4_in_stride = ps_src->i4_data_stride;
+ UWORD8 *pu1_dst = ps_dst->pv_data;
+ UWORD32 u4_out_stride = ps_dst->i4_data_stride;
+ UWORD32 u4_center_pixel_pos_src = u4_center_pixel_pos;
+
+ /* Offset the input so that the input pixel to be processed
+ co-incides with the centre of filter (4th coefficient)*/
+ pu1_src += (1 + u1_is_chroma);
+
+ ASSERT((1 << DOWNSCALER_Q) == ps_scaler_state->u4_vert_increment);
+
+ if(!u1_is_chroma)
+ {
+ for(j = 0; j < (WORD32) u4_blk_ht; j++)
+ {
+ pu1_src_j = pu1_src + (j * u4_in_stride);
+ pu1_dst_j = pu1_dst + j;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ /* Doing the Calculation for current Loop Count */
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ u1_filtered_out_pixel =
+ isvce_get_downscaler_normalized_filtered_pixel(pu1_in_pixel, pi1_filter_grid);
+ *pu1_out_pixel = u1_filtered_out_pixel;
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+ else
+ {
+ for(j = 0; j < (WORD32) u4_blk_ht; j++)
+ {
+ pu1_src_j = pu1_src + (j * u4_in_stride);
+ pu1_dst_j = pu1_dst + j;
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_grid = pai1_filters[u1_phase];
+
+ /*Doing the Calculation for current Loop Count */
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ for(k = 0; k < NUM_SCALER_FILTER_TAPS; k++)
+ {
+ au1_temp_u_buff[k] = *(pu1_in_pixel + (2 * k));
+ au1_temp_v_buff[k] = *(pu1_in_pixel + ((2 * k) + 1));
+ }
+
+ u1_filtered_out_u_pixel = isvce_get_downscaler_normalized_filtered_pixel(
+ au1_temp_u_buff, pi1_filter_grid);
+ u1_filtered_out_v_pixel = isvce_get_downscaler_normalized_filtered_pixel(
+ au1_temp_v_buff, pi1_filter_grid);
+ *pu1_out_pixel = u1_filtered_out_u_pixel;
+ *(pu1_out_pixel + u4_out_stride) = u1_filtered_out_v_pixel;
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+}
+
+void isvce_downscaler_function_selector(downscaler_state_t *ps_scaler_state, IV_ARCH_T e_arch)
+{
+ switch(e_arch)
+ {
+#if defined(X86)
+ case ARCH_X86_SSE42:
+ {
+ ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_sse42;
+
+ break;
+ }
+#elif defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ {
+ ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_neon;
+
+ break;
+ }
+#elif defined(ARM) && !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ {
+ ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose_neon;
+
+ break;
+ }
+#endif
+ default:
+ {
+ ps_scaler_state->pf_downscaler = isvce_horizontal_downscale_and_transpose;
+
+ break;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* initializes the downscaler context
+*
+* @par Description:
+* initializes the downscaler context for the given scaling factor
+* with padding size, filter size, etc.
+*
+* @param[in] ps_scaler
+* pointer downscaler context
+*
+* @param[in] ps_mem_rec
+* pointer to memory allocated to downscaler process
+*
+* @param[in] d_scaling_factor
+* scaling reatio of width/ height between two consecutive SVC layers
+*
+* @param[in] u1_num_spatial_layers
+* scaling reatio of width/ height between two consecutive SVC layers
+*
+* @param[in] u4_wd
+* width of the input
+*
+* @param[in] u4_ht
+* height of the input
+*
+* @param[in] e_arch
+* architecure type
+*
+* @returns
+*
+* @remarks
+* when ARM intrinsics are added, update should be done here
+*
+*******************************************************************************
+*/
+
+void isvce_initialize_downscaler(downscaler_ctxt_t *ps_scaler, iv_mem_rec_t *ps_mem_rec,
+ DOUBLE d_scaling_factor, UWORD8 u1_num_spatial_layers,
+ UWORD32 u4_in_width, UWORD32 u4_in_height, IV_ARCH_T e_arch)
+{
+ if(u1_num_spatial_layers > 1)
+ {
+ downscaler_state_t *ps_scaler_state;
+
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
+
+ ps_scaler_state = (downscaler_state_t *) pu1_buf;
+ pu1_buf += sizeof(ps_scaler_state[0]);
+
+ ps_scaler_state->pv_scratch_buf = pu1_buf;
+ ps_scaler_state->u4_in_wd = u4_in_width;
+ ps_scaler_state->u4_in_ht = u4_in_height;
+
+ ps_scaler->pv_scaler_state = ps_scaler_state;
+ ps_scaler->d_scaling_factor = d_scaling_factor;
+ ps_scaler->u1_num_spatial_layers = u1_num_spatial_layers;
+
+ isvce_downscaler_function_selector(ps_scaler_state, e_arch);
+
+ ps_scaler_state->u4_horz_increment = (UWORD32) (d_scaling_factor * (1 << DOWNSCALER_Q));
+
+ ps_scaler_state->u4_vert_increment = (1 << DOWNSCALER_Q);
+ ps_scaler_state->i4_init_offset = 0;
+ ps_scaler_state->pai1_filters = (d_scaling_factor == 2.0) ? gai1_lanczos_coefficients_2x
+ : gai1_lanczos_coefficients_3by2x;
+ }
+}
diff --git a/encoder/svc/isvce_downscaler.h b/encoder/svc/isvce_downscaler.h
new file mode 100644
index 0000000..bd8e4f3
--- /dev/null
+++ b/encoder/svc/isvce_downscaler.h
@@ -0,0 +1,205 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_downscaler.h
+*
+* @brief
+* Contains downscaler functions required by the SVC encoder
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_get_downscaler_data_size()
+* - isvce_get_downscaler_padding_dims()
+* - isvce_isvce_process_ctxt_t_downscaler()
+* - isvce_get_downscaler_normalized_filtered_pixel()
+* - isvce_horizontal_downscale_and_transpose()
+* - isvce_process_downscaler()
+* - isvce_initialize_downscaler()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_DOWNSCALER_H_
+#define _ISVCE_DOWNSCALER_H_
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_defs.h"
+
+typedef struct
+{
+ /**
+ * pointer to the state of downscaler
+ */
+ void *pv_scaler_state;
+
+ /**
+ * scaling factor between the dimensions of two consecutive SVC layers
+ */
+ DOUBLE d_scaling_factor;
+
+ /**
+ * Num spatial layers
+ */
+ UWORD8 u1_num_spatial_layers;
+
+} downscaler_ctxt_t;
+
+typedef struct
+{
+ UWORD8 u1_left_pad_size;
+
+ UWORD8 u1_right_pad_size;
+
+ UWORD8 u1_top_pad_size;
+
+ UWORD8 u1_bottom_pad_size;
+
+} padding_dims_t;
+
+/**
+*******************************************************************************
+*
+* @brief
+* initializes the downscaler context
+*
+* @par Description:
+* initializes the downscaler context for the given scaling factor
+* with padding size, filter size, etc.
+*
+* @param[in] ps_scaler
+* pointer downscaler context
+*
+* @param[in] ps_mem_rec
+* pointer to memory allocated to downscaler process
+*
+* @param[in] d_scaling_factor
+* scaling reatio of width/ height between two consecutive SVC layers
+*
+* @param[in] u1_num_spatial_layers
+* scaling reatio of width/ height between two consecutive SVC layers
+*
+* @param[in] u4_wd
+* width of the input
+*
+* @param[in] u4_ht
+* height of the input
+*
+* @param[in] e_arch
+* architecure type
+*
+* @returns
+*
+* @remarks
+* when ARM intrinsics are added, update should be done here
+*
+*******************************************************************************
+*/
+
+extern void isvce_initialize_downscaler(downscaler_ctxt_t *ps_scaler, iv_mem_rec_t *ps_mem_rec,
+ DOUBLE d_scaling_factor, UWORD8 u1_num_spatial_layers,
+ UWORD32 u4_in_width, UWORD32 u4_in_height,
+ IV_ARCH_T e_arch);
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the memory size required for downscaler
+*
+* @par Description:
+* returns the memory required by the downscaler context and state structs
+* for allocation.
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+extern UWORD32 isvce_get_downscaler_data_size(UWORD8 u1_num_spatial_layers, DOUBLE d_scaling_factor,
+ UWORD32 u4_width, UWORD32 u4_height);
+
+/**
+*******************************************************************************
+*
+* @brief
+* processes downscaler
+*
+* @par Description:
+* calls the function for padding and scaling
+*
+* @param[in] ps_scaler
+* pointer to downdownscaler context
+*
+* @param[in] ps_src_buf_props
+* pointer to source buffer props struct
+*
+* @param[in] u4_blk_wd
+* width of the block to be processed
+*
+* @param[in] u4_blk_ht
+* height of the block to be processed
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+extern void isvce_process_downscaler(downscaler_ctxt_t *ps_scaler,
+ yuv_buf_props_t *ps_src_buf_props,
+ yuv_buf_props_t *ps_dst_buf_props, UWORD32 u4_blk_wd,
+ UWORD32 u4_blk_ht);
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the padding size required for filtering
+*
+* @par Description:
+* gets the padding size required for filtering
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+extern void isvce_get_downscaler_padding_dims(padding_dims_t *ps_pad_dims);
+
+#endif
diff --git a/encoder/svc/isvce_downscaler_private_defs.h b/encoder/svc/isvce_downscaler_private_defs.h
new file mode 100644
index 0000000..87ad374
--- /dev/null
+++ b/encoder/svc/isvce_downscaler_private_defs.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _ISVCE_DOWNSCALER_PRIVATE_DEFS_H_
+#define _ISVCE_DOWNSCALER_PRIVATE_DEFS_H_
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_structs.h"
+#include "isvce_downscaler.h"
+
+/* Macros */
+#define DOWNSCALER_Q 16
+
+#define FILTER_COEFF_Q 7
+
+#define NUM_SCALER_FILTER_TAPS 8
+
+#define NUM_SCALER_FILTER_PHASES 8
+
+/* Typedefs */
+typedef WORD8 (*FILTER_COEFF_ARRAY)[NUM_SCALER_FILTER_TAPS * 2];
+
+typedef void FT_DOWNSCALER(downscaler_ctxt_t *ps_scaler_state, buffer_container_t *ps_src,
+ buffer_container_t *ps_dst, FILTER_COEFF_ARRAY pai1_filters,
+ UWORD32 u4_blk_wd, UWORD32 u4_blk_ht, UWORD8 u1_is_chroma);
+
+/* Structs */
+typedef struct
+{
+ /**
+ * pointer to scratch buf
+ */
+ void *pv_scratch_buf;
+
+ /**
+ * initial offset while calculating input pixel location
+ */
+ WORD32 i4_init_offset;
+
+ /**
+ * increment to the centre pixel in horizontal direction
+ */
+ UWORD32 u4_horz_increment;
+
+ /**
+ * increment to the centre pixel in vertical direction
+ */
+ UWORD32 u4_vert_increment;
+
+ /**
+ * pointer to the filter coefficients
+ */
+ FILTER_COEFF_ARRAY pai1_filters;
+
+ /**
+ * function pointer to the leaf level function for horizontal scaling
+ */
+ FT_DOWNSCALER *pf_downscaler;
+
+ /**
+ * width of the input (highest SVC layer)
+ */
+ UWORD32 u4_in_wd;
+
+ /**
+ * height of the input (highest SVC layer)
+ */
+ UWORD32 u4_in_ht;
+
+} downscaler_state_t;
+
+static FORCEINLINE UWORD32 get_filter_phase(UWORD32 u4_center_pixel_pos)
+{
+ UWORD32 au4_phase_binning_pos[NUM_SCALER_FILTER_PHASES + 1];
+ UWORD32 i;
+
+ ASSERT(NUM_SCALER_FILTER_PHASES == 8);
+
+ for(i = 0; i < NUM_SCALER_FILTER_PHASES + 1; i++)
+ {
+ au4_phase_binning_pos[i] = (i << DOWNSCALER_Q) / NUM_SCALER_FILTER_PHASES;
+ }
+
+ u4_center_pixel_pos = u4_center_pixel_pos % (1 << DOWNSCALER_Q);
+
+ for(i = 0; i < NUM_SCALER_FILTER_PHASES; i++)
+ {
+ if((u4_center_pixel_pos < au4_phase_binning_pos[i + 1]) &&
+ (u4_center_pixel_pos >= au4_phase_binning_pos[i]))
+ {
+ return i;
+ }
+ }
+
+ ASSERT(0);
+
+ return 0;
+}
+
+/* SSE42 Declarations */
+extern FT_DOWNSCALER isvce_horizontal_downscale_and_transpose_sse42;
+
+/* NEON Declarations */
+extern FT_DOWNSCALER isvce_horizontal_downscale_and_transpose_neon;
+
+#endif
diff --git a/encoder/svc/isvce_encode.c b/encoder/svc/isvce_encode.c
new file mode 100644
index 0000000..25488ec
--- /dev/null
+++ b/encoder/svc/isvce_encode.c
@@ -0,0 +1,791 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_encode.c
+*
+* @brief
+* This file contains functions for encoding the input yuv frame in synchronous
+* api mode
+*
+* @author
+* ittiam
+*
+* List of Functions
+* - isvce_join_threads()
+* - isvce_wait_for_thread()
+* - isvce_encode()
+*
+******************************************************************************
+*/
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+/* Dependencies of ih264_buf_mgr.h */
+/* Dependencies of ih264_list.h */
+#include "ih264_error.h"
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_common_tables.h"
+#include "ih264_list.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+/* Dependencies of ih264e_structs.h */
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ime_statistics.h"
+#include "ime_structs.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_defs.h"
+#include "ih264e_structs.h"
+#include "ih264e_utils.h"
+#include "ime.h"
+#include "isvce.h"
+#include "isvce_cabac.h"
+#include "isvce_deblk.h"
+#include "isvce_defs.h"
+#include "isvce_downscaler.h"
+#include "isvce_encode_header.h"
+#include "isvce_fmt_conv.h"
+#include "isvce_ibl_eval.h"
+#include "isvce_ilp_mv.h"
+#include "isvce_intra_modes_eval.h"
+#include "isvce_me.h"
+#include "isvce_process.h"
+#include "isvce_rate_control.h"
+#include "isvce_residual_pred.h"
+#include "isvce_sub_pic_rc.h"
+#include "isvce_utils.h"
+
+#define SEI_BASED_FORCE_IDR 1
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief This function puts the current thread to sleep for a duration
+* of sleep_us
+*
+* @par Description
+* ithread_yield() method causes the calling thread to yield execution to
+*another thread that is ready to run on the current processor. The operating
+*system selects the thread to yield to. ithread_usleep blocks the current thread
+*for the specified number of milliseconds. In other words, yield just says, end
+*my timeslice prematurely, look around for other threads to run. If there is
+*nothing better than me, continue. Sleep says I don't want to run for x
+* milliseconds. Even if no other thread wants to run, don't make me run.
+*
+* @param[in] sleep_us
+* thread sleep duration
+*
+* @returns error_status
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_wait_for_thread(UWORD32 sleep_us)
+{
+ /* yield thread */
+ ithread_yield();
+
+ /* put thread to sleep */
+ ithread_sleep(sleep_us);
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* Encodes in synchronous api mode
+*
+* @par Description
+* This routine processes input yuv, encodes it and outputs bitstream and recon
+*
+* @param[in] ps_codec_obj
+* Pointer to codec object at API level
+*
+* @param[in] pv_api_ip
+* Pointer to input argument structure
+*
+* @param[out] pv_api_op
+* Pointer to output argument structure
+*
+* @returns Status
+*
+******************************************************************************
+*/
+WORD32 isvce_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ /* error status */
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+
+ /* codec ctxt */
+ isvce_codec_t *ps_codec = (isvce_codec_t *) ps_codec_obj->pv_codec_handle;
+
+ /* input frame to encode */
+ isvce_video_encode_ip_t *ps_video_encode_ip = pv_api_ip;
+
+ /* output buffer to write stream */
+ isvce_video_encode_op_t *ps_video_encode_op = pv_api_op;
+
+ /* i/o structures */
+ isvce_inp_buf_t s_inp_buf;
+ isvce_out_buf_t s_out_buf;
+
+ WORD32 ctxt_sel = 0, i4_rc_pre_enc_skip;
+ WORD32 i, j;
+
+ ASSERT(MAX_CTXT_SETS == 1);
+
+ /********************************************************************/
+ /* BEGIN INIT */
+ /********************************************************************/
+ /* reset output structure */
+ ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+ ps_video_encode_op->s_ive_op.output_present = 0;
+ ps_video_encode_op->s_ive_op.dump_recon = 0;
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
+
+ /* Check for output memory allocation size */
+ {
+ UWORD32 u4_min_bufsize =
+ isvce_get_min_outbuf_size(ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht,
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
+ UWORD32 u4_bufsize_per_layer = ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize /
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+
+ if(ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < u4_min_bufsize)
+ {
+ error_status = IH264E_INSUFFICIENT_OUTPUT_BUFFER;
+
+ SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+ }
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ s_out_buf.as_bits_buf[i] = ps_video_encode_ip->s_ive_ip.s_out_buf;
+
+ s_out_buf.as_bits_buf[i].u4_bufsize = u4_bufsize_per_layer;
+ s_out_buf.as_bits_buf[i].pv_buf =
+ ((UWORD8 *) ps_video_encode_ip->s_ive_ip.s_out_buf.pv_buf) +
+ u4_bufsize_per_layer * i;
+ }
+ }
+
+ s_out_buf.u4_is_last = 0;
+ s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
+ s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
+
+ /* api call cnt */
+ ps_codec->i4_encode_api_call_cnt += 1;
+
+ /* codec context selector */
+ ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+
+ /* reset status flags */
+ ps_codec->ai4_pic_cnt[ctxt_sel] = -1;
+ ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0;
+ ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0;
+
+ /* pass output buffer to codec */
+ ps_codec->as_out_buf[ctxt_sel] = s_out_buf;
+
+ /* initialize codec ctxt with default params for the first encode api call */
+ if(ps_codec->i4_encode_api_call_cnt == 0)
+ {
+ isvce_codec_init(ps_codec);
+ }
+
+ /* parse configuration params */
+ for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
+ {
+ isvce_cfg_params_t *ps_cfg = &ps_codec->as_cfg[i];
+
+ if(1 == ps_cfg->u4_is_valid)
+ {
+ if(((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
+ (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
+ ((WORD32) ps_cfg->u4_timestamp_high == -1) ||
+ ((WORD32) ps_cfg->u4_timestamp_low == -1))
+ {
+ error_status = isvce_codec_update_config(ps_codec, ps_cfg);
+ SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ ps_cfg->u4_is_valid = 0;
+ }
+ }
+ }
+ /* Force IDR based on SEI params */
+#if SEI_BASED_FORCE_IDR
+ {
+ sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params;
+ sei_mdcv_params_t *ps_cfg_sei_mdcv_params = &ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
+ sei_cll_params_t *ps_sei_cll_params = &ps_codec->s_sei.s_sei_cll_params;
+ sei_cll_params_t *ps_cfg_sei_cll_params = &ps_codec->s_cfg.s_sei.s_sei_cll_params;
+ sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params;
+ sei_ave_params_t *ps_cfg_sei_ave_params = &ps_codec->s_cfg.s_sei.s_sei_ave_params;
+
+ if((ps_sei_mdcv_params->au2_display_primaries_x[0] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) ||
+ (ps_sei_mdcv_params->au2_display_primaries_x[1] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_x[1]) ||
+ (ps_sei_mdcv_params->au2_display_primaries_x[2] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_x[2]) ||
+ (ps_sei_mdcv_params->au2_display_primaries_y[0] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_y[0]) ||
+ (ps_sei_mdcv_params->au2_display_primaries_y[1] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_y[1]) ||
+ (ps_sei_mdcv_params->au2_display_primaries_y[2] !=
+ ps_cfg_sei_mdcv_params->au2_display_primaries_y[2]) ||
+ (ps_sei_mdcv_params->u2_white_point_x != ps_cfg_sei_mdcv_params->u2_white_point_x) ||
+ (ps_sei_mdcv_params->u2_white_point_y != ps_cfg_sei_mdcv_params->u2_white_point_y) ||
+ (ps_sei_mdcv_params->u4_max_display_mastering_luminance !=
+ ps_cfg_sei_mdcv_params->u4_max_display_mastering_luminance) ||
+ (ps_sei_mdcv_params->u4_min_display_mastering_luminance !=
+ ps_cfg_sei_mdcv_params->u4_min_display_mastering_luminance))
+ {
+ ps_codec->s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
+ ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 1;
+ }
+ else
+ {
+ ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 0;
+ }
+
+ if((ps_sei_cll_params->u2_max_content_light_level !=
+ ps_cfg_sei_cll_params->u2_max_content_light_level) ||
+ (ps_sei_cll_params->u2_max_pic_average_light_level !=
+ ps_cfg_sei_cll_params->u2_max_pic_average_light_level))
+ {
+ ps_codec->s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
+ ps_codec->s_sei.u1_sei_cll_params_present_flag = 1;
+ }
+ else
+ {
+ ps_codec->s_sei.u1_sei_cll_params_present_flag = 0;
+ }
+
+ if((ps_sei_ave_params->u4_ambient_illuminance !=
+ ps_cfg_sei_ave_params->u4_ambient_illuminance) ||
+ (ps_sei_ave_params->u2_ambient_light_x != ps_cfg_sei_ave_params->u2_ambient_light_x) ||
+ (ps_sei_ave_params->u2_ambient_light_y != ps_cfg_sei_ave_params->u2_ambient_light_y))
+ {
+ ps_codec->s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
+ ps_codec->s_sei.u1_sei_ave_params_present_flag = 1;
+ }
+ else
+ {
+ ps_codec->s_sei.u1_sei_ave_params_present_flag = 0;
+ }
+
+ if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) ||
+ (1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) ||
+ (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag))
+ {
+ ps_codec->force_curr_frame_type = IV_IDR_FRAME;
+ }
+ }
+#endif
+
+ /* In case of alt ref and B pics we will have non reference frame in stream */
+ if(ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes)
+ {
+ ps_codec->i4_non_ref_frames_in_stream = 1;
+ }
+
+ if(ps_codec->i4_encode_api_call_cnt == 0)
+ {
+ /********************************************************************/
+ /* number of mv/ref bank buffers used by the codec, */
+ /* 1 to handle curr frame */
+ /* 1 to store information of ref frame */
+ /* 1 more additional because of the codec employs 2 ctxt sets */
+ /* to assist asynchronous API */
+ /********************************************************************/
+
+ /* initialize mv bank buffer manager */
+ error_status = isvce_svc_au_data_mgr_add_bufs(ps_codec);
+
+ SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ /* initialize ref bank buffer manager */
+ error_status = isvce_svc_au_buf_mgr_add_bufs(ps_codec);
+
+ SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ /* for the first frame, generate header when not requested explicitly */
+ if(ps_codec->i4_header_mode == 0 && ps_codec->u4_header_generated == 0)
+ {
+ ps_codec->i4_gen_header = 1;
+ }
+ }
+
+ /* generate header and return when encoder is operated in header mode */
+ if(ps_codec->i4_header_mode == 1)
+ {
+ /* whenever the header is generated, this implies a start of sequence
+ * and a sequence needs to be started with IDR
+ */
+ ps_codec->force_curr_frame_type = IV_IDR_FRAME;
+
+ s_inp_buf.s_svc_params = ps_codec->s_cfg.s_svc_params;
+ s_inp_buf.s_inp_props.s_raw_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
+ s_inp_buf.s_inp_props.s_raw_buf.au4_wd[Y] = ps_codec->s_cfg.u4_wd;
+ s_inp_buf.s_inp_props.s_raw_buf.au4_ht[Y] = ps_codec->s_cfg.u4_ht;
+
+ isvce_init_svc_dimension(&s_inp_buf);
+
+ /* generate header */
+ error_status = isvce_generate_sps_pps(ps_codec, &s_inp_buf);
+
+ /* send the input to app */
+ ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
+ ps_video_encode_op->s_ive_op.u4_timestamp_low =
+ ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
+ ps_video_encode_op->s_ive_op.u4_timestamp_high =
+ ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
+
+ ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
+
+ /* send the output to app */
+ ps_video_encode_op->s_ive_op.output_present = 1;
+ ps_video_encode_op->s_ive_op.dump_recon = 0;
+ ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].as_bits_buf[0];
+
+ for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ memmove(((UWORD8 *) ps_video_encode_op->s_ive_op.s_out_buf.pv_buf +
+ ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes),
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].pv_buf,
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes);
+
+ ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes +=
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes;
+ }
+
+ /* error status */
+ SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ /* indicates that header has been generated previously */
+ ps_codec->u4_header_generated = 1;
+
+ /* api call cnt */
+ ps_codec->i4_encode_api_call_cnt--;
+
+ /* header mode tag is not sticky */
+ ps_codec->i4_header_mode = 0;
+ ps_codec->i4_gen_header = 0;
+
+ return IV_SUCCESS;
+ }
+
+ /* curr pic cnt */
+ ps_codec->i4_pic_cnt += 1;
+
+ i4_rc_pre_enc_skip = 0;
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ i4_rc_pre_enc_skip =
+ isvce_input_queue_update(ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf, i);
+ }
+
+ s_out_buf.u4_is_last = s_inp_buf.s_inp_props.u4_is_last;
+ ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.s_inp_props.u4_is_last;
+
+ /* Only encode if the current frame is not pre-encode skip */
+ if(!i4_rc_pre_enc_skip && s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
+ {
+ isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS];
+
+ WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
+
+ ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
+
+ error_status = isvce_svc_au_init(ps_codec, &s_inp_buf);
+
+ SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ isvce_nalu_info_au_init(ps_codec->as_nalu_descriptors,
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
+
+#if ENABLE_MODE_STAT_VISUALISER
+ isvce_msv_get_input_frame(ps_codec->ps_mode_stat_visualiser, &s_inp_buf);
+#endif
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ isvce_svc_layer_pic_init(ps_codec, &s_inp_buf, i);
+
+ for(j = 0; j < num_thread_cnt; j++)
+ {
+ ithread_create(ps_codec->apv_proc_thread_handle[j], NULL, isvce_process_thread,
+ &ps_codec->as_process[j + 1]);
+
+ ps_codec->ai4_process_thread_created[j] = 1;
+
+ ps_codec->i4_proc_thread_cnt++;
+ }
+
+ /* launch job */
+ isvce_process_thread(ps_proc);
+
+ /* Join threads at the end of encoding a frame */
+ isvce_join_threads(ps_codec);
+
+ ih264_list_reset(ps_codec->pv_proc_jobq);
+
+ ih264_list_reset(ps_codec->pv_entropy_jobq);
+ }
+
+#if ENABLE_MODE_STAT_VISUALISER
+ isvce_msv_dump_visualisation(ps_codec->ps_mode_stat_visualiser);
+#endif
+
+ isvce_sub_pic_rc_dump_data(ps_codec->as_process->ps_sub_pic_rc_ctxt);
+ }
+
+ /****************************************************************************
+ * RECON
+ * Since we have forward dependent frames, we cannot return recon in
+ *encoding order. It must be in poc order, or input pic order. To achieve this
+ *we introduce a delay of 1 to the recon wrt encode. Now since we have that
+ * delay, at any point minimum of pic_cnt in our ref buffer will be the
+ * correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
+ * will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
+ * encoding 4, the min in the list will be 1. After encoding 2, it will be
+ * 2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
+ * that the 1 delay is critical. Hence if we have post enc skip, we must
+ * skip here too. Note that since post enc skip already frees the recon
+ * buffer we need not do any thing here
+ *
+ * We need to return a recon when ever we consume an input buffer. This
+ * comsumption include a pre or post enc skip. Thus dump recon is set for
+ * all cases except when
+ * 1) We are waiting -> ps_codec->i4_pic_cnt >
+ *ps_codec->s_cfg.u4_num_bframe An exception need to be made for the case when
+ *we have the last buffer since we need to flush out the on remainig recon.
+ ****************************************************************************/
+
+ ps_video_encode_op->s_ive_op.dump_recon = 0;
+
+ if(ps_codec->s_cfg.u4_enable_recon &&
+ ((ps_codec->i4_pic_cnt > (WORD32) ps_codec->s_cfg.u4_num_bframes) ||
+ s_inp_buf.s_inp_props.u4_is_last))
+ {
+ /* error status */
+ IH264_ERROR_T ret = IH264_SUCCESS;
+
+ svc_au_buf_t *ps_pic_buf = NULL;
+
+ WORD32 i4_buf_status, i4_curr_poc = 32768;
+
+ /* In case of skips we return recon, but indicate that buffer is zero size
+ */
+ if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel] || i4_rc_pre_enc_skip)
+ {
+ ps_video_encode_op->s_ive_op.dump_recon = 1;
+ ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
+ ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
+ }
+ else
+ {
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1) continue;
+
+ i4_buf_status = ih264_buf_mgr_get_status(
+ ps_codec->pv_ref_buf_mgr, ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if((i4_buf_status & BUF_MGR_IO) && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
+ {
+ ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
+ i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
+ }
+ }
+
+ ps_video_encode_op->s_ive_op.s_recon_buf = ps_video_encode_ip->s_ive_ip.s_recon_buf;
+
+ /*
+ * If we get a valid buffer. output and free recon.
+ *
+ * we may get an invalid buffer if num_b_frames is 0. This is because
+ * We assume that there will be a ref frame in ref list after encoding
+ * the last frame. With B frames this is correct since its forward ref
+ * pic will be in the ref list. But if num_b_frames is 0, we will not
+ * have a forward ref pic
+ */
+
+ if(ps_pic_buf)
+ {
+ if((ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[Y] !=
+ ps_codec->s_cfg.u4_disp_wd) ||
+ (ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_ht[Y] !=
+ ps_codec->s_cfg.u4_disp_ht))
+ {
+ SET_ERROR_ON_RETURN(IH264E_NO_FREE_RECONBUF, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+ }
+
+ isvce_fmt_conv(ps_codec, ps_pic_buf,
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1], 0,
+ ps_codec->s_cfg.u4_disp_ht);
+
+ ps_video_encode_op->s_ive_op.dump_recon = 1;
+
+ ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_pic_buf->i4_buf_id,
+ BUF_MGR_IO);
+
+ if(IH264_SUCCESS != ret)
+ {
+ SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+ }
+ }
+ }
+ }
+
+ /***************************************************************************
+ * Free reference buffers:
+ * In case of a post enc skip, we have to ensure that those pics will not
+ * be used as reference anymore. In all other cases we will not even mark
+ * the ref buffers
+ ***************************************************************************/
+ if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
+ {
+ /* pic info */
+ svc_au_buf_t *ps_cur_pic;
+
+ /* mv info */
+ svc_au_data_t *ps_cur_mv_buf;
+
+ /* error status */
+ IH264_ERROR_T ret = IH264_SUCCESS;
+
+ /* Decrement coded pic count */
+ ps_codec->i4_poc--;
+
+ /* loop through to get the min pic cnt among the list of pics stored in ref
+ * list */
+ /* since the skipped frame may not be on reference list, we may not have an
+ * MV bank hence free only if we have allocated */
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
+ {
+ ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
+
+ ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_svc_au_data;
+
+ /* release this frame from reference list and recon list */
+ ret = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
+ ps_cur_mv_buf->i4_buf_id, BUF_MGR_REF);
+ ret |= ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
+ ps_cur_mv_buf->i4_buf_id, BUF_MGR_IO);
+ SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+
+ ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
+ BUF_MGR_REF);
+ ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
+ BUF_MGR_IO);
+ SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+ break;
+ }
+ }
+ }
+
+ /*
+ * Since recon is not in sync with output, ie there can be frame to be
+ * given back as recon even after last output. Hence we need to mark that
+ * the output is not the last.
+ * Hence search through reflist and mark appropriately
+ */
+ if(ps_codec->s_cfg.u4_enable_recon)
+ {
+ WORD32 i4_buf_status = 0;
+
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1) continue;
+
+ i4_buf_status |= ih264_buf_mgr_get_status(
+ ps_codec->pv_ref_buf_mgr, ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+ }
+
+ if(i4_buf_status & BUF_MGR_IO)
+ {
+ s_out_buf.u4_is_last = 0;
+ ps_video_encode_op->s_ive_op.u4_is_last = 0;
+ }
+ }
+
+ /**************************************************************************
+ * Signaling to APP
+ * 1) If we valid a valid output mark it so
+ * 2) Set the codec output ps_video_encode_op
+ * 3) Set the error status
+ * 4) Set the return Pic type
+ * Note that we already has marked recon properly
+ * 5)Send the consumed input back to app so that it can free it if possible
+ *
+ * We will have to return the output and input buffers unconditionally
+ * so that app can release them
+ **************************************************************************/
+ if(!i4_rc_pre_enc_skip && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel] &&
+ s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
+ {
+ /* receive output back from codec */
+ s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+
+ /* send the output to app */
+ ps_video_encode_op->s_ive_op.output_present = 1;
+ ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+
+ /* Set the time stamps of the encodec input */
+ ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.s_inp_props.u4_timestamp_low;
+ ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.s_inp_props.u4_timestamp_high;
+
+ switch(ps_codec->pic_type)
+ {
+ case PIC_IDR:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_IDR_FRAME;
+ break;
+
+ case PIC_I:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
+ break;
+
+ case PIC_P:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
+ break;
+
+ case PIC_B:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
+ break;
+
+ default:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
+ break;
+ }
+
+ for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
+ {
+ error_status = ps_codec->as_process[ctxt_sel + i].i4_error_code;
+ SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
+ }
+ }
+ else
+ {
+ /* receive output back from codec */
+ s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+
+ ps_video_encode_op->s_ive_op.output_present = 0;
+ ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+
+ /* Set the time stamps of the encodec input */
+ ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
+ ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
+
+ ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_inp_props.s_raw_buf;
+
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
+ }
+
+ /* Send the input to encoder so that it can free it if possible */
+ ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].as_bits_buf[0];
+
+ for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ memmove(((UWORD8 *) ps_video_encode_op->s_ive_op.s_out_buf.pv_buf +
+ ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes),
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].pv_buf,
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes);
+
+ ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes +=
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes;
+ }
+
+ if(ps_codec->s_cfg.b_nalu_info_export_enable && !i4_rc_pre_enc_skip &&
+ !ps_codec->s_rate_control.post_encode_skip[ctxt_sel] &&
+ s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
+ {
+ ps_video_encode_op->b_is_nalu_info_present = true;
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ isvce_nalu_info_csv_translator(&ps_codec->as_nalu_descriptors[i],
+ &ps_video_encode_ip->ps_nalu_info_buf[i]);
+
+ ps_video_encode_op->ps_nalu_info_buf[i] = ps_video_encode_ip->ps_nalu_info_buf[i];
+ }
+ }
+ else
+ {
+ ps_video_encode_op->b_is_nalu_info_present = false;
+ }
+
+ ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_inp_props.s_raw_buf;
+
+ return IV_SUCCESS;
+}
diff --git a/encoder/svc/isvce_encode.h b/encoder/svc/isvce_encode.h
new file mode 100644
index 0000000..45ac760
--- /dev/null
+++ b/encoder/svc/isvce_encode.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_encode.h
+*
+* @brief
+* Contains functions for encode API
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_ENCODE_H_
+#define _ISVCE_ENCODE_H_
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+
+extern WORD32 isvce_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op);
+
+#endif
diff --git a/encoder/svc/isvce_encode_header.c b/encoder/svc/isvce_encode_header.c
new file mode 100644
index 0000000..8d12535
--- /dev/null
+++ b/encoder/svc/isvce_encode_header.c
@@ -0,0 +1,2127 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_encode_header.c
+*
+* @brief
+* This file contains function definitions related to header encoding.
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_generate_sps()
+* - isvce_generate_pps()
+* - isvce_generate_slice_header()
+* - isvce_populate_sps()
+* - isvce_populate_pps()
+* - isvce_populate_slice_header()
+*
+*******************************************************************************
+*/
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+
+#include "ih264e_bitstream.h"
+
+#include "isvce_encode_header.h"
+#include "isvce_utils.h"
+
+static FORCEINLINE IH264E_ERROR_T isvce_generate_nal_unit_header(bitstrm_t *ps_bitstrm,
+ WORD32 nal_unit_type,
+ WORD32 nal_ref_idc)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ if(!((nal_unit_type > 0) && (nal_unit_type < 32)))
+ {
+ return IH264E_FAIL;
+ }
+
+ /* forbidden_zero_bit + nal_ref_idc + nal_unit_type */
+ PUT_BITS(ps_bitstrm, ((nal_ref_idc << 5) + nal_unit_type),
+ (1 + 2 + 5), /*1 forbidden zero bit + 2 nal_ref_idc + 5 nal_unit_type */
+ return_status, "nal_unit_header");
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates SPS (Sequence Parameter Set)
+*
+* @par Description
+* This function generates Sequence Parameter Set header as per the spec
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_sps
+* pointer to structure containing SPS data
+*
+* @param[in] ps_vui
+* pointer to structure containing VUI data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps, NAL_UNIT_TYPE_T nal_type)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ WORD32 i;
+ WORD8 i1_nal_ref_idc = 3;
+ vui_t *ps_vui = &ps_sps->s_vui_parameters;
+
+ /* Insert Start Code */
+ return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+ /* Insert Nal Unit Header */
+ return_status = isvce_generate_nal_unit_header(ps_bitstrm, nal_type, i1_nal_ref_idc);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+
+ /* profile_idc */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_profile_idc, 8, return_status, "profile_idc");
+
+ /* constrained_set_flags */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set0_flag, 1, return_status,
+ "constrained_set0_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set1_flag, 1, return_status,
+ "constrained_set1_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set2_flag, 1, return_status,
+ "constrained_set2_flag");
+ PUT_BITS(ps_bitstrm, ps_sps->u1_constraint_set3_flag, 1, return_status,
+ "constrained_set3_flag");
+
+ /* reserved_zero_four_bits */
+ PUT_BITS(ps_bitstrm, 0, 4, return_status, "reserved_zero_four_bits");
+
+ /* level_idc */
+ PUT_BITS(ps_bitstrm, ps_sps->u1_level_idc, 8, return_status, "level_idc");
+
+ /* seq_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_sps_id, return_status, "seq_parameter_set_id");
+
+ if((ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE) ||
+ (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH))
+ {
+ /* chroma_format_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_chroma_format_idc, return_status, "chroma_format_idc");
+
+ if(ps_sps->u1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
+ {
+ /* i1_residual_colour_transform_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_residual_colour_transform_flag, 1, return_status,
+ "i1_residual_colour_transform_flag");
+ }
+
+ /* bit_depth_luma_minus8 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_luma - 8), return_status,
+ "bit_depth_luma_minus8");
+
+ /* bit_depth_chroma_minus8 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_bit_depth_chroma - 8), return_status,
+ "bit_depth_chroma_minus8");
+
+ /* qpprime_y_zero_transform_bypass_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_qpprime_y_zero_transform_bypass_flag, 1, return_status,
+ "qpprime_y_zero_transform_bypass_flag");
+
+ /* seq_scaling_matrix_present_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_seq_scaling_matrix_present_flag, 1, return_status,
+ "seq_scaling_matrix_present_flag");
+
+ /* seq_scaling_list */
+ if(ps_sps->i1_seq_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+ }
+
+ /* log2_max_frame_num_minus4 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_frame_num - 4), return_status,
+ "log2_max_frame_num_minus4");
+
+ /* pic_order_cnt_type */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i1_pic_order_cnt_type, return_status, "pic_order_cnt_type");
+
+ if(ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ PUT_BITS_UEV(ps_bitstrm, (ps_sps->i1_log2_max_pic_order_cnt_lsb - 4), return_status,
+ "log2_max_pic_order_cnt_lsb_minus4");
+ }
+ else if(ps_sps->i1_pic_order_cnt_type == 1)
+ {
+ /* delta_pic_order_always_zero_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_delta_pic_order_always_zero_flag, 1, return_status,
+ "delta_pic_order_always_zero_flag");
+
+ /* offset_for_non_ref_pic */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_non_ref_pic, return_status,
+ "offset_for_non_ref_pic");
+
+ /* offset_for_top_to_bottom_field */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->i4_offset_for_top_to_bottom_field, return_status,
+ "offset_for_top_to_bottom_field");
+
+ /* num_ref_frames_in_pic_order_cnt_cycle */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle, return_status,
+ "num_ref_frames_in_pic_order_cnt_cycle");
+
+ /* Offset for ref frame */
+ for(i = 0; i < ps_sps->u1_num_ref_frames_in_pic_order_cnt_cycle; i++)
+ {
+ /* offset_for_ref_frame */
+ PUT_BITS_SEV(ps_bitstrm, ps_sps->ai4_offset_for_ref_frame[i], return_status,
+ "offset_for_ref_frame");
+ }
+ }
+
+ /* num_ref_frames */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->u1_max_num_ref_frames, return_status, "num_ref_frames");
+
+ /* gaps_in_frame_num_value_allowed_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_gaps_in_frame_num_value_allowed_flag, 1, return_status,
+ "gaps_in_frame_num_value_allowed_flag");
+
+ /* pic_width_in_mbs_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_width_in_mbs_minus1, return_status,
+ "pic_width_in_mbs_minus1");
+
+ /* pic_height_in_map_units_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_pic_height_in_map_units_minus1, return_status,
+ "pic_height_in_map_units_minus1");
+
+ /* frame_mbs_only_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_frame_mbs_only_flag, 1, return_status, "frame_mbs_only_flag");
+
+ if(!ps_sps->i1_frame_mbs_only_flag)
+ {
+ /* mb_adaptive_frame_field_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_mb_adaptive_frame_field_flag, 1, return_status,
+ "mb_adaptive_frame_field_flag");
+ }
+
+ /* direct_8x8_inference_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_direct_8x8_inference_flag, 1, return_status,
+ "direct_8x8_inference_flag");
+
+ /* frame_cropping_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_frame_cropping_flag, 1, return_status, "frame_cropping_flag");
+
+ if(ps_sps->i1_frame_cropping_flag)
+ {
+ /* frame_crop_left_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_left_offset, return_status,
+ "frame_crop_left_offset");
+
+ /* frame_crop_right_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_right_offset, return_status,
+ "frame_crop_right_offset");
+
+ /* frame_crop_top_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_top_offset, return_status,
+ "frame_crop_top_offset");
+
+ /* frame_crop_bottom_offset */
+ PUT_BITS_UEV(ps_bitstrm, ps_sps->i2_frame_crop_bottom_offset, return_status,
+ "frame_crop_bottom_offset");
+ }
+
+ /* vui_parameters_present_flag */
+ PUT_BITS(ps_bitstrm, ps_sps->i1_vui_parameters_present_flag, 1, return_status,
+ "vui_parameters_present_flag");
+
+ if(ps_sps->i1_vui_parameters_present_flag)
+ {
+ /* Add vui parameters to the bitstream */;
+ return_status = ih264e_generate_vui(ps_bitstrm, ps_vui);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+ }
+
+ if(nal_type != NAL_SUBSET_SPS)
+ {
+ /* rbsp trailing bits */
+ return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+ }
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates PPS (Picture Parameter Set)
+*
+* @par Description
+* Generate Picture Parameter Set as per Section 7.3.2.2
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_pps
+* pointer to structure containing PPS data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* Insert the NAL start code */
+ return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+
+ /* Insert Nal Unit Header */
+ PUT_BITS(ps_bitstrm, NAL_PPS_FIRST_BYTE, 8, return_status, "pps_header");
+
+ /* pic_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_pps_id, return_status, "pic_parameter_set_id");
+
+ /* seq_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_sps_id, return_status, "seq_parameter_set_id");
+
+ /* Entropy coding : 0-VLC; 1 - CABAC */
+ PUT_BITS(ps_bitstrm, ps_pps->u1_entropy_coding_mode_flag, 1, return_status,
+ "Entropy coding : 0-VLC; 1 - CABAC");
+
+ /* Pic order present flag */
+ PUT_BITS(ps_bitstrm, ps_pps->u1_pic_order_present_flag, 1, return_status,
+ "Pic order present flag");
+
+ /* Number of slice groups */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->u1_num_slice_groups - 1, return_status,
+ "Number of slice groups");
+
+ if(ps_pps->u1_num_slice_groups > 1)
+ {
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit
+ * stream*/
+ }
+
+ /* num_ref_idx_l0_default_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l0_default_active - 1, return_status,
+ "num_ref_idx_l0_default_active_minus1");
+
+ /* num_ref_idx_l1_default_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_pps->i1_num_ref_idx_l1_default_active - 1, return_status,
+ "num_ref_idx_l1_default_active_minus1");
+
+ /* weighted_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_pred_flag, 1, return_status, "weighted_pred_flag");
+
+ /* weighted_bipred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_weighted_bipred_idc, 2, return_status, "weighted_bipred_idc");
+
+ /* pic_init_qp_minus26 */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qp - 26, return_status, "pic_init_qp_minus26");
+
+ /* pic_init_qs_minus26 */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_pic_init_qs - 26, return_status, "pic_init_qs_minus26");
+
+ /* chroma_qp_index_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_chroma_qp_index_offset, return_status,
+ "chroma_qp_index_offset");
+
+ /* deblocking_filter_control_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_deblocking_filter_control_present_flag, 1, return_status,
+ "deblocking_filter_control_present_flag");
+
+ /* constrained_intra_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_constrained_intra_pred_flag, 1, return_status,
+ "constrained_intra_pred_flag");
+
+ /*redundant_pic_cnt_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_redundant_pic_cnt_present_flag, 1, return_status,
+ "redundant_pic_cnt_present_flag");
+
+ if(ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH)
+ {
+ /* transform_8x8_mode_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_transform_8x8_mode_flag, 1, return_status,
+ "transform_8x8_mode_flag");
+
+ /* pic_scaling_matrix_present_flag */
+ PUT_BITS(ps_bitstrm, ps_pps->i1_pic_scaling_matrix_present_flag, 1, return_status,
+ "pic_scaling_matrix_present_flag");
+
+ if(ps_pps->i1_pic_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+
+ /* Second chroma QP offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_pps->i1_second_chroma_qp_index_offset, return_status,
+ "Second chroma QP offset");
+ }
+
+ return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Generates Slice Header
+*
+* @par Description
+* Generate Slice Header as per Section 7.3.5.1
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context for generating slice header
+*
+* @param[in] ps_slice_hdr
+* pointer to slice header params
+*
+* @param[in] ps_pps
+* pointer to pps params referred by slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by slice
+*
+* @param[out] ps_dup_bit_strm_ent_offset
+* Bitstream struct to store bitstream state
+*
+* @param[out] pu4_first_slice_start_offset
+* first slice offset is returned
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_slice_header(bitstrm_t *ps_bitstrm, slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_idr_flag)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ UWORD8 u1_slice_type;
+
+ /* Insert start code */
+ return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+ /* Insert Nal Unit Header */
+ return_status = isvce_generate_nal_unit_header(ps_bitstrm, ps_slice_hdr->i1_nal_unit_type,
+ ps_slice_hdr->i1_nal_unit_idc);
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+ /* first_mb_in_slice */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status,
+ "first_mb_in_slice");
+
+ /* slice_type */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "slice_type");
+
+ /* pic_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "pic_parameter_set_id");
+
+ /* frame_num */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status,
+ "frame_num");
+
+ if(!ps_sps->i1_frame_mbs_only_flag)
+ {
+ /* field_pic_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status, "field_pic_flag");
+
+ if(ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* bottom_field_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status,
+ "bottom_field_flag");
+ }
+ }
+
+ if(u1_idr_flag == 1)
+ {
+ /* u2_idr_pic_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "idr_pic_id");
+ }
+
+ if(ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ /* pic_order_cnt_lsb */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_pic_order_cnt_lsb,
+ ps_sps->i1_log2_max_pic_order_cnt_lsb, return_status, "pic_order_cnt_lsb");
+
+ if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt_bottom */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status,
+ "delta_pic_order_cnt_bottom");
+ }
+ }
+
+ if(ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
+ {
+ /* delta_pic_order_cnt[0] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status,
+ "delta_pic_order_cnt[0]");
+
+ if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt[1] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status,
+ "delta_pic_order_cnt[1]");
+ }
+ }
+
+ if(ps_pps->i1_redundant_pic_cnt_present_flag)
+ {
+ /* redundant_pic_cnt */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status,
+ "redundant_pic_cnt");
+ }
+
+ u1_slice_type = ps_slice_hdr->u1_slice_type % EPSLICE;
+
+ if(u1_slice_type == BSLICE)
+ {
+ /* direct_spatial_mv_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status,
+ "direct_spatial_mv_pred_flag");
+ }
+
+ if(u1_slice_type == PSLICE || u1_slice_type == SPSLICE || u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_active_override_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1, return_status,
+ "num_ref_idx_active_override_flag");
+
+ if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
+ {
+ /* num_ref_idx_l0_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status,
+ "num_ref_idx_l0_active_minus1");
+
+ if(u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_l1_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1, return_status,
+ "num_ref_idx_l1_active_minus1");
+ }
+ }
+ }
+
+ /* ref_pic_list_modification */
+ if((u1_slice_type != ISLICE) && (u1_slice_type != SISLICE))
+ {
+ /* ref_pic_list_modification_flag_l0 */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0, 1,
+ return_status, "ref_pic_list_modification_flag_l0");
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
+ {
+ UWORD8 i = 0;
+
+ WORD8 *pi1_modification_of_pic_nums_idc_l0 =
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0;
+ UWORD32 *pu4_abs_diff_pic_num_minus1_l0 =
+ ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0;
+ UWORD8 *pu1_long_term_pic_num_l0 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l0;
+
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l0[i], return_status,
+ "modification_of_pic_nums_idc");
+
+ if((0 == pi1_modification_of_pic_nums_idc_l0[i]) ||
+ (1 == pi1_modification_of_pic_nums_idc_l0[i]))
+ {
+ /* abs_diff_pic_num_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l0[0], return_status,
+ "abs_diff_pic_num_minus1");
+
+ pu4_abs_diff_pic_num_minus1_l0++;
+ }
+ else if(2 == pi1_modification_of_pic_nums_idc_l0[i])
+ {
+ /* long_term_pic_num */
+ PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l0[0], return_status,
+ "abs_diff_pic_num_minus1");
+
+ pu1_long_term_pic_num_l0++;
+ }
+ } while(pi1_modification_of_pic_nums_idc_l0[i++] != 3);
+ }
+ }
+
+ if(u1_slice_type == BSLICE)
+ {
+ /* ref_pic_list_modification_flag_l1 */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1, 1,
+ return_status, "ref_pic_list_modification_flag_l1");
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
+ {
+ UWORD8 i = 0;
+
+ WORD8 *pi1_modification_of_pic_nums_idc_l1 =
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l1;
+ UWORD32 *pu4_abs_diff_pic_num_minus1_l1 =
+ ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l1;
+ UWORD8 *pu1_long_term_pic_num_l1 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l1;
+
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l1[i], return_status,
+ "modification_of_pic_nums_idc");
+
+ if((0 == pi1_modification_of_pic_nums_idc_l1[i]) ||
+ (1 == pi1_modification_of_pic_nums_idc_l1[i]))
+ {
+ /* abs_diff_pic_num_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l1[0], return_status,
+ "abs_diff_pic_num_minus1");
+
+ pu4_abs_diff_pic_num_minus1_l1++;
+ }
+ else if(2 == pi1_modification_of_pic_nums_idc_l1[i])
+ {
+ /* long_term_pic_num */
+ PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l1[0], return_status,
+ "abs_diff_pic_num_minus1");
+
+ pu1_long_term_pic_num_l1++;
+ }
+ } while(pi1_modification_of_pic_nums_idc_l1[i++] != 3);
+ }
+ }
+
+ if((ps_pps->i1_weighted_pred_flag && u1_slice_type == PSLICE) ||
+ (u1_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
+ {
+ /* TODO_LATER: Currently there is no support for weighted prediction.
+ This needs to be updated when the support is added */
+ }
+
+ if(ps_slice_hdr->i1_nal_unit_idc != 0)
+ {
+ if(u1_idr_flag == 1)
+ {
+ /* no_output_of_prior_pics_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag, 1, return_status,
+ "no_output_of_prior_pics_flag ");
+
+ /* long_term_reference_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag, 1, return_status,
+ "long_term_reference_flag ");
+ }
+ else
+ {
+ /* adaptive_ref_pic_marking_mode_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
+ return_status, "adaptive_ref_pic_marking_mode_flag ");
+
+ if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
+ {
+ /* TODO: if the reference picture marking mode is adaptive
+ add these fields in the bit-stream */
+ }
+ }
+ }
+
+ if(ps_slice_hdr->u1_entropy_coding_mode_flag && u1_slice_type != ISLICE &&
+ u1_slice_type != SISLICE)
+ {
+ /* cabac_init_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status, "cabac_init_idc");
+ }
+
+ /* slice_qp_delta */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status,
+ "slice_qp_delta");
+
+ if(ps_slice_hdr->u1_slice_type == SPSLICE || ps_slice_hdr->u1_slice_type == SISLICE)
+ {
+ if(ps_slice_hdr->u1_slice_type == SPSLICE)
+ {
+ /* sp_for_switch_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_sp_for_switch_flag, 1, return_status,
+ "sp_for_switch_flag");
+ }
+ /* slice_qs_delta */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->u1_slice_qs - ps_pps->i1_pic_init_qs, return_status,
+ "slice_qs_delta");
+ }
+
+ if(ps_pps->i1_deblocking_filter_control_present_flag)
+ {
+ /* disable_deblocking_filter_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status,
+ "disable_deblocking_filter_idc");
+
+ if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status,
+ "slice_alpha_c0_offset_div2");
+
+ /* slice_beta_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status,
+ "slice_beta_offset_div2");
+ }
+ }
+
+ if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
+ ps_pps->u1_slice_group_map_type <= 5)
+ {
+ /* slice_group_change_cycle */
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit
+ * stream */
+ }
+
+ return return_status;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates VUI structure
+*
+* @par Description
+* Populates VUI structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+static IH264E_ERROR_T isvce_populate_vui(isvce_codec_t *ps_codec, sps_t *ps_sps)
+{
+ vui_t *ps_vui = &ps_sps->s_vui_parameters;
+
+ ps_vui->u1_nal_hrd_parameters_present_flag = 0;
+ ps_vui->u1_vcl_hrd_parameters_present_flag = 0;
+
+ ps_vui->u1_bitstream_restriction_flag = 1;
+ ps_vui->u1_motion_vectors_over_pic_boundaries_flag = 1;
+ ps_vui->u1_max_bytes_per_pic_denom = 0;
+ ps_vui->u1_max_bits_per_mb_denom = 0;
+ ps_vui->u1_log2_max_mv_length_horizontal = 16;
+ ps_vui->u1_log2_max_mv_length_vertical = 16;
+
+ if(ps_codec->s_cfg.u4_num_bframes == 0)
+ {
+ ps_vui->u1_num_reorder_frames = 0;
+ }
+ else
+ {
+ ps_vui->u1_num_reorder_frames = 1;
+ }
+
+ ps_vui->u1_max_dec_frame_buffering = ps_sps->u1_max_num_ref_frames;
+
+ return 0;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates sps structure
+*
+* @par Description
+* Populates sps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_sps
+* pointer to sps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_populate_sps(isvce_codec_t *ps_codec, sps_t *ps_sps, UWORD8 u1_sps_id,
+ UWORD8 u1_profile_idc, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id)
+{
+ /* active config parameters */
+ isvce_cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
+
+ // /* level */
+ // IH264_LEVEL_T level_idc;
+
+ /* error_status */
+ IH264E_ERROR_T i4_err_code = IH264E_FAIL;
+
+ /* profile */
+ /*
+ * Baseline profile supports, 8 bits per sample, 4:2:0 format, CAVLC.
+ * B frames are not allowed. Further, Flexible mb ordering, Redundant slices,
+ * Arbitrary slice ordering are supported. The constrained baseline profile is
+ * baseline profile minus ASO, FMO and redundant slices. To the constrained
+ * baseline profile if we add support for B slices, support for encoding
+ * interlaced frames, support for weighted prediction and introduce CABAC
+ * entropy coding then we have Main Profile.
+ */
+ ps_sps->u1_profile_idc = u1_profile_idc;
+
+ /* level */
+ ps_sps->u1_level_idc = MAX(
+ ps_cfg->u4_max_level, (UWORD32) ih264e_get_min_level(ps_cfg->u4_max_wd, ps_cfg->u4_max_ht));
+
+ /* constrained flags */
+ /*
+ * baseline profile automatically implies set 0 flag
+ */
+ ps_sps->u1_constraint_set0_flag = (ps_sps->u1_profile_idc == IH264_PROFILE_BASELINE);
+ /*
+ * main profile automatically implies set 1 flag
+ * Although the encoder says it supports Baseline profile it actually supports
+ * constrained baseline profile as ASO, FMO and redundant slices are not
+ * supported
+ */
+ ps_sps->u1_constraint_set1_flag = (ps_sps->u1_profile_idc <= IH264_PROFILE_MAIN);
+ /*
+ * extended profile is not supported
+ */
+ ps_sps->u1_constraint_set2_flag = 0x00;
+ /*
+ * level 1b or level 11
+ */
+ if(ps_sps->u1_level_idc == IH264_LEVEL_1B)
+ {
+ ps_sps->u1_constraint_set3_flag = 0;
+ ps_sps->u1_level_idc = IH264_LEVEL_11;
+ }
+ else
+ {
+ ps_sps->u1_constraint_set3_flag = 0;
+ }
+
+ /* active sps id */
+ ps_sps->u1_sps_id = u1_sps_id;
+
+ if((ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE) ||
+ (ps_sps->u1_profile_idc >= IH264_PROFILE_HIGH))
+ {
+ /* chroma format idc */
+ ps_sps->u1_chroma_format_idc = CHROMA_FMT_IDC_YUV420;
+
+ /* residual_colour_transform_flag */
+ ps_sps->i1_residual_colour_transform_flag = 0;
+
+ /* luma bit depth 8 */
+ ps_sps->i1_bit_depth_luma = 8;
+
+ /* chroma bit depth 8 */
+ ps_sps->i1_bit_depth_chroma = 8;
+
+ /* qpprime_y_zero_transform_bypass_flag */
+ ps_sps->i1_qpprime_y_zero_transform_bypass_flag = 0;
+
+ /* seq_scaling_matrix_present_flag */
+ ps_sps->i1_seq_scaling_matrix_present_flag = 0;
+
+ if(ps_sps->i1_seq_scaling_matrix_present_flag)
+ {
+ /* TODO_LATER: Will be enabled once scaling list support is added */
+ }
+ }
+
+ /* log2_max_frame_num_minus4 */
+ ps_sps->i1_log2_max_frame_num = LOG2_MAX_FRAME_NUM_MINUS4 + 4;
+
+ /* pic_order_cnt_type */
+ ps_sps->i1_pic_order_cnt_type = 2;
+
+ if(ps_codec->i4_non_ref_frames_in_stream)
+ {
+ ps_sps->i1_pic_order_cnt_type = 0;
+ }
+
+ /* log2_max_pic_order_cnt_lsb_minus4 */
+ ps_sps->i1_log2_max_pic_order_cnt_lsb = 8;
+
+ /* TODO : add support for other poc types */
+ if(ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ }
+ else if(ps_sps->i1_pic_order_cnt_type == 1)
+ {
+ }
+
+ ps_sps->u1_max_num_ref_frames = ps_codec->i4_max_num_reference_frames;
+
+ /* gaps_in_frame_num_value_allowed_flag */
+ ps_sps->i1_gaps_in_frame_num_value_allowed_flag = 0;
+
+ /* pic width in mb - 1 */
+ ps_sps->i2_pic_width_in_mbs_minus1 =
+ (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width >> 4) - 1;
+
+ /* pic height in mb - 1 */
+ ps_sps->i2_pic_height_in_map_units_minus1 =
+ (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height >> 4) - 1;
+
+ /* frame_mbs_only_flag, no support for interlace encoding */
+ ps_sps->i1_frame_mbs_only_flag = 1;
+
+ /* mb_adaptive_frame_field_flag */
+ if(ps_sps->i1_frame_mbs_only_flag == 0)
+ {
+ ps_sps->i1_mb_adaptive_frame_field_flag = 0;
+ }
+
+ /* direct_8x8_inference_flag */
+ if(ps_sps->u1_level_idc < IH264_LEVEL_30)
+ {
+ ps_sps->i1_direct_8x8_inference_flag = 0;
+ }
+ else
+ {
+ ps_sps->i1_direct_8x8_inference_flag = 1;
+ }
+
+ /* cropping params */
+ /*NOTE : Cropping values depend on the chroma format
+ * For our case ,decoder interprets the cropping values as 2*num pixels
+ * Hence the difference in the disp width and width must be halved before
+ * sending to get the expected results
+ */
+ ps_sps->i1_frame_cropping_flag = 0;
+ ps_sps->i2_frame_crop_left_offset = 0;
+ ps_sps->i2_frame_crop_right_offset = (ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd) >> 1;
+ ps_sps->i2_frame_crop_top_offset = 0;
+ ps_sps->i2_frame_crop_bottom_offset = (ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht) >> 1;
+
+ if(ps_sps->i2_frame_crop_left_offset || ps_sps->i2_frame_crop_right_offset ||
+ ps_sps->i2_frame_crop_top_offset || ps_sps->i2_frame_crop_bottom_offset)
+ {
+ ps_sps->i1_frame_cropping_flag = 1;
+ }
+
+ /* vui params */
+ ps_sps->i1_vui_parameters_present_flag = !(ps_cfg->u4_disable_vui);
+
+ if(!ps_sps->i1_vui_parameters_present_flag)
+ {
+ /* populate vui params */
+ isvce_populate_vui(ps_codec, ps_sps);
+ }
+ else
+ {
+ ps_sps->s_vui_parameters = ps_cfg->s_vui;
+ }
+
+ return i4_err_code;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates pps structure
+*
+* @par Description
+* Populates pps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_pps
+* pointer to pps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_populate_pps(isvce_codec_t *ps_codec, pps_t *ps_pps, UWORD8 u1_sps_id,
+ UWORD8 u1_pps_id, UWORD8 u1_spatial_layer_id)
+{
+ /* seq_parameter_set_id */
+ ps_pps->u1_sps_id = u1_sps_id;
+
+ /* pic_parameter_set_id */
+ ps_pps->u1_pps_id = u1_pps_id;
+
+ /* entropy_coding_mode */
+ ps_pps->u1_entropy_coding_mode_flag =
+ ((ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && (0 == u1_spatial_layer_id))
+ ? CAVLC
+ : ps_codec->s_cfg.u4_entropy_coding_mode;
+
+ /* pic_order_present_flag is unset if we don't have feilds */
+ ps_pps->u1_pic_order_present_flag = 0;
+
+ /* Currently number of slice groups supported are 1 */
+ ps_pps->u1_num_slice_groups = 1;
+
+ if(ps_pps->u1_num_slice_groups - 1)
+ {
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit
+ * stream*/
+ }
+
+ /* number of reference frames for list 0 */
+ /* FIXME : fix this hard coded value */
+ ps_pps->i1_num_ref_idx_l0_default_active = 1;
+
+ /* number of reference frames for list 1 */
+ ps_pps->i1_num_ref_idx_l1_default_active = 1;
+
+ /* weighted prediction for now is disabled */
+ ps_pps->i1_weighted_pred_flag = 0;
+ ps_pps->i1_weighted_bipred_idc = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice
+ * headers */
+ ps_pps->i1_pic_init_qp = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice
+ * headers */
+ ps_pps->i1_pic_init_qs = 0;
+
+ /* The intent is to not signal qp from pps. Rather send the same in slice
+ * headers */
+ ps_pps->i1_chroma_qp_index_offset = 0;
+
+ /* deblocking filter flags present in slice header */
+ ps_pps->i1_deblocking_filter_control_present_flag = 1;
+
+ /* constrained intra prediction */
+ ps_pps->i1_constrained_intra_pred_flag =
+ ps_codec->au4_constrained_intra_pred[u1_spatial_layer_id];
+
+ /* sending redundant slices is not supported for now */
+ ps_pps->i1_redundant_pic_cnt_present_flag = 0;
+
+ ps_pps->u1_slice_group_map_type = 0;
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates slice header structure
+*
+* @par Description
+* Populates slice header structure for its use in header generation
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[out] ps_slice_hdr
+* pointer to slice header structure that needs to be populated
+*
+* @param[in] ps_pps
+* pointer to pps params structure referred by the slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by the pps
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_populate_slice_header(isvce_process_ctxt_t *ps_proc, slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_is_idr)
+{
+ /* entropy context */
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ if(ps_codec->u4_is_curr_frm_ref)
+ {
+ ps_slice_hdr->i1_nal_unit_idc = 3;
+ }
+ else
+ {
+ ps_slice_hdr->i1_nal_unit_idc = 0;
+ }
+
+ /* start mb address */
+ ps_slice_hdr->u2_first_mb_in_slice = ps_entropy->i4_mb_start_add;
+
+ /* slice type */
+ ps_slice_hdr->u1_slice_type = ps_proc->i4_slice_type;
+
+ /* pic_parameter_set_id */
+ ps_slice_hdr->u1_pps_id = ps_pps->u1_pps_id;
+
+ /* Separate color plane flag is 0,
+ * hence the syntax element color_plane_id not included */
+
+ /* frame num */
+ ps_slice_hdr->i4_frame_num = ps_proc->i4_frame_num;
+
+ /* frame_mbs_only_flag, no support for interlace encoding */
+ if(!ps_sps->i1_frame_mbs_only_flag)
+ {
+ ps_slice_hdr->i1_field_pic_flag = 0;
+
+ if(ps_slice_hdr->i1_field_pic_flag)
+ {
+ ps_slice_hdr->i1_bottom_field_flag = 0;
+ }
+ }
+
+ /* idr pic id */
+ if(u1_is_idr)
+ {
+ ps_slice_hdr->u2_idr_pic_id = ps_proc->u4_idr_pic_id;
+ ps_slice_hdr->i1_nal_unit_type = NAL_SLICE_IDR;
+ }
+ else
+ {
+ ps_slice_hdr->i1_nal_unit_type = NAL_SLICE_NON_IDR;
+ }
+
+ if(ps_proc->u1_spatial_layer_id > 0)
+ {
+ ps_slice_hdr->i1_nal_unit_type = NAL_CODED_SLICE_EXTENSION;
+ }
+
+ if(ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ WORD32 i4_poc;
+ i4_poc = ps_codec->i4_poc;
+ i4_poc %= (1 << ps_sps->i1_log2_max_pic_order_cnt_lsb);
+ ps_slice_hdr->i4_pic_order_cnt_lsb = i4_poc;
+ }
+ /* TODO add support for poc type 1 */
+ else if(ps_sps->i1_pic_order_cnt_type == 1)
+ {
+ }
+
+ /*
+ * redundant slices are not currently supported.
+ * Hence the syntax element redundant slice cnt is not initialized
+ */
+ if(ps_pps->i1_redundant_pic_cnt_present_flag)
+ {
+ }
+
+ /* direct spatial mv pred flag */
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ ps_slice_hdr->u1_direct_spatial_mv_pred_flag = 1;
+ }
+
+ if(ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE ||
+ ps_proc->i4_slice_type == BSLICE)
+ {
+ /* num_ref_idx_active_override_flag */
+ ps_slice_hdr->u1_num_ref_idx_active_override_flag = 0;
+
+ if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
+ {
+ /* num_ref_idx_l0_active_minus1 */
+
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ /* num_ref_idx_l1_active_minus1 */
+ }
+ }
+ }
+
+ /* ref_pic_list_modification */
+ if((ps_proc->i4_slice_type != ISLICE) && (ps_proc->i4_slice_type != SISLICE))
+ {
+ /* ref_pic_list_modification_flag_l0 */
+ ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0 = 1;
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
+ {
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0[0] = 0;
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0[1] = 3;
+
+ if((ps_codec->i4_frame_num - ps_proc->aps_ref_pic[L0]->i4_frame_num) < 1)
+ {
+ return IH264E_FAIL;
+ }
+
+ ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0[0] =
+ ps_codec->i4_frame_num - ps_proc->aps_ref_pic[L0]->i4_frame_num - 1;
+ }
+ }
+
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ /* ref_pic_list_modification_flag_l1 */
+ ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1 = 0;
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
+ {
+ }
+ }
+
+ /* Currently we do not support weighted pred */
+ /* ps_slice_hdr->u1_weighted_bipred_idc = 0; */
+
+ if((ps_pps->i1_weighted_pred_flag &&
+ (ps_proc->i4_slice_type == PSLICE || ps_proc->i4_slice_type == SPSLICE)) ||
+ (ps_proc->i4_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
+ {
+ /* TODO_LATER: Currently there is no support for weighted prediction.
+ This needs to be updated when the support is added */
+ }
+
+ if(ps_slice_hdr->i1_nal_unit_idc != 0)
+ {
+ if(u1_is_idr)
+ {
+ /* no_output_of_prior_pics_flag */
+ ps_slice_hdr->u1_no_output_of_prior_pics_flag = 0;
+
+ /* long_term_reference_flag */
+ ps_slice_hdr->u1_long_term_reference_flag = 0;
+ }
+ else
+ {
+ /* adaptive_ref_pic_marking_mode_flag */
+ ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag = 0;
+
+ if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
+ {
+ /* TODO: if the reference picture marking mode is adaptive
+ add these fields in the bit-stream */
+ }
+ }
+ }
+
+ /* entropy coding mode flag */
+ ps_slice_hdr->u1_entropy_coding_mode_flag = ps_entropy->u1_entropy_coding_mode_flag;
+
+ if(ps_slice_hdr->u1_entropy_coding_mode_flag && ps_proc->i4_slice_type != ISLICE &&
+ ps_proc->i4_slice_type != SISLICE)
+ {
+ /* cabac_init_idc */
+ ps_slice_hdr->i1_cabac_init_idc = CABAC_INIT_IDC;
+ }
+
+ /* slice qp */
+ ps_slice_hdr->i1_slice_qp = ps_proc->u1_frame_qp;
+
+ if(ps_proc->i4_slice_type == SPSLICE || ps_proc->i4_slice_type == SISLICE)
+ {
+ if(ps_proc->i4_slice_type == SPSLICE)
+ {
+ /* sp_for_switch_flag */
+ }
+ /* slice_qs_delta */
+ }
+
+ if(ps_pps->i1_deblocking_filter_control_present_flag)
+ {
+ /* disable_deblocking_filter_idc */
+ ps_slice_hdr->u1_disable_deblocking_filter_idc = ps_proc->u4_disable_deblock_level;
+
+ if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ ps_slice_hdr->i1_slice_alpha_c0_offset_div2 = 0;
+
+ /* slice_beta_offset_div2 */
+ ps_slice_hdr->i1_slice_beta_offset_div2 = 0;
+ }
+ }
+ ps_slice_hdr->u1_num_slice_groups_minus1 = 0;
+ if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
+ ps_pps->u1_slice_group_map_type <= 5)
+ {
+ /* slice_group_change_cycle */
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit
+ * stream */
+ }
+
+ ps_slice_hdr->i1_cabac_init_idc = CABAC_INIT_IDC;
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief Populates svc_nalu_ext structure
+*
+* @par Description
+* Populates svc_nalu_ext structure for its use in header generation
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[out] ps_slice_hdr
+* pointer to slice header structure that needs to be populated
+*
+* @param[in] ps_pps
+* pointer to pps params structure referred by the slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by the pps
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_populate_svc_nalu_extension(isvce_process_ctxt_t *ps_proc,
+ svc_nalu_ext_t *ps_svc_nalu_ext, NAL_UNIT_TYPE_T nalu_type,
+ UWORD8 u1_idr_flag)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ ps_svc_nalu_ext->u1_idr_flag = u1_idr_flag;
+
+ ps_svc_nalu_ext->u1_priority_id = 0;
+
+ ps_svc_nalu_ext->u1_no_inter_layer_pred_flag = ((nalu_type == NAL_PREFIX) ? 1 : 0);
+
+ ps_svc_nalu_ext->u1_dependency_id =
+ ((nalu_type == NAL_PREFIX) ? 0 : ps_proc->u1_spatial_layer_id);
+
+ ps_svc_nalu_ext->u1_temporal_id = ps_proc->ps_cur_pic->i1_temporal_id;
+
+ ps_svc_nalu_ext->u1_quality_id = 0;
+
+ ps_svc_nalu_ext->u1_use_ref_base_pic_flag = 0;
+
+ ps_svc_nalu_ext->u1_discardable_flag = 0;
+
+ ps_svc_nalu_ext->u1_output_flag = 1;
+
+ ps_svc_nalu_ext->u1_reserved_three_2bits = 3;
+
+ ps_svc_nalu_ext->s_nalu_header.u1_nal_ref_idc = ps_codec->u4_is_curr_frm_ref ? 3 : 0;
+
+ ps_svc_nalu_ext->s_nalu_header.u1_nal_unit_type = nalu_type;
+
+ return IH264E_SUCCESS;
+}
+
+WORD32 isvce_populate_subset_sps(isvce_codec_t *ps_codec, subset_sps_t *ps_subset_sps,
+ UWORD8 u1_sps_id, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id)
+{
+ sps_t *ps_sps = &ps_subset_sps->s_sps;
+
+ isvce_populate_sps(ps_codec, ps_sps, u1_sps_id, IH264_SCALABLE_BASELINE, ps_inp_buf,
+ u1_spatial_layer_id);
+
+ ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag = 1;
+
+ ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag = 1;
+
+ ps_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc = 0;
+
+ ps_subset_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag = 0;
+
+ ps_subset_sps->i1_svc_vui_parameters_present_flag = 0;
+
+ ps_subset_sps->i1_additional_extension2_flag = 0;
+
+ ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1 = 1;
+
+ ps_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1 = 1;
+
+ ps_subset_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag = 0;
+
+ return IH264E_SUCCESS;
+}
+
+WORD32 isvce_populate_svc_slice(isvce_process_ctxt_t *ps_proc, svc_slice_header_t *ps_svc_slice_hdr,
+ pps_t *ps_pps, subset_sps_t *ps_subset_sps,
+ svc_nalu_ext_t *ps_svc_nalu_ext)
+{
+ WORD32 i4_return_status;
+
+ i4_return_status =
+ isvce_populate_slice_header(ps_proc, &ps_svc_slice_hdr->s_slice_header, ps_pps,
+ &ps_subset_sps->s_sps, ps_svc_nalu_ext->u1_idr_flag);
+
+ if(IH264E_SUCCESS != i4_return_status)
+ {
+ return IH264E_FAIL;
+ }
+
+ ps_svc_slice_hdr->i1_slice_skip_flag = 0;
+ ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag = ENABLE_RESIDUAL_PREDICTION;
+ ps_svc_slice_hdr->i1_default_residual_prediction_flag = 0;
+ ps_svc_slice_hdr->i1_adaptive_base_mode_flag = ENABLE_ILP_MV || ENABLE_IBL_MODE;
+ ps_svc_slice_hdr->i1_default_base_mode_flag = 0;
+ ps_svc_slice_hdr->i1_tcoeff_level_prediction_flag = 0;
+ ps_svc_slice_hdr->i1_constrained_intra_resampling_flag = 0;
+ ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag = USE_ILP_MV_AS_MVP;
+ ps_svc_slice_hdr->i1_default_motion_prediction_flag = 0;
+ ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc =
+ !ENABLE_INTRA_BASE_DEBLOCK || ps_proc->u4_disable_deblock_level;
+
+ if(ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ ps_svc_slice_hdr->i4_inter_layer_slice_alpha_c0_offset_div2 = 0;
+
+ /* slice_beta_offset_div2 */
+ ps_svc_slice_hdr->i4_inter_layer_slice_beta_offset_div2 = 0;
+ }
+
+ if((ps_svc_nalu_ext->u1_quality_id == 0) && (ps_svc_nalu_ext->u1_no_inter_layer_pred_flag == 0))
+ {
+ ps_svc_slice_hdr->u4_ref_layer_dq_id = (ps_proc->u1_spatial_layer_id - 1) << 4;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief Signals prefix_nal_unit_rbsp
+*
+* @par Description
+* prefix_nal_unit_rbsp as per Section G.7.3.2.12
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context for generating slice header
+*
+* @param[in] svc_nalu_ext
+* pointer to svc NAL unit structure
+*
+* @param[in] ps_slice_header
+* pointer to slice header
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_prefix_nal(bitstrm_t *ps_bitstrm, svc_nalu_ext_t *ps_svc_nalu_ext,
+ slice_header_t *ps_slice_header, UWORD8 u1_max_num_ref_frames,
+ UWORD8 u1_num_spatial_layers)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ WORD32 i4_store_ref_base_pic_flag = 0;
+ WORD32 i4_additional_prefix_nal_unit_extension_flag = 0;
+
+ if(ps_svc_nalu_ext->u1_dependency_id == (u1_num_spatial_layers - 1))
+ {
+ i4_store_ref_base_pic_flag = 1;
+ if(u1_max_num_ref_frames < 2)
+ {
+ i4_store_ref_base_pic_flag = 0;
+ }
+ }
+
+ /* store_ref_base_pic_flag */
+ if(ps_svc_nalu_ext->s_nalu_header.u1_nal_ref_idc != 0)
+ {
+ PUT_BITS(ps_bitstrm, i4_store_ref_base_pic_flag, 1, return_status,
+ "store_ref_base_pic_flag");
+
+ if((ps_svc_nalu_ext->u1_use_ref_base_pic_flag || i4_store_ref_base_pic_flag) &&
+ !ps_svc_nalu_ext->u1_idr_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_slice_header->u1_adaptive_ref_pic_marking_mode_flag, 1,
+ return_status, "DPRM: adaptive_ref_base_pic_marking_mode_flag");
+ }
+
+ PUT_BITS(ps_bitstrm, i4_additional_prefix_nal_unit_extension_flag, 1, return_status,
+ "additional_prefix_nal_unit_extension_flag");
+ }
+
+ /* rbsp trailing bits */
+ return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+
+WORD32 isvce_generate_slice_header_svc(bitstrm_t *ps_bitstrm, pps_t *ps_pps,
+ svc_nalu_ext_t *ps_svc_nalu_ext,
+ svc_slice_header_t *ps_svc_slice_hdr,
+ subset_sps_t *ps_subset_sps)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ UWORD8 u1_slice_type;
+ sps_t *ps_sps = &ps_subset_sps->s_sps;
+ slice_header_t *ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
+
+ /* first_mb_in_slice */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_first_mb_in_slice, return_status,
+ "SH: first_mb_in_slice");
+
+ /* slice_type */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_slice_type, return_status, "SH: slice_type");
+
+ /* pic_parameter_set_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_pps_id, return_status, "SH: pic_parameter_set_id");
+
+ /* frame_num */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_frame_num, ps_sps->i1_log2_max_frame_num, return_status,
+ "SH: frame_num");
+
+ if(!ps_sps->i1_frame_mbs_only_flag)
+ {
+ /* field_pic_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_field_pic_flag, 1, return_status,
+ "SH: field_pic_flag");
+
+ if(ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* bottom_field_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i1_bottom_field_flag, 1, return_status,
+ "SH: bottom_field_flag");
+ }
+ }
+
+ if(ps_svc_nalu_ext->u1_idr_flag == 1)
+ {
+ /* u2_idr_pic_id */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u2_idr_pic_id, return_status, "SH: idr_pic_id");
+ }
+
+ if(ps_sps->i1_pic_order_cnt_type == 0)
+ {
+ /* pic_order_cnt_lsb */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->i4_pic_order_cnt_lsb,
+ ps_sps->i1_log2_max_pic_order_cnt_lsb, return_status, "SH: pic_order_cnt_lsb");
+
+ if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt_bottom */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i4_delta_pic_order_cnt_bottom, return_status,
+ "SH: delta_pic_order_cnt_bottom");
+ }
+ }
+
+ if(ps_sps->i1_pic_order_cnt_type == 1 && !ps_sps->i1_delta_pic_order_always_zero_flag)
+ {
+ /* delta_pic_order_cnt[0] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[0], return_status,
+ "SH: delta_pic_order_cnt[0]");
+
+ if(ps_pps->u1_pic_order_present_flag && !ps_slice_hdr->i1_field_pic_flag)
+ {
+ /* delta_pic_order_cnt[1] */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->ai4_delta_pic_order_cnt[1], return_status,
+ "SH: delta_pic_order_cnt[1]");
+ }
+ }
+
+ if(ps_pps->i1_redundant_pic_cnt_present_flag)
+ {
+ /* redundant_pic_cnt */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_redundant_pic_cnt, return_status,
+ "SH: redundant_pic_cnt");
+ }
+
+ u1_slice_type = ps_slice_hdr->u1_slice_type % EPSLICE;
+
+ if(ps_svc_nalu_ext->u1_quality_id == 0)
+ {
+ if(u1_slice_type == BSLICE)
+ {
+ /* direct_spatial_mv_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_direct_spatial_mv_pred_flag, 1, return_status,
+ "SH: direct_spatial_mv_pred_flag");
+ }
+
+ if(u1_slice_type == PSLICE || u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_active_override_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_num_ref_idx_active_override_flag, 1,
+ return_status, "SH: num_ref_idx_active_override_flag");
+
+ if(ps_slice_hdr->u1_num_ref_idx_active_override_flag)
+ {
+ /* num_ref_idx_l0_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l0_active - 1, return_status,
+ "SH: num_ref_idx_l0_active_minus1");
+
+ if(u1_slice_type == BSLICE)
+ {
+ /* num_ref_idx_l1_active_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_num_ref_idx_l1_active - 1,
+ return_status, "SH: num_ref_idx_l1_active_minus1");
+ }
+ }
+ }
+
+ /* ref_pic_list_modification */
+ if((u1_slice_type != ISLICE) && (u1_slice_type != SISLICE))
+ {
+ /* ref_pic_list_modification_flag_l0 */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0, 1,
+ return_status, "RPLR: ref_pic_list_reordering_flag");
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l0)
+ {
+ UWORD8 i = 0;
+
+ WORD8 *pi1_modification_of_pic_nums_idc_l0 =
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l0;
+ UWORD32 *pu4_abs_diff_pic_num_minus1_l0 =
+ ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l0;
+ UWORD8 *pu1_long_term_pic_num_l0 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l0;
+
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l0[i], return_status,
+ "RPLR: reordering_of_pic_nums_idc");
+
+ if((0 == pi1_modification_of_pic_nums_idc_l0[i]) ||
+ (1 == pi1_modification_of_pic_nums_idc_l0[i]))
+ {
+ /* abs_diff_pic_num_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l0[0], return_status,
+ "RPLR: abs_diff_pic_num_minus1");
+
+ pu4_abs_diff_pic_num_minus1_l0++;
+ }
+ else if(2 == pi1_modification_of_pic_nums_idc_l0[i])
+ {
+ /* long_term_pic_num */
+ PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l0[0], return_status,
+ "RPLR: long_term_pic_num");
+
+ pu1_long_term_pic_num_l0++;
+ }
+ } while(pi1_modification_of_pic_nums_idc_l0[i++] != 3);
+ }
+ }
+
+ if(u1_slice_type == BSLICE)
+ {
+ /* ref_pic_list_modification_flag_l1 */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1, 1,
+ return_status, "SH: ref_pic_list_modification_flag_l1");
+
+ if(ps_slice_hdr->s_rplm.i1_ref_pic_list_modification_flag_l1)
+ {
+ UWORD8 i = 0;
+
+ WORD8 *pi1_modification_of_pic_nums_idc_l1 =
+ ps_slice_hdr->s_rplm.i1_modification_of_pic_nums_idc_l1;
+ UWORD32 *pu4_abs_diff_pic_num_minus1_l1 =
+ ps_slice_hdr->s_rplm.u4_abs_diff_pic_num_minus1_l1;
+ UWORD8 *pu1_long_term_pic_num_l1 = ps_slice_hdr->s_rplm.u1_long_term_pic_num_l1;
+
+ do
+ {
+ /* modification_of_pic_nums_idc */
+ PUT_BITS_UEV(ps_bitstrm, pi1_modification_of_pic_nums_idc_l1[i], return_status,
+ "SH: modification_of_pic_nums_idc");
+
+ if((0 == pi1_modification_of_pic_nums_idc_l1[i]) ||
+ (1 == pi1_modification_of_pic_nums_idc_l1[i]))
+ {
+ /* abs_diff_pic_num_minus1 */
+ PUT_BITS_UEV(ps_bitstrm, pu4_abs_diff_pic_num_minus1_l1[0], return_status,
+ "SH: abs_diff_pic_num_minus1");
+
+ pu4_abs_diff_pic_num_minus1_l1++;
+ }
+ else if(2 == pi1_modification_of_pic_nums_idc_l1[i])
+ {
+ /* long_term_pic_num */
+ PUT_BITS_UEV(ps_bitstrm, pu1_long_term_pic_num_l1[0], return_status,
+ "SH: abs_diff_pic_num_minus1");
+
+ pu1_long_term_pic_num_l1++;
+ }
+ } while(pi1_modification_of_pic_nums_idc_l1[i++] != 3);
+ }
+ }
+
+ if((ps_pps->i1_weighted_pred_flag && u1_slice_type == PSLICE) ||
+ (u1_slice_type == BSLICE && ps_pps->i1_weighted_bipred_idc == 1))
+ {
+ /* TODO_LATER: Currently there is no support for weighted prediction.
+ This needs to be updated when the support is added */
+ }
+
+ if(ps_slice_hdr->i1_nal_unit_idc != 0)
+ {
+ if(ps_svc_nalu_ext->u1_idr_flag)
+ {
+ /* no_output_of_prior_pics_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_no_output_of_prior_pics_flag, 1,
+ return_status, "DRPM: no_output_of_prior_pics_flag ");
+
+ /* long_term_reference_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_long_term_reference_flag, 1, return_status,
+ "DRPM: long_term_reference_flag ");
+ }
+ else
+ {
+ /* adaptive_ref_pic_marking_mode_flag */
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
+ return_status, "DPRM: adaptive_ref_pic_marking_mode_flag ");
+
+ if(ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag)
+ {
+ /* TODO: if the reference picture marking mode is adaptive
+ add these fields in the bit-stream */
+ }
+ }
+ if(ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag == 0)
+ {
+ WORD32 i4_store_ref_base_pic_flag = 0;
+
+ if(ps_sps->u1_max_num_ref_frames >= 2)
+ {
+ i4_store_ref_base_pic_flag = 1;
+ }
+
+ /* store_ref_base_pic_flag */
+ PUT_BITS(ps_bitstrm, i4_store_ref_base_pic_flag, 1, return_status,
+ "SH: store_ref_base_pic_flag");
+
+ if((ps_svc_nalu_ext->u1_use_ref_base_pic_flag || i4_store_ref_base_pic_flag) &&
+ (!ps_svc_nalu_ext->u1_idr_flag))
+ {
+ PUT_BITS(ps_bitstrm, ps_slice_hdr->u1_adaptive_ref_pic_marking_mode_flag, 1,
+ return_status, "SH: adaptive_ref_base_pic_marking_mode_flag");
+ }
+ }
+ }
+ }
+
+ if(ps_slice_hdr->u1_entropy_coding_mode_flag && u1_slice_type != ISLICE)
+ {
+ /* cabac_init_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->i1_cabac_init_idc, return_status,
+ "SH: cabac_init_idc");
+ }
+
+ /* slice_qp_delta */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_qp - ps_pps->i1_pic_init_qp, return_status,
+ "SH: slice_qp_delta");
+
+ if(ps_pps->i1_deblocking_filter_control_present_flag)
+ {
+ /* disable_deblocking_filter_idc */
+ PUT_BITS_UEV(ps_bitstrm, ps_slice_hdr->u1_disable_deblocking_filter_idc, return_status,
+ "SH: disable_deblocking_filter_idc");
+
+ if(ps_slice_hdr->u1_disable_deblocking_filter_idc != 1)
+ {
+ /* slice_alpha_c0_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_alpha_c0_offset_div2, return_status,
+ "SH: slice_alpha_c0_offset_div2");
+
+ /* slice_beta_offset_div2 */
+ PUT_BITS_SEV(ps_bitstrm, ps_slice_hdr->i1_slice_beta_offset_div2, return_status,
+ "SH: slice_beta_offset_div2");
+ }
+ }
+
+ if(ps_slice_hdr->u1_num_slice_groups_minus1 > 0 && ps_pps->u1_slice_group_map_type >= 3 &&
+ ps_pps->u1_slice_group_map_type <= 5)
+ {
+ /* slice_group_change_cycle */
+ /* TODO_LATER: Currently the number of slice groups minus 1 is 0.
+ * If this is not the case, we have to add Slice group map type to the bit
+ * stream */
+ }
+
+ if((ps_svc_nalu_ext->u1_no_inter_layer_pred_flag == 0) && (ps_svc_nalu_ext->u1_quality_id == 0))
+ {
+ PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_ref_layer_dq_id, return_status,
+ "SH: ref_layer_dq_id");
+ if(ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag)
+ {
+ PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc,
+ return_status, "SH: disable_inter_layer_deblocking_filter_idc");
+ if(ps_svc_slice_hdr->u4_disable_inter_layer_deblocking_filter_idc != 1)
+ {
+ PUT_BITS_SEV(ps_bitstrm,
+ ps_svc_slice_hdr->i4_inter_layer_slice_alpha_c0_offset_div2,
+ return_status, "SH: inter_layer_slice_alpha_c0_offset_div2");
+ PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_inter_layer_slice_beta_offset_div2,
+ return_status, "SH: inter_layer_slice_beta_offset_div2");
+ }
+ }
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_constrained_intra_resampling_flag, 1,
+ return_status, "SH: constrained_intra_resampling_flag");
+ if(ps_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc == 2)
+ {
+ if(ps_sps->u1_chroma_format_idc > 0)
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_ref_layer_chroma_phase_x_plus1_flag, 1,
+ return_status, "SH: ref_layer_chroma_phase_x_plus1_flag");
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_ref_layer_chroma_phase_y_plus1, 2,
+ return_status, "SH: ref_layer_chroma_phase_y_plus1");
+ }
+ PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_left, return_status,
+ "SH: scaled_ref_layer_left_offset");
+ PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_top, return_status,
+ "SH: scaled_ref_layer_top_offset");
+ PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_right, return_status,
+ "SH: scaled_ref_layer_right_offset");
+ PUT_BITS_SEV(ps_bitstrm, ps_svc_slice_hdr->i4_scaled_ref_layer_bottom, return_status,
+ "SH: scaled_ref_layer_bottom_offset");
+ }
+ }
+
+ if(!ps_svc_nalu_ext->u1_no_inter_layer_pred_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_slice_skip_flag, 1, return_status,
+ "SH: slice_skip_flag");
+ if(ps_svc_slice_hdr->i1_slice_skip_flag)
+ {
+ PUT_BITS_UEV(ps_bitstrm, ps_svc_slice_hdr->u4_num_mbs_in_slice_minus1, return_status,
+ "SH: num_mbs_in_slice_minus1");
+ }
+ else
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_base_mode_flag, 1, return_status,
+ "SH: adaptive_base_mode_flag");
+ if(!ps_svc_slice_hdr->i1_adaptive_base_mode_flag)
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_base_mode_flag, 1, return_status,
+ "SH: default_base_mode_flag");
+
+ if(!ps_svc_slice_hdr->i1_default_base_mode_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag, 1,
+ return_status, "SH: adaptive_motion_prediction_flag");
+ if(!ps_svc_slice_hdr->i1_adaptive_motion_prediction_flag)
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_motion_prediction_flag, 1,
+ return_status, "SH: default_motion_prediction_flag");
+ }
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag, 1,
+ return_status, "SH: adaptive_residual_prediction_flag");
+ if(!ps_svc_slice_hdr->i1_adaptive_residual_prediction_flag)
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_default_residual_prediction_flag, 1,
+ return_status, "SH: default_residual_prediction_flag");
+ }
+
+ if(ps_subset_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->i1_tcoeff_level_prediction_flag, 1,
+ return_status, "SH: tcoeff_level_prediction_flag");
+ }
+ }
+
+ if(!ps_subset_sps->s_sps_svc_ext.i1_slice_header_restriction_flag &&
+ !ps_svc_slice_hdr->i1_slice_skip_flag)
+ {
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->u4_scan_idx_start, 4, return_status,
+ "SH: scan_idx_start");
+ PUT_BITS(ps_bitstrm, ps_svc_slice_hdr->u4_scan_idx_end, 4, return_status,
+ "SH: scan_idx_end");
+ }
+
+ return return_status;
+}
+
+WORD32 isvce_seq_parameter_set_svc_extension(bitstrm_t *ps_bitstrm, subset_sps_t *ps_sub_sps,
+ UWORD8 u1_chroma_format_idc)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* inter_layer_deblocking_filter_control_present_flag */
+ PUT_BITS(ps_bitstrm,
+ ps_sub_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag, 1,
+ return_status, "SPS: inter_layer_deblocking_filter_control_present_flag");
+
+ /* extended_spatial_scalability */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc, 2,
+ return_status, "SPS: extended_spatial_scalability");
+
+ if(u1_chroma_format_idc == 1 || u1_chroma_format_idc == 2)
+ {
+ /* chroma_phase_x_plus1_flag */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1, 1, return_status,
+ "SPS: chroma_phase_x_plus1_flag");
+ }
+
+ if(u1_chroma_format_idc == 1)
+ {
+ /* chroma_phase_y_plus1 */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1, 2, return_status,
+ "SPS: chroma_phase_y_plus1");
+ }
+
+ if(ps_sub_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc == 1)
+ {
+ if(u1_chroma_format_idc > 0)
+ {
+ /* seq_ref_layer_chroma_phase_x_plus1_flag */
+ PUT_BITS(ps_bitstrm,
+ ps_sub_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag, 1,
+ return_status, "SPS: seq_ref_layer_chroma_phase_x_plus1_flag");
+
+ /* seq_ref_layer_chroma_phase_y_plus1 */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1, 2,
+ return_status, "SPS: seq_ref_layer_chroma_phase_y_plus1");
+ }
+ /* seq_scaled_ref_layer_left_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset,
+ return_status, "SPS: seq_scaled_ref_layer_left_offset");
+
+ /* seq_scaled_ref_layer_top_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset,
+ return_status, "SPS: seq_scaled_ref_layer_top_offset");
+
+ /* seq_scaled_ref_layer_right_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset,
+ return_status, "SPS: seq_scaled_ref_layer_right_offset");
+
+ /* seq_scaled_ref_layer_bottom_offset */
+ PUT_BITS_SEV(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset,
+ return_status, "SPS: seq_scaled_ref_layer_bottom_offset");
+ }
+
+ /* seq_tcoeff_level_prediction_flag */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag, 1,
+ return_status, "SPS: seq_tcoeff_level_prediction_flag");
+
+ if(ps_sub_sps->s_sps_svc_ext.i1_seq_tcoeff_level_prediction_flag)
+ {
+ /* adaptive_tcoeff_level_prediction_flag */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_adaptive_tcoeff_level_prediction_flag, 1,
+ return_status, "SPS: adaptive_tcoeff_level_prediction_flag");
+ }
+
+ /* slice_header_restriction_flag */
+ PUT_BITS(ps_bitstrm, ps_sub_sps->s_sps_svc_ext.i1_slice_header_restriction_flag, 1,
+ return_status, "SPS: slice_header_restriction_flag");
+
+ return return_status;
+}
+
+WORD32 isvce_svc_vui_parameters_extension(bitstrm_t *ps_bitstrm, svc_vui_ext_t *ps_svc_vui)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ UWORD32 i;
+
+ PUT_BITS_UEV(ps_bitstrm, ps_svc_vui->u4_vui_ext_num_entries_minus1, return_status,
+ "num_layers_minus1");
+
+ for(i = 0; i < ps_svc_vui->u4_vui_ext_num_entries_minus1; i++)
+ {
+ /* dependency_id */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_dependency_id[i], 3, return_status,
+ "dependency_id");
+
+ /* quality_id */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_quality_id[i], 4, return_status, "quality_id");
+
+ /* temporal_id */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_temporal_id[i], 3, return_status,
+ "temporal_id");
+
+ /* timing_info_present_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_timing_info_present_flag[i], 1, return_status,
+ "timing_info_present_flag");
+
+ if(ps_svc_vui->u1_vui_ext_timing_info_present_flag[i])
+ {
+ /* num_units_in_tick */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u4_vui_ext_num_units_in_tick[i], 32, return_status,
+ "num_units_in_tick");
+
+ /* time_scale */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u4_vui_ext_time_scale[i], 32, return_status,
+ "time_scale");
+
+ /* fixed_frame_rate_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_fixed_frame_rate_flag[i], 1, return_status,
+ "fixed_frame_rate_flag");
+ }
+
+ /* nal_hrd_parameters_present_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i], 1,
+ return_status, "nal_hrd_parameters_present_flag");
+
+ if(ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i])
+ {
+ }
+
+ /* nal_hrd_parameters_present_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i], 1,
+ return_status, "vcl_hrd_parameters_present_flag");
+
+ if(ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i])
+ {
+ }
+
+ if(ps_svc_vui->u1_vui_ext_nal_hrd_params_present_flag[i] ||
+ ps_svc_vui->u1_vui_ext_vcl_hrd_params_present_flag[i])
+ {
+ /* low_delay_hrd_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_low_delay_hrd_flag[i], 1, return_status,
+ "low_delay_hrd_flag");
+ }
+
+ /* pic_struct_present_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_vui->u1_vui_ext_pic_struct_present_flag[i], 1, return_status,
+ "pic_struct_present_flag");
+ }
+
+ return return_status;
+}
+
+WORD32 isvce_generate_subset_sps(bitstrm_t *ps_bitstrm, subset_sps_t *ps_subset_sps)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+ sps_t *ps_sps = &ps_subset_sps->s_sps;
+ return_status = isvce_generate_sps(ps_bitstrm, &ps_subset_sps->s_sps, NAL_SUBSET_SPS);
+
+ /* generate subset sps */
+ if(ps_sps->u1_profile_idc == IH264_SCALABLE_BASELINE ||
+ ps_sps->u1_profile_idc == IH264_SCALABLE_HIGH_PROFILE)
+ {
+ isvce_seq_parameter_set_svc_extension(ps_bitstrm, ps_subset_sps,
+ ps_sps->u1_chroma_format_idc);
+
+ /* svc_vui_parameters_present_flag */
+ PUT_BITS(ps_bitstrm, ps_subset_sps->i1_svc_vui_parameters_present_flag, 1, return_status,
+ "SPS: svc_vui_parameters_present_flag");
+
+ if(ps_subset_sps->i1_svc_vui_parameters_present_flag == 1)
+ {
+ svc_vui_ext_t *ps_svc_vui = NULL;
+ isvce_svc_vui_parameters_extension(ps_bitstrm, ps_svc_vui);
+ }
+
+ /* additional_extension2_flag */
+ PUT_BITS(ps_bitstrm, ps_subset_sps->i1_additional_extension2_flag, 1, return_status,
+ "SPS: additional_extension2_flag");
+ }
+
+ /* rbsp trailing bits */
+ return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+
+ return return_status;
+}
+/**
+******************************************************************************
+*
+* @brief Generates svc_nalu_ext
+*
+* @par Description
+* Generate svc_nalu_ext as per Section G.7.3.1.1
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context for generating slice header
+*
+* @param[in] ps_svc_nalu_ext
+* pointer to svc_nalu_ext struct
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_svc_nalu_extension(bitstrm_t *ps_bitstrm, svc_nalu_ext_t *ps_svc_nalu_ext,
+ UWORD8 u1_nalu_id)
+{
+ WORD32 return_status = IH264E_SUCCESS;
+
+ /* Insert start code */
+ return_status = ih264e_put_nal_start_code_prefix(ps_bitstrm, 1);
+
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+
+ /* Insert Nal Unit Header */
+ return_status = isvce_generate_nal_unit_header(ps_bitstrm, u1_nalu_id, 3);
+
+ if(return_status != IH264E_SUCCESS)
+ {
+ return return_status;
+ }
+
+ /* reserved_one_bit */
+ PUT_BITS(ps_bitstrm, 1, 1, return_status, "NAL unit header: reserved_one_bit");
+
+ /* idr_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_idr_flag, 1, return_status,
+ "NAL unit header: idr_flag");
+
+ /* priority_id */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_priority_id, 6, return_status,
+ "NAL unit header: priority_id");
+
+ /* no_inter_layer_pred_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_no_inter_layer_pred_flag, 1, return_status,
+ "NAL unit header: no_inter_layer_pred_flag");
+
+ /* dependency_id */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_dependency_id, 3, return_status,
+ "NAL unit header: dependency_id");
+
+ /* quality_id */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_quality_id, 4, return_status,
+ "NAL unit header: quality_id");
+
+ /* temporal_id */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_temporal_id, 3, return_status,
+ "NAL unit header: temporal_id");
+
+ /* use_ref_base_pic_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_use_ref_base_pic_flag, 1, return_status,
+ "NAL unit header: use_ref_base_pic_flag");
+
+ /* discardable_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_discardable_flag, 1, return_status,
+ "NAL unit header: discardable_flag");
+
+ /* output_flag */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_output_flag, 1, return_status,
+ "NAL unit header: output_flag");
+
+ /* reserved_three_2bits */
+ PUT_BITS(ps_bitstrm, ps_svc_nalu_ext->u1_reserved_three_2bits, 2, return_status,
+ "NAL unit header: reserved_three_2bits");
+
+ return return_status;
+}
diff --git a/encoder/svc/isvce_encode_header.h b/encoder/svc/isvce_encode_header.h
new file mode 100644
index 0000000..c443ed0
--- /dev/null
+++ b/encoder/svc/isvce_encode_header.h
@@ -0,0 +1,296 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_encode_header.h
+*
+* @brief
+* This file contains structures and interface prototypes for h264 bitstream
+* header encoding
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_ENCODE_HEADER_H_
+#define _ISVCE_ENCODE_HEADER_H_
+
+#include "ih264_typedefs.h"
+
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+
+#include "ih264e_bitstream.h"
+#include "ih264e_trace.h"
+#include "isvce_structs.h"
+
+/**
+******************************************************************************
+* @brief Macro to put a code with specified number of bits into the
+* bitstream
+******************************************************************************
+*/
+#define PUT_BITS(ps_bitstrm, code_val, code_len, ret_val, syntax_string) \
+ { \
+ ENTROPY_TRACE(syntax_string, code_val); \
+ ret_val = ih264e_put_bits((ps_bitstrm), (code_val), (code_len)); \
+ if(ret_val != IH264E_SUCCESS) \
+ { \
+ return ret_val; \
+ } \
+ }
+
+/**
+******************************************************************************
+* @brief Macro to put a code with specified number of bits into the
+* bitstream using 0th order exponential Golomb encoding for
+* signed numbers
+******************************************************************************
+*/
+#define PUT_BITS_UEV(ps_bitstrm, code_val, ret_val, syntax_string) \
+ { \
+ ENTROPY_TRACE(syntax_string, code_val); \
+ ret_val = ih264e_put_uev((ps_bitstrm), (code_val)); \
+ if(ret_val != IH264E_SUCCESS) \
+ { \
+ return ret_val; \
+ } \
+ }
+/**
+******************************************************************************
+* @brief Macro to put a code with specified number of bits into the
+* bitstream using 0th order exponential Golomb encoding for
+* signed numbers
+******************************************************************************
+*/
+#define PUT_BITS_SEV(ps_bitstrm, code_val, ret_val, syntax_string) \
+ { \
+ ENTROPY_TRACE(syntax_string, code_val); \
+ ret_val = ih264e_put_sev((ps_bitstrm), (code_val)); \
+ if(ret_val != IH264E_SUCCESS) \
+ { \
+ return ret_val; \
+ } \
+ }
+
+/**
+******************************************************************************
+* @brief Macro to set active entropy threads to zero and return
+* in case of errors
+******************************************************************************
+*/
+#define RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel) \
+ if(ps_entropy->i4_error_code != IH264E_SUCCESS) \
+ { \
+ DATA_SYNC(); \
+ ps_codec->au4_entropy_thread_active[ctxt_sel] = 0; \
+ return ps_entropy->i4_error_code; \
+ }
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+extern WORD32 ih264e_generate_nal_unit_header(bitstrm_t *ps_bitstrm, WORD32 nal_unit_type,
+ WORD32 nal_ref_idc);
+
+extern WORD32 ih264e_generate_vui(bitstrm_t *ps_bitstrm, vui_t *ps_vui);
+
+extern IH264E_ERROR_T ih264e_generate_sei(bitstrm_t *ps_bitstrm, sei_params_t *ps_sei,
+ UWORD32 u4_insert_per_idr);
+
+extern IH264E_ERROR_T ih264e_add_filler_nal_unit(bitstrm_t *ps_bitstrm, WORD32 insert_fill_bytes);
+
+/**
+******************************************************************************
+*
+* @brief Generates SPS (Sequence Parameter Set)
+*
+* @par Description
+* This function generates Sequence Parameter Set header as per the spec
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_sps
+* pointer to structure containing SPS data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_sps(bitstrm_t *ps_bitstrm, sps_t *ps_sps, NAL_UNIT_TYPE_T nal_type);
+
+/**
+******************************************************************************
+*
+* @brief Generates PPS (Picture Parameter Set)
+*
+* @par Description
+* Generate Picture Parameter Set as per Section 7.3.2.2
+*
+* @param[in] ps_bitstrm
+* pointer to bitstream context (handle)
+*
+* @param[in] ps_pps
+* pointer to structure containing PPS data
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_pps(bitstrm_t *ps_bitstrm, pps_t *ps_pps, sps_t *ps_sps);
+
+/**
+******************************************************************************
+*
+* @brief Generates Slice Header
+*
+* @par Description
+* Generate Slice Header as per Section 7.3.5.1
+*
+* @param[inout] ps_bitstrm
+* pointer to bitstream context for generating slice header
+*
+* @param[in] ps_slice_hdr
+* pointer to slice header params
+*
+* @param[in] ps_pps
+* pointer to pps params referred by slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by slice
+*
+* @param[out] ps_dup_bit_strm_ent_offset
+* Bitstream struct to store bitstream state
+*
+* @param[out] pu4_first_slice_start_offset
+* first slice offset is returned
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_generate_slice_header(bitstrm_t *ps_bitstrm, slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_idr_flag);
+/**
+******************************************************************************
+*
+* @brief Populates sps structure
+*
+* @par Description
+* Populates sps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_sps
+* pointer to sps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_populate_sps(isvce_codec_t *ps_codec, sps_t *ps_sps, UWORD8 u1_sps_id,
+ UWORD8 u1_profile_idc, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id);
+
+/**
+******************************************************************************
+*
+* @brief Populates pps structure
+*
+* @par Description
+* Populates pps structure for its use in header generation
+*
+* @param[in] ps_codec
+* pointer to encoder context
+*
+* @param[out] ps_pps
+* pointer to pps params that needs to be populated
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_populate_pps(isvce_codec_t *ps_codec, pps_t *ps_pps, UWORD8 u1_sps_id,
+ UWORD8 u1_pps_id, UWORD8 u1_spatial_layer_id);
+
+/**
+******************************************************************************
+*
+* @brief Populates slice header structure
+*
+* @par Description
+* Populates slice header structure for its use in header generation
+*
+* @param[in] ps_proc
+* pointer to proc context
+*
+* @param[out] ps_slice_hdr
+* pointer to slice header structure that needs to be populated
+*
+* @param[in] ps_pps
+* pointer to pps params structure referred by the slice
+*
+* @param[in] ps_sps
+* pointer to sps params referred by the pps
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+WORD32 isvce_populate_slice_header(isvce_process_ctxt_t *ps_proc, slice_header_t *ps_slice_hdr,
+ pps_t *ps_pps, sps_t *ps_sps, UWORD8 u1_is_idr);
+
+extern WORD32 isvce_populate_svc_nalu_extension(isvce_process_ctxt_t *ps_proc,
+ svc_nalu_ext_t *ps_svc_nalu_ext,
+ NAL_UNIT_TYPE_T nalu_type, UWORD8 u1_idr_flag);
+
+extern WORD32 isvce_generate_svc_nalu_extension(bitstrm_t *ps_bitstrm,
+ svc_nalu_ext_t *ps_svc_nalu_ext, UWORD8 u1_nalu_id);
+
+extern WORD32 isvce_populate_svc_slice(isvce_process_ctxt_t *ps_proc,
+ svc_slice_header_t *ps_svc_slice_hdr, pps_t *ps_pps,
+ subset_sps_t *ps_subset_sps,
+ svc_nalu_ext_t *ps_svc_nalu_ext);
+
+extern WORD32 isvce_populate_subset_sps(isvce_codec_t *ps_codec, subset_sps_t *ps_subset_sps,
+ UWORD8 u1_sps_id, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id);
+
+extern WORD32 isvce_generate_prefix_nal(bitstrm_t *ps_bitstrm, svc_nalu_ext_t *ps_svc_nalu_ext,
+ slice_header_t *ps_slice_header,
+ UWORD8 u1_max_num_ref_frames, UWORD8 u1_num_spatial_layers);
+
+extern WORD32 isvce_generate_slice_header_svc(bitstrm_t *ps_bitstrm, pps_t *ps_pps,
+ svc_nalu_ext_t *ps_svc_nalu_ext,
+ svc_slice_header_t *ps_svc_slice_hdr,
+ subset_sps_t *ps_subset_sps);
+
+extern WORD32 isvce_generate_subset_sps(bitstrm_t *ps_bitstrm, subset_sps_t *ps_subset_sps);
+
+#endif
diff --git a/encoder/svc/isvce_error.h b/encoder/svc/isvce_error.h
new file mode 100644
index 0000000..fb4900d
--- /dev/null
+++ b/encoder/svc/isvce_error.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_error.h
+*
+* @brief
+* SVC specific error codes
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_ERROR_H_
+#define _ISVCE_ERROR_H_
+
+#include "ih264e_error.h"
+
+typedef enum ISVCE_ERRORS_T
+{
+ /**Invalid SVC params */
+ IH264E_INVALID_SVC_PARAMS = IH264E_CODEC_ERROR_START + 0x100,
+
+ /**Invalid num_temporal_layers */
+ IH264E_INVALID_NUM_TEMPORAL_LAYERS = IH264E_CODEC_ERROR_START + 0x101,
+
+ /**Invalid num_spatial_layers */
+ IH264E_INVALID_NUM_SPATIAL_LAYERS = IH264E_CODEC_ERROR_START + 0x102,
+
+ /**Invalid spatial_res_ratio */
+ IH264E_INVALID_SPATIAL_RES_RATIO = IH264E_CODEC_ERROR_START + 0x103,
+
+ /** Weighted prediction not supported */
+ IH264E_WEIGHTED_PRED_NOT_SUPPORTED = IH264E_CODEC_ERROR_START + 0x104,
+
+ /** CABAC entropy mode not supported for SVC */
+ IH264E_CABAC_NOT_SUPPORTED = IH264E_CODEC_ERROR_START + 0x105,
+
+ /**Invalid input dimensions */
+ IH264E_INVALID_SVC_INPUT_DIMENSIONS = IH264E_CODEC_ERROR_START + 0x106,
+
+ /** Invalid init QP */
+ IH264E_INVALID_DYN_INIT_QP = IH264E_CODEC_ERROR_START + 0x107,
+
+} ISVCE_ERRORS_T;
+
+#endif
diff --git a/encoder/svc/isvce_fmt_conv.c b/encoder/svc/isvce_fmt_conv.c
new file mode 100644
index 0000000..80d888b
--- /dev/null
+++ b/encoder/svc/isvce_fmt_conv.c
@@ -0,0 +1,145 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_fmt_conv.c
+*
+* @brief
+* Contains functions for format conversion or frame copy of output buffer
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_fmt_conv()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+/* Dependencies of ih264_buf_mgr.h */
+/* Dependencies of ih264_list.h */
+#include "ih264_error.h"
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_common_tables.h"
+#include "ih264_list.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+/* Dependencies of ih264e_structs.h */
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ime_statistics.h"
+#include "ime_structs.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_defs.h"
+#include "ih264e_structs.h"
+#include "ih264e_fmt_conv.h"
+#include "isvce_structs.h"
+
+IH264E_ERROR_T isvce_fmt_conv(isvce_codec_t *ps_codec, svc_au_buf_t *ps_pic, UWORD8 *pu1_y_dst,
+ UWORD8 *pu1_u_dst, UWORD8 *pu1_v_dst, UWORD32 u4_dst_y_strd,
+ UWORD32 u4_dst_uv_strd, WORD32 cur_row, WORD32 num_rows)
+{
+ IH264E_ERROR_T ret = IH264E_SUCCESS;
+ UWORD8 *pu1_y_src, *pu1_uv_src;
+ UWORD8 *pu1_y_dst_tmp, *pu1_uv_dst_tmp;
+ UWORD8 *pu1_u_dst_tmp, *pu1_v_dst_tmp;
+ WORD32 is_u_first;
+ UWORD8 *pu1_luma;
+ UWORD8 *pu1_chroma;
+ WORD32 wd;
+
+ WORD32 src_y_strd;
+ WORD32 src_uv_strd;
+
+ WORD32 layer_id = ps_pic->u1_num_spatial_layers - 1;
+
+ if(0 == num_rows)
+ {
+ return ret;
+ }
+
+ pu1_luma = ps_pic->ps_layer_yuv_buf_props[layer_id].as_component_bufs[0].pv_data;
+ pu1_chroma = ps_pic->ps_layer_yuv_buf_props[layer_id].as_component_bufs[1].pv_data;
+
+ src_y_strd = ps_pic->ps_layer_yuv_buf_props[layer_id].as_component_bufs[0].i4_data_stride;
+ src_uv_strd = ps_pic->ps_layer_yuv_buf_props[layer_id].as_component_bufs[1].i4_data_stride;
+
+ wd = ps_codec->s_cfg.u4_disp_wd;
+ is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0;
+
+ /* In case of 420P output luma copy is disabled for shared mode */
+ {
+ pu1_y_src = pu1_luma + cur_row * src_y_strd;
+ pu1_uv_src = pu1_chroma + (cur_row / 2) * src_uv_strd;
+
+ pu1_y_dst_tmp = pu1_y_dst + cur_row * u4_dst_y_strd;
+ pu1_uv_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
+ pu1_u_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
+ pu1_v_dst_tmp = pu1_v_dst + (cur_row / 2) * u4_dst_uv_strd;
+
+ /* If the call is non-blocking and there are no rows to be copied then
+ * return */
+ /* In non-shared mode, reference buffers are in 420SP UV format,
+ * if output also is in 420SP_UV, then just copy
+ * if output is in 420SP_VU then swap UV values
+ */
+ if((IV_YUV_420SP_UV == ps_codec->s_cfg.e_recon_color_fmt) ||
+ (IV_YUV_420SP_VU == ps_codec->s_cfg.e_recon_color_fmt))
+ {
+ ih264e_fmt_conv_420sp_to_420sp(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, pu1_uv_dst_tmp, wd,
+ num_rows, ps_codec->i4_rec_strd, ps_codec->i4_rec_strd,
+ u4_dst_y_strd, u4_dst_uv_strd);
+ }
+ else if(IV_YUV_420P == ps_codec->s_cfg.e_recon_color_fmt)
+ {
+ ih264e_fmt_conv_420sp_to_420p(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, pu1_u_dst_tmp,
+ pu1_v_dst_tmp, wd, num_rows, ps_codec->i4_rec_strd,
+ ps_codec->i4_rec_strd, u4_dst_y_strd, u4_dst_uv_strd,
+ is_u_first, 0);
+ }
+ }
+ return (ret);
+}
diff --git a/encoder/svc/isvce_fmt_conv.h b/encoder/svc/isvce_fmt_conv.h
new file mode 100644
index 0000000..d8d0ccf
--- /dev/null
+++ b/encoder/svc/isvce_fmt_conv.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* ih264e_fmt_conv.h
+*
+* @brief
+* The file contains extern declarations of color space conversion routines
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_FMT_CONV_H_
+#define _ISVCE_FMT_CONV_H_
+
+#include "ih264e_fmt_conv.h"
+#include "isvce_structs.h"
+
+IH264E_ERROR_T isvce_fmt_conv(isvce_codec_t *ps_codec, svc_au_buf_t *ps_pic, UWORD8 *pu1_y_dst,
+ UWORD8 *pu1_u_dst, UWORD8 *pu1_v_dst, UWORD32 u4_dst_y_strd,
+ UWORD32 u4_dst_uv_strd, WORD32 cur_row, WORD32 num_rows);
+
+#endif
diff --git a/encoder/svc/isvce_function_selector_generic.c b/encoder/svc/isvce_function_selector_generic.c
new file mode 100644
index 0000000..044bbeb
--- /dev/null
+++ b/encoder/svc/isvce_function_selector_generic.c
@@ -0,0 +1,314 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector_generic.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_init_function_ptr_generic
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_cabac.h"
+#include "isvce_core_coding.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_intra_modes_eval.h"
+#include "ih264e_fmt_conv.h"
+#include "ih264e_half_pel.h"
+#include "isvce_me.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_generic(isvce_codec_t *ps_codec)
+{
+ WORD32 i = 0;
+
+ /* curr proc ctxt */
+ isvce_process_ctxt_t *ps_proc = NULL;
+ isvce_me_ctxt_t *ps_me_ctxt = NULL;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 16x16 */
+ ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert;
+ ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz;
+ ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc;
+ ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 4x4 */
+ ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert;
+ ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz;
+ ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc;
+ ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl;
+ ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr;
+ ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r;
+ ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d;
+ ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l;
+ ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert;
+ ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc;
+ ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl;
+ ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr;
+ ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r;
+ ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d;
+ ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l;
+ ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u;
+
+ /* Init function pointers for intra pred leaf level functions chroma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_c[0] = ih264_intra_pred_chroma_8x8_mode_dc;
+ ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz;
+ ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert;
+ ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane;
+
+ /* Init luma forward transform fn ptr */
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_8x8) /
+ sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_8x8[0])) ==
+ NUM_RESI_TRANS_QUANT_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_4x4) /
+ sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_4x4[0])) ==
+ NUM_RESI_TRANS_QUANT_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4) /
+ sizeof(ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[0])) ==
+ NUM_RESI_TRANS_QUANT_VARIANTS);
+
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[0] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[0] = isvc_resi_trans_quant_4x4;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[0] = isvc_resi_trans_quant_chroma_4x4;
+ ps_enc_loop_fxns->apf_resi_trans_quant_8x8[1] = isvc_resi_trans_quant_8x8;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[1] = isvc_resi_trans_quant_4x4;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[1] = isvc_resi_trans_quant_chroma_4x4;
+ ps_enc_loop_fxns->pf_hadamard_quant_4x4 = isvc_hadamard_quant_4x4;
+ ps_enc_loop_fxns->pf_hadamard_quant_2x2_uv = isvc_hadamard_quant_2x2_uv;
+
+ /* Init inverse transform fn ptr */
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8) /
+ sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[0])) == NUM_IQ_IT_RECON_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4) /
+ sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[0])) == NUM_IQ_IT_RECON_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc) /
+ sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[0])) ==
+ NUM_IQ_IT_RECON_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4) /
+ sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[0])) ==
+ NUM_IQ_IT_RECON_VARIANTS);
+ ASSERT((sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc) /
+ sizeof(ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[0])) ==
+ NUM_IQ_IT_RECON_VARIANTS);
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[0] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[0] = isvc_iquant_itrans_recon_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[0] = isvc_iquant_itrans_recon_4x4_dc;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[0] = isvc_iquant_itrans_recon_chroma_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[0] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[1] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[1] = isvc_iquant_itrans_recon_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[1] = isvc_iquant_itrans_recon_4x4_dc;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[1] = isvc_iquant_itrans_recon_chroma_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[1] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_8x8[2] = isvc_iquant_itrans_recon_8x8;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[2] = isvc_iquant_itrans_recon_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[2] = isvc_iquant_itrans_recon_4x4_dc;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[2] = isvc_iquant_itrans_recon_chroma_4x4;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc;
+ ps_enc_loop_fxns->pf_zcbf_iquant_itrans_recon_4x4 = isvc_zcbf_iquant_itrans_recon_4x4;
+ ps_enc_loop_fxns->pf_chroma_zcbf_iquant_itrans_recon_4x4 =
+ isvc_chroma_zcbf_iquant_itrans_recon_4x4;
+
+ ps_enc_loop_fxns->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4;
+ ps_enc_loop_fxns->pf_ihadamard_scaling_2x2_uv = ih264_ihadamard_scaling_2x2_uv;
+
+ /* Init fn ptr luma core coding */
+ ps_enc_loop_fxns->apf_luma_energy_compaction[0] = isvce_code_luma_intra_macroblock_16x16;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[1] = isvce_code_luma_intra_macroblock_4x4;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[3] = isvce_code_luma_inter_macroblock_16x16;
+
+ /* Init fn ptr chroma core coding */
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[0] = isvce_code_chroma_intra_macroblock_8x8;
+ ps_enc_loop_fxns->apf_chroma_energy_compaction[1] = isvce_code_chroma_inter_macroblock_8x8;
+
+ /* Init fn ptr luma deblocking */
+ ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4;
+ ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4;
+ ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4;
+ ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4;
+
+ /* Init fn ptr chroma deblocking */
+ ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4;
+ ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4;
+ ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4;
+ ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4;
+
+ /* write mb syntax layer */
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][ISLICE] = isvce_write_islice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][PSLICE] = isvce_write_pslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CAVLC][BSLICE] = isvce_write_bslice_mb_cavlc;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][ISLICE] = isvce_write_islice_mb_cabac;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][PSLICE] = isvce_write_pslice_mb_cabac;
+ ps_codec->pf_write_mb_syntax_layer[CABAC][BSLICE] = isvce_write_bslice_mb_cabac;
+
+ /* Padding Functions */
+ ps_codec->pf_pad_top = ih264_pad_top;
+ ps_codec->pf_pad_bottom = ih264_pad_bottom;
+ ps_codec->pf_pad_left_luma = ih264_pad_left_luma;
+ ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma;
+ ps_codec->pf_pad_right_luma = ih264_pad_right_luma;
+ ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma;
+
+ /* Inter pred leaf level functions */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy;
+ ps_inter_pred_fxns->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz;
+ ps_inter_pred_fxns->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert;
+ ps_inter_pred_fxns->pf_inter_pred_luma_bilinear = ih264_inter_pred_luma_bilinear;
+ ps_inter_pred_fxns->pf_inter_pred_chroma = ih264_inter_pred_chroma;
+
+ /* sad me level functions */
+ ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16;
+ ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast;
+ ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8;
+
+ /* memory handling operations */
+ ps_mem_fxns->pf_mem_cpy = ih264_memcpy;
+ ps_mem_fxns->pf_mem_cpy_mul8 = ih264_memcpy_mul_8;
+ ps_mem_fxns->pf_mem_set = ih264_memset;
+ ps_mem_fxns->pf_mem_set_mul8 = ih264_memset_mul_8;
+ ps_mem_fxns->pf_copy_2d = isvc_copy_2d;
+ ps_mem_fxns->pf_memset_2d = isvc_memset_2d;
+ ps_mem_fxns->pf_16bit_interleaved_copy = isvc_16bit_interleaved_copy;
+ ps_mem_fxns->pf_16bit_interleaved_memset = isvc_16bit_interleaved_memset;
+ ps_mem_fxns->pf_nonzero_checker = isvc_is_nonzero_blk;
+
+ /* sad me level functions */
+ for(i = 0; i < (MAX_PROCESS_CTXT); i++)
+ {
+ ps_proc = &ps_codec->as_process[i];
+
+ ps_me_ctxt = &ps_proc->s_me_ctxt;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast;
+ ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8;
+ ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog;
+ ps_me_ctxt->pf_ime_compute_sad3_diamond = ime_calculate_sad3_prog;
+ ps_me_ctxt->pf_ime_compute_sad2_diamond = ime_calculate_sad2_prog;
+ ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16;
+ ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter;
+ }
+
+ /* intra mode eval -encoder level function */
+ ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes;
+ ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes;
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes;
+
+ /* csc */
+ ps_codec->pf_ih264e_conv_420p_to_420sp = ih264e_fmt_conv_420p_to_420sp;
+ ps_codec->pf_ih264e_fmt_conv_422i_to_420sp = ih264e_fmt_conv_422i_to_420sp;
+
+ /* Halp pel generation function - encoder level*/
+ ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz;
+ ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert;
+
+ /* ME compute */
+ ps_codec->apf_compute_me[PSLICE] = &isvce_compute_me_single_reflist;
+ ps_codec->apf_compute_me[BSLICE] = &isvce_compute_me_multi_reflist;
+
+ /* skip decision */
+ ps_codec->apf_find_skip_params_me[PSLICE] = &isvce_find_pskip_params_me;
+ ps_codec->apf_find_skip_params_me[BSLICE] = &isvce_find_bskip_params_me;
+}
diff --git a/encoder/svc/isvce_globals.c b/encoder/svc/isvce_globals.c
new file mode 100644
index 0000000..966c5e8
--- /dev/null
+++ b/encoder/svc/isvce_globals.c
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_globals.c
+*
+* @brief
+* Contains definitions of global variables used across the encoder
+*
+* @author
+* ittiam
+*
+* @par List of functions
+*
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include "ih264_typedefs.h"
+#include "ih264_defs.h"
+
+/* Raster to z scan map */
+const UWORD8 gau1_raster_to_zscan_map[MAX_TU_IN_MB] = {0, 1, 4, 5, 2, 3, 6, 7,
+ 8, 9, 12, 13, 10, 11, 14, 15};
diff --git a/encoder/svc/isvce_globals.h b/encoder/svc/isvce_globals.h
new file mode 100644
index 0000000..6e04a50
--- /dev/null
+++ b/encoder/svc/isvce_globals.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_globals.h
+*
+* @brief
+* Contains declarations of global variables for H264 encoder
+*
+* @author
+* Ittiam
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_GLOBALS_H_
+#define _ISVCE_GLOBALS_H_
+
+#include "ih264e_globals.h"
+
+extern const UWORD8 gau1_raster_to_zscan_map[MAX_TU_IN_MB];
+
+#endif
diff --git a/encoder/svc/isvce_ibl_eval.c b/encoder/svc/isvce_ibl_eval.c
new file mode 100644
index 0000000..d5eb62d
--- /dev/null
+++ b/encoder/svc/isvce_ibl_eval.c
@@ -0,0 +1,1378 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_ibl_eval.c
+*
+* @brief
+* Contains functions used for SVC intra prediction
+*
+*******************************************************************************
+*/
+#include <math.h>
+#include <limits.h>
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "ih264_padding.h"
+#include "isvce_defs.h"
+#include "isvce_ibl_private_defs.h"
+#include "isvce_ibl_eval.h"
+#include "isvce_utils.h"
+#include "isvc_intra_resample.h"
+#include "isvc_defs.h"
+
+static FORCEINLINE WORD32 isvce_get_num_mb_states(UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ return (u4_wd / MB_SIZE) * (u4_ht / MB_SIZE);
+}
+
+static FORCEINLINE WORD32 isvce_get_phase_array_size(DOUBLE d_spatial_res_ratio, bool b_is_chroma)
+{
+ return (2 == d_spatial_res_ratio) ? (b_is_chroma ? 3 : 0) : 5;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing residual pred ctxt
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @param[in] u4_ht
+* Input Height
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_svc_intra_pred_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ WORD32 i, j;
+
+ UWORD32 u4_size = 0;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ u4_size += MAX_PROCESS_CTXT * sizeof(svc_intra_pred_ctxt_t);
+ u4_size += MAX_PROCESS_CTXT * sizeof(intra_pred_state_t);
+ u4_size += MAX_PROCESS_CTXT * u1_num_spatial_layers * sizeof(intra_pred_layer_state_t);
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ WORD32 i4_layer_luma_wd =
+ (WORD32) ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_wd_mbs = i4_layer_luma_wd / MB_SIZE;
+ WORD32 i4_layer_ht_mbs = i4_layer_luma_ht / MB_SIZE;
+ /*Add PAD Mbs */
+ WORD32 i4_layer_luma_mbs =
+ ((i4_layer_luma_wd / MB_SIZE) + 2) * ((i4_layer_luma_ht / MB_SIZE) + 2);
+ WORD32 i4_num_mb_states = isvce_get_num_mb_states(i4_layer_luma_wd, i4_layer_luma_ht);
+
+ for(j = 0; j < NUM_SP_COMPONENTS; j++)
+ {
+ bool b_is_chroma = ((COMPONENT_TYPE) j) != Y;
+
+ u4_size += i4_num_mb_states * sizeof(intra_pred_mb_state_t);
+
+ /* pi4_ref_array_positions_x */
+ u4_size += MAX_REF_ARR_WD_HT * i4_layer_wd_mbs * sizeof(WORD32);
+
+ /* pi4_ref_array_positions_y */
+ u4_size += (i4_layer_ht_mbs >> b_is_chroma) * i4_layer_ht_mbs * sizeof(WORD32);
+
+ /* ps_ref_array_phases */
+ u4_size += isvce_get_phase_array_size(d_spatial_res_ratio, b_is_chroma) *
+ sizeof(coordinates_t);
+ }
+
+ /* pi1_mb_mode */
+ u4_size += i4_layer_luma_mbs * sizeof(WORD8);
+
+ /* pu1_refarray_buffer */
+ u4_size += MAX_PROCESS_CTXT * TEMP_BUF_SIZE_LUMA * sizeof(UWORD8);
+
+ /* pu1_refarray_cb, pu1_refarray_cr */
+ u4_size += MAX_PROCESS_CTXT * (TEMP_BUF_SIZE_CB + TEMP_BUF_SIZE_CR) * sizeof(UWORD8);
+
+ /* pi4_temp_interpolation_buffer */
+ u4_size += MAX_PROCESS_CTXT * TEMP_INTERPOLATION_BUF_SIZE * sizeof(WORD32);
+ }
+
+ /* intra_pred_outputs_t.s_pred_buf */
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * MB_SIZE * sizeof(UWORD8);
+
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * MB_SIZE * sizeof(UWORD8);
+ }
+
+ return u4_size;
+}
+
+static FORCEINLINE WORD32 isvce_get_scaled_pixel_pos(layer_resampler_props_t *ps_layer_props,
+ WORD32 i4_pixel_pos, UWORD8 u1_dim_id)
+{
+ if(1 == u1_dim_id)
+ {
+ return (((i4_pixel_pos - ps_layer_props->i4_offset_y) *
+ ((WORD64) ps_layer_props->u4_scale_y) +
+ ps_layer_props->i4_add_y) >>
+ (ps_layer_props->u4_shift_y - 4)) -
+ ps_layer_props->i4_delta_y;
+ }
+ else
+ {
+ return (((i4_pixel_pos - ps_layer_props->i4_offset_x) *
+ ((WORD64) ps_layer_props->u4_scale_x) +
+ ps_layer_props->i4_add_x) >>
+ (ps_layer_props->u4_shift_x - 4)) -
+ ps_layer_props->i4_delta_x;
+ }
+}
+
+static FORCEINLINE void isvce_ref_array_pos_init(
+ layer_resampler_props_t *ps_layer_props, intra_pred_mb_state_t *ps_mb_state,
+ coordinates_t *ps_mb_pos, DOUBLE d_spatial_res_ratio, UWORD8 u1_frame_mbs_only_flag,
+ UWORD8 u1_field_mb_flag, UWORD8 u1_ref_layer_frame_mbs_only_flag)
+{
+ if(1.5 == d_spatial_res_ratio)
+ {
+ UWORD32 i;
+
+ WORD32 *pi4_ref_array_positions_x = ps_mb_state->pi4_ref_array_positions_x;
+ WORD32 *pi4_ref_array_positions_y = ps_mb_state->pi4_ref_array_positions_y;
+ WORD32 i4_x_offset = ps_mb_state->s_offsets.i4_abscissa;
+ WORD32 i4_y_offset = ps_mb_state->s_offsets.i4_ordinate;
+
+ if(0 == ps_mb_pos->i4_abscissa)
+ {
+ for(i = 0; i < ps_layer_props->u4_mb_ht; i++)
+ {
+ WORD32 i4_y_ref16;
+
+ WORD32 i4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + i;
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - u1_field_mb_flag);
+ }
+
+ i4_y_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_yc, 1);
+
+ pi4_ref_array_positions_y[i] = (i4_y_ref16 >> 4) - i4_y_offset;
+ }
+ }
+
+ if(0 == ps_mb_pos->i4_ordinate)
+ {
+ for(i = 0; i < MAX_REF_ARR_WD_HT; i++)
+ {
+ WORD32 i4_x_ref16;
+
+ WORD32 i4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + i;
+
+ i4_x_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_xc, 0);
+
+ pi4_ref_array_positions_x[i] = (i4_x_ref16 >> 4) - i4_x_offset;
+ }
+ }
+ }
+}
+
+static FORCEINLINE void isvce_ref_array_phase_init(
+ layer_resampler_props_t *ps_layer_props, intra_pred_mb_state_t *ps_mb_state,
+ coordinates_t *ps_mb_pos, DOUBLE d_spatial_res_ratio, UWORD8 u1_frame_mbs_only_flag,
+ UWORD8 u1_field_mb_flag, UWORD8 u1_ref_layer_frame_mbs_only_flag)
+{
+ UWORD32 i, j;
+
+ coordinates_t *ps_ref_array_phases = ps_mb_state->ps_ref_array_phases;
+
+ WORD32 i4_x_offset = ps_mb_state->s_offsets.i4_abscissa;
+ WORD32 i4_y_offset = ps_mb_state->s_offsets.i4_ordinate;
+ UWORD32 u4_phase_array_idx = 0;
+
+ if(1.5 == d_spatial_res_ratio)
+ {
+ for(i = 0; i < 3; i++)
+ {
+ WORD32 i4_y_ref16;
+
+ WORD32 i4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + i;
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - u1_field_mb_flag);
+ }
+
+ i4_y_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_yc, 1);
+
+ for(j = 0; j < ((0 == i) ? 3 : 1); j++)
+ {
+ WORD32 i4_x_ref16;
+
+ WORD32 i4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + j;
+
+ i4_x_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_xc, 0);
+
+ ps_ref_array_phases[u4_phase_array_idx].i4_abscissa = i4_x_ref16 & 15;
+ ps_ref_array_phases[u4_phase_array_idx].i4_ordinate = i4_y_ref16 & 15;
+
+ u4_phase_array_idx++;
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 i4_y_ref16;
+
+ WORD32 i4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + i;
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - u1_field_mb_flag);
+ }
+
+ i4_y_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_yc, 1);
+
+ for(j = 0; j < ((0 == i) ? 2 : 1); j++)
+ {
+ WORD32 i4_x_ref16;
+
+ WORD32 i4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + j;
+
+ i4_x_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_xc, 0);
+
+ ps_ref_array_phases[u4_phase_array_idx].i4_abscissa =
+ (i4_x_ref16 - (16 * i4_x_offset)) & 15;
+ ps_ref_array_phases[u4_phase_array_idx].i4_ordinate =
+ (i4_y_ref16 - (16 * i4_y_offset)) & 15;
+
+ u4_phase_array_idx++;
+ }
+ }
+ }
+}
+
+static FORCEINLINE void isvce_set_mb_states(layer_resampler_props_t *ps_layer_props,
+ intra_pred_mb_state_t *ps_mb_states,
+ coordinates_t *ps_mb_pos, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd_in_mbs, bool b_is_chroma)
+{
+ WORD32 i4_x_refmin16;
+ WORD32 i4_x_refmax16;
+ WORD32 i4_y_refmin16;
+ WORD32 i4_y_refmax16;
+ WORD32 i4_x_offset, i4_y_offset;
+
+ const UWORD8 u1_frame_mbs_only_flag = 1;
+ const UWORD8 u1_ref_layer_frame_mbs_only_flag = 1;
+ const UWORD8 u1_field_mb_flag = 0;
+
+ i4_x_refmin16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props, ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd, 0);
+ i4_x_refmax16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props,
+ ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + ps_layer_props->u4_mb_wd - 1, 0);
+
+ i4_y_refmin16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props, ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht, 1);
+ i4_y_refmax16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props,
+ ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + ps_layer_props->u4_mb_ht - 1, 1);
+
+ i4_x_offset = (i4_x_refmin16 >> 4);
+ i4_y_offset = (i4_y_refmin16 >> 4);
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_offsets.i4_abscissa = i4_x_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_offsets.i4_ordinate = i4_y_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_ref_array_dims.i4_abscissa = (((i4_x_refmax16 + 15) >> 8) << 4) +
+ ((WORD32) (ps_layer_props->u4_mb_wd >> 1)) - i4_x_offset +
+ 16;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_ref_array_dims.i4_ordinate = (((i4_y_refmax16 + 15) >> 8) << 4) +
+ ((WORD32) (ps_layer_props->u4_mb_ht >> 1)) - i4_y_offset +
+ 16;
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_max_pos.i4_abscissa = ((i4_x_refmax16 + 15) >> 4) - i4_x_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_max_pos.i4_ordinate = ((i4_y_refmax16 + 15) >> 4) - i4_y_offset;
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_min_pos.i4_abscissa = (i4_x_refmin16 >> 4) - i4_x_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_min_pos.i4_ordinate = (i4_y_refmin16 >> 4) - i4_y_offset;
+
+ if((1.5 == d_spatial_res_ratio) &&
+ ((0 == ps_mb_pos->i4_abscissa) || (0 == ps_mb_pos->i4_ordinate)))
+ {
+ WORD32 i4_min, i4_max, i4_xr_index, i4_yr_index, i4_ref_array_wd, i4_ref_array_ht;
+
+ i4_x_offset = i4_x_offset - 2;
+ i4_ref_array_wd = ((i4_x_refmax16 + 15) >> 4) - (i4_x_refmin16 >> 4) + 1 + 4;
+
+ i4_min = i4_x_offset;
+ i4_xr_index = i4_min - ((i4_min / (WORD32) ps_layer_props->u4_mb_wd) *
+ (WORD32) ps_layer_props->u4_mb_wd);
+
+ if(i4_xr_index < (WORD32) (ps_layer_props->u4_mb_wd >> 1))
+ {
+ i4_ref_array_wd = i4_ref_array_wd + (ps_layer_props->u4_mb_wd >> 1);
+ i4_x_offset = i4_x_offset - ((WORD32) (ps_layer_props->u4_mb_wd >> 1));
+ }
+
+ i4_max = ((i4_x_refmax16 + 15) >> 4) + 2;
+ i4_xr_index = i4_max - ((i4_max / (WORD32) ps_layer_props->u4_mb_wd) *
+ (WORD32) ps_layer_props->u4_mb_wd);
+
+ if(i4_xr_index >= (WORD32) (ps_layer_props->u4_mb_wd >> 1))
+ {
+ i4_ref_array_wd = i4_ref_array_wd + (ps_layer_props->u4_mb_wd >> 1);
+ }
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_ref_array_dims.i4_abscissa = i4_ref_array_wd;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_offsets.i4_abscissa = i4_x_offset;
+
+ i4_ref_array_ht = ((i4_y_refmax16 + 15) >> 4) - (i4_y_refmin16 >> 4) + 1 + 4;
+
+ i4_y_offset = (i4_y_refmin16 >> 4) - 2;
+
+ i4_min = i4_y_offset;
+
+ i4_yr_index = i4_min - ((i4_min / (WORD32) ps_layer_props->u4_mb_ht) *
+ (WORD32) ps_layer_props->u4_mb_ht);
+
+ if(i4_yr_index < (WORD32) (ps_layer_props->u4_mb_ht >> 1))
+ {
+ i4_ref_array_ht = i4_ref_array_ht + (ps_layer_props->u4_mb_ht >> 1);
+ i4_y_offset = i4_y_offset - ((WORD32) (ps_layer_props->u4_mb_ht >> 1));
+ }
+
+ i4_max = ((i4_y_refmax16 + 15) >> 4) + 2;
+ i4_yr_index = i4_max - ((i4_max / (WORD32) ps_layer_props->u4_mb_ht) *
+ (WORD32) ps_layer_props->u4_mb_ht);
+
+ if(i4_yr_index >= (WORD32) (ps_layer_props->u4_mb_ht >> 1))
+ {
+ i4_ref_array_ht = i4_ref_array_ht + (ps_layer_props->u4_mb_ht >> 1);
+ }
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_ref_array_dims.i4_ordinate = i4_ref_array_ht;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_offsets.i4_ordinate = i4_y_offset;
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_max_pos.i4_abscissa = ((i4_x_refmax16 + 15) >> 4) - i4_x_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_max_pos.i4_ordinate = ((i4_y_refmax16 + 15) >> 4) - i4_y_offset;
+
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_min_pos.i4_abscissa = (i4_x_refmin16 >> 4) - i4_x_offset;
+ ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs]
+ .s_min_pos.i4_ordinate = (i4_y_refmin16 >> 4) - i4_y_offset;
+
+ isvce_ref_array_pos_init(
+ ps_layer_props,
+ &ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs],
+ ps_mb_pos, d_spatial_res_ratio, u1_frame_mbs_only_flag, u1_field_mb_flag,
+ u1_ref_layer_frame_mbs_only_flag);
+
+ isvce_ref_array_phase_init(
+ ps_layer_props,
+ &ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs],
+ ps_mb_pos, d_spatial_res_ratio, u1_frame_mbs_only_flag, u1_field_mb_flag,
+ u1_ref_layer_frame_mbs_only_flag);
+ }
+ else if((2. == d_spatial_res_ratio) &&
+ ((0 == ps_mb_pos->i4_abscissa) && (0 == ps_mb_pos->i4_ordinate) && b_is_chroma))
+ {
+ isvce_ref_array_pos_init(
+ ps_layer_props,
+ &ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs],
+ ps_mb_pos, d_spatial_res_ratio, u1_frame_mbs_only_flag, u1_field_mb_flag,
+ u1_ref_layer_frame_mbs_only_flag);
+
+ isvce_ref_array_phase_init(
+ ps_layer_props,
+ &ps_mb_states[ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * u4_wd_in_mbs],
+ ps_mb_pos, d_spatial_res_ratio, u1_frame_mbs_only_flag, u1_field_mb_flag,
+ u1_ref_layer_frame_mbs_only_flag);
+ }
+}
+
+static void isvce_ibl_layer_state_init(intra_pred_layer_state_t *ps_layer_state,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd, UWORD32 u4_ht,
+ UWORD8 u1_level_idc, IV_COLOR_FORMAT_T e_color_format)
+{
+ UWORD32 i, j, k;
+
+ const UWORD8 u1_ref_layer_field_pic_flag = 0;
+ const UWORD8 u1_field_pic_flag = 0;
+ const UWORD8 u1_frame_mbs_only_flag = 1;
+ const UWORD8 u1_ref_layer_frame_mbs_only_flag = 1;
+ const UWORD8 u1_bot_field_flag = 0;
+ const WORD32 i4_scaled_ref_layer_left_offset = 0;
+ const WORD32 i4_scaled_ref_layer_top_offset = 0;
+ const WORD32 i4_ref_layer_chroma_phase_x_plus1 = 1;
+ const WORD32 i4_ref_layer_chroma_phase_y_plus1 = 1;
+ const WORD32 i4_chroma_phase_x_plus1 = 1;
+ const WORD32 i4_chroma_phase_y_plus1 = 1;
+ const WORD32 i4_sub_wd_chroma = 2;
+ const WORD32 i4_sub_ht_chroma = 2;
+
+ ASSERT((IV_YUV_420P == e_color_format) || (IV_YUV_420SP_UV == e_color_format));
+
+ UNUSED(e_color_format);
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ intra_pred_mb_state_t *ps_mb_states;
+ layer_resampler_props_t *ps_layer_props;
+
+ UWORD32 u4_wd_in_mbs;
+ UWORD32 u4_ht_in_mbs;
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+ UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
+ UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
+ UWORD32 u4_scaled_wd = u4_wd;
+ UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
+
+ ps_mb_states =
+ u1_is_chroma ? ps_layer_state->ps_chroma_mb_states : ps_layer_state->ps_luma_mb_states;
+ ps_layer_props =
+ u1_is_chroma ? ps_layer_state->ps_chroma_props : ps_layer_state->ps_luma_props;
+
+ u4_ref_wd = u4_ref_wd >> u1_is_chroma;
+ u4_ref_ht = u4_ref_ht >> u1_is_chroma;
+ u4_scaled_wd = u4_scaled_wd >> u1_is_chroma;
+ u4_scaled_ht = u4_scaled_ht >> u1_is_chroma;
+
+ if(u1_is_chroma)
+ {
+ ps_layer_props->i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1 - 1;
+ ps_layer_props->i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
+ ps_layer_props->i4_phase_x = i4_chroma_phase_x_plus1 - 1;
+ ps_layer_props->i4_phase_y = i4_chroma_phase_y_plus1 - 1;
+ ps_layer_props->u4_sub_wd = i4_sub_wd_chroma;
+ ps_layer_props->u4_sub_ht = i4_sub_ht_chroma;
+ ps_layer_props->u4_mb_wd = MB_SIZE >> 1;
+ ps_layer_props->u4_mb_ht = MB_SIZE >> 1;
+ }
+ else
+ {
+ ps_layer_props->i4_refphase_x = 0;
+ ps_layer_props->i4_refphase_y = 0;
+ ps_layer_props->i4_phase_x = 0;
+ ps_layer_props->i4_phase_y = 0;
+ ps_layer_props->u4_sub_wd = 1;
+ ps_layer_props->u4_sub_ht = 1;
+ ps_layer_props->u4_mb_wd = MB_SIZE;
+ ps_layer_props->u4_mb_ht = MB_SIZE;
+ }
+
+ u4_wd_in_mbs = u4_scaled_wd / ps_layer_props->u4_mb_wd;
+ u4_ht_in_mbs = u4_scaled_ht / ps_layer_props->u4_mb_ht;
+
+ if(u1_level_idc <= 30)
+ {
+ ps_layer_props->u4_shift_x = 16;
+ ps_layer_props->u4_shift_y = 16;
+ }
+ else
+ {
+ ps_layer_props->u4_shift_x = 31 - isvcd_get_ceil_log2(u4_ref_wd);
+ ps_layer_props->u4_shift_y = 31 - isvcd_get_ceil_log2(u4_ref_ht);
+ }
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ if(1 == u1_ref_layer_frame_mbs_only_flag)
+ {
+ ps_layer_props->i4_phase_y = ps_layer_props->i4_phase_y + (4 * u1_bot_field_flag) +
+ 3 - ps_layer_props->u4_sub_ht;
+ ps_layer_props->i4_refphase_y = (2 * ps_layer_props->i4_refphase_y) + 2;
+ }
+ else
+ {
+ ps_layer_props->i4_phase_y = ps_layer_props->i4_phase_y + 4 * u1_bot_field_flag;
+ ps_layer_props->i4_refphase_y =
+ ps_layer_props->i4_refphase_y + (4 * u1_bot_field_flag);
+ }
+ }
+
+ ps_layer_props->u4_scale_x =
+ ((u4_ref_wd << ps_layer_props->u4_shift_x) + (u4_scaled_wd >> 1)) / (u4_scaled_wd);
+ ps_layer_props->u4_scale_y =
+ ((u4_ref_ht << ps_layer_props->u4_shift_y) + (u4_scaled_ht >> 1)) / (u4_scaled_ht);
+
+ ps_layer_props->i4_offset_x = i4_scaled_ref_layer_left_offset / ps_layer_props->u4_sub_wd;
+ ps_layer_props->i4_add_x =
+ (((u4_ref_wd * (2 + ps_layer_props->i4_phase_x)) << (ps_layer_props->u4_shift_x - 2)) +
+ (u4_scaled_wd >> 1)) /
+ u4_scaled_wd +
+ (1 << (ps_layer_props->u4_shift_x - 5));
+ ps_layer_props->i4_delta_x = 4 * (2 + ps_layer_props->i4_refphase_x);
+
+ if((1 == u1_frame_mbs_only_flag) && (1 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ ps_layer_props->i4_offset_y =
+ i4_scaled_ref_layer_top_offset / ps_layer_props->u4_sub_ht;
+ ps_layer_props->i4_add_y = (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y))
+ << (ps_layer_props->u4_shift_y - 2)) +
+ (u4_scaled_ht >> 1)) /
+ u4_scaled_ht +
+ (1 << (ps_layer_props->u4_shift_y - 5));
+ ps_layer_props->i4_delta_y = 4 * (2 + ps_layer_props->i4_refphase_y);
+ }
+ else
+ {
+ ps_layer_props->i4_offset_y =
+ i4_scaled_ref_layer_top_offset / (2 * ps_layer_props->u4_sub_ht);
+ ps_layer_props->i4_add_y = (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y))
+ << (ps_layer_props->u4_shift_y - 3)) +
+ (u4_scaled_ht >> 1)) /
+ u4_scaled_ht +
+ (1 << (ps_layer_props->u4_shift_y - 5));
+ ps_layer_props->i4_delta_y = 2 * (2 + ps_layer_props->i4_refphase_y);
+ }
+
+ for(j = 0; j < u4_ht_in_mbs; j++)
+ {
+ for(k = 0; k < u4_wd_in_mbs; k++)
+ {
+ coordinates_t s_mb_pos = {k, j};
+
+ isvce_set_mb_states(ps_layer_props, ps_mb_states, &s_mb_pos, d_spatial_res_ratio,
+ u4_wd_in_mbs, u1_is_chroma);
+ }
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc ilp buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_intra_pred_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ intra_pred_state_t *ps_intra_pred_state;
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt;
+ intra_pred_mb_state_t *aps_luma_mb_states[MAX_NUM_SPATIAL_LAYERS];
+ intra_pred_mb_state_t *aps_chroma_mb_states[MAX_NUM_SPATIAL_LAYERS];
+
+ WORD32 i, j, k, l, m;
+ WORD8 *api4_mb_modes[MAX_NUM_SPATIAL_LAYERS];
+
+ isvce_process_ctxt_t *ps_proc = ps_codec->as_process;
+
+ const WORD32 i4_num_proc_ctxts = sizeof(ps_codec->as_process) / sizeof(ps_codec->as_process[0]);
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size = isvce_get_svc_intra_pred_ctxt_size(
+ u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ if(u1_num_spatial_layers > 1)
+ {
+ for(j = 0; j < i4_num_proc_ctxts; j++)
+ {
+ ps_proc = &ps_codec->as_process[j];
+ ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt = (svc_intra_pred_ctxt_t *) pu1_buf;
+ pu1_buf += sizeof(svc_intra_pred_ctxt_t);
+ i8_alloc_mem_size -= sizeof(svc_intra_pred_ctxt_t);
+
+ ps_intra_pred_ctxt->s_intra_pred_constants.pv_state = pu1_buf;
+ ps_intra_pred_state = (intra_pred_state_t *) pu1_buf;
+ pu1_buf += sizeof(intra_pred_state_t);
+ i8_alloc_mem_size -= sizeof(intra_pred_state_t);
+
+ ps_intra_pred_state->ps_layer_state = (intra_pred_layer_state_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_intra_pred_state->ps_layer_state[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_intra_pred_state->ps_layer_state[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ intra_pred_layer_state_t *ps_layer_state = &ps_intra_pred_state->ps_layer_state[i];
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_wd_mbs = i4_layer_luma_wd / MB_SIZE;
+ WORD32 i4_layer_ht_mbs = i4_layer_luma_ht / MB_SIZE;
+ /* Add PAD MBs on all directions */
+ WORD32 i4_layer_luma_mbs =
+ ((i4_layer_luma_wd / MB_SIZE) + 2) * ((i4_layer_luma_ht / MB_SIZE) + 2);
+ WORD32 i4_num_mb_states =
+ isvce_get_num_mb_states(i4_layer_luma_wd, i4_layer_luma_ht);
+
+ if(0 == j)
+ {
+ UWORD32 au4_ref_xpos_array_size[NUM_SP_COMPONENTS];
+ UWORD32 au4_ref_ypos_array_size[NUM_SP_COMPONENTS];
+ UWORD32 au4_ref_phase_array_size[NUM_SP_COMPONENTS];
+
+ for(k = 0; k < NUM_SP_COMPONENTS; k++)
+ {
+ bool b_is_chroma = ((COMPONENT_TYPE) k) != Y;
+
+ au4_ref_xpos_array_size[k] = MAX_REF_ARR_WD_HT;
+ au4_ref_ypos_array_size[k] = (i4_layer_ht_mbs >> b_is_chroma);
+ au4_ref_phase_array_size[k] =
+ isvce_get_phase_array_size(d_spatial_res_ratio, b_is_chroma);
+ }
+
+ ps_layer_state->ps_luma_mb_states = (intra_pred_mb_state_t *) pu1_buf;
+ aps_luma_mb_states[i] = ps_layer_state->ps_luma_mb_states;
+ pu1_buf += i4_num_mb_states * sizeof(ps_layer_state->ps_luma_mb_states[0]);
+ i8_alloc_mem_size -=
+ i4_num_mb_states * sizeof(ps_layer_state->ps_luma_mb_states[0]);
+
+ ps_layer_state->ps_chroma_mb_states = (intra_pred_mb_state_t *) pu1_buf;
+ aps_chroma_mb_states[i] = ps_layer_state->ps_chroma_mb_states;
+ pu1_buf += i4_num_mb_states * sizeof(ps_layer_state->ps_chroma_mb_states[0]);
+ i8_alloc_mem_size -=
+ i4_num_mb_states * sizeof(ps_layer_state->ps_chroma_mb_states[0]);
+
+ if(1.5 == d_spatial_res_ratio)
+ {
+ for(k = 0; k < NUM_SP_COMPONENTS; k++)
+ {
+ bool b_is_chroma = ((COMPONENT_TYPE) k) != Y;
+
+ WORD32 *pi4_ref_array_positions_x = (WORD32 *) pu1_buf;
+ WORD32 *pi4_ref_array_positions_y =
+ pi4_ref_array_positions_x + MAX_REF_ARR_WD_HT * i4_layer_wd_mbs;
+ coordinates_t *ps_ref_array_phases =
+ (coordinates_t *) (pi4_ref_array_positions_y +
+ (i4_layer_ht_mbs >> b_is_chroma) *
+ i4_layer_ht_mbs);
+ intra_pred_mb_state_t *ps_mb_state =
+ b_is_chroma ? ps_layer_state->ps_chroma_mb_states
+ : ps_layer_state->ps_luma_mb_states;
+
+ for(l = 0; l < i4_layer_ht_mbs; l++)
+ {
+ for(m = 0; m < i4_layer_wd_mbs; m++)
+ {
+ ps_mb_state[l * i4_layer_wd_mbs + m].pi4_ref_array_positions_x =
+ pi4_ref_array_positions_x + m * au4_ref_xpos_array_size[k];
+ ps_mb_state[l * i4_layer_wd_mbs + m].pi4_ref_array_positions_y =
+ pi4_ref_array_positions_y + l * au4_ref_ypos_array_size[k];
+
+ ps_mb_state[l * i4_layer_wd_mbs + m].ps_ref_array_phases =
+ ps_ref_array_phases;
+ }
+ }
+
+ pu1_buf += i4_layer_wd_mbs * au4_ref_xpos_array_size[k] *
+ sizeof(pi4_ref_array_positions_x[0]);
+ pu1_buf += i4_layer_ht_mbs * au4_ref_ypos_array_size[k] *
+ sizeof(pi4_ref_array_positions_y[0]);
+ pu1_buf += au4_ref_phase_array_size[k] * sizeof(ps_ref_array_phases[0]);
+ i8_alloc_mem_size -= i4_layer_wd_mbs * au4_ref_xpos_array_size[k] *
+ sizeof(pi4_ref_array_positions_x[0]);
+ i8_alloc_mem_size -= i4_layer_ht_mbs * au4_ref_ypos_array_size[k] *
+ sizeof(pi4_ref_array_positions_y[0]);
+ i8_alloc_mem_size -=
+ au4_ref_phase_array_size[k] * sizeof(ps_ref_array_phases[0]);
+ }
+ }
+ else
+ {
+ intra_pred_mb_state_t *ps_mb_state;
+ coordinates_t *ps_ref_array_phases;
+
+ for(k = 0; k < NUM_SP_COMPONENTS; k++)
+ {
+ bool b_is_chroma = ((COMPONENT_TYPE) k) != Y;
+
+ ps_mb_state = b_is_chroma ? ps_layer_state->ps_chroma_mb_states
+ : ps_layer_state->ps_luma_mb_states;
+ ps_ref_array_phases = b_is_chroma ? ((coordinates_t *) pu1_buf) : NULL;
+
+ for(l = 0; l < i4_num_mb_states; l++)
+ {
+ ps_mb_state[l].pi4_ref_array_positions_x = NULL;
+ ps_mb_state[l].pi4_ref_array_positions_y = NULL;
+ ps_mb_state[l].ps_ref_array_phases = ps_ref_array_phases;
+ }
+ }
+
+ pu1_buf += au4_ref_phase_array_size[U] * sizeof(ps_ref_array_phases[0]);
+ i8_alloc_mem_size -=
+ au4_ref_phase_array_size[U] * sizeof(ps_ref_array_phases[0]);
+ }
+
+ ps_layer_state->i4_mb_mode_stride = (i4_layer_luma_wd / MB_SIZE) + 2;
+ ps_layer_state->pi1_mb_mode = (WORD8 *) pu1_buf;
+ ps_layer_state->pi1_mb_mode += ps_layer_state->i4_mb_mode_stride + 1;
+ api4_mb_modes[i] = ps_layer_state->pi1_mb_mode;
+ pu1_buf += i4_layer_luma_mbs * sizeof(ps_layer_state->pi1_mb_mode[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_layer_state->pi1_mb_mode[0]);
+ memset(ps_layer_state->pi1_mb_mode, -1, i4_layer_luma_mbs);
+
+ if(i > 0)
+ {
+ /* Asserts below verify that
+ * 'ps_codec->s_svc_ilp_data.aps_layer_resampler_props' is initialised
+ */
+ ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][i].u4_mb_wd ==
+ MB_SIZE);
+ ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][i].u4_mb_wd ==
+ (MB_SIZE / 2));
+
+ ps_layer_state->ps_luma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][i];
+ ps_layer_state->ps_chroma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][i];
+
+ isvce_ibl_layer_state_init(
+ ps_layer_state, d_spatial_res_ratio, i4_layer_luma_wd, i4_layer_luma_ht,
+ ps_codec->s_cfg.u4_max_level, ps_codec->s_cfg.e_inp_color_fmt);
+ }
+ else
+ {
+ ps_layer_state->ps_luma_props = NULL;
+ ps_layer_state->ps_chroma_props = NULL;
+ }
+ }
+ else
+ {
+ ps_layer_state->ps_luma_mb_states = aps_luma_mb_states[i];
+ ps_layer_state->ps_chroma_mb_states = aps_chroma_mb_states[i];
+
+ ps_layer_state->i4_mb_mode_stride = (i4_layer_luma_wd / MB_SIZE) + 2;
+ ps_layer_state->pi1_mb_mode = api4_mb_modes[i];
+
+ if(i > 0)
+ {
+ ps_layer_state->ps_luma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][i];
+ ps_layer_state->ps_chroma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][i];
+ }
+ else
+ {
+ ps_layer_state->ps_luma_props = NULL;
+ ps_layer_state->ps_chroma_props = NULL;
+ }
+ }
+
+ ps_layer_state->pu1_refarray_buffer = (UWORD8 *) pu1_buf;
+ memset(ps_layer_state->pu1_refarray_buffer, 0, TEMP_BUF_SIZE_LUMA * sizeof(UWORD8));
+ pu1_buf += TEMP_BUF_SIZE_LUMA * sizeof(UWORD8);
+ i8_alloc_mem_size -= TEMP_BUF_SIZE_LUMA * sizeof(UWORD8);
+
+ ps_layer_state->pu1_refarray_cb = (UWORD8 *) pu1_buf;
+ memset(ps_layer_state->pu1_refarray_cb, 0, TEMP_BUF_SIZE_CB * sizeof(UWORD8));
+ pu1_buf += TEMP_BUF_SIZE_CB * sizeof(UWORD8);
+ i8_alloc_mem_size -= TEMP_BUF_SIZE_CB * sizeof(UWORD8);
+
+ ps_layer_state->pu1_refarray_cr = (UWORD8 *) pu1_buf;
+ memset(ps_layer_state->pu1_refarray_cr, 0, TEMP_BUF_SIZE_CR * sizeof(UWORD8));
+ pu1_buf += TEMP_BUF_SIZE_CR * sizeof(UWORD8);
+ i8_alloc_mem_size -= TEMP_BUF_SIZE_CR * sizeof(UWORD8);
+
+ ps_layer_state->pi4_temp_interpolation_buffer = (WORD32 *) pu1_buf;
+ pu1_buf += (TEMP_INTERPOLATION_BUF_SIZE * sizeof(WORD32));
+ i8_alloc_mem_size -= (TEMP_INTERPOLATION_BUF_SIZE * sizeof(WORD32));
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+ }
+
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i];
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt;
+ yuv_buf_props_t *ps_mb_intra_pred_buf =
+ &ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf;
+
+ ps_proc->ps_mb_pred_buf = ps_mb_intra_pred_buf;
+
+ for(j = 0; j < NUM_SP_COMPONENTS; j++)
+ {
+ buffer_container_t *ps_comp_buf = &ps_mb_intra_pred_buf->as_component_bufs[j];
+
+ ps_comp_buf->pv_data = pu1_buf;
+ ps_comp_buf->i4_data_stride = MB_SIZE;
+ pu1_buf += MB_SIZE * MB_SIZE * sizeof(UWORD8);
+ i8_alloc_mem_size -= MB_SIZE * MB_SIZE * sizeof(WORD8);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+
+ ps_mb_intra_pred_buf->as_component_bufs[V].pv_data = NULL;
+ ps_mb_intra_pred_buf->e_color_format = IV_YUV_420SP_UV;
+ ps_mb_intra_pred_buf->u1_bit_depth = 16;
+ ps_mb_intra_pred_buf->u4_width = MB_SIZE;
+ ps_mb_intra_pred_buf->u4_height = MB_SIZE;
+ }
+ }
+ else
+ {
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i];
+
+ ps_proc->ps_intra_pred_ctxt = NULL;
+ }
+ }
+}
+
+void isvce_intra_sampling_function_selector(intra_sampling_ctxt_t *ps_ctxt,
+ DOUBLE d_spatial_res_ratio, IV_ARCH_T e_arch)
+{
+ if(2. == d_spatial_res_ratio)
+ {
+ switch(e_arch)
+ {
+#if defined(X86)
+ case ARCH_X86_SSE42:
+ {
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_horz_interpol_chroma =
+ isvc_horz_interpol_chroma_dyadic_sse42;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_vert_interpol_chroma =
+ isvc_vert_interpol_chroma_dyadic_sse42;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_interpolate_luma =
+ isvc_interpolate_base_luma_dyadic_sse42;
+
+ break;
+ }
+#elif defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ {
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_horz_interpol_chroma =
+ isvc_horz_interpol_chroma_dyadic_neon;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_vert_interpol_chroma =
+ isvc_vert_interpol_chroma_dyadic_neon;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_interpolate_luma =
+ isvc_interpolate_base_luma_dyadic_neon;
+
+ break;
+ }
+#elif defined(ARM) && !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ {
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_horz_interpol_chroma =
+ isvc_horz_interpol_chroma_dyadic_neon;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_vert_interpol_chroma =
+ isvc_vert_interpol_chroma_dyadic_neon;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_interpolate_luma =
+ isvc_interpolate_base_luma_dyadic_neon;
+
+ break;
+ }
+#endif
+ default:
+ {
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_horz_interpol_chroma =
+ isvc_horz_interpol_chroma_dyadic;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_vert_interpol_chroma =
+ isvc_vert_interpol_chroma_dyadic;
+ ps_ctxt->as_res_lyrs[ps_ctxt->i4_res_lyr_id].pf_interpolate_luma =
+ isvc_interpolate_base_luma_dyadic;
+
+ break;
+ }
+ }
+ }
+}
+
+static void isvce_get_mb_intra_pred(isvce_process_ctxt_t *ps_proc)
+{
+ mem_element_t s_ref_mb_mode;
+ mem_element_t s_inp_luma;
+ mem_element_t s_inp_chroma;
+ mem_element_t s_out_luma;
+ mem_element_t s_out_chroma;
+
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+
+ WORD32 i4_cur_stride;
+ WORD32 i4_ref_stride;
+ WORD32 i;
+
+ intra_sampling_ctxt_t s_intra_samp_ctxt[NUM_SP_COMPONENTS];
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt;
+ intra_pred_state_t *ps_intra_pred_state =
+ (intra_pred_state_t *) (ps_intra_pred_ctxt->s_intra_pred_constants.pv_state);
+ intra_pred_layer_state_t *ps_layer_state =
+ &ps_intra_pred_state->ps_layer_state[ps_proc->u1_spatial_layer_id];
+ intra_pred_layer_state_t *ps_ref_layer_state =
+ &ps_intra_pred_state->ps_layer_state[ps_proc->u1_spatial_layer_id - 1];
+
+ intra_pred_mb_state_t *ps_luma_mb_state;
+ intra_pred_mb_state_t *ps_chroma_mb_state;
+
+ coordinates_t *ps_mb_pos = &ps_intra_pred_ctxt->s_intra_pred_variables.s_mb_pos;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_intra_pred_ctxt->s_intra_pred_variables.ps_svc_ilp_data;
+
+ s_frame_dims.i4_abscissa =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_luma_mb_state = ps_layer_state->ps_luma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+ ps_chroma_mb_state = ps_layer_state->ps_chroma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ UWORD32 u4_ref_wd, u4_ref_ht;
+
+ bool b_is_chroma = (Y != ((COMPONENT_TYPE) i));
+ mem_element_t *ps_buf = b_is_chroma ? &s_out_chroma : &s_out_luma;
+ intra_pred_mb_state_t *ps_mb_state = b_is_chroma ? ps_chroma_mb_state : ps_luma_mb_state;
+ layer_resampler_props_t *ps_layer_props =
+ b_is_chroma ? ps_layer_state->ps_chroma_props : ps_layer_state->ps_luma_props;
+
+ s_intra_samp_ctxt[i].i4_res_lyr_id = ps_proc->u1_spatial_layer_id;
+
+ s_intra_samp_ctxt[i].i4_refarray_stride = REF_ARRAY_WIDTH;
+ s_intra_samp_ctxt[i].i4_ref_width =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_width;
+ s_intra_samp_ctxt[i].i4_ref_height =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_height;
+
+ isvce_intra_sampling_function_selector(&s_intra_samp_ctxt[i],
+ ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio,
+ ps_codec->s_cfg.e_arch);
+
+ s_intra_samp_ctxt[i].pu1_refarray_buffer = ps_layer_state->pu1_refarray_buffer;
+ s_intra_samp_ctxt[i].pu1_refarray_cb = ps_layer_state->pu1_refarray_cb;
+ s_intra_samp_ctxt[i].pu1_refarray_cr = ps_layer_state->pu1_refarray_cr;
+ s_intra_samp_ctxt[i].pi4_temp_interpolation_buffer =
+ ps_layer_state->pi4_temp_interpolation_buffer;
+
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].ps_mb_pos = ps_mb_pos;
+
+ /* Phase is used only by chroma functions */
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_x_phase_0 =
+ ps_chroma_mb_state->ps_ref_array_phases[0].i4_abscissa;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_x_phase_1 =
+ ps_chroma_mb_state->ps_ref_array_phases[1].i4_abscissa;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_y_phase_0 =
+ ps_chroma_mb_state->ps_ref_array_phases[0].i4_ordinate;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_y_phase_1 =
+ ps_chroma_mb_state->ps_ref_array_phases[2].i4_ordinate;
+ s_intra_samp_ctxt[i]
+ .as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id]
+ .i1_constrained_intra_rsmpl_flag = 0;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_ref_width =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_width;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i4_ref_height =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_height;
+
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i2_x_min_pos =
+ ps_mb_state->s_min_pos.i4_abscissa;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i2_x_max_pos =
+ ps_mb_state->s_max_pos.i4_abscissa;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i2_y_min_pos =
+ ps_mb_state->s_min_pos.i4_ordinate;
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].i2_y_max_pos =
+ ps_mb_state->s_max_pos.i4_ordinate;
+
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].ps_phase =
+ ps_mb_state->ps_ref_array_phases;
+
+ s_intra_samp_ctxt[i]
+ .as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id]
+ .pi4_ref_array_positions_x = ps_mb_state->pi4_ref_array_positions_x;
+ s_intra_samp_ctxt[i]
+ .as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id]
+ .pi4_ref_array_positions_y = ps_mb_state->pi4_ref_array_positions_y;
+
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].ps_offsets =
+ &ps_mb_state->s_offsets;
+
+ s_intra_samp_ctxt[i].as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id].ps_ref_array_dims =
+ &ps_mb_state->s_ref_array_dims;
+
+ i4_cur_stride =
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[i].i4_data_stride;
+ ps_buf->pv_buffer =
+ (UWORD8 *) (ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[i]
+ .pv_data);
+
+ ps_buf->i4_element_size = 1;
+ ps_buf->i4_num_element_stride = i4_cur_stride;
+
+ ps_buf = b_is_chroma ? &s_inp_chroma : &s_inp_luma;
+
+ i4_ref_stride = ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1]
+ .as_component_bufs[i]
+ .i4_data_stride;
+
+ u4_ref_wd = ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_width;
+ u4_ref_ht =
+ ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_height;
+
+ /* For chroma, filteringModeFlag=1 */
+ /* If filteringModeFlag=1, interpolation requires samples at an offset of -1
+ * along both directions */
+ if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.0)
+ {
+ WORD8 i1_x_odd, i1_y_odd;
+
+ ps_buf->pv_buffer =
+ (UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1]
+ .as_component_bufs[i]
+ .pv_data +
+ (ps_mb_state->s_offsets.i4_abscissa << b_is_chroma) +
+ ps_mb_state->s_offsets.i4_ordinate * i4_ref_stride;
+
+ if(!b_is_chroma)
+ {
+ ps_buf->pv_buffer = ((UWORD8 *) ps_buf->pv_buffer) + -1 + -1 * i4_ref_stride;
+ }
+
+ i1_x_odd = (ps_proc->i4_mb_x & 1);
+ i1_y_odd = (ps_proc->i4_mb_y & 1);
+
+ if(i1_x_odd)
+ {
+ ps_buf->pv_buffer = (UWORD8 *) ps_buf->pv_buffer - 8;
+ }
+ if(i1_y_odd)
+ {
+ ps_buf->pv_buffer =
+ (UWORD8 *) ps_buf->pv_buffer - ((8 >> b_is_chroma) * i4_ref_stride);
+ }
+ }
+ else
+ {
+ WORD32 i4_horz_dim = 0;
+ WORD32 i4_vert_dim = 0;
+ WORD32 i4_dim =
+ (WORD32) (ps_mb_state->s_max_pos.i4_abscissa - ps_mb_state->s_min_pos.i4_abscissa) +
+ (4 >> b_is_chroma);
+
+ if(i4_dim > i4_horz_dim)
+ {
+ i4_horz_dim = i4_dim;
+ }
+
+ i4_dim =
+ (WORD32) (ps_mb_state->s_max_pos.i4_ordinate - ps_mb_state->s_min_pos.i4_ordinate) +
+ (4 >> b_is_chroma);
+
+ if(i4_dim > i4_vert_dim)
+ {
+ i4_vert_dim = i4_dim;
+ }
+
+ isvc_intra_resamp_generate_segment_lookup(
+ &(s_intra_samp_ctxt[i]
+ .as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id]
+ .as_seg_lookup_horz[0]),
+ i4_horz_dim, ps_layer_props->u4_mb_wd, 3);
+
+ isvc_intra_resamp_generate_segment_lookup(
+ &(s_intra_samp_ctxt[i]
+ .as_res_lyrs[s_intra_samp_ctxt[i].i4_res_lyr_id]
+ .as_seg_lookup_vert[0]),
+ i4_vert_dim, ps_layer_props->u4_mb_ht, 4);
+
+ ps_buf->pv_buffer =
+ (UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1]
+ .as_component_bufs[i]
+ .pv_data +
+ (CLIP3(0, (WORD32) u4_ref_wd - 1, ps_mb_state->s_offsets.i4_abscissa)
+ << b_is_chroma) +
+ CLIP3(0, (WORD32) u4_ref_ht - 1, ps_mb_state->s_offsets.i4_ordinate) *
+ i4_ref_stride;
+ }
+
+ ps_buf->i4_element_size = 1;
+ ps_buf->i4_num_element_stride = i4_ref_stride;
+ }
+
+ s_ref_mb_mode.i4_element_size = 1;
+ s_ref_mb_mode.i4_num_element_stride =
+ (ps_svc_ilp_data->ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id - 1].u4_width >> 4) + 2;
+ s_ref_mb_mode.pv_buffer = ps_ref_layer_state->pi1_mb_mode;
+
+ if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.0)
+ {
+ isvc_intra_samp_mb_dyadic(&s_intra_samp_ctxt[Y], &s_inp_luma, &s_inp_chroma, &s_ref_mb_mode,
+ &s_out_luma, &s_out_chroma, ps_proc->i4_mb_x, ps_proc->i4_mb_y, 0,
+ 0);
+ }
+ else
+ {
+ isvc_intra_samp_mb(&s_intra_samp_ctxt[Y], &s_intra_samp_ctxt[UV], &s_inp_luma,
+ &s_inp_chroma, &s_ref_mb_mode, &s_out_luma, &s_out_chroma);
+ }
+}
+
+static FORCEINLINE void isvce_get_sad(UWORD8 *pu1_src, UWORD8 *pu1_pred, UWORD32 src_strd,
+ UWORD32 pred_strd, WORD32 *pi4_distortion, UWORD32 u4_width,
+ UWORD32 u4_height)
+{
+ UWORD32 i, j;
+ *pi4_distortion = 0;
+ for(i = 0; i < u4_width; i++)
+ {
+ for(j = 0; j < u4_height; j++)
+ {
+ *pi4_distortion += ABS(pu1_src[j] - pu1_pred[j]);
+ }
+ pu1_src += src_strd;
+ pu1_pred += pred_strd;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate IBL mode
+*
+* @par Description
+* This function evaluates IBL mode for the macro-block
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_IBL_mode(isvce_process_ctxt_t *ps_proc)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt;
+
+ /* SAD(distortion metric) of a block */
+ WORD32 i4_mb_distortion_least = INT_MAX;
+
+ /* cost = distortion + lambda*rate */
+ WORD32 i4_mb_cost_least = INT_MAX;
+
+ WORD32 i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[Y].i4_data_stride;
+
+ UWORD8 *pu1_mb_src = (UWORD8 *) (ps_proc->s_src_buf_props.as_component_bufs[Y].pv_data);
+
+ WORD32 u4_cur_stride =
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[Y].i4_data_stride;
+
+ UWORD8 *pu1_mb_pred =
+ (UWORD8 *) (ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[Y]
+ .pv_data);
+
+ ps_intra_pred_ctxt->s_intra_pred_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
+ ps_intra_pred_ctxt->s_intra_pred_variables.s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
+ ps_intra_pred_ctxt->s_intra_pred_variables.s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
+ ps_intra_pred_ctxt->s_intra_pred_variables.u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+
+ isvce_get_mb_intra_pred(ps_proc);
+
+ /* Luma cost */
+ isvce_get_sad(pu1_mb_src, pu1_mb_pred, i4_src_strd, u4_cur_stride, &i4_mb_distortion_least,
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.u4_width,
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.u4_height);
+
+ /* cost = distortion + lambda*rate */
+ i4_mb_cost_least = i4_mb_distortion_least;
+
+ /* update the type of the mb if necessary */
+ if(i4_mb_cost_least < ps_proc->i4_mb_cost)
+ {
+ ps_proc->i4_mb_cost = i4_mb_cost_least;
+ ps_proc->i4_mb_distortion = i4_mb_distortion_least;
+ ps_proc->ps_mb_info->i4_mb_distortion = i4_mb_distortion_least;
+ ps_proc->ps_mb_info->u2_mb_type = BASE_MODE;
+ ps_proc->ps_mb_info->u1_base_mode_flag = 1;
+ ps_proc->ps_mb_info->u1_is_intra = 1;
+ }
+ else if(ps_proc->ps_mb_info->u2_mb_type != BASE_MODE)
+ {
+ ps_proc->ps_mb_info->u1_base_mode_flag = 0;
+ }
+}
+
+void isvce_update_ibl_info(svc_intra_pred_ctxt_t *ps_intra_pred_ctxt, UWORD8 u1_num_spatial_layers,
+ UWORD8 u1_spatial_layer_id, UWORD16 u2_mb_type, WORD32 i4_mb_x,
+ WORD32 i4_mb_y, WORD8 u1_base_mode_flag)
+{
+ if(u1_num_spatial_layers > 1)
+ {
+ intra_pred_state_t *ps_intra_pred_state =
+ (intra_pred_state_t *) (ps_intra_pred_ctxt->s_intra_pred_constants.pv_state);
+ intra_pred_layer_state_t *ps_layer_state =
+ &ps_intra_pred_state->ps_layer_state[u1_spatial_layer_id];
+ WORD8 i1_is_intra = (u2_mb_type == I4x4 || u2_mb_type == I16x16 || u2_mb_type == I8x8);
+
+ WORD8 *pi1_mb_mode =
+ &ps_layer_state->pi1_mb_mode[i4_mb_x + (i4_mb_y * (ps_layer_state->i4_mb_mode_stride))];
+
+ if(u1_base_mode_flag == 1)
+ {
+ *pi1_mb_mode = SVC_IBL_MB;
+ }
+ else
+ {
+ if(i1_is_intra)
+ {
+ *pi1_mb_mode = SVC_INTRA_MB;
+ }
+ else
+ {
+ *pi1_mb_mode = SVC_INTER_MB;
+ }
+ }
+ }
+}
+
+void isvce_pad_mb_mode_buf(svc_intra_pred_ctxt_t *ps_intra_pred_ctxt, UWORD8 u1_spatial_layer_id,
+ UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht)
+{
+ if(u1_num_spatial_layers > 1)
+ {
+ intra_pred_state_t *ps_intra_pred_state =
+ (intra_pred_state_t *) (ps_intra_pred_ctxt->s_intra_pred_constants.pv_state);
+ intra_pred_layer_state_t *ps_layer_state =
+ &ps_intra_pred_state->ps_layer_state[u1_spatial_layer_id];
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - u1_spatial_layer_id)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - u1_spatial_layer_id)) +
+ 0.99;
+
+ WORD32 row, src_strd;
+ WORD8 *pu1_src;
+
+ WORD8 *pi1_mb_mode = ps_layer_state->pi1_mb_mode;
+ WORD32 i4_mb_mode_stride = ps_layer_state->i4_mb_mode_stride;
+
+ /* Add PAD MBs on all directions */
+ i4_layer_luma_wd /= MB_SIZE;
+ i4_layer_luma_ht /= MB_SIZE;
+
+ if(d_spatial_res_ratio == 2.0)
+ {
+ UWORD8 *pu1_mb_mode = (UWORD8 *) pi1_mb_mode;
+ /* Pad left */
+ ih264_pad_left_luma(pu1_mb_mode, i4_mb_mode_stride, i4_layer_luma_ht, 1);
+
+ /* Pad right */
+ ih264_pad_right_luma(pu1_mb_mode + i4_layer_luma_wd, i4_mb_mode_stride,
+ i4_layer_luma_ht, 1);
+
+ /* Pad top */
+ ih264_pad_top(pu1_mb_mode - 1, i4_mb_mode_stride, i4_layer_luma_wd + 2, 1);
+
+ /* Pad bottom */
+ ih264_pad_bottom(pu1_mb_mode + (i4_layer_luma_ht * i4_mb_mode_stride) - 1,
+ i4_mb_mode_stride, i4_layer_luma_wd + 2, 1);
+ }
+ else
+ {
+ /* Pad left */
+ pu1_src = pi1_mb_mode;
+ src_strd = i4_mb_mode_stride;
+ for(row = 0; row < i4_layer_luma_ht; row++)
+ {
+ memset(pu1_src - 1, -1, 1);
+ pu1_src += src_strd;
+ }
+
+ /* Pad right */
+ pu1_src = pi1_mb_mode + i4_layer_luma_wd;
+ for(row = 0; row < i4_layer_luma_ht; row++)
+ {
+ memset(pu1_src, -1, 1);
+ pu1_src += src_strd;
+ }
+
+ /* Pad top */
+ pu1_src = pi1_mb_mode - 1;
+ memset(pu1_src - src_strd, -1, i4_layer_luma_wd + 2);
+
+ /* Pad bottom */
+ pu1_src = pi1_mb_mode + (i4_layer_luma_ht * i4_mb_mode_stride) - 1;
+ memset(pu1_src, -1, i4_layer_luma_wd + 2);
+ }
+ }
+}
diff --git a/encoder/svc/isvce_ibl_eval.h b/encoder/svc/isvce_ibl_eval.h
new file mode 100644
index 0000000..b214b3d
--- /dev/null
+++ b/encoder/svc/isvce_ibl_eval.h
@@ -0,0 +1,105 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_intra_pred.h
+*
+* @brief
+* Contains function declarations for function declared in
+*isvce_intra_pred.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+#ifndef _ISVCE_IBL_EVAL_H_
+#define _ISVCE_IBL_EVAL_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvc_intra_resample.h"
+#include "isvce_structs.h"
+#include "isvce_structs.h"
+
+#define TEMP_BUF_SIZE_LUMA (REF_ARRAY_WIDTH * REF_ARRAY_WIDTH)
+#define TEMP_BUF_SIZE_CB (REF_ARRAY_WIDTH * REF_ARRAY_WIDTH)
+#define TEMP_BUF_SIZE_CR (DYADIC_REF_W_C * DYADIC_REF_H_C)
+
+#define INTERMEDIATE_BUFF_WIDTH 48
+#define INTERMEDIATE_BUFF_HEIGHT (MB_SIZE + 4)
+#define TEMP_INTERPOLATION_BUF_SIZE (INTERMEDIATE_BUFF_WIDTH * INTERMEDIATE_BUFF_HEIGHT)
+
+/* Structs */
+typedef struct intra_pred_constants_t
+{
+ void *pv_state;
+} intra_pred_constants_t;
+
+typedef struct intra_pred_outputs_t
+{
+ yuv_buf_props_t s_pred_buf;
+} intra_pred_outputs_t;
+
+typedef struct intra_pred_variables_t
+{
+ svc_ilp_data_t *ps_svc_ilp_data;
+
+ coordinates_t s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id;
+} intra_pred_variables_t;
+
+typedef struct svc_intra_pred_ctxt_t
+{
+ intra_pred_constants_t s_intra_pred_constants;
+
+ intra_pred_variables_t s_intra_pred_variables;
+
+ intra_pred_outputs_t s_intra_pred_outputs;
+
+} svc_intra_pred_ctxt_t;
+
+extern UWORD32 isvce_get_svc_intra_pred_ctxt_size(UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht);
+
+extern void isvce_intra_pred_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_update_ibl_info(svc_intra_pred_ctxt_t *ps_intra_pred_ctxt,
+ UWORD8 u1_num_spatial_layers, UWORD8 u1_spatial_layer_id,
+ UWORD16 u2_mb_type, WORD32 i4_mb_x, WORD32 i4_mb_y,
+ WORD8 u1_base_mode_flag);
+
+extern void isvce_evaluate_IBL_mode(isvce_process_ctxt_t *ps_proc);
+
+extern void isvce_pad_mb_mode_buf(svc_intra_pred_ctxt_t *ps_intra_pred_ctxt,
+ UWORD8 u1_spatial_layer_id, UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd, UWORD32 u4_ht);
+
+#endif
diff --git a/encoder/svc/isvce_ibl_private_defs.h b/encoder/svc/isvce_ibl_private_defs.h
new file mode 100644
index 0000000..7bd8169
--- /dev/null
+++ b/encoder/svc/isvce_ibl_private_defs.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_intra_pred_private_defs.h
+*
+* @brief
+* Contains datatype and macro definitions used exclusively in
+* residual prediction
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_IBL_PRIVATE_DEFS_H_
+#define _ISVCE_IBL_PRIVATE_DEFS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+#include "isvc_intra_resample.h"
+
+/* Structs */
+typedef struct intra_pred_mb_state_t
+{
+ coordinates_t s_offsets;
+
+ coordinates_t s_ref_array_dims;
+
+ WORD32 *pi4_ref_array_positions_x;
+
+ WORD32 *pi4_ref_array_positions_y;
+
+ coordinates_t *ps_ref_array_phases;
+
+ coordinates_t s_min_pos;
+
+ coordinates_t s_max_pos;
+
+} intra_pred_mb_state_t;
+
+typedef struct intra_pred_layer_state_t
+{
+ layer_resampler_props_t *ps_luma_props;
+
+ layer_resampler_props_t *ps_chroma_props;
+
+ intra_pred_mb_state_t *ps_luma_mb_states;
+
+ intra_pred_mb_state_t *ps_chroma_mb_states;
+
+ WORD8 *pi1_mb_mode;
+
+ WORD32 i4_mb_mode_stride;
+
+ /* buffer to store the reference
+ layer data before intra sampling */
+ UWORD8 *pu1_refarray_buffer;
+
+ UWORD8 *pu1_refarray_cb;
+
+ UWORD8 *pu1_refarray_cr;
+
+ WORD32 *pi4_temp_interpolation_buffer;
+
+} intra_pred_layer_state_t;
+
+typedef struct intra_pred_state_t
+{
+ /* Array of size numSpatialLayers */
+ intra_pred_layer_state_t *ps_layer_state;
+
+} intra_pred_state_t;
+
+#endif
diff --git a/encoder/svc/isvce_ilp_mv.c b/encoder/svc/isvce_ilp_mv.c
new file mode 100644
index 0000000..9aa45a3
--- /dev/null
+++ b/encoder/svc/isvce_ilp_mv.c
@@ -0,0 +1,737 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_ilp_mv.c
+*
+* @brief
+* Contains functions used for deriving inter_layer MV's
+*
+*******************************************************************************
+*/
+#include <stdint.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "isvc_macros.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvce_structs.h"
+#include "isvce_ilp_mv_private_defs.h"
+#include "isvce_ilp_mv.h"
+#include "isvce_ilp_mv_utils.h"
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing ILP MV ctxt
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @param[in] u4_ht
+* Input Height
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_ilp_mv_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 u4_size = 0;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ WORD32 i;
+
+ u4_size += MAX_PROCESS_CTXT * sizeof(svc_ilp_mv_ctxt_t);
+ u4_size += MAX_PROCESS_CTXT * sizeof(ilp_mv_state_t);
+
+ u4_size += u1_num_spatial_layers * sizeof(ilp_mv_layer_state_t);
+
+ for(i = u1_num_spatial_layers - 1; i >= 1; i--)
+ {
+ WORD32 i4_layer_luma_wd =
+ (WORD32) ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_mbs = (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
+
+ u4_size += i4_layer_luma_mbs * sizeof(ilp_mv_mb_state_t);
+ }
+ }
+
+ return u4_size;
+}
+
+static FORCEINLINE void isvce_ref_layer_pu_and_mb_pos_init(layer_resampler_props_t *ps_layer_props,
+ ilp_mv_mb_state_t *ps_mb_state,
+ coordinates_t *ps_mb_pos,
+ UWORD32 u4_ref_wd, UWORD32 u4_ref_ht,
+ UWORD8 u1_field_pic_flag,
+ UWORD8 u1_field_mb_flag)
+{
+ UWORD32 i, j;
+
+ coordinates_t(*aps_pu_positions)[MAX_PU_IN_MB_ROW] = ps_mb_state->as_pu_positions;
+ coordinates_t(*aps_mb_positions)[MAX_PU_IN_MB_ROW] = ps_mb_state->as_mb_positions;
+
+ for(i = 0; i < MAX_PU_IN_MB_COL; i++)
+ {
+ UWORD32 u4_y_ref16;
+
+ UWORD32 u4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht +
+ (4 * i + 1) * (1 + u1_field_mb_flag - u1_field_pic_flag);
+
+ u4_y_ref16 =
+ (u4_yc * ps_layer_props->u4_scale_y + (1 << (ps_layer_props->u4_shift_y - 1))) >>
+ ps_layer_props->u4_shift_y;
+ u4_y_ref16 = MIN(u4_y_ref16, u4_ref_ht - 1);
+
+ for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
+ {
+ UWORD32 u4_x_ref16;
+
+ UWORD32 u4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + 4 * j + 1;
+
+ u4_x_ref16 =
+ (u4_xc * ps_layer_props->u4_scale_x + (1 << (ps_layer_props->u4_shift_x - 1))) >>
+ ps_layer_props->u4_shift_x;
+ u4_x_ref16 = MIN(u4_x_ref16, u4_ref_wd - 1);
+
+ aps_pu_positions[i][j].i4_abscissa = u4_x_ref16;
+ aps_pu_positions[i][j].i4_ordinate = u4_y_ref16;
+
+ aps_mb_positions[i][j].i4_abscissa = (u4_x_ref16 / MB_SIZE);
+ aps_mb_positions[i][j].i4_ordinate = (u4_y_ref16 / MB_SIZE);
+ }
+ }
+}
+
+static void isvce_ilp_mv_layer_state_init(ilp_mv_layer_state_t *ps_layer_state,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 i, j;
+
+ const UWORD8 u1_ref_layer_field_pic_flag = 0;
+ const UWORD8 u1_field_pic_flag = 0;
+ const UWORD8 u1_field_mb_flag = 0;
+
+ ilp_mv_mb_state_t *ps_mb_states;
+ layer_resampler_props_t *ps_layer_props;
+
+ UWORD32 u4_wd_in_mbs;
+ UWORD32 u4_ht_in_mbs;
+
+ UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
+ UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
+ UWORD32 u4_scaled_wd = u4_wd;
+ UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
+
+ ps_mb_states = ps_layer_state->ps_mb_states;
+ ps_layer_props = ps_layer_state->ps_props;
+
+ u4_wd_in_mbs = u4_scaled_wd / ps_layer_props->u4_mb_wd;
+ u4_ht_in_mbs = u4_scaled_ht / ps_layer_props->u4_mb_ht;
+
+ ps_layer_state->s_mv_scale.i4_abscissa = ((u4_scaled_wd << 16) + (u4_ref_wd >> 1)) / u4_ref_wd;
+ ps_layer_state->s_mv_scale.i4_ordinate = ((u4_scaled_ht << 16) + (u4_ref_ht >> 1)) / u4_ref_ht;
+
+ for(i = 0; i < u4_ht_in_mbs; i++)
+ {
+ for(j = 0; j < u4_wd_in_mbs; j++)
+ {
+ coordinates_t s_mb_pos = {j, i};
+
+ isvce_ref_layer_pu_and_mb_pos_init(ps_layer_props, &ps_mb_states[j + i * u4_wd_in_mbs],
+ &s_mb_pos, u4_ref_wd, u4_ref_ht, u1_field_pic_flag,
+ u1_field_mb_flag);
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc ilp buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_ilp_mv_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ WORD32 i, j;
+
+ const WORD32 i4_num_proc_ctxts = sizeof(ps_codec->as_process) / sizeof(ps_codec->as_process[0]);
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ ilp_mv_layer_state_t *ps_layer_states;
+ ilp_mv_mb_state_t *aps_luma_mb_states[MAX_NUM_SPATIAL_LAYERS];
+
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_ilp_mv_ctxt_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ ilp_mv_state_t *ps_ilp_mv_state;
+ svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt;
+
+ isvce_process_ctxt_t *ps_proc = ps_codec->as_process + i;
+
+ ps_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt = (svc_ilp_mv_ctxt_t *) pu1_buf;
+ pu1_buf += sizeof(svc_ilp_mv_ctxt_t);
+ i8_alloc_mem_size -= sizeof(svc_ilp_mv_ctxt_t);
+
+ ps_ilp_mv_ctxt->s_ilp_mv_constants.pv_state = pu1_buf;
+ ps_ilp_mv_state = (ilp_mv_state_t *) pu1_buf;
+ pu1_buf += sizeof(ilp_mv_state_t);
+ i8_alloc_mem_size -= sizeof(ilp_mv_state_t);
+
+ if(0 == i)
+ {
+ ps_ilp_mv_state->ps_layer_state = (ilp_mv_layer_state_t *) pu1_buf;
+ ps_layer_states = ps_ilp_mv_state->ps_layer_state;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_ilp_mv_state->ps_layer_state[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_ilp_mv_state->ps_layer_state[0]);
+ }
+ else
+ {
+ ps_ilp_mv_state->ps_layer_state = ps_layer_states;
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ if(0 == i)
+ {
+ for(j = u1_num_spatial_layers - 1; j >= 1; j--)
+ {
+ ilp_mv_layer_state_t *ps_layer = &ps_ilp_mv_state->ps_layer_state[j];
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_mbs =
+ (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
+
+ ps_layer->ps_mb_states = (ilp_mv_mb_state_t *) pu1_buf;
+ aps_luma_mb_states[j] = ps_layer->ps_mb_states;
+ pu1_buf += i4_layer_luma_mbs * sizeof(ps_layer->ps_mb_states[0]);
+ i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_layer->ps_mb_states[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ /* Asserts below verify that
+ * 'ps_codec->s_svc_ilp_data.aps_layer_resampler_props' is initialised
+ */
+ ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j].u4_mb_wd ==
+ MB_SIZE);
+
+ ps_layer->ps_props = &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
+
+ isvce_ilp_mv_layer_state_init(ps_layer, d_spatial_res_ratio, i4_layer_luma_wd,
+ i4_layer_luma_ht);
+ }
+ }
+ else
+ {
+ for(j = u1_num_spatial_layers - 1; j >= 1; j--)
+ {
+ ilp_mv_layer_state_t *ps_layer = &ps_ilp_mv_state->ps_layer_state[j];
+
+ ps_layer->ps_mb_states = aps_luma_mb_states[j];
+
+ ps_layer->ps_props = &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ ps_codec->as_process[i].ps_svc_ilp_mv_ctxt = NULL;
+ }
+ }
+}
+
+static void isvce_get_ilp_mvs_for_me(svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt)
+{
+ svc_layer_data_t *ps_ref_layer_data;
+ ilp_mv_layer_state_t *ps_layer_state;
+ ilp_mv_mb_state_t *ps_mb_state;
+ isvce_mb_info_t *ps_ref_mb_info;
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+ coordinates_t s_ref_frame_dims;
+ coordinates_t s_ref_frame_dims_in_mbs;
+
+ bool b_is_mv_non_identical;
+ WORD32 i, j, k;
+
+ ilp_mv_constants_t *ps_ilp_mv_constants = &ps_ilp_mv_ctxt->s_ilp_mv_constants;
+ ilp_mv_variables_t *ps_ilp_mv_variables = &ps_ilp_mv_ctxt->s_ilp_mv_variables;
+ ilp_mv_outputs_t *ps_ilp_mv_outputs = &ps_ilp_mv_ctxt->s_ilp_mv_outputs;
+ ilp_mv_state_t *ps_ilp_mv_state = (ilp_mv_state_t *) ps_ilp_mv_constants->pv_state;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_ilp_mv_variables->ps_svc_ilp_data;
+ svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
+ coordinates_t *ps_mb_pos = &ps_ilp_mv_variables->s_mb_pos;
+ const isvce_enc_pu_mv_t s_default_mv = {{0, 0}, -1};
+
+ UWORD8 u1_spatial_layer_id = ps_ilp_mv_variables->u1_spatial_layer_id;
+ WORD32 i4_num_ilp_mvs = 0;
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+ s_ref_frame_dims.i4_abscissa =
+ ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_width;
+ s_ref_frame_dims.i4_ordinate =
+ ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_height;
+ s_ref_frame_dims_in_mbs.i4_abscissa = s_ref_frame_dims.i4_abscissa / MB_SIZE;
+ s_ref_frame_dims_in_mbs.i4_ordinate = s_ref_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_ref_layer_data = &ps_svc_au_data->ps_svc_layer_data[u1_spatial_layer_id - 1];
+ ps_layer_state = &ps_ilp_mv_state->ps_layer_state[u1_spatial_layer_id];
+ ps_mb_state =
+ &ps_layer_state->ps_mb_states[ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa];
+
+ for(i = 0; i < MAX_PU_IN_MB_COL; i++)
+ {
+ for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
+ {
+ b_is_mv_non_identical = true;
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] = s_default_mv;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] = s_default_mv;
+
+ ps_ref_mb_info =
+ &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[i][j].i4_abscissa +
+ ps_mb_state->as_mb_positions[i][j].i4_ordinate *
+ s_ref_frame_dims_in_mbs.i4_abscissa];
+
+ if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] =
+ ps_ref_mb_info->u2_mb_type;
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] =
+ ps_ref_mb_info->as_pu->u1_pred_mode;
+
+ if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L0)
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] =
+ ps_ref_mb_info->as_pu->as_me_info[L1];
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+
+ if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L1)
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] =
+ ps_ref_mb_info->as_pu->as_me_info[L0];
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+
+ if(i4_num_ilp_mvs == 0)
+ {
+ i4_num_ilp_mvs++;
+ }
+ else
+ {
+ for(k = i4_num_ilp_mvs - 1; k >= 0; k--)
+ {
+ if((ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[k] ==
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs]) &&
+ (ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k] ==
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs]) &&
+ isvce_check_identical_mv(
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[k],
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs],
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k]))
+ {
+ b_is_mv_non_identical = false;
+ }
+ }
+
+ if(b_is_mv_non_identical)
+ {
+ i4_num_ilp_mvs++;
+ }
+ }
+ }
+ else
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] = INVALID_MB_TYPE;
+ }
+ }
+ }
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.u4_num_ilp_mvs = i4_num_ilp_mvs;
+
+ for(i = 0; i < MAX_ILP_MV_IN_NBR_RGN; i++)
+ {
+ b_is_mv_non_identical = true;
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] = s_default_mv;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] = s_default_mv;
+
+ if(ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0] >= 0 &&
+ ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0] < s_frame_dims_in_mbs.i4_abscissa &&
+ ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1] >= 0 &&
+ ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1] < s_frame_dims_in_mbs.i4_ordinate)
+ {
+ ps_mb_state =
+ &ps_layer_state->ps_mb_states[(ps_mb_pos->i4_abscissa + gai1_nbr_ilp_mv_map[i][0]) +
+ (ps_mb_pos->i4_ordinate + gai1_nbr_ilp_mv_map[i][1]) *
+ s_frame_dims_in_mbs.i4_abscissa];
+
+ ps_ref_mb_info =
+ &ps_ref_layer_data->ps_mb_info[(ps_mb_state
+ ->as_mb_positions[gai1_nbr_ilp_mv_map[i][2]]
+ [gai1_nbr_ilp_mv_map[i][3]]
+ .i4_abscissa) +
+ ps_mb_state
+ ->as_mb_positions[gai1_nbr_ilp_mv_map[i][2]]
+ [gai1_nbr_ilp_mv_map[i][3]]
+ .i4_ordinate *
+ s_ref_frame_dims_in_mbs.i4_abscissa];
+
+ if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] =
+ ps_ref_mb_info->u2_mb_type;
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] =
+ ps_ref_mb_info->as_pu->u1_pred_mode;
+
+ if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L0)
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1] =
+ ps_ref_mb_info->as_pu->as_me_info[L1];
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L1].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+
+ if(ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs] != L1)
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0] =
+ ps_ref_mb_info->as_pu->as_me_info[L0];
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs][L0].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+
+ if(i4_num_ilp_mvs == 0)
+ {
+ i4_num_ilp_mvs++;
+ }
+ else
+ {
+ for(k = i4_num_ilp_mvs - 1; k >= 0; k--)
+ {
+ if((ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[k] ==
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs]) &&
+ (ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k] ==
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[i4_num_ilp_mvs]) &&
+ isvce_check_identical_mv(
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[k],
+ ps_ilp_mv_outputs->s_ilp_me_cands.as_mv[i4_num_ilp_mvs],
+ ps_ilp_mv_outputs->s_ilp_me_cands.ae_pred_mode[k]))
+ b_is_mv_non_identical = false;
+ }
+
+ if(b_is_mv_non_identical)
+ {
+ i4_num_ilp_mvs++;
+ }
+ }
+ }
+ else
+ {
+ ps_ilp_mv_outputs->s_ilp_me_cands.e_mb_type[i4_num_ilp_mvs] = INVALID_MB_TYPE;
+ }
+ }
+ }
+
+ ps_ilp_mv_outputs->s_ilp_me_cands.u4_num_ilp_mvs_incl_nbrs = i4_num_ilp_mvs;
+}
+
+void isvce_get_mb_ilp_mv(svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt)
+{
+ svc_layer_data_t *ps_ref_layer_data;
+ ilp_mv_layer_state_t *ps_layer_state;
+ ilp_mv_mb_state_t *ps_mb_state;
+ isvce_mb_info_t *ps_ref_mb_info;
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+ coordinates_t s_ref_frame_dims;
+ coordinates_t s_ref_frame_dims_in_mbs;
+
+ WORD32 i, j;
+
+ ilp_mv_constants_t *ps_ilp_mv_constants = &ps_ilp_mv_ctxt->s_ilp_mv_constants;
+ ilp_mv_variables_t *ps_ilp_mv_variables = &ps_ilp_mv_ctxt->s_ilp_mv_variables;
+ ilp_mv_outputs_t *ps_ilp_mv_outputs = &ps_ilp_mv_ctxt->s_ilp_mv_outputs;
+ ilp_mv_state_t *ps_ilp_mv_state = (ilp_mv_state_t *) ps_ilp_mv_constants->pv_state;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_ilp_mv_variables->ps_svc_ilp_data;
+ svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
+ coordinates_t *ps_mb_pos = &ps_ilp_mv_variables->s_mb_pos;
+ const isvce_enc_pu_mv_t s_default_mv = {{0, 0}, -1};
+
+ UWORD8 u1_spatial_layer_id = ps_ilp_mv_variables->u1_spatial_layer_id;
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+ s_ref_frame_dims.i4_abscissa =
+ ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_width;
+ s_ref_frame_dims.i4_ordinate =
+ ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_height;
+ s_ref_frame_dims_in_mbs.i4_abscissa = s_ref_frame_dims.i4_abscissa / MB_SIZE;
+ s_ref_frame_dims_in_mbs.i4_ordinate = s_ref_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_ref_layer_data = &ps_svc_au_data->ps_svc_layer_data[u1_spatial_layer_id - 1];
+ ps_layer_state = &ps_ilp_mv_state->ps_layer_state[u1_spatial_layer_id];
+ ps_mb_state =
+ &ps_layer_state->ps_mb_states[ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa];
+
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = s_default_mv;
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = s_default_mv;
+
+ ps_ref_mb_info = &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[0][0].i4_abscissa +
+ ps_mb_state->as_mb_positions[0][0].i4_ordinate *
+ s_ref_frame_dims_in_mbs.i4_abscissa];
+
+ if((ps_ref_mb_info->u2_mb_type == P16x16) || (ps_ref_mb_info->u2_mb_type == B16x16))
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = ps_ref_mb_info->u2_mb_type;
+
+ ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] = ps_ref_mb_info->as_pu->u1_pred_mode;
+
+ if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L0)
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = ps_ref_mb_info->as_pu->as_me_info[L1];
+ }
+
+ if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L1)
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = ps_ref_mb_info->as_pu->as_me_info[L0];
+ }
+ }
+ else
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
+ }
+
+ /* Function call to get non 16x16 ilp mvs for me candidates */
+ isvce_get_ilp_mvs_for_me(ps_ilp_mv_ctxt);
+
+ /* Encoder supports only 16x16 partition. */
+ /* The code below ensures only 16x16 ILP MV's are used */
+ for(i = 0; i < MAX_PU_IN_MB_COL; i++)
+ {
+ for(j = 0; j < MAX_PU_IN_MB_ROW; j++)
+ {
+ bool b_unsupported_mv;
+
+ ps_ref_mb_info =
+ &ps_ref_layer_data->ps_mb_info[ps_mb_state->as_mb_positions[i][j].i4_abscissa +
+ ps_mb_state->as_mb_positions[i][j].i4_ordinate *
+ s_ref_frame_dims_in_mbs.i4_abscissa];
+
+ b_unsupported_mv =
+ (ps_ref_mb_info->u2_mb_type != ps_ilp_mv_outputs->s_ilp_mv.e_mb_type) ||
+ (ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] !=
+ ps_ref_mb_info->as_pu->u1_pred_mode) ||
+ !isvce_check_identical_mv(ps_ilp_mv_outputs->s_ilp_mv.as_mv[0],
+ ps_ref_mb_info->as_pu->as_me_info,
+ ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0]);
+
+ if(b_unsupported_mv)
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0] = s_default_mv;
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1] = s_default_mv;
+ ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
+
+ return;
+ }
+ }
+ }
+
+ if(ps_ilp_mv_outputs->s_ilp_mv.e_mb_type != INVALID_MB_TYPE)
+ {
+ if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L0)
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L1].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+
+ if(ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] != L1)
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvx =
+ (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvx *
+ ps_layer_state->s_mv_scale.i4_abscissa +
+ 32768) >>
+ 16;
+ ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvy =
+ (ps_ilp_mv_outputs->s_ilp_mv.as_mv[0][L0].s_mv.i2_mvy *
+ ps_layer_state->s_mv_scale.i4_ordinate +
+ 32768) >>
+ 16;
+ }
+ }
+ else
+ {
+ ps_ilp_mv_outputs->s_ilp_mv.e_mb_type = INVALID_MB_TYPE;
+ ps_ilp_mv_outputs->s_ilp_mv.ae_pred_mode[0] = INVALID_PRED_MODE;
+ }
+}
+
+void isvce_mvp_idx_eval(isvce_mb_info_t *ps_mb_info, isvce_enc_pu_mv_t *ps_spatial_mvp,
+ isvce_enc_pu_mv_t *ps_ilp_mvp, UWORD8 *pu1_mvd_costs)
+{
+ if(USE_ILP_MV_AS_MVP && ps_ilp_mvp && !ps_mb_info->u1_is_intra &&
+ (ps_mb_info->u2_mb_type != PSKIP) && (ps_mb_info->u2_mb_type != BSKIP) &&
+ (ps_mb_info->u2_mb_type != BASE_MODE))
+ {
+ isvce_enc_pu_mv_t *ps_mv;
+ isvce_enc_pu_mv_t *aps_mvps[2];
+
+ WORD32 ai4_mvd_costs[2];
+ WORD32 i, j;
+
+ for(i = 0; i < NUM_PRED_DIRS; i++)
+ {
+ PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
+ PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
+
+ if(ps_mb_info->as_pu->u1_pred_mode != e_pred_mode)
+ {
+ ps_mv = &ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode];
+ aps_mvps[0] = &ps_spatial_mvp[e_cmpl_pred_mode];
+ aps_mvps[1] = &ps_ilp_mvp[e_cmpl_pred_mode];
+
+ for(j = 0; j < 2; j++)
+ {
+ if((aps_mvps[j]->i1_ref_idx != -1) &&
+ (!j || ((j == 1) && (ps_mv->i1_ref_idx == aps_mvps[j]->i1_ref_idx))))
+ {
+ ai4_mvd_costs[j] =
+ pu1_mvd_costs[ps_mv->s_mv.i2_mvx - aps_mvps[j]->s_mv.i2_mvx] +
+ pu1_mvd_costs[ps_mv->s_mv.i2_mvy - aps_mvps[j]->s_mv.i2_mvy];
+ }
+ else
+ {
+ ai4_mvd_costs[j] = INT32_MAX;
+ }
+ }
+
+ ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode] =
+ ai4_mvd_costs[0] > ai4_mvd_costs[1];
+ }
+ else
+ {
+ ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode] = 0;
+ }
+ }
+ }
+ else
+ {
+ ps_mb_info->as_pu->au1_mvp_idx[L0] = 0;
+ ps_mb_info->as_pu->au1_mvp_idx[L1] = 0;
+ }
+}
diff --git a/encoder/svc/isvce_ilp_mv.h b/encoder/svc/isvce_ilp_mv.h
new file mode 100644
index 0000000..f9d1df4
--- /dev/null
+++ b/encoder/svc/isvce_ilp_mv.h
@@ -0,0 +1,115 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_ilp_mv.h
+*
+* @brief
+* Contains function declarations for function declared in
+* isvce_ilp_mv.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_ILP_MV_H_
+#define _ISVCE_ILP_MV_H_
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_defs.h"
+#include "isvce_pred_structs.h"
+#include "isvce_structs.h"
+#include "isvce_structs.h"
+#include "isvce_utils.h"
+
+/* Structs */
+typedef struct ilp_mv_constants_t
+{
+ void *pv_state;
+} ilp_mv_constants_t;
+
+typedef struct ilp_mv_outputs_t
+{
+ ilp_mv_t s_ilp_mv;
+
+ ilp_me_cands_t s_ilp_me_cands;
+
+} ilp_mv_outputs_t;
+
+typedef struct ilp_mv_variables_t
+{
+ svc_ilp_data_t *ps_svc_ilp_data;
+
+ coordinates_t s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id;
+} ilp_mv_variables_t;
+
+typedef struct svc_ilp_mv_ctxt_t
+{
+ ilp_mv_constants_t s_ilp_mv_constants;
+
+ ilp_mv_variables_t s_ilp_mv_variables;
+
+ ilp_mv_outputs_t s_ilp_mv_outputs;
+
+} svc_ilp_mv_ctxt_t;
+
+/* Function declarations */
+extern UWORD32 isvce_get_ilp_mv_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht);
+
+extern void isvce_ilp_mv_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_get_mb_ilp_mv(svc_ilp_mv_ctxt_t *ps_ilp_mv_ctxt);
+
+extern void isvce_mvp_idx_eval(isvce_mb_info_t *ps_mb_info, isvce_enc_pu_mv_t *ps_spatial_mvp,
+ isvce_enc_pu_mv_t *ps_ilp_mvp, UWORD8 *pu1_mvd_costs);
+
+static FORCEINLINE UWORD8 isvce_is_ilp_mv_winning_mv(isvce_mb_info_t *ps_mb_info,
+ ilp_mv_t *ps_ilp_mv)
+{
+ if(ENABLE_ILP_MV && ps_ilp_mv && (ps_mb_info->u2_mb_type != PSKIP) &&
+ (ps_mb_info->u2_mb_type != BSKIP))
+ {
+ if((ps_mb_info->u2_mb_type == ps_ilp_mv->e_mb_type) &&
+ (((PRED_MODE_T) ps_mb_info->as_pu->u1_pred_mode) == ps_ilp_mv->ae_pred_mode[0]))
+ {
+ return isvce_check_identical_mv(ps_mb_info->as_pu->as_me_info, ps_ilp_mv->as_mv[0],
+ ps_ilp_mv->ae_pred_mode[0]);
+ }
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/encoder/svc/isvce_ilp_mv_private_defs.h b/encoder/svc/isvce_ilp_mv_private_defs.h
new file mode 100644
index 0000000..2893ca0
--- /dev/null
+++ b/encoder/svc/isvce_ilp_mv_private_defs.h
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvc_svc_ilp_mv_private_defs.h
+*
+* @brief
+* Contains datatype and macro definitions used exclusively in
+* ILP MV derivations
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_ILP_MV_PRIVATE_DEFS_H_
+#define _ISVCE_ILP_MV_PRIVATE_DEFS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+
+/* Structs */
+/* Offsets, etc used for resLayer MV upsampling */
+/* Derived as per 'G.8.6.1.1' for all MB's once during init */
+typedef struct ilp_mv_mb_state_t
+{
+ coordinates_t as_pu_positions[MAX_PU_IN_MB_COL][MAX_PU_IN_MB_ROW];
+
+ coordinates_t as_mb_positions[MAX_PU_IN_MB_COL][MAX_PU_IN_MB_ROW];
+} ilp_mv_mb_state_t;
+
+typedef struct ilp_mv_layer_state_t
+{
+ layer_resampler_props_t *ps_props;
+
+ ilp_mv_mb_state_t *ps_mb_states;
+
+ coordinates_t s_mv_scale;
+
+} ilp_mv_layer_state_t;
+
+typedef struct ilp_mv_state_t
+{
+ /* Array of size numSpatialLayers */
+ ilp_mv_layer_state_t *ps_layer_state;
+
+} ilp_mv_state_t;
+
+#endif
diff --git a/encoder/svc/isvce_ilp_mv_utils.h b/encoder/svc/isvce_ilp_mv_utils.h
new file mode 100644
index 0000000..af9708c
--- /dev/null
+++ b/encoder/svc/isvce_ilp_mv_utils.h
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_ilp_mv_utils.h
+*
+* @brief
+* Defs to perform experiments in ilp mv
+*
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+#ifndef _ISVCE_ILP_MV_UTILS_H_
+#define _ISVCE_ILP_MV_UTILS_H_
+
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_macros.h"
+#include "isvce_pred_structs.h"
+#include "isvce_structs.h"
+
+#define MAX_CAND_IF_NUM_ILP_MV_LT_2 8
+#define MAX_CAND_IF_NUM_ILP_MV_GTEQ_2 6
+
+/* nbr_mb.x, nbr_mb.y, pu_pos.x, pu_pos.y */
+#define NBR_PU_AND_MB_POS 4
+
+static const WORD8 gai1_nbr_ilp_mv_map[MAX_ILP_MV_IN_NBR_RGN][NBR_PU_AND_MB_POS] = {
+ {-1, 0, 3, 0},
+ {0, -1, 0, 3},
+ {1, 0, 0, 0},
+ {0, 1, 0, 0},
+};
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function checks if the max difference between ILP MVs is less than four
+* or not if number of ILP MVs is greater than or equal to two
+*
+* @param[in] ps_me
+* Pointer to ilp_me_cands
+*
+* @returns One if number of ILP MVs is greater than equal to two and max
+* difference between them is less than 4 otherwise returns zero
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static FORCEINLINE bool isvce_check_max_mv_diff_lt_4(ilp_me_cands_t *ps_ilp_me_cands,
+ WORD32 i4_reflist)
+{
+ UWORD32 i, j;
+ UWORD32 u4_mv_diff_x, u4_mv_diff_y;
+
+ for(i = 1; i < ps_ilp_me_cands->u4_num_ilp_mvs; i++)
+ {
+ for(j = 0; j < i; j++)
+ {
+ if(((ps_ilp_me_cands->ae_pred_mode[i] == ((PRED_MODE_T) i4_reflist)) ||
+ ((ps_ilp_me_cands->ae_pred_mode[i] == BI))) &&
+ ((ps_ilp_me_cands->ae_pred_mode[j] == ((PRED_MODE_T) i4_reflist)) ||
+ ((ps_ilp_me_cands->ae_pred_mode[j] == BI))))
+ {
+ u4_mv_diff_x = ABS(ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv.i2_mvx -
+ ps_ilp_me_cands->as_mv[j][i4_reflist].s_mv.i2_mvx);
+
+ u4_mv_diff_y = ABS(ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv.i2_mvy -
+ ps_ilp_me_cands->as_mv[j][i4_reflist].s_mv.i2_mvy);
+
+ if(u4_mv_diff_x >= 4 || u4_mv_diff_y >= 4)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#endif
diff --git a/encoder/svc/isvce_interface_structs.h b/encoder/svc/isvce_interface_structs.h
new file mode 100644
index 0000000..3ac59fb
--- /dev/null
+++ b/encoder/svc/isvce_interface_structs.h
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_interface_structs.h
+*
+* @brief
+* Contains struct definition used for interface objects such as input,
+* output, and rec
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_INTERFACE_STRUCTS_H_
+#define _ISVCE_INTERFACE_STRUCTS_H_
+
+#include "isvc_structs.h"
+
+typedef struct isvce_raw_inp_buf_t
+{
+ /** Descriptor of raw buffer */
+ iv_raw_buf_t s_raw_buf;
+
+ /** Lower 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_high;
+
+ /** Flag to indicate if the current buffer is last buffer */
+ UWORD32 u4_is_last;
+
+ /** Flag to indicate if mb info is sent along with input buffer */
+ UWORD32 u4_mb_info_type;
+
+ /** Flag to indicate the size of mb info structure */
+ UWORD32 u4_mb_info_size;
+
+ /** Buffer containing mb info if isvce_mb_info_type is non-zero */
+ void *pv_mb_info;
+
+ /** Flag to indicate if pic info is sent along with input buffer */
+ UWORD32 u4_pic_info_type;
+
+ /** Buffer containing pic info if isvce_mb_info_type is non-zero */
+ void *pv_pic_info;
+
+ /** SEI CCV params flag */
+ UWORD8 u1_sei_ccv_params_present_flag;
+
+ /** SEI CCV params info */
+ sei_ccv_params_t s_sei_ccv;
+
+} isvce_raw_inp_buf_t;
+
+typedef struct
+{
+ /** Descriptor of bitstream buffer */
+ iv_bits_buf_t as_bits_buf[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Lower 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_high;
+
+ /** Flag to indicate if the current buffer is last buffer */
+ UWORD32 u4_is_last;
+
+} isvce_out_buf_t;
+
+typedef struct
+{
+ /** Descriptor of picture buffer */
+ svc_au_buf_t s_pic_buf;
+
+ /** Lower 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to the above buffer */
+ UWORD32 u4_timestamp_high;
+
+ /** Flag to indicate if the current buffer is last buffer */
+ UWORD32 u4_is_last;
+
+ /** Picture count corresponding to current picture */
+ WORD32 i4_pic_cnt;
+
+} isvce_rec_buf_t;
+
+#endif
diff --git a/encoder/svc/isvce_intra_modes_eval.c b/encoder/svc/isvce_intra_modes_eval.c
new file mode 100644
index 0000000..58eb7b9
--- /dev/null
+++ b/encoder/svc/isvce_intra_modes_eval.c
@@ -0,0 +1,2334 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_intra_modes_eval.c
+*
+* @brief
+* This file contains definitions of routines that perform rate distortion
+* analysis on a macroblock if they are to be coded as intra.
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_derive_neighbor_availability_of_mbs()
+* - isvce_derive_ngbr_avbl_of_mb_partitions()
+* - isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff()
+* - isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff()
+* - isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff()
+* - isvce_evaluate_intra4x4_modes_for_least_cost_rdopton()
+* - isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff()
+* - isvce_evaluate_intra16x16_modes()
+* - isvce_evaluate_intra4x4_modes()
+* - isvce_evaluate_intra_chroma_modes()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+/* User include files */
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_macros.h"
+#include "ih264_intra_pred_filters.h"
+#include "isvc_structs.h"
+#include "isvc_common_tables.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_size_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "isvce_defs.h"
+#include "ime_distortion_metrics.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_intra_modes_eval.h"
+#include "isvce_globals.h"
+#include "ime_platform_macros.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief
+* derivation process for subblock/partition availability
+*
+* @par Description
+* Calculates the availability of the left, top, topright and topleft subblock
+* or partitions.
+*
+* @param[in] ps_proc_ctxt
+* pointer to macroblock context (handle)
+*
+* @param[in] i1_pel_pos_x
+* column position of the pel wrt the current block
+*
+* @param[in] i1_pel_pos_y
+* row position of the pel in wrt current block
+*
+* @remarks Assumptions: before calling this function it is assumed that
+* the neighbor availability of the current macroblock is already derived.
+* Based on table 6-3 of H264 specification
+*
+* @return availability status (yes or no)
+*
+******************************************************************************
+*/
+UWORD8 isvce_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t *ps_ngbr_avbl, WORD8 i1_pel_pos_x,
+ WORD8 i1_pel_pos_y)
+{
+ UWORD8 u1_neighbor_avail = 0;
+
+ /**********************************************************************/
+ /* values of i1_pel_pos_x in the range 0-15 inclusive correspond to */
+ /* various columns of a macroblock */
+ /* */
+ /* values of i1_pel_pos_y in the range 0-15 inclusive correspond to */
+ /* various rows of a macroblock */
+ /* */
+ /* other values of i1_pel_pos_x & i1_pel_pos_y represents elements */
+ /* outside the bound of an mb ie., represents its neighbors. */
+ /**********************************************************************/
+ if(i1_pel_pos_x < 0)
+ { /* column(-1) */
+ if(i1_pel_pos_y < 0)
+ { /* row(-1) */
+ u1_neighbor_avail = ps_ngbr_avbl->u1_mb_d; /* current mb topleft availability */
+ }
+ else if(i1_pel_pos_y >= 0 && i1_pel_pos_y < 16)
+ { /* all rows of a macroblock */
+ u1_neighbor_avail = ps_ngbr_avbl->u1_mb_a; /* current mb left availability */
+ }
+ else /* if (i1_pel_pos_y >= 16) */
+ { /* rows(+16) */
+ u1_neighbor_avail = 0; /* current mb bottom left availability */
+ }
+ }
+ else if(i1_pel_pos_x >= 0 && i1_pel_pos_x < 16)
+ { /* all columns of a macroblock */
+ if(i1_pel_pos_y < 0)
+ { /* row(-1) */
+ u1_neighbor_avail = ps_ngbr_avbl->u1_mb_b; /* current mb top availability */
+ }
+ else if(i1_pel_pos_y >= 0 && i1_pel_pos_y < 16)
+ { /* all rows of a macroblock */
+ u1_neighbor_avail = 1; /* current mb availability */
+ /* availability of the partition is dependent on the position of the
+ * partition inside the mb */
+ /* although the availability is declared as 1 in all cases these needs to
+ * be corrected somewhere else and this is not done in here */
+ }
+ else /* if (i1_pel_pos_y >= 16) */
+ { /* rows(+16) */
+ u1_neighbor_avail = 0; /* current mb bottom availability */
+ }
+ }
+ else if(i1_pel_pos_x >= 16)
+ { /* column(+16) */
+ if(i1_pel_pos_y < 0)
+ { /* row(-1) */
+ u1_neighbor_avail = ps_ngbr_avbl->u1_mb_c; /* current mb top right availability */
+ }
+ else /* if (i1_pel_pos_y >= 0) */
+ { /* all other rows */
+ u1_neighbor_avail = 0; /* current mb right & bottom right availability */
+ }
+ }
+
+ return u1_neighbor_avail;
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 16x16 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible intra 16x16 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to process context (handle)
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to
+*header bits necessary for encoding the macroblock. Assuming the deltaQP, cbp
+*bits and residual bits fall in to texture bits the number of bits taken to
+*encoding mbtype is considered as rate, we compute cost. Further we will
+*approximate the distortion as the deviation b/w input and the predicted block
+*as opposed to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for intra 16x16 macroblock,
+* the SAD and cost are one and the same.
+*
+* @return none
+*
+******************************************************************************
+*/
+
+void isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc)
+{
+ /* Codec Context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* SAD(distortion metric) of an 8x8 block */
+ WORD32 i4_mb_distortion = INT_MAX, i4_mb_distortion_least = INT_MAX;
+
+ /* lambda */
+ UWORD32 u4_lambda = ps_proc->u4_lambda;
+
+ /* cost = distortion + lambda*rate */
+ WORD32 i4_mb_cost = INT_MAX, i4_mb_cost_least = INT_MAX;
+
+ /* intra mode */
+ UWORD32 u4_intra_mode, u4_best_intra_16x16_mode = DC_I16x16;
+
+ /* neighbor pels for intra prediction */
+ UWORD8 *pu1_ngbr_pels_i16 = ps_proc->au1_ngbr_pels;
+
+ /* neighbor availability */
+ WORD32 i4_ngbr_avbl;
+
+ /* pointer to src macro block */
+ UWORD8 *pu1_curr_mb = ps_proc->s_src_buf_props.as_component_bufs[0].pv_data;
+ UWORD8 *pu1_ref_mb = ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data;
+
+ /* pointer to prediction macro block */
+ UWORD8 *pu1_pred_mb_intra_16x16 = ps_proc->pu1_pred_mb_intra_16x16;
+ UWORD8 *pu1_pred_mb_intra_16x16_plane = ps_proc->pu1_pred_mb_intra_16x16_plane;
+
+ /* strides */
+ WORD32 i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+ WORD32 i4_rec_strd = ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride;
+
+ /* pointer to neighbors left, top, topleft */
+ UWORD8 *pu1_mb_a = pu1_ref_mb - 1;
+ UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd;
+ UWORD8 *pu1_mb_d = pu1_mb_b - 1;
+ UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
+ /* valid intra modes map */
+ UWORD32 u4_valid_intra_modes;
+
+ /* lut for valid intra modes */
+ const UWORD8 u1_valid_intra_modes[8] = {4, 6, 4, 6, 5, 7, 5, 15};
+
+ UWORD32 i, u4_enable_fast_sad = 0, offset = 0;
+ isvce_mb_info_t *ps_top_mb_syn_ele = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ UWORD32 u4_constrained_intra_pred =
+ ps_codec->au4_constrained_intra_pred[ps_proc->u1_spatial_layer_id];
+
+ if(ps_proc->i4_slice_type != ISLICE)
+ {
+ /* Offset for MBtype */
+ offset = (ps_proc->i4_slice_type == PSLICE) ? 5 : 23;
+ u4_enable_fast_sad = ps_proc->s_me_ctxt.u4_enable_fast_sad;
+ }
+
+ /* locating neighbors that are available for prediction */
+
+ /* gather prediction pels from the neighbors, if particular set is not
+ * available it is set to zero*/
+ /* left pels */
+ u1_mb_a =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_a) &&
+ (u4_constrained_intra_pred ? (ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra &&
+ !ps_proc->s_nbr_info.ps_left_mb_info->u1_base_mode_flag)
+ : 1));
+ if(u1_mb_a)
+ {
+ for(i = 0; i < 16; i++) pu1_ngbr_pels_i16[16 - 1 - i] = pu1_mb_a[i * i4_rec_strd];
+ }
+ else
+ {
+ ps_mem_fxns->pf_mem_set_mul8(pu1_ngbr_pels_i16, 0, MB_SIZE);
+ }
+ /* top pels */
+ u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_mb_syn_ele->u1_is_intra && !ps_top_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+ if(u1_mb_b)
+ {
+ ps_mem_fxns->pf_mem_cpy_mul8(pu1_ngbr_pels_i16 + 16 + 1, pu1_mb_b, 16);
+ }
+ else
+ {
+ ps_mem_fxns->pf_mem_set_mul8(pu1_ngbr_pels_i16 + 16 + 1, 0, MB_SIZE);
+ }
+ /* topleft pels */
+ u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d) &&
+ (u4_constrained_intra_pred ? (ps_top_mb_syn_ele[-1].u1_is_intra &&
+ !ps_top_mb_syn_ele[-1].u1_base_mode_flag)
+ : 1));
+ if(u1_mb_d)
+ {
+ pu1_ngbr_pels_i16[16] = *pu1_mb_d;
+ }
+ else
+ {
+ pu1_ngbr_pels_i16[16] = 0;
+ }
+
+ i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
+ ps_proc->i4_ngbr_avbl_16x16_mb = i4_ngbr_avbl;
+
+ /* set valid intra modes for evaluation */
+ u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
+
+ if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST ||
+ ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
+ u4_valid_intra_modes &= ~(1 << PLANE_I16x16);
+
+ /* evaluate b/w HORZ_I16x16, VERT_I16x16 & DC_I16x16 */
+ ps_codec->pf_ih264e_evaluate_intra16x16_modes(
+ pu1_curr_mb, pu1_ngbr_pels_i16, pu1_pred_mb_intra_16x16, i4_src_strd, i4_pred_strd,
+ i4_ngbr_avbl, &u4_intra_mode, &i4_mb_distortion_least, u4_valid_intra_modes);
+
+ /* cost = distortion + lambda*rate */
+ i4_mb_cost_least = i4_mb_distortion_least;
+
+ if(((u4_valid_intra_modes >> 3) & 1) != 0)
+ {
+ /* intra prediction for PLANE mode*/
+ (ps_codec->apf_intra_pred_16_l)[PLANE_I16x16](
+ pu1_ngbr_pels_i16, pu1_pred_mb_intra_16x16_plane, 0, i4_pred_strd, i4_ngbr_avbl);
+
+ /* evaluate distortion between the actual blk and the estimated blk for the
+ * given mode */
+ ps_codec->apf_compute_sad_16x16[u4_enable_fast_sad](
+ pu1_curr_mb, pu1_pred_mb_intra_16x16_plane, i4_src_strd, i4_pred_strd, i4_mb_cost_least,
+ &i4_mb_distortion);
+
+ /* cost = distortion + lambda*rate */
+ i4_mb_cost = i4_mb_distortion;
+
+ /* update the least cost information if necessary */
+ if(i4_mb_cost < i4_mb_distortion_least)
+ {
+ u4_intra_mode = PLANE_I16x16;
+
+ i4_mb_cost_least = i4_mb_cost;
+ i4_mb_distortion_least = i4_mb_distortion;
+ }
+ }
+
+ u4_best_intra_16x16_mode = u4_intra_mode;
+
+ DEBUG("%d partition cost, %d intra mode\n", i4_mb_cost_least * 32, u4_best_intra_16x16_mode);
+
+ ps_proc->u1_l_i16_mode = u4_best_intra_16x16_mode;
+
+ /* cost = distortion + lambda*rate */
+ i4_mb_cost_least =
+ i4_mb_distortion_least + u4_lambda * u1_uev_codelength[offset + u4_best_intra_16x16_mode];
+
+ /* update the type of the mb if necessary */
+ if(i4_mb_cost_least < ps_proc->i4_mb_cost)
+ {
+ ps_proc->i4_mb_cost = i4_mb_cost_least;
+ ps_proc->i4_mb_distortion = i4_mb_distortion_least;
+ ps_proc->ps_mb_info->u2_mb_type = I16x16;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 8x8 mode (rate distortion opt on)
+*
+* @par Description
+* This function evaluates all the possible intra 8x8 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to
+*header bits necessary for encoding the macroblock. Assuming the deltaQP, cbp
+*bits and residual bits fall in to texture bits the number of bits taken to
+*encoding mbtype is considered as rate, we compute cost. Further we will
+*approximate the distortion as the deviation b/w input and the predicted block
+*as opposed to input and reconstructed block.
+*
+* NOTE: TODO: This function needs to be tested
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc)
+{
+ /* Codec Context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ /* SAD(distortion metric) of an 4x4 block */
+ WORD32 i4_partition_distortion, i4_partition_distortion_least = INT_MAX,
+ i4_total_distortion = 0;
+
+ /* lambda */
+ UWORD32 u4_lambda = ps_proc->u4_lambda;
+
+ /* cost = distortion + lambda*rate */
+ WORD32 i4_partition_cost, i4_partition_cost_least, i4_total_cost = u4_lambda;
+
+ /* cost due to mbtype */
+ UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
+
+ /* intra mode */
+ UWORD32 u4_intra_mode, u4_best_intra_8x8_mode = DC_I8x8, u4_estimated_intra_8x8_mode;
+
+ /* neighbor pels for intra prediction */
+ UWORD8 *pu1_ngbr_pels_i8 = ps_proc->au1_ngbr_pels;
+
+ /* pointer to curr partition */
+ UWORD8 *pu1_mb_curr;
+
+ /* pointer to prediction macro block */
+ UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
+
+ /* strides */
+ WORD32 i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+
+ /* neighbors left, top, top right, top left */
+ UWORD8 *pu1_mb_a;
+ UWORD8 *pu1_mb_b;
+ UWORD8 *pu1_mb_d;
+
+ /* neighbor availability */
+ WORD32 i4_ngbr_avbl;
+ block_neighbors_t s_ngbr_avbl;
+
+ /* temp vars */
+ UWORD32 b8, u4_pix_x, u4_pix_y;
+ UWORD32 u4_constrained_intra_pred =
+ ps_codec->au4_constrained_intra_pred[ps_proc->u1_spatial_layer_id];
+ block_neighbors_t s_ngbr_avbl_MB;
+
+ /* ngbr mb syntax information */
+ UWORD8 *pu1_top_mb_intra_modes =
+ ps_proc->s_nbr_info.ps_top_mb_intra_modes[ps_proc->i4_mb_x].au1_intra_modes;
+ isvce_mb_info_t *ps_top_mb_syn_ele = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ isvce_mb_info_t *ps_top_right_mb_syn_ele = ps_top_mb_syn_ele + 1;
+ /* valid intra modes map */
+ UWORD32 u4_valid_intra_modes;
+
+ if(ps_proc->ps_ngbr_avbl->u1_mb_c)
+ {
+ ps_top_right_mb_syn_ele = ps_top_mb_syn_ele + 1;
+ }
+ /* left pels */
+ s_ngbr_avbl_MB.u1_mb_a =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_a) &&
+ (u4_constrained_intra_pred ? (ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra &&
+ !ps_proc->s_nbr_info.ps_left_mb_info->u1_base_mode_flag)
+ : 1));
+
+ /* top pels */
+ s_ngbr_avbl_MB.u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b) &&
+ (u4_constrained_intra_pred ? (ps_top_mb_syn_ele->u1_is_intra &&
+ !ps_top_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+
+ /* topleft pels */
+ s_ngbr_avbl_MB.u1_mb_d =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_d) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_mb_syn_ele[-1].u1_is_intra && !ps_top_mb_syn_ele[-1].u1_base_mode_flag)
+ : 1));
+
+ /* top right */
+ s_ngbr_avbl_MB.u1_mb_c =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_c) &&
+ (u4_constrained_intra_pred ? (ps_top_right_mb_syn_ele->u1_is_intra &&
+ !ps_top_right_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+
+ for(b8 = 0; b8 < 4; b8++)
+ {
+ u4_pix_x = (b8 & 0x01) << 3;
+ u4_pix_y = (b8 >> 1) << 3;
+
+ pu1_mb_curr = ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) +
+ u4_pix_x + (u4_pix_y * i4_src_strd);
+ /* when rdopt is off, we use the input as reference for constructing
+ * prediction buffer */
+ /* as opposed to using the recon pels. (open loop intra prediction) */
+ pu1_mb_a = pu1_mb_curr - 1; /* pointer to left macro block */
+ pu1_mb_b = pu1_mb_curr - i4_src_strd; /* pointer to top macro block */
+ pu1_mb_d = pu1_mb_b - 1; /* pointer to top left macro block */
+
+ /* locating neighbors that are available for prediction */
+ /* TODO : update the neighbor availability information basing on constrained
+ * intra pred information */
+ /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be
+ * split in to distinct routines */
+ /* basing on neighbors available and hence evade the computation of neighbor
+ * availability totally. */
+ s_ngbr_avbl.u1_mb_a = isvce_derive_ngbr_avbl_of_mb_partitions(
+ &s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y); /* xD = -1, yD = 0 */
+ s_ngbr_avbl.u1_mb_b = isvce_derive_ngbr_avbl_of_mb_partitions(
+ &s_ngbr_avbl_MB, u4_pix_x, u4_pix_y - 1); /* xD = 0, yD = -1 */
+ s_ngbr_avbl.u1_mb_c = isvce_derive_ngbr_avbl_of_mb_partitions(
+ &s_ngbr_avbl_MB, u4_pix_x + 8, u4_pix_y - 1); /* xD = BLK_8x8_SIZE, yD = -1 */
+ s_ngbr_avbl.u1_mb_d = isvce_derive_ngbr_avbl_of_mb_partitions(
+ &s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y - 1); /* xD = -1, yD = -1 */
+
+ /* i4_ngbr_avbl = blk_a * LEFT_MB_AVAILABLE_MASK + blk_b *
+ * TOP_MB_AVAILABLE_MASK + blk_c * TOP_RIGHT_MB_AVAILABLE_MASK + blk_d *
+ * TOP_LEFT_MB_AVAILABLE_MASK */
+ i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) +
+ (s_ngbr_avbl.u1_mb_b << 2) + (s_ngbr_avbl.u1_mb_c << 3) +
+ (s_ngbr_avbl.u1_mb_a << 4);
+ /* if top partition is available and top right is not available for intra
+ * prediction, then */
+ /* padd top right samples using top sample and make top right also available
+ */
+ /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) +
+ * (s_ngbr_avbl.u1_mb_b << 2) + ((s_ngbr_avbl.u1_mb_b |
+ * s_ngbr_avbl.u1_mb_c) << 3); */
+ ps_proc->ai4_neighbor_avail_8x8_subblks[b8] = i4_ngbr_avbl;
+
+ ih264_intra_pred_luma_8x8_mode_ref_filtering(pu1_mb_a, pu1_mb_b, pu1_mb_d, pu1_ngbr_pels_i8,
+ i4_src_strd, i4_ngbr_avbl);
+
+ i4_partition_cost_least = INT_MAX;
+ /* set valid intra modes for evaluation */
+ u4_valid_intra_modes = 0x1ff;
+
+ if(!s_ngbr_avbl.u1_mb_b)
+ {
+ u4_valid_intra_modes &= ~(1 << VERT_I4x4);
+ u4_valid_intra_modes &= ~(1 << DIAG_DL_I4x4);
+ u4_valid_intra_modes &= ~(1 << VERT_L_I4x4);
+ }
+ if(!s_ngbr_avbl.u1_mb_a)
+ {
+ u4_valid_intra_modes &= ~(1 << HORZ_I4x4);
+ u4_valid_intra_modes &= ~(1 << HORZ_U_I4x4);
+ }
+ if(!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b || !s_ngbr_avbl.u1_mb_d)
+ {
+ u4_valid_intra_modes &= ~(1 << DIAG_DR_I4x4);
+ u4_valid_intra_modes &= ~(1 << VERT_R_I4x4);
+ u4_valid_intra_modes &= ~(1 << HORZ_D_I4x4);
+ }
+
+ /* estimate the intra 8x8 mode for the current partition (for evaluating
+ * cost) */
+ if(!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
+ {
+ u4_estimated_intra_8x8_mode = DC_I8x8;
+ }
+ else
+ {
+ UWORD32 u4_left_intra_8x8_mode = DC_I8x8;
+ UWORD32 u4_top_intra_8x8_mode = DC_I8x8;
+
+ if(u4_pix_x == 0)
+ {
+ if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I8x8)
+ {
+ u4_left_intra_8x8_mode =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[b8 + 1];
+ }
+ else if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I4x4)
+ {
+ u4_left_intra_8x8_mode = ps_proc->s_nbr_info.ps_left_mb_intra_modes
+ ->au1_intra_modes[(b8 + 1) * 4 + 2];
+ }
+ }
+ else
+ {
+ u4_left_intra_8x8_mode = ps_proc->au1_intra_luma_mb_8x8_modes[b8 - 1];
+ }
+
+ if(u4_pix_y == 0)
+ {
+ if(ps_top_mb_syn_ele->u2_mb_type == I8x8)
+ {
+ u4_top_intra_8x8_mode = pu1_top_mb_intra_modes[b8 + 2];
+ }
+ else if(ps_top_mb_syn_ele->u2_mb_type == I4x4)
+ {
+ u4_top_intra_8x8_mode = pu1_top_mb_intra_modes[(b8 + 2) * 4 + 2];
+ }
+ }
+ else
+ {
+ u4_top_intra_8x8_mode = ps_proc->au1_intra_luma_mb_8x8_modes[b8 - 2];
+ }
+
+ u4_estimated_intra_8x8_mode = MIN(u4_left_intra_8x8_mode, u4_top_intra_8x8_mode);
+ }
+
+ /* perform intra mode 8x8 evaluation */
+ for(u4_intra_mode = VERT_I8x8; u4_valid_intra_modes != 0;
+ u4_intra_mode++, u4_valid_intra_modes >>= 1)
+ {
+ if((u4_valid_intra_modes & 1) == 0) continue;
+
+ /* intra prediction */
+ (ps_codec->apf_intra_pred_8_l)[u4_intra_mode](pu1_ngbr_pels_i8, pu1_pred_mb, 0,
+ i4_pred_strd, i4_ngbr_avbl);
+
+ /* evaluate distortion between the actual blk and the estimated blk for
+ * the given mode */
+ ime_compute_sad_8x8(pu1_mb_curr, pu1_pred_mb, i4_src_strd, i4_pred_strd,
+ i4_partition_cost_least, &i4_partition_distortion);
+
+ i4_partition_cost =
+ i4_partition_distortion + ((u4_estimated_intra_8x8_mode == u4_intra_mode)
+ ? u4_cost_one_bit
+ : u4_cost_four_bits);
+
+ /* update the least cost information if necessary */
+ if(i4_partition_cost < i4_partition_cost_least)
+ {
+ i4_partition_cost_least = i4_partition_cost;
+ i4_partition_distortion_least = i4_partition_distortion;
+ u4_best_intra_8x8_mode = u4_intra_mode;
+ }
+ }
+ /* macroblock distortion */
+ i4_total_cost += i4_partition_cost_least;
+ i4_total_distortion += i4_partition_distortion_least;
+ /* mb partition mode */
+ ps_proc->au1_intra_luma_mb_8x8_modes[b8] = u4_best_intra_8x8_mode;
+ }
+
+ /* update the type of the mb if necessary */
+ if(i4_total_cost < ps_proc->i4_mb_cost)
+ {
+ ps_proc->i4_mb_cost = i4_total_cost;
+ ps_proc->i4_mb_distortion = i4_total_distortion;
+ ps_proc->ps_mb_info->u2_mb_type = I8x8;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 4x4 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible intra 4x4 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to
+*header bits necessary for encoding the macroblock. Assuming the deltaQP, cbp
+*bits and residual bits fall in to texture bits the number of bits taken to
+*encoding mbtype is considered as rate, we compute cost. Further we will
+*approximate the distortion as the deviation b/w input and the predicted block
+*as opposed to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
+* 24*lambda is added to the SAD before comparison with the best SAD for
+* inter prediction. This is an empirical value to prevent using too many intra
+* blocks.
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc)
+{
+ /* Codec Context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ /* SAD(distortion metric) of an 4x4 block */
+ WORD32 i4_partition_distortion_least = INT_MAX, i4_total_distortion = 0;
+
+ /* lambda */
+ UWORD32 u4_lambda = ps_proc->u4_lambda;
+
+ /* cost = distortion + lambda*rate */
+ WORD32 i4_partition_cost_least, i4_total_cost = (24 + 1) * u4_lambda;
+
+ /* cost due to mbtype */
+ UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
+
+ /* intra mode */
+ UWORD32 u4_best_intra_4x4_mode = DC_I4x4, u4_estimated_intra_4x4_mode;
+
+ /* neighbor pels for intra prediction */
+ UWORD8 *pu1_ngbr_pels_i4 = ps_proc->au1_ngbr_pels;
+
+ /* pointer to curr partition */
+ UWORD8 *pu1_mb_curr;
+
+ /* pointer to prediction macro block */
+ UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
+
+ /* strides */
+ WORD32 i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+
+ /* neighbors left, top, top right, top left */
+ UWORD8 *pu1_mb_a;
+ UWORD8 *pu1_mb_b;
+ UWORD8 *pu1_mb_c;
+ UWORD8 *pu1_mb_d;
+
+ /* neighbor availability */
+ WORD32 i4_ngbr_avbl;
+ block_neighbors_t s_ngbr_avbl;
+
+ /* temp vars */
+ UWORD32 i, b8, b4, u4_blk_x, u4_blk_y, u4_pix_x, u4_pix_y;
+
+ /* ngbr sub mb modes */
+ UWORD8 *pu1_top_mb_intra_modes =
+ ps_proc->s_nbr_info.ps_top_mb_intra_modes[ps_proc->i4_mb_x].au1_intra_modes;
+ isvce_mb_info_t *ps_top_mb_syn_ele = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ isvce_mb_info_t *ps_top_right_mb_syn_ele = ps_top_mb_syn_ele + 1;
+
+ /* valid intra modes map */
+ UWORD32 u4_valid_intra_modes;
+ UWORD16 u2_valid_modes[8] = {4, 262, 4, 262, 141, 399, 141, 511};
+
+ UWORD32 u4_constrained_intra_pred =
+ ps_codec->au4_constrained_intra_pred[ps_proc->u1_spatial_layer_id];
+ UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
+ if(ps_proc->ps_ngbr_avbl->u1_mb_c)
+ {
+ ps_top_right_mb_syn_ele = ps_top_mb_syn_ele + 1;
+ }
+ /* left pels */
+ u1_mb_a =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_a) &&
+ (u4_constrained_intra_pred ? (ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra &&
+ !ps_proc->s_nbr_info.ps_left_mb_info->u1_base_mode_flag)
+ : 1));
+
+ /* top pels */
+ u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_mb_syn_ele->u1_is_intra && !ps_top_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+
+ /* topleft pels */
+ u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d) &&
+ (u4_constrained_intra_pred ? (ps_top_mb_syn_ele[-1].u1_is_intra &&
+ !ps_top_mb_syn_ele[-1].u1_base_mode_flag)
+ : 1));
+
+ /* top right */
+ u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c) &&
+ (u4_constrained_intra_pred ? (ps_top_right_mb_syn_ele->u1_is_intra &&
+ !ps_top_right_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+
+ i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
+ memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
+
+ for(b8 = 0; b8 < 4; b8++)
+ {
+ u4_blk_x = (b8 & 0x01) << 3;
+ u4_blk_y = (b8 >> 1) << 3;
+ for(b4 = 0; b4 < 4; b4++)
+ {
+ u4_pix_x = u4_blk_x + ((b4 & 0x01) << 2);
+ u4_pix_y = u4_blk_y + ((b4 >> 1) << 2);
+
+ pu1_mb_curr = ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) +
+ u4_pix_x + (u4_pix_y * i4_src_strd);
+ /* when rdopt is off, we use the input as reference for constructing
+ * prediction buffer */
+ /* as opposed to using the recon pels. (open loop intra prediction) */
+ pu1_mb_a = pu1_mb_curr - 1; /* pointer to left macro block */
+ pu1_mb_b = pu1_mb_curr - i4_src_strd; /* pointer to top macro block */
+ pu1_mb_c = pu1_mb_b + 4; /* pointer to top macro block */
+ pu1_mb_d = pu1_mb_b - 1; /* pointer to top left macro block */
+
+ /* locating neighbors that are available for prediction */
+ /* TODO : update the neighbor availability information basing on
+ * constrained intra pred information */
+ /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be
+ * split in to distinct routines */
+ /* basing on neighbors available and hence evade the computation of
+ * neighbor availability totally. */
+
+ i4_ngbr_avbl = ps_proc->au1_ngbr_avbl_4x4_subblks[(b8 << 2) + b4];
+ s_ngbr_avbl.u1_mb_a = (i4_ngbr_avbl & 0x1);
+ s_ngbr_avbl.u1_mb_d = (i4_ngbr_avbl & 0x2) >> 1;
+ s_ngbr_avbl.u1_mb_b = (i4_ngbr_avbl & 0x4) >> 2;
+ s_ngbr_avbl.u1_mb_c = (i4_ngbr_avbl & 0x8) >> 3;
+ /* set valid intra modes for evaluation */
+ u4_valid_intra_modes = u2_valid_modes[i4_ngbr_avbl & 0x7];
+
+ /* if top partition is available and top right is not available for intra
+ * prediction, then */
+ /* padd top right samples using top sample and make top right also
+ * available */
+ /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) +
+ * (s_ngbr_avbl.u1_mb_b << 2) + ((s_ngbr_avbl.u1_mb_b |
+ * s_ngbr_avbl.u1_mb_c) << 3); */
+
+ /* gather prediction pels from the neighbors */
+ if(s_ngbr_avbl.u1_mb_a)
+ {
+ for(i = 0; i < 4; i++) pu1_ngbr_pels_i4[4 - 1 - i] = pu1_mb_a[i * i4_src_strd];
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4, 0, 4);
+ }
+
+ if(s_ngbr_avbl.u1_mb_b)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 4 + 1, pu1_mb_b, 4);
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4 + 5, 0, 4);
+ }
+
+ if(s_ngbr_avbl.u1_mb_d)
+ pu1_ngbr_pels_i4[4] = *pu1_mb_d;
+ else
+ pu1_ngbr_pels_i4[4] = 0;
+
+ if(s_ngbr_avbl.u1_mb_c)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 8 + 1, pu1_mb_c, 4);
+ }
+ else if(s_ngbr_avbl.u1_mb_b)
+ {
+ memset(pu1_ngbr_pels_i4 + 8 + 1, pu1_ngbr_pels_i4[8], 4);
+ s_ngbr_avbl.u1_mb_c = s_ngbr_avbl.u1_mb_b;
+ }
+
+ i4_partition_cost_least = INT_MAX;
+
+ /* predict the intra 4x4 mode for the current partition (for evaluating
+ * cost) */
+ if(!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
+ {
+ u4_estimated_intra_4x4_mode = DC_I4x4;
+ }
+ else
+ {
+ UWORD32 u4_left_intra_4x4_mode = DC_I4x4;
+ UWORD32 u4_top_intra_4x4_mode = DC_I4x4;
+
+ if(u4_pix_x == 0)
+ {
+ if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I4x4)
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes
+ ->au1_intra_modes[gau1_raster_to_zscan_map[3 + u4_pix_y]];
+ }
+ else if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I8x8)
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[b8 + 1];
+ }
+ }
+ else
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->au1_intra_luma_mb_4x4_modes
+ [gau1_raster_to_zscan_map[(u4_pix_x >> 2) + u4_pix_y - 1]];
+ }
+
+ if(u4_pix_y == 0)
+ {
+ if(ps_top_mb_syn_ele->u2_mb_type == I4x4)
+ {
+ u4_top_intra_4x4_mode =
+ pu1_top_mb_intra_modes[gau1_raster_to_zscan_map[12 + (u4_pix_x >> 2)]];
+ }
+ else if(ps_top_mb_syn_ele->u2_mb_type == I8x8)
+ {
+ u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[b8 + 2];
+ }
+ }
+ else
+ {
+ u4_top_intra_4x4_mode =
+ ps_proc->au1_intra_luma_mb_4x4_modes
+ [gau1_raster_to_zscan_map[(u4_pix_x >> 2) + u4_pix_y - 4]];
+ }
+
+ u4_estimated_intra_4x4_mode = MIN(u4_left_intra_4x4_mode, u4_top_intra_4x4_mode);
+ }
+
+ ps_proc->au1_predicted_intra_luma_mb_4x4_modes[(b8 << 2) + b4] =
+ u4_estimated_intra_4x4_mode;
+
+ /* mode evaluation and prediction */
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes(
+ pu1_mb_curr, pu1_ngbr_pels_i4, pu1_pred_mb, i4_src_strd, i4_pred_strd, i4_ngbr_avbl,
+ &u4_best_intra_4x4_mode, &i4_partition_cost_least, u4_valid_intra_modes, u4_lambda,
+ u4_estimated_intra_4x4_mode);
+
+ i4_partition_distortion_least =
+ i4_partition_cost_least - ((u4_estimated_intra_4x4_mode == u4_best_intra_4x4_mode)
+ ? u4_cost_one_bit
+ : u4_cost_four_bits);
+
+ DEBUG("%d partition cost, %d intra mode\n", i4_partition_cost_least,
+ u4_best_intra_4x4_mode);
+ /* macroblock distortion */
+ i4_total_distortion += i4_partition_distortion_least;
+ i4_total_cost += i4_partition_cost_least;
+ /* mb partition mode */
+ ps_proc->au1_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_best_intra_4x4_mode;
+ }
+ }
+
+ /* update the type of the mb if necessary */
+ if(i4_total_cost < ps_proc->i4_mb_cost)
+ {
+ ps_proc->i4_mb_cost = i4_total_cost;
+ ps_proc->i4_mb_distortion = i4_total_distortion;
+ ps_proc->ps_mb_info->u2_mb_type = I4x4;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief evaluate best intra 4x4 mode (rate distortion opt on)
+*
+* @par Description
+* This function evaluates all the possible intra 4x4 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to
+*header bits necessary for encoding the macroblock. Assuming the deltaQP, cbp
+*bits and residual bits fall in to texture bits the number of bits taken to
+*encoding mbtype is considered as rate, we compute cost. Further we will
+*approximate the distortion as the deviation b/w input and the predicted block
+*as opposed to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
+* 24*lambda is added to the SAD before comparison with the best SAD for
+* inter prediction. This is an empirical value to prevent using too many intra
+* blocks.
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(isvce_process_ctxt_t *ps_proc)
+{
+ block_neighbors_t s_ngbr_avbl;
+ buffer_container_t s_src;
+ buffer_container_t s_pred;
+ buffer_container_t s_recon;
+ buffer_container_t s_quant_coeffs;
+ buffer_container_t s_res_pred;
+
+ /* neighbors left, top, top right, top left */
+ UWORD8 *pu1_mb_a;
+ UWORD8 *pu1_mb_b;
+ UWORD8 *pu1_mb_c;
+ UWORD8 *pu1_mb_d;
+ UWORD8 *pu1_mb_curr;
+ UWORD8 *pu1_mb_ref_left, *pu1_mb_ref_top;
+ UWORD8 *pu1_ref_mb_intra_4x4;
+ WORD32 i4_ref_strd_left, i4_ref_strd_top;
+ WORD32 i4_ngbr_avbl;
+ UWORD32 i, b8, b4, u4_blk_x, u4_blk_y, u4_pix_x, u4_pix_y;
+ /* valid intra modes map */
+ UWORD32 u4_valid_intra_modes;
+ /* Dummy variable for 4x4 trans function */
+ WORD16 i2_dc_dummy;
+ UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ isvce_mb_info_t *ps_top_mb = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ isvce_mb_info_t *ps_top_right_mb = ps_top_mb + 1;
+ isvce_mb_info_t *ps_top_left_mb = ps_top_mb - 1;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ resi_trans_quant_constants_t s_resi_trans_quant_constants = {
+ .pu2_scale_matrix = ps_qp_params->pu2_scale_mat,
+ .pu2_threshold_matrix = ps_qp_params->pu2_thres_mat,
+ .u4_qbits = ps_qp_params->u1_qbits,
+ .u4_round_factor = ps_qp_params->u4_dead_zone};
+ iq_it_res_rec_constants_t s_iq_it_res_rec_constants = {
+ .pu2_iscal_mat = ps_qp_params->pu2_iscale_mat,
+ .pu2_weigh_mat = ps_qp_params->pu2_weigh_mat,
+ .u4_qp_div_6 = ps_qp_params->u1_qp_div};
+
+ const UWORD16 u2_valid_modes[8] = {4, 262, 4, 262, 141, 399, 141, 511};
+ WORD32 i4_partition_distortion_least = INT_MAX, i4_total_distortion = 0;
+ UWORD32 u4_lambda = ps_proc->u4_lambda;
+ WORD32 i4_partition_cost_least, i4_total_cost = (24 + 1) * u4_lambda;
+ /* cost due to mbtype */
+ UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
+ UWORD32 u4_best_intra_4x4_mode = DC_I4x4, u4_estimated_intra_4x4_mode;
+ UWORD8 *pu1_ngbr_pels_i4 = ps_proc->au1_ngbr_pels;
+ WORD16 *pi2_quant_coeffs = ps_proc->pi2_res_buf_intra_4x4;
+ UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
+ WORD32 i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+ UWORD8 *pu1_nnz = (UWORD8 *) ps_proc->au4_nnz_intra_4x4;
+ UWORD8 *pu1_top_mb_intra_modes =
+ ps_proc->s_nbr_info.ps_top_mb_intra_modes[ps_proc->i4_mb_x].au1_intra_modes;
+ UWORD32 u4_constrained_intra_pred =
+ ps_codec->au4_constrained_intra_pred[ps_proc->u1_spatial_layer_id];
+ UWORD8 u1_resi_trans_fxn_idx = isvc_get_resi_trans_quant_variant_idx(0);
+ UWORD8 u1_iq_it_recon_fxn_idx = isvc_get_iq_it_recon_variant_idx(1, 0);
+
+ s_res_pred = ps_proc->ps_mb_res_buf->as_component_bufs[Y];
+
+ /* compute ngbr availability for sub blks */
+ if(ps_proc->ps_ngbr_avbl->u1_mb_c)
+ {
+ ps_top_right_mb = ps_top_mb + 1;
+ }
+
+ /* left pels */
+ u1_mb_a =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_a) &&
+ (u4_constrained_intra_pred ? (ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra &&
+ !ps_proc->s_nbr_info.ps_left_mb_info->u1_base_mode_flag)
+ : 1));
+
+ /* top pels */
+ u1_mb_b =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_b) &&
+ (u4_constrained_intra_pred ? (ps_top_mb->u1_is_intra && !ps_top_mb->u1_base_mode_flag)
+ : 1));
+
+ /* topleft pels */
+ u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_left_mb->u1_is_intra && !ps_top_left_mb->u1_base_mode_flag)
+ : 1));
+
+ /* top right pels */
+ u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_right_mb->u1_is_intra && !ps_top_right_mb->u1_base_mode_flag)
+ : 1));
+
+ i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
+ memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
+
+ for(b8 = 0; b8 < 4; b8++)
+ {
+ u4_blk_x = (b8 & 0x01) << 3;
+ u4_blk_y = (b8 >> 1) << 3;
+ for(b4 = 0; b4 < 4; b4++, pu1_nnz++, pi2_quant_coeffs += MB_SIZE)
+ {
+ u4_pix_x = u4_blk_x + ((b4 & 0x01) << 2);
+ u4_pix_y = u4_blk_y + ((b4 >> 1) << 2);
+
+ pu1_ref_mb_intra_4x4 =
+ ps_proc->pu1_ref_mb_intra_4x4 + u4_pix_x + (u4_pix_y * i4_pred_strd);
+ pu1_mb_curr = ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) +
+ u4_pix_x + (u4_pix_y * i4_src_strd);
+ pu1_pred_mb = ps_proc->pu1_pred_mb + u4_pix_x + (u4_pix_y * i4_pred_strd);
+ if(u4_pix_x == 0)
+ {
+ i4_ref_strd_left = ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride;
+ pu1_mb_ref_left =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + u4_pix_x +
+ (u4_pix_y * i4_ref_strd_left);
+ }
+ else
+ {
+ i4_ref_strd_left = i4_pred_strd;
+ pu1_mb_ref_left = pu1_ref_mb_intra_4x4;
+ }
+ if(u4_pix_y == 0)
+ {
+ i4_ref_strd_top = ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride;
+ pu1_mb_ref_top =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + u4_pix_x +
+ (u4_pix_y * i4_ref_strd_top);
+ }
+ else
+ {
+ i4_ref_strd_top = i4_pred_strd;
+ pu1_mb_ref_top = pu1_ref_mb_intra_4x4;
+ }
+
+ pu1_mb_a = pu1_mb_ref_left - 1; /* pointer to left macro block */
+ pu1_mb_b = pu1_mb_ref_top - i4_ref_strd_top; /* pointer to top macro block */
+ pu1_mb_c = pu1_mb_b + 4; /* pointer to top right macro block */
+ if(u4_pix_y == 0)
+ pu1_mb_d = pu1_mb_b - 1;
+ else
+ pu1_mb_d = pu1_mb_a - i4_ref_strd_left; /* pointer to top left macro block */
+
+ /* locating neighbors that are available for prediction */
+ /* TODO : update the neighbor availability information basing on
+ * constrained intra pred information */
+ /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be
+ * split in to distinct routines */
+ /* basing on neighbors available and hence evade the computation of
+ * neighbor availability totally. */
+
+ i4_ngbr_avbl = ps_proc->au1_ngbr_avbl_4x4_subblks[(b8 << 2) + b4];
+ s_ngbr_avbl.u1_mb_a = (i4_ngbr_avbl & 0x1);
+ s_ngbr_avbl.u1_mb_d = (i4_ngbr_avbl & 0x2) >> 1;
+ s_ngbr_avbl.u1_mb_b = (i4_ngbr_avbl & 0x4) >> 2;
+ s_ngbr_avbl.u1_mb_c = (i4_ngbr_avbl & 0x8) >> 3;
+ /* set valid intra modes for evaluation */
+ u4_valid_intra_modes = u2_valid_modes[i4_ngbr_avbl & 0x7];
+
+ /* if top partition is available and top right is not available for intra
+ * prediction, then */
+ /* padd top right samples using top sample and make top right also
+ * available */
+ /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) +
+ * (s_ngbr_avbl.u1_mb_b << 2) + ((s_ngbr_avbl.u1_mb_b |
+ * s_ngbr_avbl.u1_mb_c) << 3); */
+
+ /* gather prediction pels from the neighbors */
+ if(s_ngbr_avbl.u1_mb_a)
+ {
+ for(i = 0; i < 4; i++) pu1_ngbr_pels_i4[4 - 1 - i] = pu1_mb_a[i * i4_ref_strd_left];
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4, 0, 4);
+ }
+ if(s_ngbr_avbl.u1_mb_b)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 4 + 1, pu1_mb_b, 4);
+ }
+ else
+ {
+ memset(pu1_ngbr_pels_i4 + 4 + 1, 0, 4);
+ }
+ if(s_ngbr_avbl.u1_mb_d)
+ pu1_ngbr_pels_i4[4] = *pu1_mb_d;
+ else
+ pu1_ngbr_pels_i4[4] = 0;
+ if(s_ngbr_avbl.u1_mb_c)
+ {
+ memcpy(pu1_ngbr_pels_i4 + 8 + 1, pu1_mb_c, 4);
+ }
+ else if(s_ngbr_avbl.u1_mb_b)
+ {
+ memset(pu1_ngbr_pels_i4 + 8 + 1, pu1_ngbr_pels_i4[8], 4);
+ s_ngbr_avbl.u1_mb_c = s_ngbr_avbl.u1_mb_b;
+ }
+
+ i4_partition_cost_least = INT_MAX;
+
+ /* predict the intra 4x4 mode for the current partition (for evaluating
+ * cost) */
+ if(!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
+ {
+ u4_estimated_intra_4x4_mode = DC_I4x4;
+ }
+ else
+ {
+ UWORD32 u4_left_intra_4x4_mode = DC_I4x4;
+ UWORD32 u4_top_intra_4x4_mode = DC_I4x4;
+
+ if(u4_pix_x == 0)
+ {
+ if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I4x4)
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes
+ ->au1_intra_modes[gau1_raster_to_zscan_map[3 + u4_pix_y]];
+ }
+ else if(ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == I8x8)
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[b8 + 1];
+ }
+ }
+ else
+ {
+ u4_left_intra_4x4_mode =
+ ps_proc->au1_intra_luma_mb_4x4_modes
+ [gau1_raster_to_zscan_map[(u4_pix_x >> 2) + u4_pix_y - 1]];
+ }
+
+ if(u4_pix_y == 0)
+ {
+ if(ps_top_mb->u2_mb_type == I4x4)
+ {
+ u4_top_intra_4x4_mode =
+ pu1_top_mb_intra_modes[gau1_raster_to_zscan_map[12 + (u4_pix_x >> 2)]];
+ }
+ else if(ps_top_mb->u2_mb_type == I8x8)
+ {
+ u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[b8 + 2];
+ }
+ }
+ else
+ {
+ u4_top_intra_4x4_mode =
+ ps_proc->au1_intra_luma_mb_4x4_modes
+ [gau1_raster_to_zscan_map[(u4_pix_x >> 2) + u4_pix_y - 4]];
+ }
+
+ u4_estimated_intra_4x4_mode = MIN(u4_left_intra_4x4_mode, u4_top_intra_4x4_mode);
+ }
+
+ ps_proc->au1_predicted_intra_luma_mb_4x4_modes[(b8 << 2) + b4] =
+ u4_estimated_intra_4x4_mode;
+
+ /*mode evaluation and prediction*/
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes(
+ pu1_mb_curr, pu1_ngbr_pels_i4, pu1_pred_mb, i4_src_strd, i4_pred_strd, i4_ngbr_avbl,
+ &u4_best_intra_4x4_mode, &i4_partition_cost_least, u4_valid_intra_modes, u4_lambda,
+ u4_estimated_intra_4x4_mode);
+
+ i4_partition_distortion_least =
+ i4_partition_cost_least - ((u4_estimated_intra_4x4_mode == u4_best_intra_4x4_mode)
+ ? u4_cost_one_bit
+ : u4_cost_four_bits);
+
+ DEBUG("%d partition cost, %d intra mode\n", i4_partition_cost_least,
+ u4_best_intra_4x4_mode);
+
+ /* macroblock distortion */
+ i4_total_distortion += i4_partition_distortion_least;
+ i4_total_cost += i4_partition_cost_least;
+
+ /* mb partition mode */
+ ps_proc->au1_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_best_intra_4x4_mode;
+
+ /********************************************************/
+ /* error estimation, */
+ /* transform */
+ /* quantization */
+ /********************************************************/
+ s_src.pv_data = pu1_mb_curr;
+ s_src.i4_data_stride = i4_src_strd;
+
+ s_pred.pv_data = pu1_pred_mb;
+ s_pred.i4_data_stride = i4_pred_strd;
+
+ s_quant_coeffs.pv_data = pi2_quant_coeffs;
+ s_quant_coeffs.i4_data_stride = 4;
+
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[u1_resi_trans_fxn_idx](
+ &s_src, &s_pred, &s_quant_coeffs, &s_res_pred,
+ /* No op stride, this implies a buff of lenght 1x16 */
+ &s_resi_trans_quant_constants, pu1_nnz, &i2_dc_dummy, 0);
+
+ /********************************************************/
+ /* ierror estimation, */
+ /* itransform */
+ /* iquantization */
+ /********************************************************/
+
+ /* Tx blk coeffs are stored blk by blk */
+ /* Hence, in order to access rows of each Tx blk, one needs to stride of
+ * TxxSize */
+ s_quant_coeffs.i4_data_stride = 4;
+
+ s_recon.pv_data = pu1_ref_mb_intra_4x4;
+ s_recon.i4_data_stride = i4_pred_strd;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[u1_iq_it_recon_fxn_idx](
+ &s_quant_coeffs, &s_pred, &s_res_pred, &s_res_pred, &s_recon,
+ &s_iq_it_res_rec_constants, ps_proc->pv_scratch_buff, s_quant_coeffs.pv_data, 0, 0);
+ }
+ }
+
+ /* update the type of the mb if necessary */
+ if(i4_total_cost < ps_proc->i4_mb_cost)
+ {
+ ps_proc->i4_mb_cost = i4_total_cost;
+ ps_proc->i4_mb_distortion = i4_total_distortion;
+ ps_proc->ps_mb_info->u2_mb_type = I4x4;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best chroma intra 8x8 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible chroma intra 8x8 modes and finds
+* the mode that best represents the macroblock (least distortion) and occupies
+* fewer bits in the bitstream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to macroblock context (handle)
+*
+* @remarks
+* For chroma best intra pred mode is calculated based only on SAD
+*
+* @returns none
+*
+******************************************************************************
+*/
+
+void isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc)
+{
+ /* Codec Context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* SAD(distortion metric) of an 8x8 block */
+ WORD32 i4_mb_distortion, i4_chroma_mb_distortion;
+
+ /* intra mode */
+ UWORD32 u4_best_chroma_intra_8x8_mode = DC_CH_I8x8;
+
+ /* neighbor pels for intra prediction */
+ UWORD8 *pu1_ngbr_pels_c_i8x8 = ps_proc->au1_ngbr_pels;
+
+ /* pointer to curr macro block */
+ UWORD8 *pu1_curr_mb = ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data);
+ UWORD8 *pu1_ref_mb = ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data);
+
+ /* pointer to prediction macro block */
+ UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb_intra_chroma;
+ UWORD8 *pu1_pred_mb_plane = ps_proc->pu1_pred_mb_intra_chroma_plane;
+
+ /* strides */
+ WORD32 i4_src_strd_c = ps_proc->s_src_buf_props.as_component_bufs[1].i4_data_stride;
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+ WORD32 i4_rec_strd_c = ps_proc->s_rec_buf_props.as_component_bufs[1].i4_data_stride;
+
+ /* neighbors left, top, top left */
+ UWORD8 *pu1_mb_a = pu1_ref_mb - 2;
+ UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd_c;
+ UWORD8 *pu1_mb_d = pu1_mb_b - 2;
+
+ /* neighbor availability */
+ const UWORD8 u1_valid_intra_modes[8] = {1, 3, 1, 3, 5, 7, 5, 15};
+ WORD32 i4_ngbr_avbl;
+
+ /* valid intra modes map */
+ UWORD32 u4_valid_intra_modes;
+ isvce_mb_info_t *ps_top_mb_syn_ele = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+
+ /* temp var */
+ UWORD8 i;
+ UWORD32 u4_constrained_intra_pred =
+ ps_codec->au4_constrained_intra_pred[ps_proc->u1_spatial_layer_id];
+ UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
+ /* locating neighbors that are available for prediction */
+
+ /* gather prediction pels from the neighbors */
+ /* left pels */
+ u1_mb_a =
+ ((ps_proc->ps_ngbr_avbl->u1_mb_a) &&
+ (u4_constrained_intra_pred ? (ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra &&
+ !ps_proc->s_nbr_info.ps_left_mb_info->u1_base_mode_flag)
+ : 1));
+ if(u1_mb_a)
+ {
+ for(i = 0; i < 16; i += 2)
+ {
+ pu1_ngbr_pels_c_i8x8[16 - 2 - i] = pu1_mb_a[(i / 2) * i4_rec_strd_c];
+ pu1_ngbr_pels_c_i8x8[16 - 1 - i] = pu1_mb_a[(i / 2) * i4_rec_strd_c + 1];
+ }
+ }
+ else
+ {
+ ps_mem_fxns->pf_mem_set_mul8(pu1_ngbr_pels_c_i8x8, 0, MB_SIZE);
+ }
+
+ /* top pels */
+ u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b) &&
+ (u4_constrained_intra_pred
+ ? (ps_top_mb_syn_ele->u1_is_intra && !ps_top_mb_syn_ele->u1_base_mode_flag)
+ : 1));
+ if(u1_mb_b)
+ {
+ ps_mem_fxns->pf_mem_cpy_mul8(&pu1_ngbr_pels_c_i8x8[18], pu1_mb_b, 16);
+ }
+ else
+ {
+ ps_mem_fxns->pf_mem_set_mul8((pu1_ngbr_pels_c_i8x8 + 18), 0, MB_SIZE);
+ }
+
+ /* top left pels */
+ u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d) &&
+ (u4_constrained_intra_pred ? (ps_top_mb_syn_ele[-1].u1_is_intra &&
+ !ps_top_mb_syn_ele[-1].u1_base_mode_flag)
+ : 1));
+ if(u1_mb_d)
+ {
+ pu1_ngbr_pels_c_i8x8[16] = *pu1_mb_d;
+ pu1_ngbr_pels_c_i8x8[17] = *(pu1_mb_d + 1);
+ }
+ i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
+ ps_proc->i4_chroma_neighbor_avail_8x8_mb = i4_ngbr_avbl;
+
+ u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
+
+ if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST ||
+ ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
+ u4_valid_intra_modes &= ~(1 << PLANE_CH_I8x8);
+
+ i4_chroma_mb_distortion = INT_MAX;
+
+ /* perform intra mode chroma 8x8 evaluation */
+ /* intra prediction */
+ ps_codec->pf_ih264e_evaluate_intra_chroma_modes(
+ pu1_curr_mb, pu1_ngbr_pels_c_i8x8, pu1_pred_mb, i4_src_strd_c, i4_pred_strd, i4_ngbr_avbl,
+ &u4_best_chroma_intra_8x8_mode, &i4_chroma_mb_distortion, u4_valid_intra_modes);
+
+ if(u4_valid_intra_modes & 8) /* if Chroma PLANE is valid*/
+ {
+ (ps_codec->apf_intra_pred_c)[PLANE_CH_I8x8](pu1_ngbr_pels_c_i8x8, pu1_pred_mb_plane, 0,
+ i4_pred_strd, i4_ngbr_avbl);
+
+ /* evaluate distortion(sad) */
+ ps_codec->pf_compute_sad_16x8(pu1_curr_mb, pu1_pred_mb_plane, i4_src_strd_c, i4_pred_strd,
+ i4_chroma_mb_distortion, &i4_mb_distortion);
+
+ /* update the least distortion information if necessary */
+ if(i4_mb_distortion < i4_chroma_mb_distortion)
+ {
+ i4_chroma_mb_distortion = i4_mb_distortion;
+ u4_best_chroma_intra_8x8_mode = PLANE_CH_I8x8;
+ }
+ }
+
+ DEBUG("%d partition cost, %d intra mode\n", i4_chroma_mb_distortion,
+ u4_best_chroma_intra_8x8_mode);
+
+ ps_proc->u1_c_i8_mode = u4_best_chroma_intra_8x8_mode;
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* Evaluate best intra 16x16 mode (among VERT, HORZ and DC) and do the
+* prediction.
+*
+* @par Description
+* This function evaluates first three 16x16 modes and compute corresponding sad
+* and return the buffer predicted with best mode.
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] pu1_ngbr_pels_i16
+* UWORD8 pointer to neighbouring pels
+*
+* @param[out] pu1_dst
+* UWORD8 pointer to the destination
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] dst_strd
+* integer destination stride
+*
+* @param[in] u4_n_avblty
+* availability of neighbouring pixels
+*
+* @param[in] u4_intra_mode
+* Pointer to the variable in which best mode is returned
+*
+* @param[in] pu4_sadmin
+* Pointer to the variable in which minimum sad is returned
+*
+* @param[in] u4_valid_intra_modes
+* Says what all modes are valid
+*
+* @returns none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra16x16_modes(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels_i16, UWORD8 *pu1_dst,
+ UWORD32 src_strd, UWORD32 dst_strd, WORD32 u4_n_avblty,
+ UWORD32 *u4_intra_mode, WORD32 *pu4_sadmin,
+ UWORD32 u4_valid_intra_modes)
+{
+ UWORD8 *pu1_neighbour;
+ UWORD8 *pu1_src_temp = pu1_src;
+ UWORD8 left = 0, top = 0;
+ WORD32 u4_dcval = 0;
+ WORD32 i, j;
+ WORD32 i4_sad_vert = INT_MAX, i4_sad_horz = INT_MAX, i4_sad_dc = INT_MAX, i4_min_sad = INT_MAX;
+ UWORD8 val;
+
+ left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
+ top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
+
+ /* left available */
+ if(left)
+ {
+ i4_sad_horz = 0;
+
+ for(i = 0; i < 16; i++)
+ {
+ val = pu1_ngbr_pels_i16[15 - i];
+
+ u4_dcval += val;
+
+ for(j = 0; j < 16; j++)
+ {
+ i4_sad_horz += ABS(val - pu1_src_temp[j]);
+ }
+
+ pu1_src_temp += src_strd;
+ }
+ u4_dcval += 8;
+ }
+
+ pu1_src_temp = pu1_src;
+ /* top available */
+ if(top)
+ {
+ i4_sad_vert = 0;
+
+ for(i = 0; i < 16; i++)
+ {
+ u4_dcval += pu1_ngbr_pels_i16[17 + i];
+
+ for(j = 0; j < 16; j++)
+ {
+ i4_sad_vert += ABS(pu1_ngbr_pels_i16[17 + j] - pu1_src_temp[j]);
+ }
+ pu1_src_temp += src_strd;
+ }
+ u4_dcval += 8;
+ }
+
+ u4_dcval = (u4_dcval) >> (3 + left + top);
+
+ pu1_src_temp = pu1_src;
+
+ /* none available */
+ u4_dcval += (left == 0) * (top == 0) * 128;
+
+ i4_sad_dc = 0;
+
+ for(i = 0; i < 16; i++)
+ {
+ for(j = 0; j < 16; j++)
+ {
+ i4_sad_dc += ABS(u4_dcval - pu1_src_temp[j]);
+ }
+ pu1_src_temp += src_strd;
+ }
+
+ if((u4_valid_intra_modes & 04) == 0) /* If DC is disabled */
+ i4_sad_dc = INT_MAX;
+
+ if((u4_valid_intra_modes & 01) == 0) /* If VERT is disabled */
+ i4_sad_vert = INT_MAX;
+
+ if((u4_valid_intra_modes & 02) == 0) /* If HORZ is disabled */
+ i4_sad_horz = INT_MAX;
+
+ i4_min_sad = MIN3(i4_sad_horz, i4_sad_dc, i4_sad_vert);
+
+ /* Finding Minimum sad and doing corresponding prediction */
+ if(i4_min_sad < *pu4_sadmin)
+ {
+ *pu4_sadmin = i4_min_sad;
+ if(i4_min_sad == i4_sad_vert)
+ {
+ *u4_intra_mode = VERT_I16x16;
+ pu1_neighbour = pu1_ngbr_pels_i16 + 17;
+ for(j = 0; j < 16; j++)
+ {
+ memcpy(pu1_dst, pu1_neighbour, MB_SIZE);
+ pu1_dst += dst_strd;
+ }
+ }
+ else if(i4_min_sad == i4_sad_horz)
+ {
+ *u4_intra_mode = HORZ_I16x16;
+ for(j = 0; j < 16; j++)
+ {
+ val = pu1_ngbr_pels_i16[15 - j];
+ memset(pu1_dst, val, MB_SIZE);
+ pu1_dst += dst_strd;
+ }
+ }
+ else
+ {
+ *u4_intra_mode = DC_I16x16;
+ for(j = 0; j < 16; j++)
+ {
+ memset(pu1_dst, u4_dcval, MB_SIZE);
+ pu1_dst += dst_strd;
+ }
+ }
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* Evaluate best intra 4x4 mode and perform prediction.
+*
+* @par Description
+* This function evaluates 4x4 modes and compute corresponding sad
+* and return the buffer predicted with best mode.
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] pu1_ngbr_pels
+* UWORD8 pointer to neighbouring pels
+*
+* @param[out] pu1_dst
+* UWORD8 pointer to the destination
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] dst_strd
+* integer destination stride
+*
+* @param[in] u4_n_avblty
+* availability of neighbouring pixels
+*
+* @param[in] u4_intra_mode
+* Pointer to the variable in which best mode is returned
+*
+* @param[in] pu4_sadmin
+* Pointer to the variable in which minimum cost is returned
+*
+* @param[in] u4_valid_intra_modes
+* Says what all modes are valid
+*
+* @param[in] u4_lambda
+* Lamda value for computing cost from SAD
+*
+* @param[in] u4_predictd_mode
+* Predicted mode for cost computation
+*
+* @returns none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra_4x4_modes(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels, UWORD8 *pu1_dst,
+ UWORD32 src_strd, UWORD32 dst_strd, WORD32 u4_n_avblty,
+ UWORD32 *u4_intra_mode, WORD32 *pu4_sadmin,
+ UWORD32 u4_valid_intra_modes, UWORD32 u4_lambda,
+ UWORD32 u4_predictd_mode)
+{
+ UWORD8 *pu1_src_temp = pu1_src;
+ UWORD8 *pu1_pred = pu1_ngbr_pels;
+ UWORD8 left = 0, top = 0;
+ UWORD8 u1_pred_val = 0;
+ UWORD8 u1_pred_vals[4] = {0};
+ UWORD8 *pu1_pred_val = NULL;
+ /* To store FILT121 operated values*/
+ UWORD8 u1_pred_vals_diag_121[15] = {0};
+ /* To store FILT11 operated values*/
+ UWORD8 u1_pred_vals_diag_11[15] = {0};
+ UWORD8 u1_pred_vals_vert_r[8] = {0};
+ UWORD8 u1_pred_vals_horz_d[10] = {0};
+ UWORD8 u1_pred_vals_horz_u[10] = {0};
+ WORD32 u4_dcval = 0;
+ WORD32 i4_sad[MAX_I4x4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX,
+ INT_MAX, INT_MAX, INT_MAX, INT_MAX};
+
+ WORD32 i4_cost[MAX_I4x4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX,
+ INT_MAX, INT_MAX, INT_MAX, INT_MAX};
+ WORD32 i, i4_min_cost = INT_MAX;
+
+ left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
+ top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
+
+ /* Computing SAD */
+
+ /* VERT mode valid */
+ if(u4_valid_intra_modes & 1)
+ {
+ pu1_pred = pu1_ngbr_pels + 5;
+ i4_sad[VERT_I4x4] = 0;
+ i4_cost[VERT_I4x4] = 0;
+
+ USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
+
+ i4_cost[VERT_I4x4] =
+ i4_sad[VERT_I4x4] + ((u4_predictd_mode == VERT_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ /* HORZ mode valid */
+ if(u4_valid_intra_modes & 2)
+ {
+ i4_sad[HORZ_I4x4] = 0;
+ i4_cost[HORZ_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+
+ u1_pred_val = pu1_ngbr_pels[3];
+
+ i4_sad[HORZ_I4x4] +=
+ ABS(pu1_src_temp[0] - u1_pred_val) + ABS(pu1_src_temp[1] - u1_pred_val) +
+ ABS(pu1_src_temp[2] - u1_pred_val) + ABS(pu1_src_temp[3] - u1_pred_val);
+ pu1_src_temp += src_strd;
+
+ u1_pred_val = pu1_ngbr_pels[2];
+
+ i4_sad[HORZ_I4x4] +=
+ ABS(pu1_src_temp[0] - u1_pred_val) + ABS(pu1_src_temp[1] - u1_pred_val) +
+ ABS(pu1_src_temp[2] - u1_pred_val) + ABS(pu1_src_temp[3] - u1_pred_val);
+ pu1_src_temp += src_strd;
+
+ u1_pred_val = pu1_ngbr_pels[1];
+
+ i4_sad[HORZ_I4x4] +=
+ ABS(pu1_src_temp[0] - u1_pred_val) + ABS(pu1_src_temp[1] - u1_pred_val) +
+ ABS(pu1_src_temp[2] - u1_pred_val) + ABS(pu1_src_temp[3] - u1_pred_val);
+ pu1_src_temp += src_strd;
+
+ u1_pred_val = pu1_ngbr_pels[0];
+
+ i4_sad[HORZ_I4x4] +=
+ ABS(pu1_src_temp[0] - u1_pred_val) + ABS(pu1_src_temp[1] - u1_pred_val) +
+ ABS(pu1_src_temp[2] - u1_pred_val) + ABS(pu1_src_temp[3] - u1_pred_val);
+
+ i4_cost[HORZ_I4x4] =
+ i4_sad[HORZ_I4x4] + ((u4_predictd_mode == HORZ_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ /* DC mode valid */
+ if(u4_valid_intra_modes & 4)
+ {
+ i4_sad[DC_I4x4] = 0;
+ i4_cost[DC_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+
+ if(left)
+ u4_dcval =
+ pu1_ngbr_pels[0] + pu1_ngbr_pels[1] + pu1_ngbr_pels[2] + pu1_ngbr_pels[3] + 2;
+ if(top)
+ u4_dcval +=
+ pu1_ngbr_pels[5] + pu1_ngbr_pels[6] + pu1_ngbr_pels[7] + pu1_ngbr_pels[8] + 2;
+
+ u4_dcval = (u4_dcval) ? (u4_dcval >> (1 + left + top)) : 128;
+
+ /* none available */
+ memset(u1_pred_vals, u4_dcval, 4);
+ USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
+ pu1_src_temp += src_strd;
+
+ i4_cost[DC_I4x4] =
+ i4_sad[DC_I4x4] + ((u4_predictd_mode == DC_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ /* if modes other than VERT, HORZ and DC are valid */
+ if(u4_valid_intra_modes > 7)
+ {
+ pu1_pred = pu1_ngbr_pels;
+ pu1_pred[13] = pu1_pred[14] = pu1_pred[12];
+
+ /* Performing FILT121 and FILT11 operation for all neighbour values*/
+ for(i = 0; i < 13; i++)
+ {
+ u1_pred_vals_diag_121[i] = FILT121(pu1_pred[0], pu1_pred[1], pu1_pred[2]);
+ u1_pred_vals_diag_11[i] = FILT11(pu1_pred[0], pu1_pred[1]);
+
+ pu1_pred++;
+ }
+
+ if(u4_valid_intra_modes & 8) /* DIAG_DL */
+ {
+ i4_sad[DIAG_DL_I4x4] = 0;
+ i4_cost[DIAG_DL_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+ pu1_pred_val = u1_pred_vals_diag_121 + 5;
+
+ USADA8(pu1_src_temp, pu1_pred_val, i4_sad[DIAG_DL_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 1), i4_sad[DIAG_DL_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[DIAG_DL_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 3), i4_sad[DIAG_DL_I4x4]);
+ pu1_src_temp += src_strd;
+ i4_cost[DIAG_DL_I4x4] =
+ i4_sad[DIAG_DL_I4x4] +
+ ((u4_predictd_mode == DIAG_DL_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ if(u4_valid_intra_modes & 16) /* DIAG_DR */
+ {
+ i4_sad[DIAG_DR_I4x4] = 0;
+ i4_cost[DIAG_DR_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+ pu1_pred_val = u1_pred_vals_diag_121 + 3;
+
+ USADA8(pu1_src_temp, pu1_pred_val, i4_sad[DIAG_DR_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val - 1), i4_sad[DIAG_DR_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val - 2), i4_sad[DIAG_DR_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val - 3), i4_sad[DIAG_DR_I4x4]);
+ pu1_src_temp += src_strd;
+ i4_cost[DIAG_DR_I4x4] =
+ i4_sad[DIAG_DR_I4x4] +
+ ((u4_predictd_mode == DIAG_DR_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ if(u4_valid_intra_modes & 32) /* VERT_R mode valid ????*/
+ {
+ i4_sad[VERT_R_I4x4] = 0;
+
+ pu1_src_temp = pu1_src;
+ u1_pred_vals_vert_r[0] = u1_pred_vals_diag_121[2];
+ memcpy((u1_pred_vals_vert_r + 1), (u1_pred_vals_diag_11 + 4), 3);
+ u1_pred_vals_vert_r[4] = u1_pred_vals_diag_121[1];
+ memcpy((u1_pred_vals_vert_r + 5), (u1_pred_vals_diag_121 + 3), 3);
+
+ pu1_pred_val = u1_pred_vals_diag_11 + 4;
+ USADA8(pu1_src_temp, pu1_pred_val, i4_sad[VERT_R_I4x4]);
+ pu1_pred_val = u1_pred_vals_diag_121 + 3;
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, pu1_pred_val, i4_sad[VERT_R_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (u1_pred_vals_vert_r), i4_sad[VERT_R_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (u1_pred_vals_vert_r + 4), i4_sad[VERT_R_I4x4]);
+
+ i4_cost[VERT_R_I4x4] = i4_sad[VERT_R_I4x4] +
+ ((u4_predictd_mode == VERT_R_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ if(u4_valid_intra_modes & 64) /* HORZ_D mode valid ????*/
+ {
+ i4_sad[HORZ_D_I4x4] = 0;
+
+ pu1_src_temp = pu1_src;
+ u1_pred_vals_horz_d[6] = u1_pred_vals_diag_11[3];
+ memcpy((u1_pred_vals_horz_d + 7), (u1_pred_vals_diag_121 + 3), 3);
+ u1_pred_vals_horz_d[0] = u1_pred_vals_diag_11[0];
+ u1_pred_vals_horz_d[1] = u1_pred_vals_diag_121[0];
+ u1_pred_vals_horz_d[2] = u1_pred_vals_diag_11[1];
+ u1_pred_vals_horz_d[3] = u1_pred_vals_diag_121[1];
+ u1_pred_vals_horz_d[4] = u1_pred_vals_diag_11[2];
+ u1_pred_vals_horz_d[5] = u1_pred_vals_diag_121[2];
+
+ pu1_pred_val = u1_pred_vals_horz_d;
+ USADA8(pu1_src_temp, (pu1_pred_val + 6), i4_sad[HORZ_D_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 4), i4_sad[HORZ_D_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[HORZ_D_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[HORZ_D_I4x4]);
+
+ i4_cost[HORZ_D_I4x4] = i4_sad[HORZ_D_I4x4] +
+ ((u4_predictd_mode == HORZ_D_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ if(u4_valid_intra_modes & 128) /* VERT_L mode valid ????*/
+ {
+ i4_sad[VERT_L_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+ pu1_pred_val = u1_pred_vals_diag_11 + 5;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
+ pu1_src_temp += src_strd;
+ pu1_pred_val = u1_pred_vals_diag_121 + 5;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
+ pu1_src_temp += src_strd;
+ pu1_pred_val = u1_pred_vals_diag_11 + 6;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
+ pu1_src_temp += src_strd;
+ pu1_pred_val = u1_pred_vals_diag_121 + 6;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
+
+ i4_cost[VERT_L_I4x4] = i4_sad[VERT_L_I4x4] +
+ ((u4_predictd_mode == VERT_L_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ if(u4_valid_intra_modes & 256) /* HORZ_U mode valid ????*/
+ {
+ i4_sad[HORZ_U_I4x4] = 0;
+ pu1_src_temp = pu1_src;
+ u1_pred_vals_horz_u[0] = u1_pred_vals_diag_11[2];
+ u1_pred_vals_horz_u[1] = u1_pred_vals_diag_121[1];
+ u1_pred_vals_horz_u[2] = u1_pred_vals_diag_11[1];
+ u1_pred_vals_horz_u[3] = u1_pred_vals_diag_121[0];
+ u1_pred_vals_horz_u[4] = u1_pred_vals_diag_11[0];
+ u1_pred_vals_horz_u[5] = FILT121(pu1_ngbr_pels[0], pu1_ngbr_pels[0], pu1_ngbr_pels[1]);
+
+ memset((u1_pred_vals_horz_u + 6), pu1_ngbr_pels[0], 4);
+
+ pu1_pred_val = u1_pred_vals_horz_u;
+ USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[HORZ_U_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[HORZ_U_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 4), i4_sad[HORZ_U_I4x4]);
+ pu1_src_temp += src_strd;
+ USADA8(pu1_src_temp, (pu1_pred_val + 6), i4_sad[HORZ_U_I4x4]);
+
+ i4_cost[HORZ_U_I4x4] = i4_sad[HORZ_U_I4x4] +
+ ((u4_predictd_mode == HORZ_U_I4x4) ? u4_lambda : 4 * u4_lambda);
+ }
+
+ i4_min_cost =
+ MIN3(MIN3(i4_cost[0], i4_cost[1], i4_cost[2]), MIN3(i4_cost[3], i4_cost[4], i4_cost[5]),
+ MIN3(i4_cost[6], i4_cost[7], i4_cost[8]));
+ }
+ else
+ {
+ /* Only first three modes valid */
+ i4_min_cost = MIN3(i4_cost[0], i4_cost[1], i4_cost[2]);
+ }
+
+ *pu4_sadmin = i4_min_cost;
+
+ if(i4_min_cost == i4_cost[0])
+ {
+ *u4_intra_mode = VERT_I4x4;
+ pu1_pred_val = pu1_ngbr_pels + 5;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ }
+ else if(i4_min_cost == i4_cost[1])
+ {
+ *u4_intra_mode = HORZ_I4x4;
+ memset(pu1_dst, pu1_ngbr_pels[3], 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, pu1_ngbr_pels[2], 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, pu1_ngbr_pels[1], 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, pu1_ngbr_pels[0], 4);
+ }
+ else if(i4_min_cost == i4_cost[2])
+ {
+ *u4_intra_mode = DC_I4x4;
+ memset(pu1_dst, u4_dcval, 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, u4_dcval, 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, u4_dcval, 4);
+ pu1_dst += dst_strd;
+ memset(pu1_dst, u4_dcval, 4);
+ }
+
+ else if(i4_min_cost == i4_cost[3])
+ {
+ *u4_intra_mode = DIAG_DL_I4x4;
+ pu1_pred_val = u1_pred_vals_diag_121 + 5;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 1), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 2), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 3), 4);
+ }
+ else if(i4_min_cost == i4_cost[4])
+ {
+ *u4_intra_mode = DIAG_DR_I4x4;
+ pu1_pred_val = u1_pred_vals_diag_121 + 3;
+
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val - 1), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val - 2), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val - 3), 4);
+ }
+
+ else if(i4_min_cost == i4_cost[5])
+ {
+ *u4_intra_mode = VERT_R_I4x4;
+ pu1_pred_val = u1_pred_vals_diag_11 + 4;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ pu1_pred_val = u1_pred_vals_diag_121 + 3;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (u1_pred_vals_vert_r), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (u1_pred_vals_vert_r + 4), 4);
+ }
+ else if(i4_min_cost == i4_cost[6])
+ {
+ *u4_intra_mode = HORZ_D_I4x4;
+ pu1_pred_val = u1_pred_vals_horz_d;
+ memcpy(pu1_dst, (pu1_pred_val + 6), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 4), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 2), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ }
+ else if(i4_min_cost == i4_cost[7])
+ {
+ *u4_intra_mode = VERT_L_I4x4;
+ pu1_pred_val = u1_pred_vals_diag_11 + 5;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ pu1_pred_val = u1_pred_vals_diag_121 + 5;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ pu1_pred_val = u1_pred_vals_diag_11 + 6;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ pu1_pred_val = u1_pred_vals_diag_121 + 6;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ }
+ else if(i4_min_cost == i4_cost[8])
+ {
+ *u4_intra_mode = HORZ_U_I4x4;
+ pu1_pred_val = u1_pred_vals_horz_u;
+ memcpy(pu1_dst, (pu1_pred_val), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 2), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 4), 4);
+ pu1_dst += dst_strd;
+ memcpy(pu1_dst, (pu1_pred_val + 6), 4);
+ pu1_dst += dst_strd;
+ }
+
+ return;
+}
+
+/**
+******************************************************************************
+*
+* @brief:
+* Evaluate best intr chroma mode (among VERT, HORZ and DC ) and do the
+*prediction.
+*
+* @par Description
+* This function evaluates first three intra chroma modes and compute
+*corresponding sad and return the buffer predicted with best mode.
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] pu1_ngbr_pels
+* UWORD8 pointer to neighbouring pels
+*
+* @param[out] pu1_dst
+* UWORD8 pointer to the destination
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] dst_strd
+* integer destination stride
+*
+* @param[in] u4_n_avblty
+* availability of neighbouring pixels
+*
+* @param[in] u4_intra_mode
+* Pointer to the variable in which best mode is returned
+*
+* @param[in] pu4_sadmin
+* Pointer to the variable in which minimum sad is returned
+*
+* @param[in] u4_valid_intra_modes
+* Says what all modes are valid
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra_chroma_modes(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels, UWORD8 *pu1_dst,
+ UWORD32 src_strd, UWORD32 dst_strd, WORD32 u4_n_avblty,
+ UWORD32 *u4_intra_mode, WORD32 *pu4_sadmin,
+ UWORD32 u4_valid_intra_modes)
+{
+ UWORD8 *pu1_neighbour;
+ UWORD8 *pu1_src_temp = pu1_src;
+ UWORD8 left = 0, top = 0;
+ WORD32 u4_dcval_u_l[2] = {0, 0}, /*sum left neighbours for 'U' ,two separate sets - sum of
+ first four from top,and sum of four values from bottom */
+ u4_dcval_u_t[2] = {0, 0}; /*sum top neighbours for 'U'*/
+
+ WORD32 u4_dcval_v_l[2] = {0, 0}, /*sum left neighbours for 'V'*/
+ u4_dcval_v_t[2] = {0, 0}; /*sum top neighbours for 'V'*/
+
+ WORD32 i, j, row, col, i4_sad_vert = INT_MAX, i4_sad_horz = INT_MAX, i4_sad_dc = INT_MAX,
+ i4_min_sad = INT_MAX;
+ UWORD8 val_u, val_v;
+
+ WORD32 u4_dc_val[2][2][2]; /* -----------
+ | | | Chroma can have four
+ | 00 | 01 | separate dc value...
+ ----------- u4_dc_val corresponds to this dc
+ values | | | with u4_dc_val[2][2][U] and
+ u4_dc_val[2][2][V] | 10 | 11 |
+ ----------- */
+ left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
+ top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
+
+ /*Evaluating HORZ*/
+ if(left) /* Ifleft available*/
+ {
+ i4_sad_horz = 0;
+
+ for(i = 0; i < 8; i++)
+ {
+ val_v = pu1_ngbr_pels[15 - 2 * i];
+ val_u = pu1_ngbr_pels[15 - 2 * i - 1];
+ row = i / 4;
+ u4_dcval_u_l[row] += val_u;
+ u4_dcval_v_l[row] += val_v;
+ for(j = 0; j < 8; j++)
+ {
+ i4_sad_horz += ABS(val_u - pu1_src_temp[2 * j]); /* Finding SAD for HORZ mode*/
+ i4_sad_horz += ABS(val_v - pu1_src_temp[2 * j + 1]);
+ }
+
+ pu1_src_temp += src_strd;
+ }
+ u4_dcval_u_l[0] += 2;
+ u4_dcval_u_l[1] += 2;
+ u4_dcval_v_l[0] += 2;
+ u4_dcval_v_l[1] += 2;
+ }
+
+ /*Evaluating VERT**/
+ pu1_src_temp = pu1_src;
+ if(top) /* top available*/
+ {
+ i4_sad_vert = 0;
+
+ for(i = 0; i < 8; i++)
+ {
+ col = i / 4;
+
+ val_u = pu1_ngbr_pels[18 + i * 2];
+ val_v = pu1_ngbr_pels[18 + i * 2 + 1];
+ u4_dcval_u_t[col] += val_u;
+ u4_dcval_v_t[col] += val_v;
+
+ for(j = 0; j < 16; j++)
+ {
+ i4_sad_vert +=
+ ABS(pu1_ngbr_pels[18 + j] - pu1_src_temp[j]); /* Finding SAD for VERT mode*/
+ }
+ pu1_src_temp += src_strd;
+ }
+ u4_dcval_u_t[0] += 2;
+ u4_dcval_u_t[1] += 2;
+ u4_dcval_v_t[0] += 2;
+ u4_dcval_v_t[1] += 2;
+ }
+
+ /* computing DC value*/
+ /* Equation 8-128 in spec*/
+ u4_dc_val[0][0][0] = (u4_dcval_u_l[0] + u4_dcval_u_t[0]) >> (1 + left + top);
+ u4_dc_val[0][0][1] = (u4_dcval_v_l[0] + u4_dcval_v_t[0]) >> (1 + left + top);
+ u4_dc_val[1][1][0] = (u4_dcval_u_l[1] + u4_dcval_u_t[1]) >> (1 + left + top);
+ u4_dc_val[1][1][1] = (u4_dcval_v_l[1] + u4_dcval_v_t[1]) >> (1 + left + top);
+
+ if(top)
+ {
+ /* Equation 8-132 in spec*/
+ u4_dc_val[0][1][0] = (u4_dcval_u_t[1]) >> (1 + top);
+ u4_dc_val[0][1][1] = (u4_dcval_v_t[1]) >> (1 + top);
+ }
+ else
+ {
+ u4_dc_val[0][1][0] = (u4_dcval_u_l[0]) >> (1 + left);
+ u4_dc_val[0][1][1] = (u4_dcval_v_l[0]) >> (1 + left);
+ }
+
+ if(left)
+ {
+ u4_dc_val[1][0][0] = (u4_dcval_u_l[1]) >> (1 + left);
+ u4_dc_val[1][0][1] = (u4_dcval_v_l[1]) >> (1 + left);
+ }
+ else
+ {
+ u4_dc_val[1][0][0] = (u4_dcval_u_t[0]) >> (1 + top);
+ u4_dc_val[1][0][1] = (u4_dcval_v_t[0]) >> (1 + top);
+ }
+
+ if(!(left || top))
+ {
+ /*none available*/
+ u4_dc_val[0][0][0] = u4_dc_val[0][0][1] = u4_dc_val[0][1][0] = u4_dc_val[0][1][1] =
+ u4_dc_val[1][0][0] = u4_dc_val[1][0][1] = u4_dc_val[1][1][0] = u4_dc_val[1][1][1] = 128;
+ }
+
+ /* Evaluating DC */
+ pu1_src_temp = pu1_src;
+ i4_sad_dc = 0;
+ for(i = 0; i < 8; i++)
+ {
+ for(j = 0; j < 8; j++)
+ {
+ col = j / 4;
+ row = i / 4;
+ val_u = u4_dc_val[row][col][0];
+ val_v = u4_dc_val[row][col][1];
+
+ i4_sad_dc += ABS(val_u - pu1_src_temp[2 * j]); /* Finding SAD for DC mode*/
+ i4_sad_dc += ABS(val_v - pu1_src_temp[2 * j + 1]);
+ }
+ pu1_src_temp += src_strd;
+ }
+
+ if((u4_valid_intra_modes & 01) == 0) /* If DC is disabled*/
+ i4_sad_dc = INT_MAX;
+ if((u4_valid_intra_modes & 02) == 0) /* If HORZ is disabled*/
+ i4_sad_horz = INT_MAX;
+ if((u4_valid_intra_modes & 04) == 0) /* If VERT is disabled*/
+ i4_sad_vert = INT_MAX;
+
+ i4_min_sad = MIN3(i4_sad_horz, i4_sad_dc, i4_sad_vert);
+
+ /* Finding Minimum sad and doing corresponding prediction*/
+ if(i4_min_sad < *pu4_sadmin)
+ {
+ *pu4_sadmin = i4_min_sad;
+
+ if(i4_min_sad == i4_sad_dc)
+ {
+ *u4_intra_mode = DC_CH_I8x8;
+ for(i = 0; i < 8; i++)
+ {
+ for(j = 0; j < 8; j++)
+ {
+ col = j / 4;
+ row = i / 4;
+
+ pu1_dst[2 * j] = u4_dc_val[row][col][0];
+ pu1_dst[2 * j + 1] = u4_dc_val[row][col][1];
+ }
+ pu1_dst += dst_strd;
+ }
+ }
+ else if(i4_min_sad == i4_sad_horz)
+ {
+ *u4_intra_mode = HORZ_CH_I8x8;
+ for(j = 0; j < 8; j++)
+ {
+ val_v = pu1_ngbr_pels[15 - 2 * j];
+ val_u = pu1_ngbr_pels[15 - 2 * j - 1];
+
+ for(i = 0; i < 8; i++)
+ {
+ pu1_dst[2 * i] = val_u;
+ pu1_dst[2 * i + 1] = val_v;
+ }
+ pu1_dst += dst_strd;
+ }
+ }
+ else
+ {
+ *u4_intra_mode = VERT_CH_I8x8;
+ pu1_neighbour = pu1_ngbr_pels + 18;
+ for(j = 0; j < 8; j++)
+ {
+ memcpy(pu1_dst, pu1_neighbour, MB_SIZE);
+ pu1_dst += dst_strd;
+ }
+ }
+ }
+
+ return;
+}
diff --git a/encoder/svc/isvce_intra_modes_eval.h b/encoder/svc/isvce_intra_modes_eval.h
new file mode 100644
index 0000000..00ba756
--- /dev/null
+++ b/encoder/svc/isvce_intra_modes_eval.h
@@ -0,0 +1,361 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_intra_modes_eval.h
+*
+* @brief
+* This file contains declarations of routines that perform rate distortion
+* analysis on a macroblock if coded as intra.
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_INTRA_MODES_EVAL_H_
+#define _ISVCE_INTRA_MODES_EVAL_H_
+
+/**
+******************************************************************************
+*
+* @brief
+* derivation process for subblock/partition availability
+*
+* @par Description
+* Calculates the availability of the left, top, topright and topleft subblock
+* or partitions.
+*
+* @param[in] ps_proc_ctxt
+* pointer to macroblock context (handle)
+*
+* @param[in] i1_pel_pos_x
+* column position of the pel wrt the current block
+*
+* @param[in] i1_pel_pos_y
+* row position of the pel in wrt current block
+*
+* @remarks Assumptions: before calling this function it is assumed that
+* the neighbor availability of the current macroblock is already derived.
+* Based on table 6-3 of H264 specification
+*
+* @return availability status (yes or no)
+*
+******************************************************************************
+*/
+UWORD8 isvce_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t *s_ngbr_avbl, WORD8 i1_pel_pos_x,
+ WORD8 i1_pel_pos_y);
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 16x16 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible intra 16x16 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to process context (handle)
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to header
+* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
+* and residual bits fall in to texture bits the number of bits taken to encoding
+* mbtype is considered as rate, we compute cost. Further we will approximate
+* the distortion as the deviation b/w input and the predicted block as opposed
+* to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for intra 16x16 macroblock,
+* the SAD and cost are one and the same.
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc_ctxt);
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 8x8 mode (rate distortion opt on)
+*
+* @par Description
+* This function evaluates all the possible intra 8x8 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to header
+* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
+* and residual bits fall in to texture bits the number of bits taken to encoding
+* mbtype is considered as rate, we compute cost. Further we will approximate
+* the distortion as the deviation b/w input and the predicted block as opposed
+* to input and reconstructed block.
+*
+* NOTE: TODO: This function needs to be tested
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc_ctxt);
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 4x4 mode (rate distortion opt on)
+*
+* @par Description
+* This function evaluates all the possible intra 4x4 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to header
+* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
+* and residual bits fall in to texture bits the number of bits taken to encoding
+* mbtype is considered as rate, we compute cost. Further we will approximate
+* the distortion as the deviation b/w input and the predicted block as opposed
+* to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
+* 24*lambda is added to the SAD before comparison with the best SAD for
+* inter prediction. This is an empirical value to prevent using too many intra
+* blocks.
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(isvce_process_ctxt_t *ps_proc_ctxt);
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best intra 4x4 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible intra 4x4 modes and finds the mode
+* that best represents the macro-block (least distortion) and occupies fewer
+* bits in the bit-stream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc ctxt
+*
+* @remarks
+* Ideally the cost of encoding a macroblock is calculated as
+* (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
+* input block and the reconstructed block and rate is the number of bits taken
+* to place the macroblock in the bit-stream. In this routine the rate does not
+* exactly point to the total number of bits it takes, rather it points to header
+* bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
+* and residual bits fall in to texture bits the number of bits taken to encoding
+* mbtype is considered as rate, we compute cost. Further we will approximate
+* the distortion as the deviation b/w input and the predicted block as opposed
+* to input and reconstructed block.
+*
+* NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
+* 24*lambda is added to the SAD before comparison with the best SAD for
+* inter prediction. This is an empirical value to prevent using too many intra
+* blocks.
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(isvce_process_ctxt_t *ps_proc_ctxt);
+
+/**
+******************************************************************************
+*
+* @brief
+* evaluate best chroma intra 8x8 mode (rate distortion opt off)
+*
+* @par Description
+* This function evaluates all the possible chroma intra 8x8 modes and finds
+* the mode that best represents the macroblock (least distortion) and occupies
+* fewer bits in the bitstream.
+*
+* @param[in] ps_proc_ctxt
+* pointer to macroblock context (handle)
+*
+* @remarks
+* For chroma best intra pred mode is calculated based only on SAD
+*
+* @returns none
+*
+******************************************************************************
+*/
+void isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(
+ isvce_process_ctxt_t *ps_proc_ctxt);
+
+/**
+******************************************************************************
+*
+* @brief
+* Evaluate best intra 16x16 mode (among VERT, HORZ and DC) and do the
+* prediction.
+*
+* @par Description
+* This function evaluates first three 16x16 modes and compute corresponding sad
+* and return the buffer predicted with best mode.
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] pu1_ngbr_pels_i16
+* UWORD8 pointer to neighbouring pels
+*
+* @param[out] pu1_dst
+* UWORD8 pointer to the destination
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] dst_strd
+* integer destination stride
+*
+* @param[in] u4_n_avblty
+* availability of neighbouring pixels
+*
+* @param[in] u4_intra_mode
+* Pointer to the variable in which best mode is returned
+*
+* @param[in] pu4_sadmin
+* Pointer to the variable in which minimum sad is returned
+*
+* @param[in] u4_valid_intra_modes
+* Says what all modes are valid
+*
+* @returns none
+*
+******************************************************************************
+*/
+typedef void isvce_evaluate_intra_modes_ft(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels_i16,
+ UWORD8 *pu1_dst, UWORD32 src_strd, UWORD32 dst_strd,
+ WORD32 u4_n_avblty, UWORD32 *u4_intra_mode,
+ WORD32 *pu4_sadmin, UWORD32 u4_valid_intra_modes);
+
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra16x16_modes;
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra_chroma_modes;
+
+/* assembly */
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra16x16_modes_a9q;
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra_chroma_modes_a9q;
+
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra16x16_modes_av8;
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra_chroma_modes_av8;
+
+/* x86 intrinsics */
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra16x16_modes_ssse3;
+isvce_evaluate_intra_modes_ft isvce_evaluate_intra_chroma_modes_ssse3;
+
+/**
+******************************************************************************
+*
+* @brief
+* Evaluate best intra 4x4 mode and perform prediction.
+*
+* @par Description
+* This function evaluates 4x4 modes and compute corresponding sad
+* and return the buffer predicted with best mode.
+*
+* @param[in] pu1_src
+* UWORD8 pointer to the source
+*
+* @param[in] pu1_ngbr_pels
+* UWORD8 pointer to neighbouring pels
+*
+* @param[out] pu1_dst
+* UWORD8 pointer to the destination
+*
+* @param[in] src_strd
+* integer source stride
+*
+* @param[in] dst_strd
+* integer destination stride
+*
+* @param[in] u4_n_avblty
+* availability of neighbouring pixels
+*
+* @param[in] u4_intra_mode
+* Pointer to the variable in which best mode is returned
+*
+* @param[in] pu4_sadmin
+* Pointer to the variable in which minimum cost is returned
+*
+* @param[in] u4_valid_intra_modes
+* Says what all modes are valid
+*
+* @param[in] u4_lambda
+* Lamda value for computing cost from SAD
+*
+* @param[in] u4_predictd_mode
+* Predicted mode for cost computation
+*
+* @returns none
+*
+******************************************************************************
+*/
+typedef void isvce_evaluate_intra_4x4_modes_ft(UWORD8 *pu1_src, UWORD8 *pu1_ngbr_pels,
+ UWORD8 *pu1_dst, UWORD32 src_strd, UWORD32 dst_strd,
+ WORD32 u4_n_avblty, UWORD32 *u4_intra_mode,
+ WORD32 *pu4_sadmin, UWORD32 u4_valid_intra_modes,
+ UWORD32 u4_lambda, UWORD32 u4_predictd_mode);
+
+isvce_evaluate_intra_4x4_modes_ft isvce_evaluate_intra_4x4_modes;
+
+/* x86 intrinsics */
+isvce_evaluate_intra_4x4_modes_ft isvce_evaluate_intra_4x4_modes_ssse3;
+
+/* assembly */
+isvce_evaluate_intra_4x4_modes_ft isvce_evaluate_intra_4x4_modes_a9q;
+isvce_evaluate_intra_4x4_modes_ft isvce_evaluate_intra_4x4_modes_av8;
+
+#endif
diff --git a/encoder/svc/isvce_mc.c b/encoder/svc/isvce_mc.c
new file mode 100644
index 0000000..0710545
--- /dev/null
+++ b/encoder/svc/isvce_mc.c
@@ -0,0 +1,480 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_mc.c
+ *
+ * @brief
+ * Contains definition of functions for motion compensation
+ *
+ * @author
+ * ittiam
+ *
+ * @par List of Functions:
+ * - isvce_motion_comp_luma()
+ * - isvce_motion_comp_chroma()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "isvc_structs.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_cabac_tables.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_mc.h"
+#include "ih264e_half_pel.h"
+#include "isvce_ibl_eval.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+ ******************************************************************************
+ *
+ * @brief
+ * performs motion compensation for a luma mb for the given mv.
+ *
+ * @par Description
+ * This routine performs motion compensation of an inter mb. When the inter
+ * mb mode is P16x16, there is no need to copy 16x16 unit from reference buffer
+ * to pred buffer. In this case the function returns pointer and stride of the
+ * ref. buffer and this info is used in place of pred buffer else where.
+ * In other cases, the pred buffer is populated via copy / filtering + copy
+ * (q pel cases) and returned.
+ *
+ * @param[in] ps_proc
+ * pointer to current proc ctxt
+ *
+ * @return none
+ *
+ * @remarks Assumes half pel buffers for the entire frame are populated.
+ *
+ ******************************************************************************
+ */
+void isvce_motion_comp_luma(isvce_process_ctxt_t *ps_proc, buffer_container_t *ps_pred)
+{
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ /* me ctxt */
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ /* Pointer to the structure having motion vectors, size and position of curr
+ * partitions */
+ isvce_enc_pu_t *ps_curr_pu;
+
+ /* pointers to full pel, half pel x, half pel y, half pel xy reference buffer
+ */
+ UWORD8 *pu1_ref[4];
+
+ /* pred buffer ptr */
+ UWORD8 *pu1_pred;
+
+ /* strides of full pel, half pel x, half pel y, half pel xy reference buffer
+ */
+ WORD32 i4_ref_strd[4];
+
+ /* pred buffer stride */
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+
+ /* full pel motion vectors */
+ WORD32 u4_mv_x_full, u4_mv_y_full;
+
+ /* half pel motion vectors */
+ WORD32 u4_mv_x_hpel, u4_mv_y_hpel;
+
+ /* quarter pel motion vectors */
+ WORD32 u4_mv_x_qpel, u4_mv_y_qpel;
+
+ /* width & height of the partition */
+ UWORD32 wd, ht;
+
+ /* partition idx */
+ UWORD32 u4_num_prtn;
+
+ /* half / qpel coefficient */
+ UWORD32 u4_subpel_factor;
+
+ /* BIPRED Flag */
+ WORD32 i4_bipred_flag;
+
+ /* temp var */
+ UWORD32 u4_lkup_idx1;
+
+ if((ps_proc->ps_mb_info->u2_mb_type == BASE_MODE) && ps_proc->ps_mb_info->u1_is_intra)
+ {
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt;
+
+ ps_pred->pv_data =
+ (UWORD8 *) (ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[Y]
+ .pv_data);
+ ps_pred->i4_data_stride =
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[Y].i4_data_stride;
+
+ return;
+ }
+
+ /* Init */
+ i4_ref_strd[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].i4_data_stride;
+
+ i4_ref_strd[1] = i4_ref_strd[2] = i4_ref_strd[3] = ps_me_ctxt->u4_subpel_buf_strd;
+
+ for(u4_num_prtn = 0; u4_num_prtn < ps_proc->u4_num_sub_partitions; u4_num_prtn++)
+ {
+ mv_t *ps_curr_mv;
+
+ /* update ptr to curr partition */
+ ps_curr_pu = ps_proc->ps_mb_info->as_pu + u4_num_prtn;
+
+ /* Set no no bipred */
+ i4_bipred_flag = 0;
+
+ switch(ps_curr_pu->u1_pred_mode)
+ {
+ case PRED_L0:
+ ps_curr_mv = &ps_curr_pu->as_me_info[0].s_mv;
+ pu1_ref[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data;
+ break;
+
+ case PRED_L1:
+ ps_curr_mv = &ps_curr_pu->as_me_info[1].s_mv;
+ pu1_ref[0] = ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data;
+ break;
+
+ case PRED_BI:
+ /*
+ * In case of PRED_BI, we only need to ensure that
+ * the reference buffer that gets selected is
+ * ps_proc->pu1_best_subpel_buf
+ */
+
+ /* Dummy */
+ ps_curr_mv = &ps_curr_pu->as_me_info[0].s_mv;
+ pu1_ref[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data;
+
+ i4_bipred_flag = 1;
+ break;
+
+ default:
+ ps_curr_mv = &ps_curr_pu->as_me_info[0].s_mv;
+ pu1_ref[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data;
+ break;
+ }
+
+ /* get full pel mv's (full pel units) */
+ u4_mv_x_full = ps_curr_mv->i2_mvx >> 2;
+ u4_mv_y_full = ps_curr_mv->i2_mvy >> 2;
+
+ /* get half pel mv's */
+ u4_mv_x_hpel = (ps_curr_mv->i2_mvx & 0x2) >> 1;
+ u4_mv_y_hpel = (ps_curr_mv->i2_mvy & 0x2) >> 1;
+
+ /* get quarter pel mv's */
+ u4_mv_x_qpel = (ps_curr_mv->i2_mvx & 0x1);
+ u4_mv_y_qpel = (ps_curr_mv->i2_mvy & 0x1);
+
+ /* width and height of partition */
+ wd = (ps_curr_pu->u1_wd_in_4x4_m1 + 1) << 2;
+ ht = (ps_curr_pu->u1_ht_in_4x4_m1 + 1) << 2;
+
+ /* decision ? qpel/hpel, fpel */
+ u4_subpel_factor =
+ (u4_mv_y_hpel << 3) + (u4_mv_x_hpel << 2) + (u4_mv_y_qpel << 1) + (u4_mv_x_qpel);
+
+ /* Move ref to position given by MV */
+ pu1_ref[0] += ((u4_mv_y_full * i4_ref_strd[0]) + u4_mv_x_full);
+
+ /* Sub pel ptrs/ Biperd pointers init */
+ pu1_ref[1] = ps_proc->pu1_best_subpel_buf;
+ i4_ref_strd[1] = ps_proc->u4_bst_spel_buf_strd;
+
+ /* update pred buff ptr */
+ pu1_pred = ps_proc->pu1_pred_mb + 4 * ps_curr_pu->u1_pos_y_in_4x4 * i4_pred_strd +
+ 4 * ps_curr_pu->u1_pos_x_in_4x4;
+
+ /* u4_lkup_idx1 will be non zero for half pel and bipred */
+ u4_lkup_idx1 = ((u4_subpel_factor >> 2) != 0) || i4_bipred_flag;
+
+ {
+ /********************************************************************/
+ /* if the block is P16x16 MB and mv are not quarter pel motion */
+ /* vectors, there is no need to copy 16x16 unit from reference frame*/
+ /* to pred buffer. We might as well send the reference frame buffer */
+ /* pointer as pred buffer (ofc with updated stride) to fwd transform*/
+ /* and inverse transform unit. */
+ /********************************************************************/
+ if(ps_proc->u4_num_sub_partitions == 1)
+ {
+ ps_pred->pv_data = pu1_ref[u4_lkup_idx1];
+ ps_pred->i4_data_stride = i4_ref_strd[u4_lkup_idx1];
+ }
+ /*
+ * Copying half pel or full pel to prediction buffer
+ * Currently ps_proc->u4_num_sub_partitions will always be 1 as we only
+ * support 16x16 in P mbs
+ */
+ else
+ {
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(pu1_ref[u4_lkup_idx1], pu1_pred,
+ i4_ref_strd[u4_lkup_idx1], i4_pred_strd,
+ ht, wd, NULL, 0);
+ }
+ }
+ }
+}
+
+/**
+ ******************************************************************************
+ *
+ * @brief
+ * performs motion compensation for chroma mb
+ *
+ * @par Description
+ * Copies a MB of data from the reference buffer (Full pel, half pel or q pel)
+ * according to the motion vectors given
+ *
+ * @param[in] ps_proc
+ * pointer to current proc ctxt
+ *
+ * @return none
+ *
+ * @remarks Assumes half pel and quarter pel buffers for the entire frame are
+ * populated.
+ ******************************************************************************
+ */
+void isvce_motion_comp_chroma(isvce_process_ctxt_t *ps_proc, buffer_container_t *ps_pred)
+{
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ /* Pointer to the structure having motion vectors, size and position of curr
+ * partitions */
+ isvce_enc_pu_t *ps_curr_pu;
+
+ /* pointers to full pel, half pel x, half pel y, half pel xy reference buffer
+ */
+ UWORD8 *pu1_ref;
+
+ /* pred buffer ptr */
+ UWORD8 *pu1_pred;
+
+ /* strides of full pel reference buffer */
+ WORD32 i4_ref_strd;
+
+ /* pred buffer stride */
+ WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
+
+ /* full pel motion vectors */
+ WORD32 u4_mv_x_full, u4_mv_y_full;
+
+ /* half pel motion vectors */
+ WORD32 u4_mv_x_hpel, u4_mv_y_hpel;
+
+ /* quarter pel motion vectors */
+ WORD32 u4_mv_x_qpel, u4_mv_y_qpel;
+
+ /* width & height of the partition */
+ UWORD32 wd, ht;
+
+ /* partition idx */
+ UWORD32 u4_num_prtn;
+
+ WORD32 u4_mv_x;
+ WORD32 u4_mv_y;
+ UWORD8 u1_dx, u1_dy;
+
+ ASSERT(ps_proc->u4_num_sub_partitions <= ENC_MAX_PU_IN_MB);
+
+ if((ps_proc->ps_mb_info->u2_mb_type == BASE_MODE) && ps_proc->ps_mb_info->u1_is_intra)
+ {
+ svc_intra_pred_ctxt_t *ps_intra_pred_ctxt = ps_proc->ps_intra_pred_ctxt;
+
+ ps_pred->pv_data =
+ (UWORD8 *) (ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[UV]
+ .pv_data);
+ ps_pred->i4_data_stride =
+ ps_intra_pred_ctxt->s_intra_pred_outputs.s_pred_buf.as_component_bufs[UV]
+ .i4_data_stride;
+
+ return;
+ }
+ else
+ {
+ ps_pred->pv_data = ps_proc->pu1_pred_mb;
+ ps_pred->i4_data_stride = ps_proc->i4_pred_strd;
+ }
+
+ for(u4_num_prtn = 0; u4_num_prtn < ps_proc->u4_num_sub_partitions; u4_num_prtn++)
+ {
+ mv_t *ps_curr_mv;
+
+ ps_curr_pu = ps_proc->ps_mb_info->as_pu + u4_num_prtn;
+
+ if(ps_curr_pu->u1_pred_mode != BI)
+ {
+ ps_curr_mv = &ps_curr_pu->as_me_info[ps_curr_pu->u1_pred_mode].s_mv;
+ pu1_ref =
+ ps_proc->as_ref_buf_props[ps_curr_pu->u1_pred_mode].as_component_bufs[1].pv_data;
+ i4_ref_strd = ps_proc->as_ref_buf_props[ps_curr_pu->u1_pred_mode]
+ .as_component_bufs[1]
+ .i4_data_stride;
+
+ u4_mv_x = ps_curr_mv->i2_mvx >> 3;
+ u4_mv_y = ps_curr_mv->i2_mvy >> 3;
+
+ /* corresponds to full pel motion vector in luma, but in chroma
+ * corresponds to pel formed wiith dx, dy =4 */
+ u4_mv_x_full = (ps_curr_mv->i2_mvx & 0x4) >> 2;
+ u4_mv_y_full = (ps_curr_mv->i2_mvy & 0x4) >> 2;
+
+ /* get half pel mv's */
+ u4_mv_x_hpel = (ps_curr_mv->i2_mvx & 0x2) >> 1;
+ u4_mv_y_hpel = (ps_curr_mv->i2_mvy & 0x2) >> 1;
+
+ /* get quarter pel mv's */
+ u4_mv_x_qpel = (ps_curr_mv->i2_mvx & 0x1);
+ u4_mv_y_qpel = (ps_curr_mv->i2_mvy & 0x1);
+
+ /* width and height of sub macro block */
+ wd = (ps_curr_pu->u1_wd_in_4x4_m1 + 1) << 1;
+ ht = (ps_curr_pu->u1_ht_in_4x4_m1 + 1) << 1;
+
+ /* move the pointers so that they point to the motion compensated
+ * locations */
+ pu1_ref += ((u4_mv_y * i4_ref_strd) + (u4_mv_x << 1));
+
+ pu1_pred = ps_proc->pu1_pred_mb + 4 * ps_curr_pu->u1_pos_y_in_4x4 * i4_pred_strd +
+ 2 * ps_curr_pu->u1_pos_x_in_4x4;
+
+ u1_dx = (u4_mv_x_full << 2) + (u4_mv_x_hpel << 1) + (u4_mv_x_qpel);
+ u1_dy = (u4_mv_y_full << 2) + (u4_mv_y_hpel << 1) + (u4_mv_y_qpel);
+
+ /* cases where u1_dx = 0 or u1_dy = 0 are dealt separately in neon with
+ * separate functions for better performance
+ *
+ * isvc_inter_pred_chroma_dx_zero_a9q
+ * and
+ * isvc_inter_pred_chroma_dy_zero_a9q
+ */
+
+ ps_inter_pred_fxns->pf_inter_pred_chroma(pu1_ref, pu1_pred, i4_ref_strd, i4_pred_strd,
+ u1_dx, u1_dy, ht, wd);
+ }
+ else
+ {
+ /*
+ * We need to interpolate the L0 and L1 ref pics with the chorma MV
+ * then use them to average for bilinrar interpred
+ */
+ WORD32 i4_predmode;
+ UWORD8 *pu1_ref_buf[2];
+
+ /* Temporary buffers to store the interpolated value from L0 and L1 */
+ pu1_ref_buf[L0] = ps_proc->apu1_subpel_buffs[0];
+ pu1_ref_buf[L1] = ps_proc->apu1_subpel_buffs[1];
+
+ for(i4_predmode = 0; i4_predmode < BI; i4_predmode++)
+ {
+ ps_curr_mv = &ps_curr_pu->as_me_info[i4_predmode].s_mv;
+ pu1_ref = ps_proc->as_ref_buf_props[i4_predmode].as_component_bufs[1].pv_data;
+ i4_ref_strd =
+ ps_proc->as_ref_buf_props[i4_predmode].as_component_bufs[1].i4_data_stride;
+
+ u4_mv_x = ps_curr_mv->i2_mvx >> 3;
+ u4_mv_y = ps_curr_mv->i2_mvy >> 3;
+
+ /*
+ * corresponds to full pel motion vector in luma, but in chroma
+ * corresponds to pel formed wiith dx, dy =4
+ */
+ u4_mv_x_full = (ps_curr_mv->i2_mvx & 0x4) >> 2;
+ u4_mv_y_full = (ps_curr_mv->i2_mvy & 0x4) >> 2;
+
+ /* get half pel mv's */
+ u4_mv_x_hpel = (ps_curr_mv->i2_mvx & 0x2) >> 1;
+ u4_mv_y_hpel = (ps_curr_mv->i2_mvy & 0x2) >> 1;
+
+ /* get quarter pel mv's */
+ u4_mv_x_qpel = (ps_curr_mv->i2_mvx & 0x1);
+ u4_mv_y_qpel = (ps_curr_mv->i2_mvy & 0x1);
+
+ /* width and height of sub macro block */
+ wd = (ps_curr_pu->u1_wd_in_4x4_m1 + 1) << 1;
+ ht = (ps_curr_pu->u1_ht_in_4x4_m1 + 1) << 1;
+
+ /* move the pointers so that they point to the motion compensated
+ * locations */
+ pu1_ref += ((u4_mv_y * i4_ref_strd) + (u4_mv_x << 1));
+
+ pu1_pred = ps_proc->pu1_pred_mb + 4 * ps_curr_pu->u1_pos_y_in_4x4 * i4_pred_strd +
+ 2 * ps_curr_pu->u1_pos_x_in_4x4;
+
+ u1_dx = (u4_mv_x_full << 2) + (u4_mv_x_hpel << 1) + (u4_mv_x_qpel);
+ u1_dy = (u4_mv_y_full << 2) + (u4_mv_y_hpel << 1) + (u4_mv_y_qpel);
+
+ ps_inter_pred_fxns->pf_inter_pred_chroma(
+ pu1_ref, pu1_ref_buf[i4_predmode], i4_ref_strd, MB_SIZE, u1_dx, u1_dy, ht, wd);
+ }
+
+ ps_inter_pred_fxns->pf_inter_pred_luma_bilinear(pu1_ref_buf[L0], pu1_ref_buf[L1],
+ pu1_pred, MB_SIZE, MB_SIZE,
+ i4_pred_strd, MB_SIZE >> 1, MB_SIZE);
+ }
+ }
+}
diff --git a/encoder/svc/isvce_mc.h b/encoder/svc/isvce_mc.h
new file mode 100644
index 0000000..fd2fd71
--- /dev/null
+++ b/encoder/svc/isvce_mc.h
@@ -0,0 +1,87 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_mc.h
+*
+* @brief
+* This file contains declarations of routines that perform motion compensation
+* of luma and chroma macroblocks.
+*
+* @author
+* ittiam
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+#ifndef _ISVCE_MC_H_
+#define _ISVCE_MC_H_
+
+/**
+******************************************************************************
+*
+* @brief
+* performs motion compensation for a luma mb for the given mv.
+*
+* @par Description
+* This routine performs motion compensation of an inter mb. When the inter
+* mb mode is P16x16, there is no need to copy 16x16 unit from reference buffer
+* to pred buffer. In this case the function returns pointer and stride of the
+* ref. buffer and this info is used in place of pred buffer else where.
+* In other cases, the pred buffer is populated via copy / filtering + copy
+* (q pel cases) and returned.
+*
+* @param[in] ps_proc
+* pointer to current proc ctxt
+*
+* @return none
+*
+* @remarks Assumes half pel buffers for the entire frame are populated.
+*
+******************************************************************************
+*/
+extern void isvce_motion_comp_luma(isvce_process_ctxt_t *ps_proc, buffer_container_t *ps_pred);
+
+/**
+******************************************************************************
+*
+* @brief
+* performs motion compensation for chroma mb
+*
+* @par Description
+* Copies a MB of data from the reference buffer (Full pel, half pel or q pel)
+* according to the motion vectors given
+*
+* @param[in] ps_proc
+* pointer to current proc ctxt
+*
+* @return none
+*
+* @remarks Assumes half pel and quarter pel buffers for the entire frame are
+* populated.
+******************************************************************************
+*/
+extern void isvce_motion_comp_chroma(isvce_process_ctxt_t *ps_proc, buffer_container_t *ps_pred);
+
+#endif
diff --git a/encoder/svc/isvce_me.c b/encoder/svc/isvce_me.c
new file mode 100644
index 0000000..3e7fec7
--- /dev/null
+++ b/encoder/svc/isvce_me.c
@@ -0,0 +1,2924 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_me.c
+ *
+ * @brief
+ * Contains definition of functions for motion estimation
+ *
+ * @author
+ * ittiam
+ *
+ * @par List of Functions:
+ * - isvce_init_mv_bits()
+ * - isvce_skip_analysis_chroma()
+ * - isvce_skip_analysis_luma()
+ * - isvce_analyse_skip()
+ * - isvce_get_search_candidates()
+ * - isvce_find_skip_motion_vector()
+ * - isvce_get_mv_predictor()
+ * - isvce_mv_pred()
+ * - isvce_mv_pred_me()
+ * - isvce_init_me()
+ * - isvce_compute_me()
+ * - isvce_compute_me_nmb()
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ithread.h"
+#include "ih264_platform_macros.h"
+#include "isvc_defs.h"
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+#include "ime_structs.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_globals.h"
+#include "isvce_me.h"
+#include "ime.h"
+#include "ih264_debug.h"
+#include "ih264e_intra_modes_eval.h"
+#include "isvce_core_coding.h"
+#include "isvce_mc.h"
+#include "ih264e_debug.h"
+#include "ih264e_half_pel.h"
+#include "ime_statistics.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_defs.h"
+#include "isvce_structs.h"
+#include "isvce_ilp_mv_utils.h"
+#include "isvce_utils.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief Diamond Search
+*
+* @par Description:
+* This function computes the sad at vertices of several layers of diamond grid
+* at a time. The number of layers of diamond grid that would be evaluated is
+* configurable.The function computes the sad at vertices of a diamond grid. If
+* the sad at the center of the diamond grid is lesser than the sad at any other
+* point of the diamond grid, the function marks the candidate Mb partition as
+* mv.
+*
+* @param[in] ps_mb_part
+* pointer to current mb partition ctxt with respect to ME
+*
+* @param[in] ps_me_ctxt
+* pointer to me context
+*
+* @param[in] u4_lambda_motion
+* lambda motion
+*
+* @param[in] u4_enable_fast_sad
+* enable/disable fast sad computation
+*
+* @returns mv pair & corresponding distortion and cost
+*
+* @remarks Diamond Srch, radius is 1
+*
+*******************************************************************************
+*/
+static void isvce_diamond_search_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
+{
+ /* MB partition info */
+ mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
+
+ /* lagrange parameter */
+ UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
+
+ /* srch range*/
+ WORD32 i4_srch_range_n = ps_me_ctxt->i4_srch_range_n;
+ WORD32 i4_srch_range_s = ps_me_ctxt->i4_srch_range_s;
+ WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
+ WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
+
+ /* pointer to src macro block */
+ UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
+ UWORD8 *pu1_ref_mb = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist];
+
+ /* strides */
+ WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
+ WORD32 i4_ref_strd = ps_me_ctxt->ai4_rec_strd[i4_reflist];
+
+ /* least cost */
+ WORD32 i4_cost_least = ps_mb_part->i4_mb_cost;
+
+ /* least sad */
+ WORD32 i4_distortion_least = ps_mb_part->i4_mb_distortion;
+
+ /* mv pair */
+ WORD16 i2_mvx, i2_mvy;
+
+ /* mv bits */
+ UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
+
+ /* temp var */
+ WORD32 i4_cost[4];
+ WORD32 i4_sad[4];
+ UWORD8 *pu1_ref;
+ WORD16 i2_mv_u_x, i2_mv_u_y;
+
+ /* Diamond search Iteration Max Cnt */
+ WORD64 i8_num_layers = ps_me_ctxt->u4_num_layers;
+
+ /* mv with best sad during initial evaluation */
+ i2_mvx = ps_mb_part->s_mv_curr.i2_mvx;
+ i2_mvy = ps_mb_part->s_mv_curr.i2_mvy;
+
+ i2_mv_u_x = i2_mvx;
+ i2_mv_u_y = i2_mvy;
+
+ while(i8_num_layers--)
+ {
+ /* FIXME : is this the write way to check for out of bounds ? */
+ if((i2_mvx - 1 < i4_srch_range_w) || (i2_mvx + 1 > i4_srch_range_e) ||
+ (i2_mvy - 1 < i4_srch_range_n) || (i2_mvy + 1 > i4_srch_range_s))
+ {
+ break;
+ }
+
+ pu1_ref = pu1_ref_mb + i2_mvx + (i2_mvy * i4_ref_strd);
+
+ ps_me_ctxt->pf_ime_compute_sad4_diamond(pu1_ref, pu1_curr_mb, i4_ref_strd, i4_src_strd,
+ i4_sad);
+
+ DEBUG_SAD_HISTOGRAM_ADD(i4_sad[0], 2);
+ DEBUG_SAD_HISTOGRAM_ADD(i4_sad[1], 2);
+ DEBUG_SAD_HISTOGRAM_ADD(i4_sad[2], 2);
+ DEBUG_SAD_HISTOGRAM_ADD(i4_sad[3], 2);
+
+ /* compute cost */
+ i4_cost[0] =
+ i4_sad[0] +
+ u4_lambda_motion * (pu1_mv_bits[((i2_mvx - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
+ i4_cost[1] =
+ i4_sad[1] +
+ u4_lambda_motion * (pu1_mv_bits[((i2_mvx + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
+ i4_cost[2] =
+ i4_sad[2] +
+ u4_lambda_motion * (pu1_mv_bits[(i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[((i2_mvy - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
+ i4_cost[3] =
+ i4_sad[3] +
+ u4_lambda_motion * (pu1_mv_bits[(i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[((i2_mvy + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
+
+ if(i4_cost_least > i4_cost[0])
+ {
+ i4_cost_least = i4_cost[0];
+ i4_distortion_least = i4_sad[0];
+
+ i2_mv_u_x = (i2_mvx - 1);
+ i2_mv_u_y = i2_mvy;
+ }
+
+ if(i4_cost_least > i4_cost[1])
+ {
+ i4_cost_least = i4_cost[1];
+ i4_distortion_least = i4_sad[1];
+
+ i2_mv_u_x = (i2_mvx + 1);
+ i2_mv_u_y = i2_mvy;
+ }
+
+ if(i4_cost_least > i4_cost[2])
+ {
+ i4_cost_least = i4_cost[2];
+ i4_distortion_least = i4_sad[2];
+
+ i2_mv_u_x = i2_mvx;
+ i2_mv_u_y = i2_mvy - 1;
+ }
+
+ if(i4_cost_least > i4_cost[3])
+ {
+ i4_cost_least = i4_cost[3];
+ i4_distortion_least = i4_sad[3];
+
+ i2_mv_u_x = i2_mvx;
+ i2_mv_u_y = i2_mvy + 1;
+ }
+
+ if((i2_mv_u_x == i2_mvx) && (i2_mv_u_y == i2_mvy))
+ {
+ ps_mb_part->u4_exit = 1;
+ break;
+ }
+ else
+ {
+ i2_mvx = i2_mv_u_x;
+ i2_mvy = i2_mv_u_y;
+ }
+ }
+
+ if(i4_cost_least < ps_mb_part->i4_mb_cost)
+ {
+ ps_mb_part->i4_mb_cost = i4_cost_least;
+ ps_mb_part->i4_mb_distortion = i4_distortion_least;
+ ps_mb_part->s_mv_curr.i2_mvx = i2_mvx;
+ ps_mb_part->s_mv_curr.i2_mvy = i2_mvy;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function computes the best motion vector among the tentative mv
+* candidates chosen.
+*
+* @par Description:
+* This function determines the position in the search window at which the
+*motion estimation should begin in order to minimise the number of search
+*iterations.
+*
+* @param[in] ps_mb_part
+* pointer to current mb partition ctxt with respect to ME
+*
+* @param[in] u4_lambda_motion
+* lambda motion
+*
+* @param[in] u4_fast_flag
+* enable/disable fast sad computation
+*
+* @returns mv pair & corresponding distortion and cost
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+
+static void isvce_evaluate_init_srchposn_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
+{
+ UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
+
+ /* candidate mv cnt */
+ UWORD32 u4_num_candidates = ps_me_ctxt->u4_num_candidates[i4_reflist];
+
+ /* list of candidate mvs */
+ ime_mv_t *ps_mv_list = ps_me_ctxt->as_mv_init_search[i4_reflist];
+
+ /* pointer to src macro block */
+ UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
+ UWORD8 *pu1_ref_mb = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist];
+
+ /* strides */
+ WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
+ WORD32 i4_ref_strd = ps_me_ctxt->ai4_rec_strd[i4_reflist];
+
+ /* enabled fast sad computation */
+ UWORD32 u4_enable_fast_sad = ps_me_ctxt->u4_enable_fast_sad;
+
+ /* SAD(distortion metric) of an 8x8 block */
+ WORD32 i4_mb_distortion;
+
+ /* cost = distortion + u4_lambda_motion * rate */
+ WORD32 i4_mb_cost, i4_mb_cost_least = INT_MAX, i4_distortion_least = INT_MAX;
+
+ /* mb partitions info */
+ mb_part_ctxt *ps_mb_part = &(ps_me_ctxt->as_mb_part[i4_reflist]);
+
+ /* mv bits */
+ UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
+
+ /* temp var */
+ UWORD32 i, j;
+ WORD32 i4_srch_pos_idx = 0;
+ UWORD8 *pu1_ref = NULL;
+
+ /* Carry out a search using each of the motion vector pairs identified above
+ * as predictors. */
+ /* TODO : Just like Skip, Do we need to add any bias to zero mv as well */
+ for(i = 0; i < u4_num_candidates; i++)
+ {
+ /* compute sad */
+ WORD32 c_sad = 1;
+
+ for(j = 0; j < i; j++)
+ {
+ if((ps_mv_list[i].i2_mvx == ps_mv_list[j].i2_mvx) &&
+ (ps_mv_list[i].i2_mvy == ps_mv_list[j].i2_mvy))
+ {
+ c_sad = 0;
+ break;
+ }
+ }
+ if(c_sad)
+ {
+ /* adjust ref pointer */
+ pu1_ref = pu1_ref_mb + ps_mv_list[i].i2_mvx + (ps_mv_list[i].i2_mvy * i4_ref_strd);
+
+ /* compute distortion */
+ ps_me_ctxt->pf_ime_compute_sad_16x16[u4_enable_fast_sad](
+ pu1_curr_mb, pu1_ref, i4_src_strd, i4_ref_strd, i4_mb_cost_least,
+ &i4_mb_distortion);
+
+ DEBUG_SAD_HISTOGRAM_ADD(i4_mb_distortion, 3);
+ /* compute cost */
+ i4_mb_cost =
+ i4_mb_distortion +
+ u4_lambda_motion *
+ (pu1_mv_bits[(ps_mv_list[i].i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[(ps_mv_list[i].i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
+
+ if(i4_mb_cost < i4_mb_cost_least)
+ {
+ i4_mb_cost_least = i4_mb_cost;
+
+ i4_distortion_least = i4_mb_distortion;
+
+ i4_srch_pos_idx = i;
+ }
+ }
+ }
+
+ if(i4_mb_cost_least < ps_mb_part->i4_mb_cost)
+ {
+ ps_mb_part->i4_srch_pos_idx = i4_srch_pos_idx;
+ ps_mb_part->i4_mb_cost = i4_mb_cost_least;
+ ps_mb_part->i4_mb_distortion = i4_distortion_least;
+ ps_mb_part->s_mv_curr.i2_mvx = ps_mv_list[i4_srch_pos_idx].i2_mvx;
+ ps_mb_part->s_mv_curr.i2_mvy = ps_mv_list[i4_srch_pos_idx].i2_mvy;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Searches for the best matching full pixel predictor within the search
+* range
+*
+* @par Description:
+* This function begins by computing the mv predict vector for the current mb.
+* This is used for cost computations. Further basing on the algo. chosen, it
+* looks through a set of candidate vectors that best represent the mb a least
+* cost and returns this information.
+*
+* @param[in] ps_proc
+* pointer to current proc ctxt
+*
+* @param[in] ps_me_ctxt
+* pointer to me context
+*
+* @returns mv pair & corresponding distortion and cost
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static void isvce_full_pel_motion_estimation_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_ref_list)
+{
+ /* mb part info */
+ mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_ref_list];
+
+ /******************************************************************/
+ /* Modify Search range about initial candidate instead of zero mv */
+ /******************************************************************/
+ /*
+ * FIXME: The motion vectors in a way can become unbounded. It may so happen
+ * that MV might exceed the limit of the profile configured.
+ */
+ ps_me_ctxt->i4_srch_range_w =
+ MAX(ps_me_ctxt->i4_srch_range_w,
+ -ps_me_ctxt->ai2_srch_boundaries[0] + ps_mb_part->s_mv_curr.i2_mvx);
+ ps_me_ctxt->i4_srch_range_e =
+ MIN(ps_me_ctxt->i4_srch_range_e,
+ ps_me_ctxt->ai2_srch_boundaries[0] + ps_mb_part->s_mv_curr.i2_mvx);
+ ps_me_ctxt->i4_srch_range_n =
+ MAX(ps_me_ctxt->i4_srch_range_n,
+ -ps_me_ctxt->ai2_srch_boundaries[1] + ps_mb_part->s_mv_curr.i2_mvy);
+ ps_me_ctxt->i4_srch_range_s =
+ MIN(ps_me_ctxt->i4_srch_range_s,
+ ps_me_ctxt->ai2_srch_boundaries[1] + ps_mb_part->s_mv_curr.i2_mvy);
+
+ /************************************************************/
+ /* Traverse about best initial candidate for mv */
+ /************************************************************/
+
+ switch(ps_me_ctxt->u4_me_speed_preset)
+ {
+ case DMND_SRCH:
+ isvce_diamond_search_16x16(ps_me_ctxt, i4_ref_list);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Searches for the best matching sub pixel predictor within the search
+* range
+*
+* @par Description:
+* This function begins by searching across all sub pixel sample points
+* around the full pel motion vector. The vector with least cost is chosen as
+* the mv for the current mb. If the skip mode is not evaluated while analysing
+* the initial search candidates then analyse it here and update the mv.
+*
+* @param[in] ps_proc
+* pointer to current proc ctxt
+*
+* @param[in] ps_me_ctxt
+* pointer to me context
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static void isvce_sub_pel_motion_estimation_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
+{
+ /* pointers to src & ref macro block */
+ UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
+
+ /* pointers to ref. half pel planes */
+ UWORD8 *pu1_ref_mb_half_x;
+ UWORD8 *pu1_ref_mb_half_y;
+ UWORD8 *pu1_ref_mb_half_xy;
+
+ /* pointers to ref. half pel planes */
+ UWORD8 *pu1_ref_mb_half_x_temp;
+ UWORD8 *pu1_ref_mb_half_y_temp;
+ UWORD8 *pu1_ref_mb_half_xy_temp;
+
+ /* strides */
+ WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
+
+ WORD32 i4_ref_strd = ps_me_ctxt->u4_subpel_buf_strd;
+
+ /* mb partitions info */
+ mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
+
+ /* SAD(distortion metric) of an mb */
+ WORD32 i4_mb_distortion;
+ WORD32 i4_distortion_least = ps_mb_part->i4_mb_distortion;
+
+ /* cost = distortion + u4_lambda_motion * rate */
+ WORD32 i4_mb_cost;
+ WORD32 i4_mb_cost_least = ps_mb_part->i4_mb_cost;
+
+ /*Best half pel buffer*/
+ UWORD8 *pu1_best_hpel_buf = NULL;
+
+ /* mv bits */
+ UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
+
+ /* Motion vectors in full-pel units */
+ WORD16 mv_x, mv_y;
+
+ /* lambda - lagrange constant */
+ UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
+
+ /* Flags to check if half pel points needs to be evaluated */
+ /**************************************/
+ /* 1 bit for each half pel candidate */
+ /* bit 0 - half x = 1, half y = 0 */
+ /* bit 1 - half x = -1, half y = 0 */
+ /* bit 2 - half x = 0, half y = 1 */
+ /* bit 3 - half x = 0, half y = -1 */
+ /* bit 4 - half x = 1, half y = 1 */
+ /* bit 5 - half x = -1, half y = 1 */
+ /* bit 6 - half x = 1, half y = -1 */
+ /* bit 7 - half x = -1, half y = -1 */
+ /**************************************/
+ /* temp var */
+ WORD16 i2_mv_u_x, i2_mv_u_y;
+ WORD32 i, j;
+ WORD32 ai4_sad[8];
+
+ WORD32 i4_srch_pos_idx = ps_mb_part->i4_srch_pos_idx;
+
+ i2_mv_u_x = ps_mb_part->s_mv_curr.i2_mvx;
+ i2_mv_u_y = ps_mb_part->s_mv_curr.i2_mvy;
+
+ /************************************************************/
+ /* Evaluate half pel */
+ /************************************************************/
+ mv_x = ps_mb_part->s_mv_curr.i2_mvx >> 2;
+ mv_y = ps_mb_part->s_mv_curr.i2_mvy >> 2;
+
+ /**************************************************************/
+ /* ps_me_ctxt->pu1_half_x points to the half pel pixel on the */
+ /* left side of full pel */
+ /* ps_me_ctxt->pu1_half_y points to the half pel pixel on the */
+ /* top side of full pel */
+ /* ps_me_ctxt->pu1_half_xy points to the half pel pixel */
+ /* on the top left side of full pel */
+ /* for the function pf_ime_sub_pel_compute_sad_16x16 the */
+ /* default postions are */
+ /* ps_me_ctxt->pu1_half_x = right halp_pel */
+ /* ps_me_ctxt->pu1_half_y = bottom halp_pel */
+ /* ps_me_ctxt->pu1_half_xy = bottom right halp_pel */
+ /* Hence corresponding adjustments made here */
+ /**************************************************************/
+
+ pu1_ref_mb_half_x_temp = pu1_ref_mb_half_x = ps_me_ctxt->apu1_subpel_buffs[0] + 1;
+ pu1_ref_mb_half_y_temp = pu1_ref_mb_half_y = ps_me_ctxt->apu1_subpel_buffs[1] + 1 + i4_ref_strd;
+ pu1_ref_mb_half_xy_temp = pu1_ref_mb_half_xy =
+ ps_me_ctxt->apu1_subpel_buffs[2] + 1 + i4_ref_strd;
+
+ ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16(pu1_curr_mb, pu1_ref_mb_half_x, pu1_ref_mb_half_y,
+ pu1_ref_mb_half_xy, i4_src_strd, i4_ref_strd,
+ ai4_sad);
+
+ /* Half x plane */
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 mv_x_tmp = (mv_x << 2) + 2;
+ WORD32 mv_y_tmp = (mv_y << 2);
+
+ mv_x_tmp -= (i * 4);
+
+ i4_mb_distortion = ai4_sad[i];
+
+ /* compute cost */
+ i4_mb_cost = i4_mb_distortion +
+ u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
+
+ if(i4_mb_cost < i4_mb_cost_least)
+ {
+ i4_mb_cost_least = i4_mb_cost;
+
+ i4_distortion_least = i4_mb_distortion;
+
+ i2_mv_u_x = mv_x_tmp;
+
+ i2_mv_u_y = mv_y_tmp;
+
+ ps_me_ctxt->apu1_subpel_buffs[0] = pu1_ref_mb_half_x_temp - i;
+ pu1_best_hpel_buf = pu1_ref_mb_half_x_temp - i;
+
+ i4_srch_pos_idx = 0;
+ }
+ }
+
+ /* Half y plane */
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 mv_x_tmp = (mv_x << 2);
+ WORD32 mv_y_tmp = (mv_y << 2) + 2;
+
+ mv_y_tmp -= (i * 4);
+
+ i4_mb_distortion = ai4_sad[2 + i];
+
+ /* compute cost */
+ i4_mb_cost = i4_mb_distortion +
+ u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
+
+ if(i4_mb_cost < i4_mb_cost_least)
+ {
+ i4_mb_cost_least = i4_mb_cost;
+
+ i4_distortion_least = i4_mb_distortion;
+
+ i2_mv_u_x = mv_x_tmp;
+
+ i2_mv_u_y = mv_y_tmp;
+
+ ps_me_ctxt->apu1_subpel_buffs[1] = pu1_ref_mb_half_y_temp - i * (i4_ref_strd);
+ pu1_best_hpel_buf = pu1_ref_mb_half_y_temp - i * (i4_ref_strd);
+
+ i4_srch_pos_idx = 1;
+ }
+ }
+
+ /* Half xy plane */
+ for(j = 0; j < 2; j++)
+ {
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 mv_x_tmp = (mv_x << 2) + 2;
+ WORD32 mv_y_tmp = (mv_y << 2) + 2;
+
+ mv_x_tmp -= (i * 4);
+ mv_y_tmp -= (j * 4);
+
+ i4_mb_distortion = ai4_sad[4 + i + 2 * j];
+
+ /* compute cost */
+ i4_mb_cost = i4_mb_distortion +
+ u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
+ pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
+
+ if(i4_mb_cost < i4_mb_cost_least)
+ {
+ i4_mb_cost_least = i4_mb_cost;
+
+ i4_distortion_least = i4_mb_distortion;
+
+ i2_mv_u_x = mv_x_tmp;
+
+ i2_mv_u_y = mv_y_tmp;
+
+ ps_me_ctxt->apu1_subpel_buffs[2] = pu1_ref_mb_half_xy_temp - j * (i4_ref_strd) -i;
+ pu1_best_hpel_buf = pu1_ref_mb_half_xy_temp - j * (i4_ref_strd) -i;
+
+ i4_srch_pos_idx = 2;
+ }
+ }
+ }
+
+ if(i4_mb_cost_least < ps_mb_part->i4_mb_cost)
+ {
+ ps_mb_part->i4_mb_cost = i4_mb_cost_least;
+ ps_mb_part->i4_mb_distortion = i4_distortion_least;
+ ps_mb_part->s_mv_curr.i2_mvx = i2_mv_u_x;
+ ps_mb_part->s_mv_curr.i2_mvy = i2_mv_u_y;
+ ps_mb_part->pu1_best_hpel_buf = pu1_best_hpel_buf;
+ ps_mb_part->i4_srch_pos_idx = i4_srch_pos_idx;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function computes cost of skip macroblocks
+*
+* @par Description:
+*
+* @param[in] ps_me_ctxt
+* pointer to me ctxt
+*
+*
+* @returns none
+*
+* @remarks
+* NOTE: while computing the skip cost, do not enable early exit from compute
+* sad function because, a negative bias gets added later
+* Note tha the last ME candidate in me ctxt is taken as skip motion vector
+*
+*******************************************************************************
+*/
+static void isvce_compute_skip_cost(isvce_me_ctxt_t *ps_me_ctxt, ime_mv_t *ps_skip_mv,
+ mb_part_ctxt *ps_smb_part_info, UWORD32 u4_use_stat_sad,
+ WORD32 i4_reflist, WORD32 i4_is_slice_type_b)
+{
+ /* SAD(distortion metric) of an mb */
+ WORD32 i4_mb_distortion;
+
+ /* cost = distortion + u4_lambda_motion * rate */
+ WORD32 i4_mb_cost;
+
+ /* temp var */
+ UWORD8 *pu1_ref = NULL;
+
+ ime_mv_t s_skip_mv;
+
+ s_skip_mv.i2_mvx = (ps_skip_mv->i2_mvx + 2) >> 2;
+ s_skip_mv.i2_mvy = (ps_skip_mv->i2_mvy + 2) >> 2;
+
+ /* Check if the skip mv is out of bounds or subpel */
+ {
+ /* skip mv */
+ ime_mv_t s_clip_skip_mv;
+
+ s_clip_skip_mv.i2_mvx =
+ CLIP3(ps_me_ctxt->i4_srch_range_w, ps_me_ctxt->i4_srch_range_e, s_skip_mv.i2_mvx);
+ s_clip_skip_mv.i2_mvy =
+ CLIP3(ps_me_ctxt->i4_srch_range_n, ps_me_ctxt->i4_srch_range_s, s_skip_mv.i2_mvy);
+
+ if((s_clip_skip_mv.i2_mvx != s_skip_mv.i2_mvx) ||
+ (s_clip_skip_mv.i2_mvy != s_skip_mv.i2_mvy) || (ps_skip_mv->i2_mvx & 0x3) ||
+ (ps_skip_mv->i2_mvy & 0x3))
+ {
+ return;
+ }
+ }
+
+ /* adjust ref pointer */
+ pu1_ref = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist] + s_skip_mv.i2_mvx +
+ (s_skip_mv.i2_mvy * ps_me_ctxt->ai4_rec_strd[i4_reflist]);
+
+ if(u4_use_stat_sad == 1)
+ {
+ UWORD32 u4_is_nonzero;
+
+ ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16(
+ ps_me_ctxt->pu1_src_buf_luma, pu1_ref, ps_me_ctxt->i4_src_strd,
+ ps_me_ctxt->ai4_rec_strd[i4_reflist], ps_me_ctxt->pu2_sad_thrsh, &i4_mb_distortion,
+ &u4_is_nonzero);
+
+ if(u4_is_nonzero == 0 || i4_mb_distortion <= ps_me_ctxt->i4_min_sad)
+ {
+ ps_me_ctxt->u4_min_sad_reached = 1; /* found min sad */
+ ps_me_ctxt->i4_min_sad = (u4_is_nonzero == 0) ? 0 : i4_mb_distortion;
+ }
+ }
+ else
+ {
+ ps_me_ctxt->pf_ime_compute_sad_16x16[ps_me_ctxt->u4_enable_fast_sad](
+ ps_me_ctxt->pu1_src_buf_luma, pu1_ref, ps_me_ctxt->i4_src_strd,
+ ps_me_ctxt->ai4_rec_strd[i4_reflist], INT_MAX, &i4_mb_distortion);
+
+ if(i4_mb_distortion <= ps_me_ctxt->i4_min_sad)
+ {
+ ps_me_ctxt->i4_min_sad = i4_mb_distortion;
+ ps_me_ctxt->u4_min_sad_reached = 1; /* found min sad */
+ }
+ }
+
+ /* for skip mode cost & distortion are identical
+ * But we shall add a bias to favor skip mode.
+ * Doc. JVT B118 Suggests SKIP_BIAS as 16.
+ * TODO : Empirical analysis of SKIP_BIAS is necessary */
+
+ i4_mb_cost = i4_mb_distortion -
+ (ps_me_ctxt->u4_lambda_motion *
+ (ps_me_ctxt->i4_skip_bias[0] + ps_me_ctxt->i4_skip_bias[1] * i4_is_slice_type_b));
+
+ if(i4_mb_cost <= ps_smb_part_info->i4_mb_cost)
+ {
+ ps_smb_part_info->i4_mb_cost = i4_mb_cost;
+ ps_smb_part_info->i4_mb_distortion = i4_mb_distortion;
+ ps_smb_part_info->s_mv_curr.i2_mvx = s_skip_mv.i2_mvx;
+ ps_smb_part_info->s_mv_curr.i2_mvy = s_skip_mv.i2_mvy;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function populates the length of the codewords for motion vectors in the
+* range (-search range, search range) in pixels
+*
+* @param[in] ps_me
+* Pointer to me ctxt
+*
+* @param[out] pu1_mv_bits
+* length of the codeword for all mv's
+*
+* @remarks The length of the code words are derived from signed exponential
+* goloumb codes.
+*
+*******************************************************************************
+*/
+void isvce_init_mv_bits(isvce_me_ctxt_t *ps_me_ctxt)
+{
+ /* temp var */
+ WORD32 i, codesize = 3, diff, limit;
+ UWORD32 u4_code_num, u4_range;
+ UWORD32 u4_uev_min, u4_uev_max, u4_sev_min, u4_sev_max;
+
+ /* max srch range */
+ diff = MAX(DEFAULT_MAX_SRCH_RANGE_X, DEFAULT_MAX_SRCH_RANGE_Y);
+ /* sub pel */
+ diff <<= 2;
+ /* delta mv */
+ diff <<= 1;
+
+ /* codeNum for positive integer = 2x-1 : Table9-3 */
+ u4_code_num = (diff << 1);
+
+ /* get range of the bit string and put using put_bits() */
+ GETRANGE(u4_range, u4_code_num);
+
+ limit = 2 * u4_range - 1;
+
+ /* init mv bits */
+ ps_me_ctxt->pu1_mv_bits[0] = 1;
+
+ while(codesize < limit)
+ {
+ u4_uev_min = (1 << (codesize >> 1));
+ u4_uev_max = 2 * u4_uev_min - 1;
+
+ u4_sev_min = u4_uev_min >> 1;
+ u4_sev_max = u4_uev_max >> 1;
+
+ DEBUG("\n%d min, %d max %d codesize", u4_sev_min, u4_sev_max, codesize);
+
+ for(i = u4_sev_min; i <= (WORD32) u4_sev_max; i++)
+ {
+ ps_me_ctxt->pu1_mv_bits[-i] = ps_me_ctxt->pu1_mv_bits[i] = codesize;
+ }
+
+ codesize += 2;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Adds valid MVs as initial search candidates for motion estimation by
+* cheking if it is distinct or not.
+*
+* @param[in] ps_search_cand
+* MV to add as search candidate
+*
+* @param[in] ps_me_ctxt
+* pointer to ME context
+*
+* @param[in] u4_num_candidates
+* Number of inital search candidates value
+*
+*******************************************************************************
+*/
+static FORCEINLINE void isvce_add_me_init_search_cands(mv_t *ps_search_cand,
+ isvce_me_ctxt_t *ps_me_ctxt,
+ WORD32 i4_reflist,
+ UWORD32 *u4_num_candidates,
+ bool b_is_max_mv_diff_lt_4)
+{
+ WORD32 k;
+ WORD32 i4_mv_x, i4_mv_y;
+
+ bool b_is_mv_identical = false;
+
+ WORD32 i4_srch_range_n = ps_me_ctxt->i4_srch_range_n;
+ WORD32 i4_srch_range_s = ps_me_ctxt->i4_srch_range_s;
+ WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
+ WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
+ UWORD32 u4_num_init_search_cands = u4_num_candidates[0];
+
+ i4_mv_x = (ps_search_cand->i2_mvx + 2) >> 2;
+ i4_mv_y = (ps_search_cand->i2_mvy + 2) >> 2;
+
+ i4_mv_x = CLIP3(i4_srch_range_w, i4_srch_range_e, i4_mv_x);
+ i4_mv_y = CLIP3(i4_srch_range_n, i4_srch_range_s, i4_mv_y);
+
+ if(u4_num_init_search_cands == 0)
+ {
+ b_is_mv_identical = false;
+ }
+ else
+ {
+ for(k = u4_num_init_search_cands - 1; k >= 0; k--)
+ {
+ if((ps_me_ctxt->as_mv_init_search[i4_reflist][k].i2_mvx == i4_mv_x &&
+ ps_me_ctxt->as_mv_init_search[i4_reflist][k].i2_mvy == i4_mv_y))
+ {
+ b_is_mv_identical = true;
+ }
+ }
+ }
+
+ if(!b_is_mv_identical)
+ {
+ if(USE_ILP_MV_IN_ME && ps_me_ctxt->ps_ilp_me_cands)
+ {
+ if(ps_me_ctxt->ps_ilp_me_cands->u4_num_ilp_mvs < 2 || b_is_max_mv_diff_lt_4)
+ {
+ if(u4_num_init_search_cands < MAX_CAND_IF_NUM_ILP_MV_LT_2)
+ {
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx =
+ i4_mv_x;
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy =
+ i4_mv_y;
+
+ u4_num_candidates[0] += 1;
+ }
+ }
+ else if(ps_me_ctxt->ps_ilp_me_cands->u4_num_ilp_mvs >= 2 && !b_is_max_mv_diff_lt_4)
+ {
+ if(u4_num_init_search_cands < MAX_CAND_IF_NUM_ILP_MV_GTEQ_2)
+ {
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx =
+ i4_mv_x;
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy =
+ i4_mv_y;
+
+ u4_num_candidates[0] += 1;
+ }
+ }
+ }
+ else
+ {
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx = i4_mv_x;
+ ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy = i4_mv_y;
+
+ u4_num_candidates[0] += 1;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Determines the valid candidates for which the initial search shall
+*happen. The best of these candidates is used to center the diamond pixel
+*search.
+*
+* @par Description: The function sends the skip, (0,0), left, top and top-right
+* neighbouring MBs MVs. The left, top and top-right MBs MVs are used because
+* these are the same MVs that are used to form the MV predictor. This initial MV
+* search candidates need not take care of slice boundaries and hence neighbor
+* availability checks are not made here.
+*
+* @param[in] ps_left_mb_pu
+* pointer to left mb motion vector info
+*
+* @param[in] ps_top_mb_pu
+* pointer to top & top right mb motion vector info
+*
+* @param[in] ps_top_left_mb_pu
+* pointer to top left mb motion vector info
+*
+* @param[out] ps_skip_mv
+* pointer to skip motion vectors for the curr mb
+*
+* @param[in] i4_mb_x
+* mb index x
+*
+* @param[in] i4_mb_y
+* mb index y
+*
+* @param[in] i4_wd_mbs
+* pic width in mbs
+*
+* @param[in] ps_motionEst
+* pointer to me context
+*
+* @returns The list of MVs to be used of priming the full pel search and the
+* number of such MVs
+*
+* @remarks
+* Assumptions : 1. Assumes Only partition of size 16x16
+*
+*******************************************************************************
+*/
+static void isvce_get_search_candidates(isvce_process_ctxt_t *ps_proc, isvce_me_ctxt_t *ps_me_ctxt,
+ WORD32 i4_reflist)
+{
+ mv_t s_zero_mv;
+ mv_t *ps_left_mv, *ps_top_mv, *ps_top_left_mv, *ps_top_right_mv;
+
+ UWORD32 i;
+ WORD32 i4_left_mode, i4_top_mode, i4_top_left_mode, i4_top_right_mode;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+ mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
+ ilp_me_cands_t *ps_ilp_me_cands = ps_me_ctxt->ps_ilp_me_cands;
+
+ bool b_is_max_mv_diff_lt_4 = false;
+ WORD32 i4_mb_x = ps_proc->i4_mb_x;
+ WORD32 i4_cmpl_predmode = (i4_reflist == 0) ? L1 : L0;
+ UWORD32 u4_num_candidates = 0;
+
+ s_zero_mv.i2_mvx = 0;
+ s_zero_mv.i2_mvy = 0;
+ ps_left_mv = &ps_proc->s_nbr_info.ps_left_mb_info->as_pu->as_me_info[i4_reflist].s_mv;
+ ps_top_mv =
+ &(ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x)->as_pu->as_me_info[i4_reflist].s_mv;
+ ps_top_left_mv = &ps_proc->s_nbr_info.ps_top_row_mb_info->as_pu->as_me_info[i4_reflist].s_mv;
+ ps_top_right_mv =
+ &(ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x + 1)->as_pu->as_me_info[i4_reflist].s_mv;
+
+ i4_left_mode =
+ ps_ngbr_avbl->u1_mb_a
+ ? (ps_proc->s_nbr_info.ps_left_mb_info->as_pu->u1_pred_mode != i4_cmpl_predmode)
+ : 0;
+ i4_top_mode = ps_ngbr_avbl->u1_mb_b
+ ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x)->as_pu->u1_pred_mode !=
+ i4_cmpl_predmode)
+ : 0;
+ i4_top_right_mode =
+ ps_ngbr_avbl->u1_mb_c
+ ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x + 1)->as_pu->u1_pred_mode !=
+ i4_cmpl_predmode)
+ : 0;
+ i4_top_left_mode =
+ ps_ngbr_avbl->u1_mb_d
+ ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x - 1)->as_pu->u1_pred_mode !=
+ i4_cmpl_predmode)
+ : 0;
+
+ if(USE_ILP_MV_IN_ME && ps_ilp_me_cands)
+ {
+ if(ps_ilp_me_cands->u4_num_ilp_mvs >= 2)
+ {
+ b_is_max_mv_diff_lt_4 = isvce_check_max_mv_diff_lt_4(ps_ilp_me_cands, i4_reflist);
+ }
+
+ /* Taking ILP MV Predictor as one of the candidates */
+ if(ps_ilp_me_cands->u4_num_ilp_mvs < 2 || b_is_max_mv_diff_lt_4)
+ {
+ for(i = 0; i < ps_ilp_me_cands->u4_num_ilp_mvs_incl_nbrs; i++)
+ {
+ if(((ps_ilp_me_cands->ae_pred_mode[i] == ((PRED_MODE_T) i4_reflist)) ||
+ ((ps_ilp_me_cands->ae_pred_mode[i] == BI))))
+ {
+ isvce_add_me_init_search_cands(&ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv,
+ ps_me_ctxt, i4_reflist, &u4_num_candidates,
+ b_is_max_mv_diff_lt_4);
+ }
+ }
+ }
+ }
+
+ /* Taking the Top MV Predictor as one of the candidates */
+ if(ps_ngbr_avbl->u1_mb_b && i4_top_mode)
+ {
+ isvce_add_me_init_search_cands(ps_top_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
+ b_is_max_mv_diff_lt_4);
+ }
+
+ /* Taking the Left MV Predictor as one of the candidates */
+ if(ps_ngbr_avbl->u1_mb_a && i4_left_mode)
+ {
+ isvce_add_me_init_search_cands(ps_left_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
+ b_is_max_mv_diff_lt_4);
+ }
+
+ /********************************************************************/
+ /* MV Prediction */
+ /********************************************************************/
+ isvce_mv_pred_me(ps_proc, i4_reflist);
+
+ ps_mb_part->s_mv_pred.i2_mvx = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvx;
+ ps_mb_part->s_mv_pred.i2_mvy = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvy;
+
+ /* Get the skip motion vector */
+ {
+ ps_me_ctxt->i4_skip_type =
+ ps_codec->apf_find_skip_params_me[ps_proc->i4_slice_type](ps_proc, i4_reflist);
+
+ /* Taking the Skip motion vector as one of the candidates */
+ isvce_add_me_init_search_cands(&ps_proc->ps_skip_mv[i4_reflist].s_mv, ps_me_ctxt,
+ i4_reflist, &u4_num_candidates, b_is_max_mv_diff_lt_4);
+
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ /* Taking the temporal Skip motion vector as one of the candidates */
+ isvce_add_me_init_search_cands(&ps_proc->ps_skip_mv[i4_reflist + 2].s_mv, ps_me_ctxt,
+ i4_reflist, &u4_num_candidates, b_is_max_mv_diff_lt_4);
+ }
+ }
+
+ /* Taking ILP MV Predictor as one of the candidates */
+ if(USE_ILP_MV_IN_ME && ps_ilp_me_cands &&
+ (ps_ilp_me_cands->u4_num_ilp_mvs >= 2 && !b_is_max_mv_diff_lt_4))
+ {
+ for(i = 0; i < ps_ilp_me_cands->u4_num_ilp_mvs_incl_nbrs; i++)
+ {
+ if(((ps_ilp_me_cands->ae_pred_mode[i] == ((PRED_MODE_T) i4_reflist)) ||
+ ((ps_ilp_me_cands->ae_pred_mode[i] == BI))))
+ {
+ isvce_add_me_init_search_cands(&ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv,
+ ps_me_ctxt, i4_reflist, &u4_num_candidates,
+ b_is_max_mv_diff_lt_4);
+ }
+ }
+ }
+
+ if(ps_ngbr_avbl->u1_mb_b && i4_top_mode)
+ {
+ /* Taking the TopRt MV Predictor as one of the candidates */
+ if(ps_ngbr_avbl->u1_mb_c && i4_top_right_mode)
+ {
+ isvce_add_me_init_search_cands(ps_top_right_mv, ps_me_ctxt, i4_reflist,
+ &u4_num_candidates, b_is_max_mv_diff_lt_4);
+ }
+
+ /* Taking the TopLt MV Predictor as one of the candidates */
+ else if(ps_ngbr_avbl->u1_mb_d && i4_top_left_mode)
+ {
+ isvce_add_me_init_search_cands(ps_top_left_mv, ps_me_ctxt, i4_reflist,
+ &u4_num_candidates, b_is_max_mv_diff_lt_4);
+ }
+ }
+
+ /* Taking the Zero motion vector as one of the candidates */
+ isvce_add_me_init_search_cands(&s_zero_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
+ b_is_max_mv_diff_lt_4);
+
+ ASSERT(u4_num_candidates <= MAX_FPEL_SEARCH_CANDIDATES);
+
+ ps_me_ctxt->u4_num_candidates[i4_reflist] = u4_num_candidates;
+}
+
+/**
+*******************************************************************************
+*
+* @brief The function computes parameters for a PSKIP MB
+*
+* @par Description:
+* The function updates the skip motion vector and checks if the current
+* MB can be a skip PSKIP mB or not
+*
+* @param[in] ps_proc
+* Pointer to process context
+*
+* @param[in] u4_for_me
+* Flag to indicate function is called for ME or not
+*
+* @param[out] i4_ref_list
+* Current active refernce list
+*
+* @returns Flag indicating if the current MB can be marked as skip
+*
+* @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
+* specification.
+*
+*******************************************************************************
+*/
+WORD32 isvce_find_pskip_params(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
+{
+ /* left mb motion vector */
+ isvce_enc_pu_t *ps_left_mb_pu;
+
+ /* top mb motion vector */
+ isvce_enc_pu_t *ps_top_mb_pu;
+
+ /* Skip mv */
+ mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[L0].s_mv;
+
+ UNUSED(i4_reflist);
+
+ ps_left_mb_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
+ ps_top_mb_pu = (ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x)->as_pu;
+
+ if((!ps_proc->ps_ngbr_avbl->u1_mb_a) || (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
+ ((ps_left_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
+ (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
+ (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)) ||
+ ((ps_top_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
+ (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
+ (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)))
+
+ {
+ ps_skip_mv->i2_mvx = 0;
+ ps_skip_mv->i2_mvy = 0;
+ }
+ else
+ {
+ ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
+ ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
+ }
+
+ if((ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx == ps_skip_mv->i2_mvx) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy == ps_skip_mv->i2_mvy))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+*******************************************************************************
+*
+* @brief The function computes parameters for a PSKIP MB
+*
+* @par Description:
+* The function updates the skip motion vector and checks if the current
+* MB can be a skip PSKIP mB or not
+*
+* @param[in] ps_proc
+* Pointer to process context
+*
+* @param[in] u4_for_me
+* Flag to dincate fucntion is called for ME or not
+*
+* @param[out] i4_ref_list
+* Current active refernce list
+*
+* @returns Flag indicating if the current MB can be marked as skip
+*
+* @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
+* specification.
+*
+*******************************************************************************
+*/
+WORD32 isvce_find_pskip_params_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
+{
+ /* left mb motion vector */
+ isvce_enc_pu_t *ps_left_mb_pu;
+
+ /* top mb motion vector */
+ isvce_enc_pu_t *ps_top_mb_pu;
+
+ /* Skip mv */
+ mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[L0].s_mv;
+
+ UNUSED(i4_reflist);
+
+ ps_left_mb_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
+ ps_top_mb_pu = (ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x)->as_pu;
+
+ if((!ps_proc->ps_ngbr_avbl->u1_mb_a) || (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
+ ((ps_left_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
+ (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
+ (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)) ||
+ ((ps_top_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
+ (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
+ (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)))
+
+ {
+ ps_skip_mv->i2_mvx = 0;
+ ps_skip_mv->i2_mvy = 0;
+ }
+ else
+ {
+ ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
+ ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
+ }
+
+ return L0;
+}
+
+/**
+*******************************************************************************
+*
+* @brief motion vector predictor
+*
+* @par Description:
+* The routine calculates the motion vector predictor for a given block,
+* given the candidate MV predictors.
+*
+* @param[in] ps_left_mb_pu
+* pointer to left mb motion vector info
+*
+* @param[in] ps_top_row_pu
+* pointer to top & top right mb motion vector info
+*
+* @param[out] ps_pred_mv
+* pointer to candidate predictors for the current block
+*
+* @returns The x & y components of the MV predictor.
+*
+* @remarks The code implements the logic as described in sec 8.4.1.3 in H264
+* specification.
+* Assumptions : 1. Assumes Single reference frame
+* 2. Assumes Only partition of size 16x16
+*
+*******************************************************************************
+*/
+void isvce_get_mv_predictor(isvce_enc_pu_mv_t *ps_pred_mv, isvce_enc_pu_mv_t *ps_neig_mv,
+ WORD32 pred_algo)
+{
+ switch(pred_algo)
+ {
+ case 0:
+ /* left */
+ ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[0].s_mv.i2_mvx;
+ ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[0].s_mv.i2_mvy;
+ break;
+ case 1:
+ /* top */
+ ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[1].s_mv.i2_mvx;
+ ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[1].s_mv.i2_mvy;
+ break;
+ case 2:
+ /* top right */
+ ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[2].s_mv.i2_mvx;
+ ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[2].s_mv.i2_mvy;
+ break;
+ case 3:
+ /* median */
+ MEDIAN(ps_neig_mv[0].s_mv.i2_mvx, ps_neig_mv[1].s_mv.i2_mvx, ps_neig_mv[2].s_mv.i2_mvx,
+ ps_pred_mv->s_mv.i2_mvx);
+ MEDIAN(ps_neig_mv[0].s_mv.i2_mvy, ps_neig_mv[1].s_mv.i2_mvy, ps_neig_mv[2].s_mv.i2_mvy,
+ ps_pred_mv->s_mv.i2_mvy);
+
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs MV prediction
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns none
+*
+* @remarks none
+* This function will update the MB availability since intra inter decision
+* should be done before the call
+*
+*******************************************************************************
+*/
+void isvce_mv_pred(isvce_process_ctxt_t *ps_proc, WORD32 i4_slice_type)
+{
+ isvce_enc_pu_mv_t as_pu_mv[3];
+
+ UWORD8 u1_reflist, u1_cmpl_predmode;
+ WORD32 i;
+
+ isvce_enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
+ isvce_enc_pu_mv_t s_default_mv_info = {{0, 0}, -1};
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+ isvce_mb_info_t *ps_top_mb = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ isvce_mb_info_t *ps_top_left_mb = ps_top_mb - 1;
+ isvce_mb_info_t *ps_top_right_mb = ps_top_mb + 1;
+ isvce_mb_info_t *ps_left_mb = ps_proc->s_nbr_info.ps_left_mb_info;
+
+ UWORD8 u1_left_is_intra = ps_left_mb->u1_is_intra;
+ UWORD8 u1_num_ref_lists = (i4_slice_type == PSLICE) ? 1 : 2;
+
+ for(u1_reflist = 0; u1_reflist < u1_num_ref_lists; u1_reflist++)
+ {
+ WORD8 i1_cur_ref_idx = 0;
+
+ WORD32 pred_algo = 3, a, b, c;
+
+ for(i = 0; i < 3; i++)
+ {
+ as_pu_mv[i] = s_default_mv_info;
+ }
+
+ u1_cmpl_predmode = (u1_reflist == 0) ? L1 : L0;
+
+ /* Before performing mv prediction prepare the ngbr information and
+ * reset motion vectors basing on their availability */
+ if(ps_ngbr_avbl->u1_mb_a && (u1_left_is_intra != 1) &&
+ (ps_left_mb->as_pu->u1_pred_mode != u1_cmpl_predmode))
+ {
+ /* left mv */
+ as_pu_mv[0].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
+ as_pu_mv[0].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
+
+ /* Only left available */
+ if(!ps_ngbr_avbl->u1_mb_b && !ps_ngbr_avbl->u1_mb_c && !ps_ngbr_avbl->u1_mb_d)
+ {
+ as_pu_mv[1].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
+ as_pu_mv[1].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
+
+ as_pu_mv[2].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
+ }
+ }
+ if(ps_ngbr_avbl->u1_mb_b && !ps_top_mb->u1_is_intra &&
+ (ps_top_mb->as_pu[0].u1_pred_mode != u1_cmpl_predmode))
+ {
+ /* top mv */
+ as_pu_mv[1].s_mv = ps_top_mb->as_pu[0].as_me_info[u1_reflist].s_mv;
+ as_pu_mv[1].i1_ref_idx = ps_top_mb->as_pu[0].as_me_info[u1_reflist].i1_ref_idx;
+ }
+
+ if(!ps_ngbr_avbl->u1_mb_c)
+ {
+ /* top right mv - When top right partition is not available for
+ * prediction if top left is available use it for prediction else
+ * set the mv information to -1 and (0, 0)
+ * */
+ if(ps_ngbr_avbl->u1_mb_d && !ps_top_left_mb->u1_is_intra &&
+ (ps_top_left_mb->as_pu->u1_pred_mode != u1_cmpl_predmode))
+ {
+ as_pu_mv[2].s_mv = ps_top_left_mb->as_pu[0].as_me_info[u1_reflist].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_top_left_mb->as_pu[0].as_me_info[u1_reflist].i1_ref_idx;
+ }
+ }
+ else if(ps_top_right_mb->as_pu->u1_pred_mode != u1_cmpl_predmode &&
+ !ps_top_right_mb->u1_is_intra)
+ {
+ as_pu_mv[2].s_mv = ps_top_right_mb->as_pu->as_me_info[u1_reflist].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_top_right_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
+ }
+
+ /* If only one of the candidate blocks has a reference frame equal to
+ * the current block then use the same block as the final predictor */
+ a = (as_pu_mv[0].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+ b = (as_pu_mv[1].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+ c = (as_pu_mv[2].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+ if(a == 0 && b == -1 && c == -1)
+ pred_algo = 0; /* LEFT */
+ else if(a == -1 && b == 0 && c == -1)
+ pred_algo = 1; /* TOP */
+ else if(a == -1 && b == -1 && c == 0)
+ pred_algo = 2;
+
+ isvce_get_mv_predictor(&ps_pred_mv[u1_reflist], &as_pu_mv[0], pred_algo);
+
+ ps_pred_mv[u1_reflist].i1_ref_idx = i1_cur_ref_idx;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function approximates Pred. MV
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns none
+*
+* @remarks none
+* Motion estimation happens at nmb level. For cost calculations, mv is appro
+* ximated using this function
+*
+*******************************************************************************
+*/
+void isvce_mv_pred_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_ref_list)
+{
+ isvce_enc_pu_mv_t as_pu_mv[3];
+
+ WORD32 i, a, b, c;
+
+ isvce_enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
+ isvce_enc_pu_mv_t s_default_mv_info = {{0, 0}, -1};
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+ isvce_mb_info_t *ps_top_mb = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ isvce_mb_info_t *ps_top_left_mb = ps_top_mb - 1;
+ isvce_mb_info_t *ps_top_right_mb = ps_top_mb + 1;
+ isvce_mb_info_t *ps_left_mb = ps_proc->s_nbr_info.ps_left_mb_info;
+
+ WORD8 i1_cur_ref_idx = 0;
+ WORD32 i4_cmpl_predmode = (i4_ref_list == 0) ? L1 : L0;
+ WORD32 pred_algo = 3;
+
+ for(i = 0; i < 3; i++)
+ {
+ as_pu_mv[i] = s_default_mv_info;
+ }
+
+ if(ps_ngbr_avbl->u1_mb_a && !ps_left_mb->u1_is_intra &&
+ (ps_left_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
+ {
+ /* left mv */
+ as_pu_mv[0].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[0].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+
+ /* Only left available */
+ if(!ps_ngbr_avbl->u1_mb_b && !ps_ngbr_avbl->u1_mb_c && !ps_ngbr_avbl->u1_mb_d)
+ {
+ as_pu_mv[1].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[1].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+
+ as_pu_mv[2].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+ }
+ }
+ if(ps_ngbr_avbl->u1_mb_b && !ps_top_mb->u1_is_intra &&
+ (ps_top_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
+ {
+ /* top mv */
+ as_pu_mv[1].s_mv = ps_top_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[1].i1_ref_idx = ps_top_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+ }
+ if(!ps_ngbr_avbl->u1_mb_c)
+ {
+ /* top right mv - When top right partition is not available for
+ * prediction if top left is available use it for prediction else
+ * set the mv information to -1 and (0, 0)
+ * */
+ if(ps_ngbr_avbl->u1_mb_d && !ps_top_left_mb->u1_is_intra &&
+ (ps_top_left_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
+ {
+ as_pu_mv[2].s_mv = ps_top_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_top_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+ }
+ }
+ else if(ps_top_right_mb->as_pu->u1_pred_mode != i4_cmpl_predmode &&
+ !ps_top_right_mb->u1_is_intra)
+ {
+ as_pu_mv[2].s_mv = ps_top_right_mb->as_pu->as_me_info[i4_ref_list].s_mv;
+ as_pu_mv[2].i1_ref_idx = ps_top_right_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
+ }
+
+ /* If only one of the candidate blocks has a reference frame equal to
+ * the current block then use the same block as the final predictor */
+ a = (as_pu_mv[0].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+ b = (as_pu_mv[1].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+ c = (as_pu_mv[2].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
+
+ if(a == 0 && b == -1 && c == -1)
+ pred_algo = 0; /* LEFT */
+ else if(a == -1 && b == 0 && c == -1)
+ pred_algo = 1; /* TOP */
+ else if(a == -1 && b == -1 && c == 0)
+ pred_algo = 2;
+
+ isvce_get_mv_predictor(&ps_pred_mv[i4_ref_list], &as_pu_mv[0], pred_algo);
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function initializes me ctxt
+*
+* @par Description:
+* Before dispatching the current job to me thread, the me context associated
+* with the job is initialized.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_me(isvce_process_ctxt_t *ps_proc)
+{
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ ps_me_ctxt->i4_skip_bias[BSLICE] = SKIP_BIAS_B;
+
+ if(ps_codec->s_cfg.u4_num_bframes == 0)
+ {
+ ps_me_ctxt->i4_skip_bias[PSLICE] = 4 * SKIP_BIAS_P;
+ }
+ else
+ {
+ ps_me_ctxt->i4_skip_bias[PSLICE] = SKIP_BIAS_P;
+ }
+
+ ps_me_ctxt->pu1_src_buf_luma = ps_proc->s_src_buf_props.as_component_bufs[0].pv_data;
+ ps_me_ctxt->i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
+
+ ps_me_ctxt->apu1_ref_buf_luma[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data;
+ ps_me_ctxt->apu1_ref_buf_luma[1] = ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data;
+
+ ps_me_ctxt->ai4_rec_strd[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].i4_data_stride;
+ ps_me_ctxt->ai4_rec_strd[1] = ps_proc->as_ref_buf_props[1].as_component_bufs[0].i4_data_stride;
+
+ ps_me_ctxt->u4_lambda_motion = gu1_qp0[ps_me_ctxt->u1_mb_qp];
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs motion estimation for the current mb using
+* single reference list
+*
+* @par Description:
+* The current mb is compared with a list of mb's in the reference frame for
+* least cost. The mb that offers least cost is chosen as predicted mb and the
+* displacement of the predicted mb from index location of the current mb is
+* signaled as mv. The list of the mb's that are chosen in the reference frame
+* are dependent on the speed of the ME configured.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns motion vector of the pred mb, sad, cost.
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_compute_me_single_reflist(isvce_process_ctxt_t *ps_proc)
+{
+ mb_part_ctxt s_skip_mbpart;
+
+ /* source buffer for halp pel generation functions */
+ UWORD8 *pu1_hpel_src;
+
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
+
+ ASSERT(1 == MAX_REF_FRAMES_PER_PRED_DIR);
+
+ {
+ WORD32 rows_above, rows_below, columns_left, columns_right;
+
+ /* During evaluation for motion vectors do not search through padded regions
+ */
+ /* Obtain number of rows and columns that are effective for computing for me
+ * evaluation */
+ rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
+ rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
+ columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
+ columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
+
+ /* init srch range */
+ /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X /
+ * 2 on all sides.
+ */
+ ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
+ ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
+ ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
+ ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
+
+ /* this is to facilitate fast sub pel computation with minimal loads */
+ ps_me_ctxt->i4_srch_range_w += 1;
+ ps_me_ctxt->i4_srch_range_e -= 1;
+ ps_me_ctxt->i4_srch_range_n += 1;
+ ps_me_ctxt->i4_srch_range_s -= 1;
+ }
+
+ /***********************************************************************
+ * Compute ME for list L0
+ ***********************************************************************/
+
+ /* Init SATQD for the current list */
+ ps_me_ctxt->u4_min_sad_reached = 0;
+ ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
+
+ /* Get the seed motion vector candidates */
+ isvce_get_search_candidates(ps_proc, ps_me_ctxt, L0);
+
+ /* ****************************************************************
+ *Evaluate the SKIP for current list
+ * ****************************************************************/
+ s_skip_mbpart.s_mv_curr.i2_mvx = 0;
+ s_skip_mbpart.s_mv_curr.i2_mvy = 0;
+ s_skip_mbpart.i4_mb_cost = INT_MAX;
+ s_skip_mbpart.i4_mb_distortion = INT_MAX;
+
+ isvce_compute_skip_cost(ps_me_ctxt, (ime_mv_t *) (&ps_proc->ps_skip_mv[L0].s_mv),
+ &s_skip_mbpart, ps_codec->s_cfg.u4_enable_satqd, PRED_L0,
+ 0 /* Not a Bslice */);
+
+ s_skip_mbpart.s_mv_curr.i2_mvx <<= 2;
+ s_skip_mbpart.s_mv_curr.i2_mvy <<= 2;
+
+ /******************************************************************
+ * Evaluate ME For current list
+ *****************************************************************/
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx = 0;
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy = 0;
+ ps_me_ctxt->as_mb_part[L0].i4_mb_cost = INT_MAX;
+ ps_me_ctxt->as_mb_part[L0].i4_mb_distortion = INT_MAX;
+
+ /* Init Hpel */
+ ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf = NULL;
+
+ /* In case we found out the minimum SAD, exit the ME eval */
+ if(!ps_me_ctxt->u4_min_sad_reached)
+ {
+ /* Evaluate search candidates for initial mv pt */
+ isvce_evaluate_init_srchposn_16x16(ps_me_ctxt, L0);
+
+ /********************************************************************/
+ /* full pel motion estimation */
+ /********************************************************************/
+ isvce_full_pel_motion_estimation_16x16(ps_me_ctxt, L0);
+
+ /* Scale the MV to qpel resolution */
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx <<= 2;
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy <<= 2;
+
+ if(ps_me_ctxt->u4_enable_hpel)
+ {
+ /* moving src pointer to the converged motion vector location*/
+ pu1_hpel_src =
+ ps_me_ctxt->apu1_ref_buf_luma[L0] +
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) * ps_me_ctxt->ai4_rec_strd[L0];
+
+ ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
+ ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
+ ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
+
+ ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
+
+ /* half pel search is done for both sides of full pel,
+ * hence half_x of width x height = 17x16 is created
+ * starting from left half_x of converged full pel */
+ pu1_hpel_src -= 1;
+
+ /* computing half_x */
+ ps_codec->pf_ih264e_sixtapfilter_horz(pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[0],
+ ps_me_ctxt->ai4_rec_strd[L0],
+ ps_me_ctxt->u4_subpel_buf_strd);
+
+ /*
+ * Halfpel search is done for both sides of full pel,
+ * hence half_y of width x height = 16x17 is created
+ * starting from top half_y of converged full pel
+ * for half_xy top_left is required
+ * hence it starts from pu1_hpel_src = full_pel_converged_point -
+ * i4_rec_strd - 1
+ */
+ pu1_hpel_src -= ps_me_ctxt->ai4_rec_strd[L0];
+
+ /* computing half_y , and half_xy*/
+ ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
+ pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1], ps_me_ctxt->apu1_subpel_buffs[2],
+ ps_me_ctxt->ai4_rec_strd[L0], ps_me_ctxt->u4_subpel_buf_strd,
+ ps_proc->ai16_pred1 + 3, ps_me_ctxt->u4_subpel_buf_strd);
+
+ isvce_sub_pel_motion_estimation_16x16(ps_me_ctxt, L0);
+ }
+ }
+
+ /***********************************************************************
+ * If a particular skiip Mv is giving better sad, copy to the corresponding
+ * MBPART
+ * In B slices this loop should go only to PREDL1: If we found min sad
+ * we will go to the skip ref list only
+ * Have to find a way to make it without too much change or new vars
+ **********************************************************************/
+ if(s_skip_mbpart.i4_mb_cost < ps_me_ctxt->as_mb_part[L0].i4_mb_cost)
+ {
+ ps_me_ctxt->as_mb_part[L0].i4_mb_cost = s_skip_mbpart.i4_mb_cost;
+ ps_me_ctxt->as_mb_part[L0].i4_mb_distortion = s_skip_mbpart.i4_mb_distortion;
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr = s_skip_mbpart.s_mv_curr;
+ }
+ else if(ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf)
+ {
+ /* Now we have to copy the buffers */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(
+ ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf, ps_proc->pu1_best_subpel_buf,
+ ps_me_ctxt->u4_subpel_buf_strd, ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL,
+ 0);
+ }
+
+ /**********************************************************************
+ * Now get the minimum of MB part sads by searching over all ref lists
+ **********************************************************************/
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx =
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx;
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy =
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy;
+ ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[L0].i4_mb_cost;
+ ps_proc->ps_cur_mb->i4_mb_distortion = ps_me_ctxt->as_mb_part[L0].i4_mb_distortion;
+ ps_proc->ps_cur_mb->u4_mb_type = P16x16;
+ ps_proc->ps_mb_info->as_pu->u1_pred_mode = L0;
+
+ /* Mark the reflists */
+ ps_proc->ps_mb_info->as_pu->as_me_info[0].i1_ref_idx = 0;
+ ps_proc->ps_mb_info->as_pu->as_me_info[1].i1_ref_idx = -1;
+
+ /* number of partitions */
+ ps_proc->u4_num_sub_partitions = 1;
+ *(ps_proc->pu4_mb_pu_cnt) = 1;
+
+ /* position in-terms of PU */
+ ps_proc->ps_mb_info->as_pu->u1_pos_x_in_4x4 = 0;
+ ps_proc->ps_mb_info->as_pu->u1_pos_y_in_4x4 = 0;
+
+ /* PU size */
+ ps_proc->ps_mb_info->as_pu->u1_wd_in_4x4_m1 = 3;
+ ps_proc->ps_mb_info->as_pu->u1_ht_in_4x4_m1 = 3;
+
+ /* Update min sad conditions */
+ if(ps_me_ctxt->u4_min_sad_reached == 1)
+ {
+ ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
+ ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs motion estimation for the current NMB
+*
+* @par Description:
+* Intializes input and output pointers required by the function
+*isvce_compute_me and calls the function isvce_compute_me in a loop to process
+*NMBs.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_compute_me_nmb(isvce_process_ctxt_t *ps_proc, UWORD32 u4_nmb_count)
+{
+ UWORD32 u4_i;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isvce_mb_info_t *ps_mb_begin = ps_proc->ps_mb_info;
+
+ UWORD32 *pu4_mb_pu_cnt_begin = ps_proc->pu4_mb_pu_cnt;
+ UWORD8 *pu1_me_map = ps_proc->pu1_me_map + (ps_proc->i4_mb_y * ps_proc->i4_wd_mbs);
+
+ /* Spatial dependencies for skip are not met if nmb > 1 */
+ ASSERT(1 == u4_nmb_count);
+
+ if(ps_proc->i4_mb_x)
+ {
+ ps_proc->s_me_ctxt.u4_left_is_intra = ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra;
+ ps_proc->s_me_ctxt.u4_left_is_skip =
+ (ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == PSKIP);
+ }
+
+ for(u4_i = 0; u4_i < u4_nmb_count; u4_i++)
+ {
+ /* Wait for ME map */
+ if(ps_proc->i4_mb_y > 0)
+ {
+ /* Wait for top right ME to be done */
+ UWORD8 *pu1_me_map_tp_rw =
+ ps_proc->pu1_me_map + (ps_proc->i4_mb_y - 1) * ps_proc->i4_wd_mbs;
+
+ while(1)
+ {
+ volatile UWORD8 *pu1_buf;
+ WORD32 idx = ps_proc->i4_mb_x + u4_i + 1;
+
+ idx = MIN(idx, (ps_proc->i4_wd_mbs - 1));
+ pu1_buf = pu1_me_map_tp_rw + idx;
+ if(*pu1_buf) break;
+ ithread_yield();
+ }
+ }
+
+ ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_i].as_skip_mv[0]);
+ ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_i].s_ngbr_avbl);
+ ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_i].as_pred_mv[0]);
+ ps_proc->ps_cur_mb = &(ps_proc->ps_nmb_info[u4_i]);
+
+ ps_proc->ps_cur_mb->u4_min_sad = ps_proc->u4_min_sad;
+ ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
+
+ ps_proc->ps_cur_mb->i4_mb_cost = INT_MAX;
+ ps_proc->ps_cur_mb->i4_mb_distortion = SHRT_MAX;
+
+ /* Set the best subpel buf to the correct mb so that the buffer can be
+ * copied */
+ ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_i].pu1_best_sub_pel_buf;
+ ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_i].u4_bst_spel_buf_strd;
+
+ /* Set the min sad conditions */
+ ps_proc->ps_cur_mb->u4_min_sad = ps_codec->u4_min_sad;
+ ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
+
+ isvce_derive_nghbr_avbl_of_mbs(ps_proc);
+
+ isvce_init_me(ps_proc);
+
+ /* Compute ME according to slice type */
+ ps_codec->apf_compute_me[ps_proc->i4_slice_type](ps_proc);
+
+ /* update top and left structs */
+ if(u4_nmb_count > 1)
+ {
+ isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
+
+ ps_left_syn[0] = ps_proc->ps_mb_info[0];
+ ps_left_syn[0].u1_is_intra = 0;
+ ps_left_syn[0].u2_mb_type = ps_proc->ps_cur_mb->u4_mb_type;
+ }
+
+ /* Copy the min sad reached info */
+ ps_proc->ps_nmb_info[u4_i].u4_min_sad_reached = ps_proc->ps_cur_mb->u4_min_sad_reached;
+ ps_proc->ps_nmb_info[u4_i].u4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
+
+ /*
+ * To make sure that the MV map is properly sync to the
+ * cache we need to do a DDB
+ */
+ {
+ DATA_SYNC();
+
+ pu1_me_map[ps_proc->i4_mb_x] = 1;
+ }
+ ps_proc->i4_mb_x++;
+
+ ps_proc->s_me_ctxt.u4_left_is_intra = 0;
+ ps_proc->s_me_ctxt.u4_left_is_skip = (ps_proc->ps_cur_mb->u4_mb_type == PSKIP);
+
+ /* update buffers pointers */
+ ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) + MB_SIZE;
+
+ /*
+ * Note: Although chroma mb size is 8, as the chroma buffers are
+ * interleaved, the stride per MB is MB_SIZE
+ */
+ ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
+
+ ps_proc->pu4_mb_pu_cnt++;
+ ps_proc->ps_mb_info++;
+ }
+
+ ps_proc->ps_mb_info = ps_mb_begin;
+ ps_proc->pu4_mb_pu_cnt = pu4_mb_pu_cnt_begin;
+ ps_proc->i4_mb_x = ps_proc->i4_mb_x - u4_nmb_count;
+
+ /* update buffers pointers */
+ ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) - MB_SIZE * u4_nmb_count;
+ ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) - MB_SIZE * u4_nmb_count;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) -
+ MB_SIZE * u4_nmb_count;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) -
+ MB_SIZE * u4_nmb_count;
+
+ /*
+ * Note: Although chroma mb size is 8, as the chroma buffers are
+ * interleaved, the stride per MB is MB_SIZE
+ */
+ ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) - MB_SIZE * u4_nmb_count;
+ ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) - MB_SIZE * u4_nmb_count;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) -
+ MB_SIZE * u4_nmb_count;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) -
+ MB_SIZE * u4_nmb_count;
+}
+
+/**
+*******************************************************************************
+*
+* @brief The function computes parameters for a BSKIP MB
+*
+* @par Description:
+* The function updates the skip motion vector for B Mb, check if the Mb can be
+* marked as skip and returns it
+*
+* @param[in] ps_proc
+* Pointer to process context
+*
+* @param[in] u4_for_me
+* Dummy
+*
+* @param[in] i4_reflist
+* Dummy
+*
+* @returns Flag indicating if the current Mb can be skip or not
+*
+* @remarks
+* The code implements the logic as described in sec 8.4.1.2.2
+* It also computes co-located MB parmas according to sec 8.4.1.2.1
+*
+* Need to add condition for this fucntion to be used in ME
+*
+*******************************************************************************/
+WORD32 isvce_find_bskip_params_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
+{
+ /* Colzero for co-located MB */
+ WORD32 i4_colzeroflag;
+
+ /* motion vectors for neighbouring MBs */
+ isvce_enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
+
+ /* Variables to check if a particular mB is available */
+ WORD32 i4_a, i4_b, i4_c, i4_c_avail;
+
+ /* Mode availability, init to no modes available */
+ WORD32 i4_mode_avail;
+
+ /* mb neighbor availability */
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+
+ /* Temp var */
+ WORD32 i, i4_cmpl_mode, i4_skip_type = -1;
+
+ /*
+ * Colocated motion vector
+ */
+ mv_t s_mvcol;
+
+ /*
+ * Colocated picture idx
+ */
+ WORD32 i4_refidxcol;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ UNUSED(i4_reflist);
+
+ /**************************************************************************
+ *Find co-located MB parameters
+ * See sec 8.4.1.2.1 for reference
+ **************************************************************************/
+ {
+ /*
+ * Find the co-located Mb and update the skip and pred appropriately
+ * 1) Default colpic is forward ref : Table 8-6
+ * 2) Default mb col is current MB : Table 8-8
+ */
+
+ if(ps_proc->ps_col_mb->u1_is_intra)
+ {
+ s_mvcol.i2_mvx = 0;
+ s_mvcol.i2_mvy = 0;
+ i4_refidxcol = -1;
+ }
+ else
+ {
+ if(ps_proc->ps_col_mb->as_pu->u1_pred_mode != L1)
+ {
+ s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L0].s_mv;
+ i4_refidxcol = 0;
+ }
+ else
+ {
+ s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L1].s_mv;
+ i4_refidxcol = 0;
+ }
+ }
+
+ /* RefPicList1[ 0 ] is marked as "used for short-term reference", as
+ * default */
+ i4_colzeroflag =
+ (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1) && (ABS(s_mvcol.i2_mvy) <= 1));
+ }
+
+ /***************************************************************************
+ * Evaluating skip params : Spatial Skip
+ **************************************************************************/
+ {
+ /* Get the neighbouring MBS according to Section 8.4.1.2.2 */
+ ps_a_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
+ ps_b_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x].as_pu;
+
+ i4_c_avail = 0;
+ if(ps_ngbr_avbl->u1_mb_c)
+ {
+ ps_c_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1].as_pu;
+ i4_c_avail = 1;
+ }
+ else
+ {
+ ps_c_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1].as_pu;
+ i4_c_avail = ps_ngbr_avbl->u1_mb_d;
+ }
+
+ i4_a = ps_ngbr_avbl->u1_mb_a;
+ i4_b = ps_ngbr_avbl->u1_mb_b;
+ i4_c = i4_c_avail;
+
+ /* Init to no mode avail */
+ i4_mode_avail = 0;
+ for(i = 0; i < 2; i++)
+ {
+ i4_cmpl_mode = (i == 0) ? L1 : L0;
+
+ i4_mode_avail |= (i4_a && (ps_a_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_a_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ i4_mode_avail |= (i4_b && (ps_b_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_b_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ i4_mode_avail |= (i4_c && (ps_c_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_c_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ }
+
+ if(i4_mode_avail == 0x3 || i4_mode_avail == 0x0)
+ {
+ i4_skip_type = BI;
+ }
+ else if(i4_mode_avail == 0x1)
+ {
+ i4_skip_type = L0;
+ }
+ else if(i4_mode_avail == 0x2)
+ {
+ i4_skip_type = L1;
+ }
+
+ /* Update skip MV for L0 */
+ if((i4_mode_avail & 0x1) && (!i4_colzeroflag))
+ {
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
+ }
+
+ /* Update skip MV for L1 */
+ if((i4_mode_avail & 0x2) && (!i4_colzeroflag))
+ {
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
+ }
+ }
+
+ /***************************************************************************
+ * Evaluating skip params : Temporal skip
+ **************************************************************************/
+ {
+ svc_au_buf_t *ps_ref_pic[MAX_REF_PIC_CNT];
+ WORD32 i4_td, i4_tx, i4_tb, i4_dist_scale_factor;
+ isvce_enc_pu_mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[2];
+
+ ps_ref_pic[L0] = ps_proc->aps_ref_pic[L0];
+ ps_ref_pic[L1] = ps_proc->aps_ref_pic[L1];
+
+ i4_tb = ps_codec->i4_poc - ps_ref_pic[L0]->i4_abs_poc;
+ i4_td = ps_ref_pic[L1]->i4_abs_poc - ps_ref_pic[L0]->i4_abs_poc;
+
+ i4_tb = CLIP3(-128, 127, i4_tb);
+ i4_td = CLIP3(-128, 127, i4_td);
+
+ i4_tx = (16384 + ABS(i4_td / 2)) / i4_td;
+ i4_dist_scale_factor = CLIP3(-1024, 1023, (i4_tb * i4_tx + 32) >> 6);
+
+ /* Motion vectors taken in full pel resolution , hence -> (& 0xfffc)
+ * operation */
+ ps_skip_mv[L0].s_mv.i2_mvx = ((i4_dist_scale_factor * s_mvcol.i2_mvx + 128) >> 8) & 0xfffc;
+ ps_skip_mv[L0].s_mv.i2_mvy = ((i4_dist_scale_factor * s_mvcol.i2_mvy + 128) >> 8) & 0xfffc;
+
+ ps_skip_mv[L1].s_mv.i2_mvx = (ps_skip_mv[L0].s_mv.i2_mvx - s_mvcol.i2_mvx) & 0xfffc;
+ ps_skip_mv[L1].s_mv.i2_mvy = (ps_skip_mv[L0].s_mv.i2_mvy - s_mvcol.i2_mvy) & 0xfffc;
+ }
+
+ return i4_skip_type;
+}
+
+/**
+*******************************************************************************
+*
+* @brief The function computes the skip motion vectoe for B mb
+*
+* @par Description:
+* The function gives the skip motion vector for B Mb, check if the Mb can be
+* marked as skip
+*
+* @param[in] ps_proc
+* Pointer to process context
+*
+* @param[in] u4_for_me
+* Dummy
+*
+* @param[in] u4_for_me
+* Dummy
+*
+* @returns Flag indicating if the current Mb can be skip or not
+*
+* @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
+* specification. It also computes co-located MB parmas according to
+*sec 8.4.1.2.1
+*
+*******************************************************************************/
+WORD32 isvce_find_bskip_params(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
+{
+ WORD32 i4_colzeroflag;
+
+ /* motion vectors */
+ isvce_enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
+
+ /* Syntax elem */
+ isvce_mb_info_t *ps_a_syn, *ps_b_syn, *ps_c_syn;
+
+ /* Variables to check if a particular mB is available */
+ WORD32 i4_a, i4_b, i4_c, i4_c_avail;
+
+ /* Mode availability, init to no modes available */
+ WORD32 i4_mode_avail;
+
+ /* mb neighbor availability */
+ block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+
+ /* Temp var */
+ WORD32 i, i4_cmpl_mode;
+
+ UNUSED(i4_reflist);
+
+ /**************************************************************************
+ *Find co-locates parameters
+ * See sec 8.4.1.2.1 for reference
+ **************************************************************************/
+ {
+ /*
+ * Find the co-located Mb and update the skip and pred appropriately
+ * 1) Default colpic is forward ref : Table 8-6
+ * 2) Default mb col is current MB : Table 8-8
+ */
+
+ mv_t s_mvcol;
+ WORD32 i4_refidxcol;
+
+ if(ps_proc->ps_col_mb->u1_is_intra)
+ {
+ s_mvcol.i2_mvx = 0;
+ s_mvcol.i2_mvy = 0;
+ i4_refidxcol = -1;
+ }
+ else
+ {
+ if(ps_proc->ps_col_mb->as_pu->u1_pred_mode != L1)
+ {
+ s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L0].s_mv;
+ i4_refidxcol = 0;
+ }
+ else
+ {
+ s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L1].s_mv;
+ i4_refidxcol = 0;
+ }
+ }
+
+ /* RefPicList1[ 0 ] is marked as "used for short-term reference", as
+ * default */
+ i4_colzeroflag =
+ (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1) && (ABS(s_mvcol.i2_mvy) <= 1));
+ }
+
+ /***************************************************************************
+ * Evaluating skip params
+ **************************************************************************/
+ /* Section 8.4.1.2.2 */
+ ps_a_syn = ps_proc->s_nbr_info.ps_left_mb_info;
+ ps_a_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
+
+ ps_b_syn = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
+ ps_b_pu = ps_b_syn->as_pu;
+
+ i4_c_avail = 0;
+ if(ps_ngbr_avbl->u1_mb_c)
+ {
+ ps_c_syn = ps_b_syn + 1;
+ ps_c_pu = ps_c_syn->as_pu;
+ i4_c_avail = 1;
+ }
+ else
+ {
+ ps_c_syn = ps_b_syn - 1;
+ ps_c_pu = ps_c_syn->as_pu;
+ i4_c_avail = ps_ngbr_avbl->u1_mb_d;
+ }
+
+ i4_a = ps_ngbr_avbl->u1_mb_a;
+ i4_a &= !ps_a_syn->u1_is_intra;
+
+ i4_b = ps_ngbr_avbl->u1_mb_b;
+ i4_b &= !ps_b_syn->u1_is_intra;
+
+ i4_c = i4_c_avail;
+ i4_c &= !ps_c_syn->u1_is_intra;
+
+ /* Init to no mode avail */
+ i4_mode_avail = 0;
+ for(i = 0; i < 2; i++)
+ {
+ i4_cmpl_mode = (i == 0) ? L1 : L0;
+
+ i4_mode_avail |= (i4_a && (ps_a_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_a_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ i4_mode_avail |= (i4_b && (ps_b_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_b_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ i4_mode_avail |= (i4_c && (ps_c_pu->u1_pred_mode != i4_cmpl_mode) &&
+ (ps_c_pu->as_me_info[i].i1_ref_idx == 0))
+ << i;
+ }
+
+ /* Update skip MV for L0 */
+ if((i4_mode_avail & 0x1) && (!i4_colzeroflag))
+ {
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
+ }
+
+ /* Update skip MV for L1 */
+ if((i4_mode_avail & 0x2) && (!i4_colzeroflag))
+ {
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
+ }
+
+ /* Now see if the ME information matches the SKIP information */
+ switch(ps_proc->ps_mb_info->as_pu->u1_pred_mode)
+ {
+ case PRED_BI:
+ if((ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvx ==
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvy ==
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvx ==
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvy ==
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy) &&
+ (i4_mode_avail == 0x3 || i4_mode_avail == 0x0))
+ {
+ return 1;
+ }
+ break;
+
+ case PRED_L0:
+ if((ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvx ==
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvx) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvy ==
+ ps_proc->ps_skip_mv[0].s_mv.i2_mvy) &&
+ (i4_mode_avail == 0x1))
+ {
+ return 1;
+ }
+ break;
+
+ case PRED_L1:
+ if((ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvx ==
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvx) &&
+ (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvy ==
+ ps_proc->ps_skip_mv[1].s_mv.i2_mvy) &&
+ (i4_mode_avail == 0x2))
+ {
+ return 1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function computes the best motion vector among the tentative mv
+* candidates chosen.
+*
+* @par Description:
+* This function determines the position in the search window at which the
+*motion estimation should begin in order to minimise the number of search
+*iterations.
+*
+* @param[in] ps_mb_part
+* pointer to current mb partition ctxt with respect to ME
+*
+* @param[in] u4_lambda_motion
+* lambda motion
+*
+* @param[in] u4_fast_flag
+* enable/disable fast sad computation
+*
+* @returns mv pair & corresponding distortion and cost
+*
+* @remarks Currently onyl 4 search candiates are supported
+*
+*******************************************************************************
+*/
+void isvce_evaluate_bipred(isvce_me_ctxt_t *ps_me_ctxt, isvce_process_ctxt_t *ps_proc,
+ mb_part_ctxt *ps_mb_ctxt_bi)
+{
+ UWORD32 i, u4_fast_sad;
+
+ WORD32 i4_dest_buff;
+
+ mv_t *ps_l0_pred_mv, *ps_l1_pred_mv, s_l0_mv, s_l1_mv;
+
+ UWORD8 *pu1_ref_mb_l0, *pu1_ref_mb_l1;
+
+ UWORD8 *pu1_dst_buf;
+
+ WORD32 i4_ref_l0_stride, i4_ref_l1_stride;
+
+ WORD32 i4_mb_distortion, i4_mb_cost;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ u4_fast_sad = ps_me_ctxt->u4_enable_fast_sad;
+
+ i4_dest_buff = 0;
+ for(i = 0; i < ps_me_ctxt->u4_num_candidates[BI]; i += 2)
+ {
+ pu1_dst_buf = ps_me_ctxt->apu1_subpel_buffs[i4_dest_buff];
+
+ s_l0_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx >> 2;
+ s_l0_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy >> 2;
+ s_l1_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx >> 2;
+ s_l1_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy >> 2;
+
+ ps_l0_pred_mv = &ps_proc->ps_pred_mv[L0].s_mv;
+ ps_l1_pred_mv = &ps_proc->ps_pred_mv[L1].s_mv;
+
+ if((ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx & 0x3) ||
+ (ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy & 0x3))
+ {
+ pu1_ref_mb_l0 = ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf;
+ i4_ref_l0_stride = ps_me_ctxt->u4_subpel_buf_strd;
+ }
+ else
+ {
+ pu1_ref_mb_l0 = ps_me_ctxt->apu1_ref_buf_luma[L0] + (s_l0_mv.i2_mvx) +
+ ((s_l0_mv.i2_mvy) * ps_me_ctxt->ai4_rec_strd[L0]);
+ i4_ref_l0_stride = ps_me_ctxt->ai4_rec_strd[L0];
+ }
+
+ if((ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx & 0x3) ||
+ (ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy & 0x3))
+ {
+ pu1_ref_mb_l1 = ps_me_ctxt->as_mb_part[L1].pu1_best_hpel_buf;
+ i4_ref_l1_stride = ps_me_ctxt->u4_subpel_buf_strd;
+ }
+ else
+ {
+ pu1_ref_mb_l1 = ps_me_ctxt->apu1_ref_buf_luma[L1] + (s_l1_mv.i2_mvx) +
+ ((s_l1_mv.i2_mvy) * ps_me_ctxt->ai4_rec_strd[L1]);
+ i4_ref_l1_stride = ps_me_ctxt->ai4_rec_strd[L1];
+ }
+
+ ps_inter_pred_fxns->pf_inter_pred_luma_bilinear(
+ pu1_ref_mb_l0, pu1_ref_mb_l1, pu1_dst_buf, i4_ref_l0_stride, i4_ref_l1_stride,
+ ps_me_ctxt->u4_subpel_buf_strd, MB_SIZE, MB_SIZE);
+
+ ps_me_ctxt->pf_ime_compute_sad_16x16[u4_fast_sad](
+ ps_me_ctxt->pu1_src_buf_luma, pu1_dst_buf, ps_me_ctxt->i4_src_strd,
+ ps_me_ctxt->u4_subpel_buf_strd, INT_MAX, &i4_mb_distortion);
+
+ /* compute cost */
+ i4_mb_cost =
+ ps_me_ctxt
+ ->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx - ps_l0_pred_mv->i2_mvx];
+ i4_mb_cost +=
+ ps_me_ctxt
+ ->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy - ps_l0_pred_mv->i2_mvy];
+ i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx -
+ ps_l1_pred_mv->i2_mvx];
+ i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy -
+ ps_l1_pred_mv->i2_mvy];
+
+ i4_mb_cost -=
+ (ps_me_ctxt->i4_skip_bias[BSLICE]) * (ps_me_ctxt->i4_skip_type == BI) * (i == 0);
+
+ i4_mb_cost *= ps_me_ctxt->u4_lambda_motion;
+ i4_mb_cost += i4_mb_distortion;
+
+ if(i4_mb_cost < ps_mb_ctxt_bi->i4_mb_cost)
+ {
+ ps_mb_ctxt_bi->i4_srch_pos_idx = (i >> 1);
+ ps_mb_ctxt_bi->i4_mb_cost = i4_mb_cost;
+ ps_mb_ctxt_bi->i4_mb_distortion = i4_mb_distortion;
+ ps_mb_ctxt_bi->pu1_best_hpel_buf = pu1_dst_buf;
+ i4_dest_buff = (i4_dest_buff + 1) % 2;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs motion estimation for the current mb
+*
+* @par Description:
+* The current mb is compared with a list of mb's in the reference frame for
+* least cost. The mb that offers least cost is chosen as predicted mb and the
+* displacement of the predicted mb from index location of the current mb is
+* signaled as mv. The list of the mb's that are chosen in the reference frame
+* are dependent on the speed of the ME configured.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns motion vector of the pred mb, sad, cost.
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_compute_me_multi_reflist(isvce_process_ctxt_t *ps_proc)
+{
+ /* me ctxt */
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+
+ /* Temp variables for looping over ref lists */
+ WORD32 i4_reflist, i4_max_reflist;
+
+ /* source buffer for halp pel generation functions */
+ UWORD8 *pu1_hpel_src;
+
+ /* quantization parameters */
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+
+ /* Mb part ctxts for SKIP */
+ mb_part_ctxt as_skip_mbpart[2];
+
+ ASSERT(1 == MAX_REF_FRAMES_PER_PRED_DIR);
+
+ /* Sad therholds */
+ ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
+
+ {
+ WORD32 rows_above, rows_below, columns_left, columns_right;
+
+ /* During evaluation for motion vectors do not search through padded regions
+ */
+ /* Obtain number of rows and columns that are effective for computing for me
+ * evaluation */
+ rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
+ rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
+ columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
+ columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
+
+ /* init srch range */
+ /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X /
+ * 2 on all sides.
+ */
+ ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
+ ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
+ ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
+ ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
+
+ /* this is to facilitate fast sub pel computation with minimal loads */
+ if(ps_me_ctxt->u4_enable_hpel)
+ {
+ ps_me_ctxt->i4_srch_range_w += 1;
+ ps_me_ctxt->i4_srch_range_e -= 1;
+ ps_me_ctxt->i4_srch_range_n += 1;
+ ps_me_ctxt->i4_srch_range_s -= 1;
+ }
+ }
+
+ /* Compute ME and store the MVs */
+ {
+ /***********************************************************************
+ * Compute ME for lists L0 and L1
+ * For L0 -> L0 skip + L0
+ * for L1 -> L0 skip + L0 + L1 skip + L1
+ ***********************************************************************/
+ i4_max_reflist = (ps_proc->i4_slice_type == PSLICE) ? L0 : L1;
+
+ /* Init SATQD for the current list */
+ ps_me_ctxt->u4_min_sad_reached = 0;
+ ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
+
+ for(i4_reflist = L0; i4_reflist <= i4_max_reflist; i4_reflist++)
+ {
+ /* Get the seed motion vector candidates */
+ isvce_get_search_candidates(ps_proc, ps_me_ctxt, i4_reflist);
+
+ /* ****************************************************************
+ *Evaluate the SKIP for current list
+ * ****************************************************************/
+ as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx = 0;
+ as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy = 0;
+ as_skip_mbpart[i4_reflist].i4_mb_cost = INT_MAX;
+ as_skip_mbpart[i4_reflist].i4_mb_distortion = INT_MAX;
+
+ if(ps_me_ctxt->i4_skip_type == i4_reflist)
+ {
+ isvce_compute_skip_cost(
+ ps_me_ctxt, (ime_mv_t *) (&ps_proc->ps_skip_mv[i4_reflist].s_mv),
+ &as_skip_mbpart[i4_reflist], ps_codec->s_cfg.u4_enable_satqd, i4_reflist,
+ (ps_proc->i4_slice_type == BSLICE));
+ }
+
+ as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx <<= 2;
+ as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy <<= 2;
+
+ /******************************************************************
+ * Evaluate ME For current list
+ *****************************************************************/
+ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx = 0;
+ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy = 0;
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost = INT_MAX;
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion = INT_MAX;
+
+ /* Init Hpel */
+ ps_me_ctxt->as_mb_part[i4_reflist].pu1_best_hpel_buf = NULL;
+
+ /* In case we found out the minimum SAD, exit the ME eval */
+ if(ps_me_ctxt->u4_min_sad_reached)
+ {
+ i4_max_reflist = i4_reflist;
+ break;
+ }
+
+ /* Evaluate search candidates for initial mv pt */
+ isvce_evaluate_init_srchposn_16x16(ps_me_ctxt, i4_reflist);
+
+ /********************************************************************/
+ /* full pel motion estimation */
+ /********************************************************************/
+ isvce_full_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
+
+ DEBUG_MV_HISTOGRAM_ADD((ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvx >> 2),
+ (ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvy >> 2));
+
+ DEBUG_SAD_HISTOGRAM_ADD(ps_me_ctxt->s_mb_part.i4_mb_distortion, 1);
+
+ /* Scale the MV to qpel resolution */
+ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx <<= 2;
+ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy <<= 2;
+
+ if(ps_me_ctxt->u4_enable_hpel)
+ {
+ /* moving src pointer to the converged motion vector location */
+ pu1_hpel_src = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist] +
+ (ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx >> 2) +
+ ((ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy >> 2) *
+ ps_me_ctxt->ai4_rec_strd[i4_reflist]);
+
+ ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
+ ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
+ ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
+
+ /* Init the search position to an invalid number */
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_srch_pos_idx = 3;
+
+ /* Incase a buffer is still in use by L0, replace it with spare buff */
+ ps_me_ctxt->apu1_subpel_buffs[ps_me_ctxt->as_mb_part[L0].i4_srch_pos_idx] =
+ ps_proc->apu1_subpel_buffs[3];
+
+ ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
+
+ /* half pel search is done for both sides of full pel,
+ * hence half_x of width x height = 17x16 is created
+ * starting from left half_x of converged full pel */
+ pu1_hpel_src -= 1;
+
+ /* computing half_x */
+ ps_codec->pf_ih264e_sixtapfilter_horz(
+ pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[0],
+ ps_me_ctxt->ai4_rec_strd[i4_reflist], ps_me_ctxt->u4_subpel_buf_strd);
+
+ /*
+ * Halfpel search is done for both sides of full pel,
+ * hence half_y of width x height = 16x17 is created
+ * starting from top half_y of converged full pel
+ * for half_xy top_left is required
+ * hence it starts from pu1_hpel_src = full_pel_converged_point -
+ * i4_rec_strd - 1
+ */
+ pu1_hpel_src -= ps_me_ctxt->ai4_rec_strd[i4_reflist];
+
+ /* computing half_y and half_xy */
+ ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
+ pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1],
+ ps_me_ctxt->apu1_subpel_buffs[2], ps_me_ctxt->ai4_rec_strd[i4_reflist],
+ ps_me_ctxt->u4_subpel_buf_strd, ps_proc->ai16_pred1 + 3,
+ ps_me_ctxt->u4_subpel_buf_strd);
+
+ isvce_sub_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
+ }
+ }
+
+ /***********************************************************************
+ * If a particular skiip Mv is giving better sad, copy to the corresponding
+ * MBPART
+ * In B slices this loop should go only to PREDL1: If we found min sad
+ * we will go to the skip ref list only
+ * Have to find a way to make it without too much change or new vars
+ **********************************************************************/
+ for(i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
+ {
+ if(as_skip_mbpart[i4_reflist].i4_mb_cost <
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost)
+ {
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost =
+ as_skip_mbpart[i4_reflist].i4_mb_cost;
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion =
+ as_skip_mbpart[i4_reflist].i4_mb_distortion;
+ ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr = as_skip_mbpart[i4_reflist].s_mv_curr;
+ }
+ }
+
+ /***********************************************************************
+ * Compute ME for BI
+ * In case of BI we do ME for two candidates
+ * 1) The best L0 and L1 Mvs
+ * 2) Skip L0 and L1 MVs
+ *
+ * TODO
+ * one of the search candidates is skip. Hence it may be duplicated
+ ***********************************************************************/
+ if(i4_max_reflist == L1 && ps_me_ctxt->u4_min_sad_reached == 0)
+ {
+ WORD32 i, j = 0;
+ WORD32 l0_srch_pos_idx, l1_srch_pos_idx;
+ WORD32 i4_l0_skip_mv_idx, i4_l1_skip_mv_idx;
+
+ /* Get the free buffers */
+ l0_srch_pos_idx = ps_me_ctxt->as_mb_part[L0].i4_srch_pos_idx;
+ l1_srch_pos_idx = ps_me_ctxt->as_mb_part[L1].i4_srch_pos_idx;
+
+ /* Search for the two free buffers in subpel list */
+ for(i = 0; i < SUBPEL_BUFF_CNT; i++)
+ {
+ if(i != l0_srch_pos_idx && i != l1_srch_pos_idx)
+ {
+ ps_me_ctxt->apu1_subpel_buffs[j] = ps_proc->apu1_subpel_buffs[i];
+ j++;
+ }
+ }
+ ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
+
+ /* Copy the statial SKIP MV of each list */
+ i4_l0_skip_mv_idx = ps_me_ctxt->u4_num_candidates[L0] - 2;
+ i4_l1_skip_mv_idx = ps_me_ctxt->u4_num_candidates[L1] - 2;
+ ps_me_ctxt->as_mv_init_search[BI][0].i2_mvx =
+ ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvx << 2;
+ ps_me_ctxt->as_mv_init_search[BI][0].i2_mvy =
+ ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvy << 2;
+ ps_me_ctxt->as_mv_init_search[BI][1].i2_mvx =
+ ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvx << 2;
+ ps_me_ctxt->as_mv_init_search[BI][1].i2_mvy =
+ ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvy << 2;
+
+ /* Copy the SKIP MV temporal of each list */
+ i4_l0_skip_mv_idx++;
+ i4_l1_skip_mv_idx++;
+ ps_me_ctxt->as_mv_init_search[BI][2].i2_mvx =
+ ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvx << 2;
+ ps_me_ctxt->as_mv_init_search[BI][2].i2_mvy =
+ ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvy << 2;
+ ps_me_ctxt->as_mv_init_search[BI][3].i2_mvx =
+ ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvx << 2;
+ ps_me_ctxt->as_mv_init_search[BI][3].i2_mvy =
+ ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvy << 2;
+
+ /* Copy the best MV after ME */
+ ps_me_ctxt->as_mv_init_search[BI][4] = ps_me_ctxt->as_mb_part[L0].s_mv_curr;
+ ps_me_ctxt->as_mv_init_search[BI][5] = ps_me_ctxt->as_mb_part[L1].s_mv_curr;
+
+ ps_me_ctxt->u4_num_candidates[BI] = 6;
+
+ ps_me_ctxt->as_mb_part[BI].i4_mb_cost = INT_MAX;
+ ps_me_ctxt->as_mb_part[BI].i4_mb_distortion = INT_MAX;
+
+ isvce_evaluate_bipred(ps_me_ctxt, ps_proc, &ps_me_ctxt->as_mb_part[BI]);
+
+ i4_max_reflist = BI;
+ }
+
+ /**********************************************************************
+ * Now get the minimum of MB part sads by searching over all ref lists
+ **********************************************************************/
+ ps_proc->ps_mb_info->as_pu->u1_pred_mode = 0x3;
+
+ for(i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
+ {
+ if(ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost < ps_proc->ps_cur_mb->i4_mb_cost)
+ {
+ ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost;
+ ps_proc->ps_cur_mb->i4_mb_distortion =
+ ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion;
+ ps_proc->ps_cur_mb->u4_mb_type =
+ (ps_proc->i4_slice_type == PSLICE) ? P16x16 : B16x16;
+ ps_proc->ps_mb_info->as_pu->u1_pred_mode = i4_reflist;
+ }
+ }
+
+ /**********************************************************************
+ * In case we have a BI MB, we have to copy the buffers and set proer MV's
+ * 1)In case its BI, we need to get the best MVs given by BI and update
+ * to their corresponding MB part
+ * 2)We also need to copy the buffer in which bipred buff is populated
+ *
+ * Not that if we have
+ **********************************************************************/
+ if(ps_proc->ps_mb_info->as_pu->u1_pred_mode == BI)
+ {
+ WORD32 i4_srch_pos = ps_me_ctxt->as_mb_part[BI].i4_srch_pos_idx;
+ UWORD8 *pu1_bi_buf = ps_me_ctxt->as_mb_part[BI].pu1_best_hpel_buf;
+
+ ps_me_ctxt->as_mb_part[L0].s_mv_curr =
+ ps_me_ctxt->as_mv_init_search[BI][i4_srch_pos << 1];
+ ps_me_ctxt->as_mb_part[L1].s_mv_curr =
+ ps_me_ctxt->as_mv_init_search[BI][(i4_srch_pos << 1) + 1];
+
+ /* Now we have to copy the buffers */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(
+ pu1_bi_buf, ps_proc->pu1_best_subpel_buf, ps_me_ctxt->u4_subpel_buf_strd,
+ ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL, 0);
+ }
+ else if(ps_me_ctxt->as_mb_part[ps_proc->ps_mb_info->as_pu->u1_pred_mode].pu1_best_hpel_buf)
+ {
+ /* Now we have to copy the buffers */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy(
+ ps_me_ctxt->as_mb_part[ps_proc->ps_mb_info->as_pu->u1_pred_mode].pu1_best_hpel_buf,
+ ps_proc->pu1_best_subpel_buf, ps_me_ctxt->u4_subpel_buf_strd,
+ ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL, 0);
+ }
+ }
+
+ /**************************************************************************
+ *Now copy the MVs to the current PU with qpel scaling
+ ***************************************************************************/
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx =
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx);
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy =
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy);
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx =
+ (ps_me_ctxt->as_mb_part[L1].s_mv_curr.i2_mvx);
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy =
+ (ps_me_ctxt->as_mb_part[L1].s_mv_curr.i2_mvy);
+
+ ps_proc->ps_mb_info->as_pu->as_me_info[0].i1_ref_idx =
+ (ps_proc->ps_mb_info->as_pu->u1_pred_mode != L1) ? 0 : -1;
+ ps_proc->ps_mb_info->as_pu->as_me_info[1].i1_ref_idx =
+ (ps_proc->ps_mb_info->as_pu->u1_pred_mode != L0) ? 0 : -1;
+
+ /* number of partitions */
+ ps_proc->u4_num_sub_partitions = 1;
+ *(ps_proc->pu4_mb_pu_cnt) = 1;
+
+ /* position in-terms of PU */
+ ps_proc->ps_mb_info->as_pu->u1_pos_x_in_4x4 = 0;
+ ps_proc->ps_mb_info->as_pu->u1_pos_y_in_4x4 = 0;
+
+ /* PU size */
+ ps_proc->ps_mb_info->as_pu->u1_wd_in_4x4_m1 = 3;
+ ps_proc->ps_mb_info->as_pu->u1_ht_in_4x4_m1 = 3;
+
+ /* Update min sad conditions */
+ if(ps_me_ctxt->u4_min_sad_reached == 1)
+ {
+ ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
+ ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
+ }
+}
diff --git a/encoder/svc/isvce_me.h b/encoder/svc/isvce_me.h
new file mode 100644
index 0000000..06e3b22
--- /dev/null
+++ b/encoder/svc/isvce_me.h
@@ -0,0 +1,381 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+ *******************************************************************************
+ * @file
+ * isvce_me.h
+ *
+ * @brief
+ * Contains declarations of global variables for H264 encoder
+ *
+ * @author
+ * ittiam
+ *
+ * @remarks
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCE_ME_H_
+#define _ISVCE_ME_H_
+
+#include "ih264_typedefs.h"
+
+#include "isvce_structs.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+* @brief Skip Bias value for P slice
+******************************************************************************
+*/
+#define SKIP_BIAS_P 0
+
+/**
+******************************************************************************
+* @brief Skip Bias value for B slice
+******************************************************************************
+*/
+#define SKIP_BIAS_B 0
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+
+/**
+ ******************************************************************************
+ * @brief compute median of 3 elements (a, b, c) and store the output
+ * in to result. This is used for mv prediction
+ ******************************************************************************
+ */
+
+#define MEDIAN(a, b, c, result) \
+ if(a > b) \
+ { \
+ if(b > c) \
+ result = b; \
+ else \
+ { \
+ if(a > c) \
+ result = c; \
+ else \
+ result = a; \
+ } \
+ } \
+ else \
+ { \
+ if(c > b) \
+ result = b; \
+ else \
+ { \
+ if(c > a) \
+ result = c; \
+ else \
+ result = a; \
+ } \
+ }
+
+/*****************************************************************************/
+/* Extern Function Declarations */
+/*****************************************************************************/
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * This function populates the length of the codewords for motion vectors in
+ *the range (-search range, search range) in pixels
+ *
+ * @param[in] ps_me
+ * Pointer to me ctxt
+ *
+ * @param[out] pu1_mv_bits
+ * length of the codeword for all mv's
+ *
+ * @remarks The length of the code words are derived from signed exponential
+ * goloumb codes.
+ *
+ *******************************************************************************
+ */
+void isvce_init_mv_bits(isvce_me_ctxt_t *ps_me);
+
+/**
+ *******************************************************************************
+ *
+ * @brief The function computes the parameters for a P skip MB
+ *
+ * @par Description:
+ * The function computes the parameters for a P skip MB
+ *
+ * @param[in] ps_proc
+ * Process context
+ *
+ * @param[in] u4_for_me
+ * Flag to indicate the purpose of computing skip
+ *
+ * @param[out] ps_pred_mv
+ * Flag to indicate the current active refernce list
+ *
+ * @returns
+ * 1) Updates skip MV in proc
+ * 2) Returns if the current MB can be coded as skip or not
+ *
+ * @remarks The code implements the logic as described in sec 8.4.1.1 in H264
+ * specification.
+ *
+ *******************************************************************************
+ */
+FT_FIND_SKIP_PARAMS isvce_find_pskip_params;
+
+/**
+ *******************************************************************************
+ *
+ * @brief The function computes the parameters for a P skip MB
+ *
+ * @par Description:
+ * The function computes the parameters for a P skip MB
+ *
+ * @param[in] ps_proc
+ * Process context
+ *
+ * @param[in] u4_for_me
+ * Flag to indicate the purpose of computing skip
+ *
+ * @param[out] ps_pred_mv
+ * Flag to indicate the current active refernce list
+ *
+ * @returns
+ * 1) Updates skip MV in proc
+ * 2) Returns if the current MB can be coded as skip or not
+ *
+ * @remarks The code implements the logic as described in sec 8.4.1.1 in H264
+ * specification.
+ *
+ *******************************************************************************
+ */
+FT_FIND_SKIP_PARAMS isvce_find_pskip_params_me;
+
+/**
+ *******************************************************************************
+ *
+ * @brief The function computes the parameters for a B skip MB
+ *
+ * @par Description:
+ * The function computes the parameters for a B skip MB
+ *
+ * @param[in] ps_proc
+ * Process context
+ *
+ * @param[in] u4_for_me
+ * Flag to indicate the purpose of computing skip
+ *
+ * @param[out] ps_pred_mv
+ * Flag to indicate the current active refernce list
+ *
+ * @returns
+ * 1) Updates skip MV in proc
+ * 2) Returns if the current MB can be coded as skip or not
+ *
+ * @remarks The code implements the logic as described in sec 8.4.1.1 in H264
+ * specification.
+ *
+ *******************************************************************************
+ */
+FT_FIND_SKIP_PARAMS isvce_find_bskip_params;
+
+/**
+ *******************************************************************************
+ *
+ * @brief The function computes the parameters for a B skip MB
+ *
+ * @par Description:
+ * The function computes the parameters for a B skip MB
+ *
+ * @param[in] ps_proc
+ * Process context
+ *
+ * @param[in] u4_for_me
+ * Flag to indicate the purpose of computing skip
+ *
+ * @param[out] ps_pred_mv
+ * Flag to indicate the current active refernce list
+ *
+ * @returns
+ * 1) Updates skip MV in proc
+ * 2) The type of SKIP [L0/L1/BI]
+ *
+ * @remarks
+ *******************************************************************************
+ */
+FT_FIND_SKIP_PARAMS isvce_find_bskip_params_me;
+
+/**
+ *******************************************************************************
+ *
+ * @brief motion vector predictor
+ *
+ * @par Description:
+ * The routine calculates the motion vector predictor for a given block,
+ * given the candidate MV predictors.
+ *
+ * @param[in] ps_left_mb_pu
+ * pointer to left mb motion vector info
+ *
+ * @param[in] ps_top_row_pu
+ * pointer to top & top right mb motion vector info
+ *
+ * @param[out] ps_pred_mv
+ * pointer to candidate predictors for the current block
+ *
+ * @returns The x & y components of the MV predictor.
+ *
+ * @remarks The code implements the logic as described in sec 8.4.1.3 in H264
+ * specification.
+ * Assumptions : 1. Assumes Only partition of size 16x16
+ *
+ *******************************************************************************
+ */
+void isvce_get_mv_predictor(isvce_enc_pu_mv_t *ps_pred_mv, isvce_enc_pu_mv_t *ps_neig_mv,
+ WORD32 pred_algo);
+
+/**
+ *******************************************************************************
+ *
+ * @brief This fucntion evalues ME for 2 reference lists
+ *
+ * @par Description:
+ * It evaluates skip, full-pel an half-pel and assigns the correct MV in proc
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+FT_ME_ALGORITHM isvce_compute_me_multi_reflist;
+
+/**
+ *******************************************************************************
+ *
+ * @brief This fucntion evalues ME for single reflist [Pred L0]
+ *
+ * @par Description:
+ * It evaluates skip, full-pel an half-pel and assigns the correct MV in proc
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+FT_ME_ALGORITHM isvce_compute_me_single_reflist;
+
+/**
+ *******************************************************************************
+ *
+ * @brief This function initializes me ctxt
+ *
+ * @par Description:
+ * Before dispatching the current job to me thread, the me context associated
+ * with the job is initialized.
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns none
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvce_init_me(isvce_process_ctxt_t *ps_proc);
+
+/**
+ *******************************************************************************
+ *
+ * @brief This function performs motion estimation for the current NMB
+ *
+ * @par Description:
+ * Intializes input and output pointers required by the function
+ *isvce_compute_me and calls the function isvce_compute_me in a loop to
+ *process NMBs.
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns
+ *
+ * @remarks none
+ *
+ *******************************************************************************
+ */
+void isvce_compute_me_nmb(isvce_process_ctxt_t *ps_proc, UWORD32 u4_nmb_count);
+
+/**
+ *******************************************************************************
+ *
+ * @brief This function performs MV prediction
+ *
+ * @par Description:
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns none
+ *
+ * @remarks none
+ * This function will update the MB availability since intra inter decision
+ * should be done before the call
+ *
+ *******************************************************************************
+ */
+void isvce_mv_pred(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist);
+
+/**
+ *******************************************************************************
+ *
+ * @brief This function approximates Pred. MV
+ *
+ * @par Description:
+ *
+ * @param[in] ps_proc
+ * Process context corresponding to the job
+ *
+ * @returns none
+ *
+ * @remarks none
+ * Motion estimation happens at nmb level. For cost calculations, mv is appro
+ * ximated using this function
+ *
+ *******************************************************************************
+ */
+void isvce_mv_pred_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_ref_list);
+
+#endif
diff --git a/encoder/svc/isvce_mode_stat_visualiser.c b/encoder/svc/isvce_mode_stat_visualiser.c
new file mode 100644
index 0000000..ed4a1f2
--- /dev/null
+++ b/encoder/svc/isvce_mode_stat_visualiser.c
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_mode_stat_visualiser.c
+*
+* @brief
+* Contains functions used for synthesising analysis YUV
+*
+*******************************************************************************
+*/
+#include "isvce_defs.h"
+
+#if ENABLE_MODE_STAT_VISUALISER
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_fmt_conv.h"
+#include "isvce_mode_stat_visualiser.h"
+
+#define MAX_NUM_MB_MODE_VISUALISATIONS 1
+
+static const UWORD8 gau1_output_file_path[] = "out.yuv";
+
+static const double gd_alpha = 0.5;
+
+static const UWORD8 gau1_colors[MAX_NUM_MB_MODE_VISUALISATIONS][NUM_COMPONENTS] = {
+ /* Red */
+ {81, 90, 240},
+};
+
+UWORD32 isvce_get_msv_ctxt_size(UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 u4_size = sizeof(mode_stat_visualiser_t);
+ WORD32 i4_num_luma_samples = u4_wd * u4_ht;
+ WORD32 i4_num_chroma_samples = i4_num_luma_samples / 4;
+
+ u4_size += (i4_num_luma_samples + i4_num_chroma_samples * 2) * sizeof(UWORD8);
+
+ return u4_size;
+}
+
+void isvce_msv_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ mode_stat_visualiser_t *ps_mode_stat_visualiser;
+ yuv_buf_props_t *ps_frame_buf;
+
+ WORD32 i;
+
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ WORD32 i4_num_luma_samples = u4_wd * u4_ht;
+ WORD32 i4_num_chroma_samples = i4_num_luma_samples / 4;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size = isvce_get_msv_ctxt_size(u4_wd, u4_ht);
+
+ ps_mode_stat_visualiser = ps_codec->ps_mode_stat_visualiser =
+ (mode_stat_visualiser_t *) pu1_buf;
+ pu1_buf += sizeof(ps_mode_stat_visualiser[0]);
+ i8_alloc_mem_size -= sizeof(ps_mode_stat_visualiser[0]);
+
+ ps_frame_buf = &ps_mode_stat_visualiser->s_frame_buf;
+
+ ps_mode_stat_visualiser->ps_output_file = fopen((const char *) gau1_output_file_path, "w");
+
+ ps_frame_buf->e_color_format = IV_YUV_420P;
+ ps_frame_buf->u1_bit_depth = 8;
+ ps_frame_buf->u4_width = u4_wd;
+ ps_frame_buf->u4_height = u4_ht;
+
+ for(i = 0; i < NUM_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (((COMPONENT_TYPE) i) != Y);
+ UWORD32 u4_buf_size = u1_is_chroma ? i4_num_chroma_samples : i4_num_luma_samples;
+ UWORD32 u4_stride = u4_wd >> u1_is_chroma;
+
+ ps_frame_buf->as_component_bufs[i].pv_data = pu1_buf;
+ ps_frame_buf->as_component_bufs[i].i4_data_stride = u4_stride;
+
+ pu1_buf += u4_buf_size;
+ i8_alloc_mem_size -= u4_buf_size;
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+}
+
+void isvce_msv_ctxt_delete(mode_stat_visualiser_t *ps_mode_stat_visualiser)
+{
+ fclose(ps_mode_stat_visualiser->ps_output_file);
+}
+
+void isvce_msv_get_input_frame(mode_stat_visualiser_t *ps_mode_stat_visualiser,
+ isvce_inp_buf_t *ps_inp_buf)
+{
+ svc_params_t *ps_svc_params = &ps_inp_buf->s_svc_params;
+ yuv_buf_props_t *ps_target_layer_yuv_buf =
+ &ps_inp_buf->as_layer_yuv_buf_props[ps_svc_params->u1_num_spatial_layers - 1];
+ yuv_buf_props_t *ps_frame_buf = &ps_mode_stat_visualiser->s_frame_buf;
+
+ ASSERT(ps_target_layer_yuv_buf->u4_width == ps_frame_buf->u4_width);
+ ASSERT(ps_target_layer_yuv_buf->u4_height == ps_frame_buf->u4_height);
+ ASSERT(ps_target_layer_yuv_buf->u1_bit_depth == ps_frame_buf->u1_bit_depth);
+ ASSERT(ps_target_layer_yuv_buf->e_color_format == IV_YUV_420SP_UV);
+ ASSERT(ps_frame_buf->u1_bit_depth == IV_YUV_420P);
+ ASSERT(ps_target_layer_yuv_buf->as_component_bufs[U].i4_data_stride ==
+ ps_target_layer_yuv_buf->as_component_bufs[V].i4_data_stride);
+
+ isvce_fmt_conv_420sp_to_420p(
+ ps_target_layer_yuv_buf->as_component_bufs[Y].pv_data,
+ ps_target_layer_yuv_buf->as_component_bufs[UV].pv_data,
+ ps_frame_buf->as_component_bufs[Y].pv_data, ps_frame_buf->as_component_bufs[U].pv_data,
+ ps_frame_buf->as_component_bufs[V].pv_data, ps_frame_buf->u4_width, ps_frame_buf->u4_height,
+ ps_target_layer_yuv_buf->as_component_bufs[Y].i4_data_stride,
+ ps_target_layer_yuv_buf->as_component_bufs[UV].i4_data_stride,
+ ps_frame_buf->as_component_bufs[Y].i4_data_stride,
+ ps_frame_buf->as_component_bufs[U].i4_data_stride, 1, 0);
+}
+
+void isvce_msv_set_mode(mode_stat_visualiser_t *ps_mode_stat_visualiser,
+ isvce_mb_info_t *ps_mb_info, coordinates_t *ps_mb_pos)
+{
+ UWORD32 i, j, k;
+
+ for(i = 0; i < NUM_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (((COMPONENT_TYPE) i) != Y);
+ UWORD32 u4_wd = MB_SIZE >> u1_is_chroma;
+ UWORD32 u4_ht = MB_SIZE >> u1_is_chroma;
+ UWORD8 *pu1_buf = ps_mode_stat_visualiser->s_frame_buf.as_component_bufs[i].pv_data;
+ WORD32 i4_stride = ps_mode_stat_visualiser->s_frame_buf.as_component_bufs[i].i4_data_stride;
+
+ pu1_buf += ps_mb_pos->i4_abscissa * u4_wd + ps_mb_pos->i4_ordinate * u4_ht * i4_stride;
+
+ for(j = 0; j < u4_ht; j++)
+ {
+ for(k = 0; k < u4_wd; k++)
+ {
+ if(ps_mb_info->u1_residual_prediction_flag)
+ {
+ pu1_buf[k + j * i4_stride] =
+ (UWORD8) (gd_alpha * gau1_colors[0][i] +
+ (1. - gd_alpha) * pu1_buf[k + j * i4_stride] + 0.5);
+ }
+ }
+ }
+ }
+}
+
+void isvce_msv_dump_visualisation(mode_stat_visualiser_t *ps_mode_stat_visualiser)
+{
+ WORD32 i;
+
+ FILE *ps_output_file = ps_mode_stat_visualiser->ps_output_file;
+ yuv_buf_props_t *ps_frame_buf = &ps_mode_stat_visualiser->s_frame_buf;
+
+ for(i = 0; i < NUM_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (((COMPONENT_TYPE) i) != Y);
+ UWORD32 u4_wd = ps_frame_buf->u4_width >> u1_is_chroma;
+ UWORD32 u4_ht = ps_frame_buf->u4_height >> u1_is_chroma;
+ UWORD32 u4_size = u4_wd * u4_ht;
+
+ ASSERT(u4_wd == ps_frame_buf->as_component_bufs[i].i4_data_stride);
+
+ fwrite(ps_frame_buf->as_component_bufs[i].pv_data, sizeof(UWORD8), u4_size, ps_output_file);
+ }
+}
+#endif
diff --git a/encoder/svc/isvce_mode_stat_visualiser.h b/encoder/svc/isvce_mode_stat_visualiser.h
new file mode 100644
index 0000000..3a01589
--- /dev/null
+++ b/encoder/svc/isvce_mode_stat_visualiser.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_mode_stat_visualiser.h
+*
+* @brief
+* Contains function declarations for function declared in
+* isvce_mode_stat_visualiser.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_MODE_STAT_VISUALISER_H_
+#define _ISVCE_MODE_STAT_VISUALISER_H_
+#if ENABLE_MODE_STAT_VISUALISER
+
+#include <stdio.h>
+
+#include "ih264_typedefs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+
+typedef struct mode_stat_visualiser_t
+{
+ FILE *ps_output_file;
+
+ yuv_buf_props_t s_frame_buf;
+
+} mode_stat_visualiser_t;
+
+extern UWORD32 isvce_get_msv_ctxt_size(UWORD32 u4_wd, UWORD32 u4_ht);
+
+extern void isvce_msv_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_msv_ctxt_delete(mode_stat_visualiser_t *ps_mode_stat_visualiser);
+
+extern void isvce_msv_get_input_frame(mode_stat_visualiser_t *ps_mode_stat_visualiser,
+ isvce_inp_buf_t *ps_inp_buf);
+
+extern void isvce_msv_dump_visualisation(mode_stat_visualiser_t *ps_mode_stat_visualiser);
+
+extern void isvce_msv_set_mode(mode_stat_visualiser_t *ps_mode_stat_visualiser,
+ isvce_mb_info_t *ps_mb_info, coordinates_t *ps_mb_pos);
+#endif
+
+#endif
diff --git a/encoder/svc/isvce_nalu_stat_aggregator.c b/encoder/svc/isvce_nalu_stat_aggregator.c
new file mode 100644
index 0000000..eabdd63
--- /dev/null
+++ b/encoder/svc/isvce_nalu_stat_aggregator.c
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_nalu_stat_aggregator.c
+*
+* @brief
+* Contains objects used for aggregating nalu statistics
+*
+*******************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvce_structs.h"
+#include "isvce_nalu_stat_aggregator.h"
+
+void isvce_nalu_info_au_init(nalu_descriptors_t *ps_nalu_descriptor, UWORD8 u1_num_spatial_layers)
+{
+ WORD32 i;
+
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ ps_nalu_descriptor[i].u1_num_nalus = 0;
+ }
+}
+
+void isvce_nalu_info_csv_translator(nalu_descriptors_t *ps_nalu_descriptor,
+ isvce_nalu_info_buf_t *ps_csv_buf)
+{
+ char ac_csv_string[MAX_BYTES_PER_NALU_INFO];
+ WORD32 i;
+
+ WORD64 i8_num_bytes_available = ps_csv_buf->u4_buf_size - ps_csv_buf->u4_num_bytes;
+
+ for(i = 0; i < ps_nalu_descriptor->u1_num_nalus; i++)
+ {
+ if(ps_nalu_descriptor->as_nalu_info[i].b_is_vcl_nal)
+ {
+ snprintf(ac_csv_string, MAX_BYTES_PER_NALU_INFO, "%d,%u,%d,%d,%d,%d,%d\n",
+ ps_nalu_descriptor->as_nalu_info[i].e_nalu_type,
+ (UWORD32) (ps_nalu_descriptor->as_nalu_info[i].i8_num_bits / 8),
+ ps_nalu_descriptor->as_nalu_info[i].u1_spatial_layer_id,
+ ps_nalu_descriptor->as_nalu_info[i].u1_temporal_layer_id,
+ ps_nalu_descriptor->as_nalu_info[i].b_is_idr, 1, 1);
+ }
+ else
+ {
+ snprintf(ac_csv_string, MAX_BYTES_PER_NALU_INFO, "%d,%u,%d,%d,%d,%d,%d\n",
+ ps_nalu_descriptor->as_nalu_info[i].e_nalu_type,
+ (UWORD32) (ps_nalu_descriptor->as_nalu_info[i].i8_num_bits / 8), -1, -1, -1,
+ -1, -1);
+ }
+
+ snprintf((char *) (ps_csv_buf->pu1_buf + ps_csv_buf->u4_num_bytes), i8_num_bytes_available,
+ "%s", ac_csv_string);
+
+ ps_csv_buf->u4_num_bytes = (UWORD32) strlen((char *) ps_csv_buf->pu1_buf);
+ i8_num_bytes_available = ps_csv_buf->u4_buf_size - ps_csv_buf->u4_num_bytes;
+
+ ASSERT(i8_num_bytes_available >= 0);
+ }
+}
+
+nalu_info_t *isvce_get_next_nalu_info_buf(nalu_descriptors_t *ps_nalu_descriptor)
+{
+ return &ps_nalu_descriptor->as_nalu_info[ps_nalu_descriptor->u1_num_nalus];
+}
+
+void isvce_nalu_info_buf_init(nalu_info_t *ps_nalu_info, WORD64 i8_init_bits,
+ NAL_UNIT_TYPE_T e_nalu_type, UWORD8 u1_spatial_layer_id,
+ UWORD8 u1_temporal_layer_id, UWORD8 u1_num_slices, bool b_is_idr)
+{
+ ps_nalu_info->e_nalu_type = e_nalu_type;
+ ps_nalu_info->i8_num_bits = i8_init_bits;
+ ps_nalu_info->b_is_idr = b_is_idr;
+
+ switch(e_nalu_type)
+ {
+ case NAL_SLICE_NON_IDR:
+ case NAL_SLICE_IDR:
+ case NAL_CODED_SLICE_EXTENSION:
+ {
+ ps_nalu_info->b_is_vcl_nal = true;
+ ps_nalu_info->u1_spatial_layer_id = u1_spatial_layer_id;
+ ps_nalu_info->u1_temporal_layer_id = u1_temporal_layer_id;
+ ps_nalu_info->u1_num_slices = u1_num_slices;
+
+ break;
+ }
+ default:
+ {
+ ps_nalu_info->b_is_vcl_nal = false;
+
+ break;
+ }
+ }
+}
+
+void isvce_update_nalu_count(nalu_descriptors_t *ps_nalu_descriptor)
+{
+ ps_nalu_descriptor->u1_num_nalus++;
+}
diff --git a/encoder/svc/isvce_nalu_stat_aggregator.h b/encoder/svc/isvce_nalu_stat_aggregator.h
new file mode 100644
index 0000000..b235218
--- /dev/null
+++ b/encoder/svc/isvce_nalu_stat_aggregator.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_nalu_stat_aggregator.h
+*
+* @brief
+* Contains objects used for aggregating nalu statistics
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_NALU_STAT_AGGREGATOR_H_
+#define _ISVCE_NALU_STAT_AGGREGATOR_H_
+
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+#include "isvce.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+
+/* Macros */
+/* +1 for '\0' */
+#define MAX_BYTES_PER_NALU_INFO (45 + 1)
+
+/* SPS + (MAX_NUM_SPATIAL_LAYERS - 1) * SUBSET_SPS +
+ * MAX_NUM_SPATIAL_LAYERS * PPS + */
+/* 1 PREFIX_NALU + 1 SLICE_[NON|]IDR + (MAX_NUM_SPATIAL_LAYERS - 1) *
+ * CODED_SLICE_EXTENSION */
+#define MAX_NALU_PER_LAYER 10
+
+/* Structs */
+typedef struct nalu_info_t
+{
+ NAL_UNIT_TYPE_T e_nalu_type;
+
+ WORD64 i8_num_bits;
+
+ bool b_is_vcl_nal;
+
+ bool b_is_idr;
+
+ UWORD8 u1_spatial_layer_id;
+
+ UWORD8 u1_temporal_layer_id;
+
+ UWORD8 u1_num_slices;
+} nalu_info_t;
+
+typedef struct nalu_descriptors_t
+{
+ nalu_info_t as_nalu_info[MAX_NALU_PER_LAYER];
+
+ UWORD8 u1_num_nalus;
+
+} nalu_descriptors_t;
+
+/* Function declarations */
+static FORCEINLINE UWORD32 isvce_get_nalu_info_buf_size(UWORD8 u1_num_spatial_layers)
+{
+ return MAX_NALU_PER_LAYER * u1_num_spatial_layers * MAX_BYTES_PER_NALU_INFO;
+}
+
+extern void isvce_nalu_info_au_init(nalu_descriptors_t *ps_nalu_descriptor,
+ UWORD8 u1_num_spatial_layers);
+
+extern void isvce_nalu_info_csv_translator(nalu_descriptors_t *ps_nalu_descriptor,
+ isvce_nalu_info_buf_t *ps_csv_buf);
+
+extern nalu_info_t *isvce_get_next_nalu_info_buf(nalu_descriptors_t *ps_nalu_descriptor);
+
+extern void isvce_nalu_info_buf_init(nalu_info_t *ps_nalu_info, WORD64 i8_init_bytes,
+ NAL_UNIT_TYPE_T e_nalu_type, UWORD8 u1_spatial_layer_id,
+ UWORD8 u1_temporal_layer_id, UWORD8 u1_num_slices,
+ bool b_is_idr);
+
+extern void isvce_update_nalu_count(nalu_descriptors_t *ps_nalu_descriptor);
+
+#endif
diff --git a/encoder/svc/isvce_pred_structs.h b/encoder/svc/isvce_pred_structs.h
new file mode 100644
index 0000000..9e255d9
--- /dev/null
+++ b/encoder/svc/isvce_pred_structs.h
@@ -0,0 +1,156 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_pred_structs.h
+*
+* @brief
+* Contains struct definition used for prediction
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_PRED_STRUCTS_H_
+#define _ISVCE_PRED_STRUCTS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_defs.h"
+
+/**
+ * PU information
+ */
+typedef struct
+{
+ /**
+ * Motion Vector
+ */
+ mv_t s_mv;
+
+ /**
+ * Ref index
+ */
+ WORD8 i1_ref_idx;
+
+} isvce_enc_pu_mv_t;
+
+/*
+ * Total Pu info for an MB
+ */
+typedef struct isvce_enc_pu_t
+{
+ /* Array with ME info for all lists */
+ isvce_enc_pu_mv_t as_me_info[NUM_PRED_DIRS];
+
+ UWORD8 au1_mvp_idx[NUM_PRED_DIRS];
+
+ /**
+ * PU X position in terms of min PU (4x4) units
+ */
+ UWORD8 u1_pos_x_in_4x4;
+
+ /**
+ * PU Y position in terms of min PU (4x4) units
+ */
+ UWORD8 u1_pos_y_in_4x4;
+
+ /**
+ * PU width in pixels = (u1_wd_in_4x4_m1 + 1) << 2
+ */
+ UWORD8 u1_wd_in_4x4_m1;
+
+ /**
+ * PU height in pixels = (u1_ht_in_4x4_m1 + 1) << 2
+ */
+ UWORD8 u1_ht_in_4x4_m1;
+
+ /**
+ * PRED_L0, PRED_L1, PRED_BI
+ */
+ UWORD8 u1_pred_mode;
+
+} isvce_enc_pu_t;
+
+typedef struct intra4x4_mode_data_t
+{
+ UWORD8 u1_predicted_mode;
+
+ UWORD8 u1_mode;
+
+} intra4x4_mode_data_t;
+
+typedef intra4x4_mode_data_t intra8x8_mode_data_t;
+
+typedef struct intra16x16_mode_data_t
+{
+ UWORD8 u1_mode;
+
+} intra16x16_mode_data_t;
+
+typedef struct enc_intra_pu_t
+{
+ intra4x4_mode_data_t as_i4x4_mode_data[MAX_TU_IN_MB];
+
+ intra8x8_mode_data_t as_i8x8_mode_data[MIN_TU_IN_MB];
+
+ intra16x16_mode_data_t s_i16x16_mode_data;
+
+ UWORD8 u1_chroma_intra_mode;
+
+} enc_intra_pu_t;
+
+typedef struct isvce_mb_info_t
+{
+ isvce_enc_pu_t as_pu[ENC_MAX_PU_IN_MB];
+
+ enc_intra_pu_t s_intra_pu;
+
+ UWORD32 u4_cbp;
+
+ UWORD32 u4_csbp;
+
+ UWORD32 u4_res_csbp;
+
+ UWORD16 u2_mb_type;
+
+ WORD32 i4_mb_distortion;
+
+ UWORD8 u1_base_mode_flag;
+
+ UWORD8 u1_residual_prediction_flag;
+
+ UWORD8 u1_tx_size;
+
+ UWORD8 u1_mb_qp;
+
+ UWORD8 u1_is_intra;
+
+} isvce_mb_info_t;
+
+#endif
diff --git a/encoder/svc/isvce_process.c b/encoder/svc/isvce_process.c
new file mode 100644
index 0000000..5aafff7
--- /dev/null
+++ b/encoder/svc/isvce_process.c
@@ -0,0 +1,2787 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_process.c
+*
+* @brief
+* Contains functions for codec thread
+*
+* @author
+* Harish
+*
+* @par List of Functions:
+* - isvce_generate_sps_pps()
+* - isvce_init_entropy_ctxt()
+* - isvce_entropy()
+* - isvce_pack_header_data()
+* - isvce_update_proc_ctxt()
+* - isvce_init_proc_ctxt()
+* - isvce_pad_recon_buffer()
+* - isvce_dblk_n_mbs()
+* - isvce_process()
+* - isvce_set_rc_pic_params()
+* - isvce_update_rc_post_enc()
+* - isvce_isvce_isvce_process_ctxt_thread()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "ih264_typedefs.h"
+/* Dependencies of ih264_buf_mgr.h */
+/* Dependencies of ih264_list.h */
+#include "ih264_error.h"
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_common_tables.h"
+#include "ih264_list.h"
+#include "ih264_platform_macros.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+/* Dependencies of ih264e_structs.h */
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "ime_statistics.h"
+#include "ime_structs.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_defs.h"
+#include "ih264e_structs.h"
+#include "ih264e_utils.h"
+#include "ime.h"
+#include "isvce_cabac.h"
+#include "isvce_cavlc.h"
+#include "isvce_deblk.h"
+#include "isvce_defs.h"
+#include "isvce_downscaler.h"
+#include "isvce_encode_header.h"
+#include "isvce_ibl_eval.h"
+#include "isvce_ilp_mv.h"
+#include "isvce_intra_modes_eval.h"
+#include "isvce_me.h"
+#include "isvce_rate_control.h"
+#include "isvce_residual_pred.h"
+#include "isvce_sub_pic_rc.h"
+#include "isvce_utils.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief This function generates sps, pps set on request
+*
+* @par Description
+* When the encoder is set in header generation mode, the following function
+* is called. This generates sps and pps headers and returns the control back
+* to caller.
+*
+* @param[in] ps_codec
+* pointer to codec context
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_generate_sps_pps(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf)
+{
+ sps_t *ps_sps;
+ pps_t *ps_pps;
+ subset_sps_t *ps_subset_sps;
+
+ WORD32 i;
+
+ isvce_process_ctxt_t *ps_proc = ps_codec->as_process;
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+ bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
+ isvce_out_buf_t *ps_out_buf = ps_codec->as_out_buf;
+
+ UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
+
+ ASSERT(1 == MAX_CTXT_SETS);
+
+ ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
+ ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
+
+ ps_sps = ps_codec->ps_sps_base;
+ isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
+
+ ps_pps = ps_codec->ps_pps_base;
+ isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
+
+ for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_subset_sps = ps_codec->ps_subset_sps_base + i;
+ isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
+
+ ps_pps = ps_codec->ps_pps_base + i;
+ isvce_populate_pps(ps_codec, ps_pps, i, i, i);
+ }
+
+ ps_entropy->i4_error_code = IH264E_SUCCESS;
+
+ ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
+ if(ps_entropy->i4_error_code != IH264E_SUCCESS)
+ {
+ return ps_entropy->i4_error_code;
+ }
+
+ ps_pps = ps_codec->ps_pps_base;
+ ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
+
+ for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_subset_sps = ps_codec->ps_subset_sps_base + i;
+ isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
+
+ /* populate pps header */
+ ps_pps = ps_codec->ps_pps_base + i;
+ isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
+ }
+
+ /* queue output buffer */
+ ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bytes = ps_bitstrm->u4_strm_buf_offset;
+
+ return ps_entropy->i4_error_code;
+}
+
+/**
+*******************************************************************************
+*
+* @brief initialize entropy context.
+*
+* @par Description:
+* Before invoking the call to perform to entropy coding the entropy context
+* associated with the job needs to be initialized. This involves the start
+* mb address, end mb address, slice index and the pointer to location at
+* which the mb residue info and mb header info are packed.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_init_entropy_ctxt(isvce_process_ctxt_t *ps_proc)
+{
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ /* entropy ctxt */
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+
+ /* start address */
+ ps_entropy->i4_mb_start_add = ps_entropy->i4_mb_y * ps_entropy->i4_wd_mbs + ps_entropy->i4_mb_x;
+
+ /* end address */
+ ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
+
+ /* slice index */
+ ps_entropy->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_entropy->i4_mb_start_add];
+
+ /* sof */
+ /* @ start of frame or start of a new slice, set sof flag */
+ if(ps_entropy->i4_mb_start_add == 0)
+ {
+ ps_entropy->i4_sof = 1;
+ }
+
+ if(ps_entropy->i4_mb_x == 0)
+ {
+ /* packed mb coeff data */
+ ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
+ ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
+
+ /* packed mb header data */
+ ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
+ ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to update rc context after encoding
+*
+* @par Description
+* This function updates the rate control context after the frame is encoded.
+* Number of bits consumed by the current frame, frame distortion, frame cost,
+* number of intra/inter mb's, ... are passed on to rate control context for
+* updating the rc model.
+*
+* @param[in] ps_codec
+* Handle to codec context
+*
+* @param[in] ctxt_sel
+* frame context selector
+*
+* @param[in] pic_cnt
+* pic count
+*
+* @returns i4_stuffing_byte
+* number of stuffing bytes (if necessary)
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_update_rc_post_enc(isvce_codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_is_first_frm)
+{
+ WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
+
+ isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
+
+#if ENABLE_RE_ENC_AS_SKIP
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+
+ UWORD8 u1_is_post_enc_skip = 0;
+#endif
+
+ /* frame qp */
+ UWORD8 u1_frame_qp = ps_codec->au4_frame_qp[ps_proc->u1_spatial_layer_id];
+
+ /* cbr rc return status */
+ WORD32 i4_stuffing_byte = 0;
+
+ /* current frame stats */
+ frame_info_t s_frame_info;
+ picture_type_e rc_pic_type = I_PIC;
+
+ /* temp var */
+ WORD32 i, j;
+
+ /********************************************************************/
+ /* BEGIN INIT */
+ /********************************************************************/
+
+ /* init frame info */
+ irc_init_frame_info(&s_frame_info);
+
+ /* get frame info */
+ for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
+ {
+ /*****************************************************************/
+ /* One frame can be encoded by max of u4_num_cores threads */
+ /* Accumulating the num mbs, sad, qp and intra_mb_cost from */
+ /* u4_num_cores threads */
+ /*****************************************************************/
+ for(j = 0; j < MAX_MB_TYPE; j++)
+ {
+ s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
+
+ s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
+
+ s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
+ }
+
+ s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
+
+ s_frame_info.activity_sum += ps_proc[i].s_frame_info.activity_sum;
+
+ /*****************************************************************/
+ /* gather number of residue and header bits consumed by the frame*/
+ /*****************************************************************/
+ isvce_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
+ }
+
+ /* get pic type */
+ switch(ps_codec->pic_type)
+ {
+ case PIC_I:
+ case PIC_IDR:
+ rc_pic_type = I_PIC;
+ break;
+ case PIC_P:
+ rc_pic_type = P_PIC;
+ break;
+ case PIC_B:
+ rc_pic_type = B_PIC;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ /* update rc lib with current frame stats */
+ i4_stuffing_byte = isvce_rc_post_enc(
+ ps_codec->s_rate_control.apps_rate_control_api[ps_proc->u1_spatial_layer_id],
+ &(s_frame_info), ps_codec->s_rate_control.pps_pd_frm_rate,
+ ps_codec->s_rate_control.pps_time_stamp, ps_codec->s_rate_control.pps_frame_time,
+ (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs), &rc_pic_type, i4_is_first_frm,
+ &ps_codec->s_rate_control.post_encode_skip[ctxt_sel], u1_frame_qp,
+ &ps_codec->s_rate_control.ai4_num_intra_in_prev_frame[ps_proc->u1_spatial_layer_id],
+ &ps_codec->s_rate_control.ai4_avg_activity[ps_proc->u1_spatial_layer_id]
+#if ENABLE_RE_ENC_AS_SKIP
+ ,
+ &u1_is_post_enc_skip
+#endif
+ );
+
+#if ENABLE_RE_ENC_AS_SKIP
+ if(u1_is_post_enc_skip)
+ {
+ buffer_container_t s_dst;
+
+ WORD32 i;
+
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+ svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
+
+ UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+
+ WORD32 i4_layer_luma_wd =
+ (WORD32) (((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
+ 0.99);
+ WORD32 i4_layer_luma_ht =
+ (WORD32) (((DOUBLE) u4_ht /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
+ 0.99);
+
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
+ {
+ isvce_reencode_as_skip_frame_cabac(ps_entropy);
+ }
+ else
+ {
+ isvce_reencode_as_skip_frame_cavlc(ps_entropy);
+ }
+
+ if(u1_num_spatial_layers > 1)
+ {
+ for(i = 0; i < ps_proc->i4_ht_mbs; i++)
+ {
+ for(j = 0; j < ps_proc->i4_wd_mbs; j++)
+ {
+ isvce_update_ibl_info(ps_proc->ps_intra_pred_ctxt, u1_num_spatial_layers,
+ u1_spatial_layer_id, PSKIP, j, i, 0);
+ }
+ }
+
+ if(ENABLE_ILP_MV)
+ {
+ svc_layer_data_t *ps_layer_data;
+
+ svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
+
+ WORD32 i4_num_mbs = ps_proc->i4_ht_mbs * ps_proc->i4_wd_mbs;
+
+ ps_layer_data = &ps_svc_au_data->ps_svc_layer_data[ps_entropy->u1_spatial_layer_id];
+
+ memset(ps_layer_data->ps_mb_info, 0,
+ i4_num_mbs * sizeof(ps_layer_data->ps_mb_info[0]));
+
+ for(i = 0; i < i4_num_mbs; i++)
+ {
+ ps_layer_data->pu4_num_pus_in_mb[i] = 1;
+ }
+ }
+ }
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+ WORD32 i4_src_strd = ps_proc->aps_ref_pic[0]
+ ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .i4_data_stride;
+ WORD32 i4_dst_strd = ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .i4_data_stride;
+
+ if(u1_spatial_layer_id < (u1_num_spatial_layers - 1))
+ {
+ s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .i4_data_stride;
+ s_dst.pv_data =
+ ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .pv_data);
+
+ ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
+ i4_layer_luma_wd, (i4_layer_luma_ht >> u1_is_chroma));
+
+ if(ENABLE_RESIDUAL_PREDICTION)
+ {
+ WORD16 *pi2_res;
+ yuv_buf_props_t *ps_residual_buf =
+ &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
+
+ pi2_res = ps_residual_buf->as_component_bufs[u1_is_chroma].pv_data;
+
+ ps_mem_fxns->pf_memset_2d(
+ (UWORD8 *) pi2_res,
+ ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
+ (sizeof(WORD16) / sizeof(UWORD8)),
+ 0,
+ ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
+ (sizeof(WORD16) / sizeof(UWORD8)),
+ i4_layer_luma_ht >> u1_is_chroma);
+ }
+ }
+
+ ps_mem_fxns->pf_copy_2d(
+ (UWORD8 *) (ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .pv_data) -
+ PAD_LEFT - (PAD_TOP * i4_dst_strd),
+ i4_dst_strd,
+ (UWORD8 *) (ps_proc->aps_ref_pic[0]
+ ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .pv_data) -
+ PAD_LEFT - (PAD_TOP * i4_src_strd),
+ i4_src_strd, (i4_layer_luma_wd + PAD_WD),
+ (i4_layer_luma_ht >> u1_is_chroma) + PAD_HT);
+ }
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+
+#endif
+ return i4_stuffing_byte;
+}
+
+/**
+*******************************************************************************
+*
+* @brief entry point for entropy coding
+*
+* @par Description
+* This function calls lower level functions to perform entropy coding for a
+* group (n rows) of mb's. After encoding 1 row of mb's, the function takes
+* back the control, updates the ctxt and calls lower level functions again.
+* This process is repeated till all the rows or group of mb's (which ever is
+* minimum) are coded
+*
+* @param[in] ps_proc
+* process context
+*
+* @returns error status
+*
+* @remarks
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_entropy(isvce_process_ctxt_t *ps_proc)
+{
+ svc_nalu_ext_t *aps_svc_nalu_ext[2];
+ isvce_out_buf_t s_out_buf;
+ sei_params_t s_sei;
+ nalu_info_t *ps_slice_nalu_info;
+ nalu_info_t *ps_non_vcl_nalu_info;
+
+ UWORD8 *pu1_proc_map;
+ UWORD8 *pu1_entropy_map_curr;
+ WORD32 i4_wd_mbs, i4_ht_mbs;
+ UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
+ WORD32 bitstream_start_offset, bitstream_end_offset;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+ isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
+ sps_t *ps_sps = ps_entropy->ps_sps_base;
+ subset_sps_t *ps_subset_sps = ps_entropy->ps_subset_sps_base;
+ pps_t *ps_pps = ps_entropy->ps_pps_base;
+ slice_header_t *ps_slice_hdr =
+ ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+ svc_slice_header_t *ps_svc_slice_hdr = NULL;
+ bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
+#if ENABLE_RE_ENC_AS_SKIP
+ bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
+#endif
+ nalu_descriptors_t *ps_nalu_descriptor =
+ &ps_codec->as_nalu_descriptors[ps_proc->u1_spatial_layer_id];
+
+ WORD32 i4_slice_type = ps_proc->i4_slice_type;
+ WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+
+ aps_svc_nalu_ext[0] =
+ ps_entropy->ps_svc_nalu_ext_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+ aps_svc_nalu_ext[1] = ps_entropy->ps_svc_nalu_ext_base + 1 +
+ (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ /********************************************************************/
+ /* BEGIN INIT */
+ /********************************************************************/
+
+ /* entropy encode start address */
+ u4_mb_idx = ps_entropy->i4_mb_start_add;
+
+ /* entropy encode end address */
+ u4_mb_end_idx = ps_entropy->i4_mb_end_add;
+
+ /* width in mbs */
+ i4_wd_mbs = ps_entropy->i4_wd_mbs;
+
+ /* height in mbs */
+ i4_ht_mbs = ps_entropy->i4_ht_mbs;
+
+ /* total mb cnt */
+ u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
+
+ /* proc map */
+ pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
+
+ /* entropy map */
+ pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
+
+ /********************************************************************/
+ /* @ start of frame / slice, */
+ /* initialize the output buffer, */
+ /* initialize the bit stream buffer, */
+ /* check if sps and pps headers have to be generated, */
+ /* populate and generate slice header */
+ /********************************************************************/
+ if(ps_entropy->i4_sof)
+ {
+ /********************************************************************/
+ /* initialize the output buffer */
+ /********************************************************************/
+ s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+
+ /* is last frame to encode */
+ s_out_buf.u4_is_last = ps_entropy->u4_is_last;
+
+ /* frame idx */
+ s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
+ s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
+
+ /********************************************************************/
+ /* initialize the bit stream buffer */
+ /********************************************************************/
+ ih264e_bitstrm_init(ps_bitstrm, s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
+ s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
+
+ /********************************************************************/
+ /* BEGIN HEADER GENERATION */
+ /********************************************************************/
+ if(1 == ps_entropy->i4_gen_header)
+ {
+ WORD32 i;
+
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
+ -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SPS,
+ ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+
+ for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
+
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(
+ ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
+ NAL_SUBSET_SPS, ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code = isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+ }
+
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
+ -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
+ ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+
+ for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_pps = ps_entropy->ps_pps_base + i;
+ ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
+
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(
+ ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
+ ps_proc->u1_spatial_layer_id, ps_proc->ps_cur_pic->i1_temporal_id, 1,
+ !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code =
+ isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+ }
+
+ ps_entropy->i4_gen_header = 0;
+ }
+
+ ps_svc_slice_hdr = ps_entropy->ps_svc_slice_hdr_base +
+ (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ if((ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1) ||
+ (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
+ {
+ isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
+ ps_proc->u4_is_idr);
+
+ if(ps_proc->u1_spatial_layer_id > 0)
+ {
+ isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[1],
+ NAL_CODED_SLICE_EXTENSION, ps_proc->u4_is_idr);
+ }
+ }
+ else
+ {
+ isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
+ ps_proc->u4_is_idr);
+ }
+
+ if(ps_proc->u1_spatial_layer_id > 0)
+ {
+ ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
+ ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
+
+ ps_entropy->i4_error_code = isvce_populate_svc_slice(
+ ps_proc, ps_svc_slice_hdr, ps_pps, ps_subset_sps, aps_svc_nalu_ext[1]);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
+ }
+ else
+ {
+ ps_pps = ps_entropy->ps_pps_base;
+ ps_sps = ps_entropy->ps_sps_base;
+
+ ps_entropy->i4_error_code = isvce_populate_slice_header(
+ ps_proc, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+
+ /* generate sei */
+ u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
+
+ memset(&s_sei, 0, sizeof(sei_params_t));
+ s_sei.u1_sei_mdcv_params_present_flag =
+ ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
+ s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
+ s_sei.u1_sei_cll_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
+ s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
+ s_sei.u1_sei_ave_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
+ s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
+ s_sei.u1_sei_ccv_params_present_flag = 0;
+ s_sei.s_sei_ccv_params =
+ ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES].s_inp_props.s_sei_ccv;
+
+ if((1 == ps_sps->i1_vui_parameters_present_flag) &&
+ (1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
+ (1 == ps_codec->s_cfg.s_vui.u1_colour_description_present_flag) &&
+ (2 != ps_codec->s_cfg.s_vui.u1_colour_primaries) &&
+ (2 != ps_codec->s_cfg.s_vui.u1_matrix_coefficients) &&
+ (2 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
+ (4 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
+ (5 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics))
+ {
+ s_sei.u1_sei_ccv_params_present_flag =
+ ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
+ .s_inp_props.u1_sei_ccv_params_present_flag;
+ }
+
+ if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
+ (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
+ (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
+ (1 == s_sei.u1_sei_ccv_params_present_flag))
+ {
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
+ -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SEI,
+ ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code = ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+ }
+
+ ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
+ .s_inp_props.u1_sei_ccv_params_present_flag = 0;
+
+ if((ps_proc->u1_spatial_layer_id == 0) &&
+ (ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1 ||
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
+ {
+ ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
+ -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PREFIX,
+ ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ ps_entropy->i4_error_code =
+ isvce_generate_svc_nalu_extension(ps_bitstrm, aps_svc_nalu_ext[0], NAL_PREFIX);
+
+ ps_entropy->i4_error_code = isvce_generate_prefix_nal(
+ ps_bitstrm, aps_svc_nalu_ext[0], ps_slice_hdr, ps_sps->u1_max_num_ref_frames,
+ ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+ }
+
+ ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ isvce_nalu_info_buf_init(ps_slice_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
+ ps_slice_hdr->i1_nal_unit_type, ps_proc->u1_spatial_layer_id,
+ ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
+
+ if(ps_proc->u1_spatial_layer_id > 0)
+ {
+ ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
+ ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
+
+ ps_entropy->i4_error_code = isvce_generate_svc_nalu_extension(
+ ps_bitstrm, aps_svc_nalu_ext[1], NAL_CODED_SLICE_EXTENSION);
+
+ ps_entropy->i4_error_code = isvce_generate_slice_header_svc(
+ ps_bitstrm, ps_pps, aps_svc_nalu_ext[1], ps_svc_slice_hdr, ps_subset_sps);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ else
+ {
+ /* generate slice header */
+ ps_entropy->i4_error_code = isvce_generate_slice_header(
+ ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+
+ /* once start of frame / slice is done, you can reset it */
+ /* it is the responsibility of the caller to set this flag */
+ ps_entropy->i4_sof = 0;
+
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
+ {
+ BITSTREAM_BYTE_ALIGN(ps_bitstrm);
+ BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
+ isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
+ }
+
+#if ENABLE_RE_ENC_AS_SKIP
+ ps_bitstrm_after_slice_hdr[0] = ps_bitstrm[0];
+#endif
+ }
+
+ /* begin entropy coding for the mb set */
+ while(u4_mb_idx < u4_mb_end_idx)
+ {
+ mb_bits_info_t s_mb_bits = {
+ .i8_header_bits = -((WORD64) ps_entropy->u4_header_bits[i4_slice_type == PSLICE]),
+ .i8_texture_bits = -((WORD64) ps_entropy->u4_residue_bits[i4_slice_type == PSLICE])};
+
+ /* init ptrs/indices */
+ if(ps_entropy->i4_mb_x == i4_wd_mbs)
+ {
+ ps_entropy->i4_mb_y++;
+ ps_entropy->i4_mb_x = 0;
+
+ /* packed mb coeff data */
+ ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
+ ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
+
+ /* packed mb header data */
+ ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
+ ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
+
+ /* proc map */
+ pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
+
+ /* entropy map */
+ pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
+ }
+
+ DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
+ ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
+ ENTROPY_TRACE("mb index y %d", ps_entropy->i4_mb_y);
+
+ /* wait until the curr mb is core coded */
+ /* The wait for curr mb to be core coded is essential when entropy is
+ * launched as a separate job
+ */
+ while(1)
+ {
+ volatile UWORD8 *pu1_buf1;
+ WORD32 idx = ps_entropy->i4_mb_x;
+
+ pu1_buf1 = pu1_proc_map + idx;
+ if(*pu1_buf1) break;
+ ithread_yield();
+ }
+
+ /* write mb layer */
+ ps_entropy->i4_error_code =
+ ps_codec->pf_write_mb_syntax_layer[ps_entropy->u1_entropy_coding_mode_flag]
+ [i4_slice_type](ps_entropy);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ /* Starting bitstream offset for header in bits */
+ bitstream_start_offset = isvce_get_num_bits(ps_bitstrm);
+
+ /* set entropy map */
+ pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
+ ASSERT(ps_entropy->i4_mb_x < i4_wd_mbs);
+
+ u4_mb_idx++;
+ ps_entropy->i4_mb_x++;
+ /* check for eof */
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
+ {
+ if(ps_entropy->i4_mb_x < i4_wd_mbs)
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
+ }
+ }
+
+ if(ps_entropy->i4_mb_x == i4_wd_mbs)
+ {
+ /* if slices are enabled */
+ if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
+ {
+ /* current slice index */
+ WORD32 i4_curr_slice_idx = ps_entropy->i4_cur_slice_idx;
+
+ /* slice map */
+ UWORD8 *pu1_slice_idx = ps_entropy->pu1_slice_idx;
+
+ /* No need to open a slice at end of frame. The current slice can be
+ * closed at the time of signaling eof flag.
+ */
+ if((u4_mb_idx != u4_mb_cnt) && (i4_curr_slice_idx != pu1_slice_idx[u4_mb_idx]))
+ {
+ if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
+ { /* mb skip run */
+ if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
+ {
+ if(*ps_entropy->pi4_mb_skip_run)
+ {
+ PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
+ ps_entropy->i4_error_code, "mb skip run");
+ *ps_entropy->pi4_mb_skip_run = 0;
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ }
+ /* put rbsp trailing bits for the previous slice */
+ ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ else
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
+ }
+
+ /* update slice header pointer */
+ i4_curr_slice_idx = pu1_slice_idx[u4_mb_idx];
+ ps_entropy->i4_cur_slice_idx = i4_curr_slice_idx;
+ ps_slice_hdr =
+ ps_entropy->ps_slice_hdr_base + (i4_curr_slice_idx % SVC_MAX_SLICE_HDR_CNT);
+
+ ps_entropy->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+
+ /* populate slice header */
+ ps_entropy->i4_mb_start_add = u4_mb_idx;
+
+ /* generate slice header */
+ if(ps_proc->u1_spatial_layer_id > 0)
+ {
+ ps_entropy->i4_error_code =
+ isvce_generate_slice_header_svc(ps_bitstrm, ps_pps, aps_svc_nalu_ext[1],
+ ps_svc_slice_hdr, ps_subset_sps);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
+ }
+ else
+ {
+ ps_entropy->i4_error_code =
+ isvce_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps,
+ aps_svc_nalu_ext[0]->u1_idr_flag);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+
+ ps_entropy->i4_error_code =
+ isvce_generate_slice_header(ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps,
+ aps_svc_nalu_ext[0]->u1_idr_flag);
+
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
+ {
+ BITSTREAM_BYTE_ALIGN(ps_bitstrm);
+ BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
+ isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
+ }
+ }
+ else
+ {
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag && u4_mb_idx != u4_mb_cnt)
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
+ }
+ }
+ }
+ }
+
+ /* Ending bitstream offset for header in bits */
+ bitstream_end_offset = isvce_get_num_bits(ps_bitstrm);
+ ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
+ bitstream_end_offset - bitstream_start_offset;
+
+ {
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
+ svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
+
+ s_mb_bits.i8_header_bits += ps_entropy->u4_header_bits[i4_slice_type == PSLICE];
+ s_mb_bits.i8_texture_bits += ps_entropy->u4_residue_bits[i4_slice_type == PSLICE];
+
+ ps_sub_pic_rc_variables->s_mb_bits = s_mb_bits;
+ ps_sub_pic_rc_variables->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+ ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_entropy->i4_mb_x - 1;
+ ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_entropy->i4_mb_y;
+
+ isvce_sub_pic_rc_get_entropy_data(ps_proc->ps_sub_pic_rc_ctxt);
+ }
+ }
+
+ /* check for eof */
+ if(u4_mb_idx == u4_mb_cnt)
+ {
+ /* set end of frame flag */
+ ps_entropy->i4_eof = 1;
+ }
+ else
+ {
+ if(CABAC == ps_entropy->u1_entropy_coding_mode_flag &&
+ ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_BLOCKS)
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
+ }
+ }
+
+ if(ps_entropy->i4_eof)
+ {
+ if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
+ {
+ /* mb skip run */
+ if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
+ {
+ if(*ps_entropy->pi4_mb_skip_run)
+ {
+ PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
+ ps_entropy->i4_error_code, "mb skip run");
+ *ps_entropy->pi4_mb_skip_run = 0;
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ }
+ /* put rbsp trailing bits */
+ ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ else
+ {
+ isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
+ }
+
+ /* update current frame stats to rc library */
+ /* number of bytes to stuff */
+ {
+ WORD32 i4_stuff_bytes;
+
+ /* update */
+ i4_stuff_bytes = isvce_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0));
+
+ if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
+ {
+ /* cbr rc - house keeping */
+ if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
+ {
+ ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0;
+ }
+ else if(i4_stuff_bytes > 0)
+ {
+ /* add filler nal units */
+ ps_entropy->i4_error_code =
+ ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
+ RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
+ }
+ }
+ }
+
+ /*
+ *Frame number is to be incremented only if the current frame is a
+ * reference frame. After each successful frame encode, we increment
+ * frame number by 1
+ */
+ if(!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] && ps_codec->u4_is_curr_frm_ref &&
+ (ps_proc->u1_spatial_layer_id == ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
+ {
+ ps_codec->i4_frame_num++;
+ }
+
+ /********************************************************************/
+ /* signal the output */
+ /********************************************************************/
+ ps_codec->as_out_buf[ctxt_sel].as_bits_buf[ps_entropy->u1_spatial_layer_id].u4_bytes =
+ ps_bitstrm->u4_strm_buf_offset;
+
+ ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
+ ps_slice_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
+ isvce_update_nalu_count(ps_nalu_descriptor);
+
+ DEBUG("entropy status %x", ps_entropy->i4_error_code);
+ ps_entropy->i4_eof = 0;
+ }
+
+ /* Dont execute any further instructions until store synchronization took
+ * place */
+ DATA_SYNC();
+
+ /* allow threads to dequeue entropy jobs */
+ ps_codec->au4_entropy_thread_active[ctxt_sel] = 0;
+
+ return ps_entropy->i4_error_code;
+}
+
+/**
+*******************************************************************************
+*
+* @brief Packs header information of a mb in to a buffer
+*
+* @par Description:
+* After the deciding the mode info of a macroblock, the syntax elements
+* associated with the mb are packed and stored. The entropy thread unpacks
+* this buffer and generates the end bit stream.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_pack_header_data(isvce_process_ctxt_t *ps_proc)
+{
+ /* curr mb type */
+ UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
+
+ /* pack mb syntax layer of curr mb (used for entropy coding) */
+ if(u4_mb_type == I4x4)
+ {
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_i4x4_t *ps_mb_hdr = (isvce_mb_hdr_i4x4_t *) ps_proc->pv_mb_header_data;
+
+ /* temp var */
+ WORD32 i4, byte;
+
+ /* mb type plus mode */
+ ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
+
+ /* cbp */
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ /* mb qp delta */
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ /* sub mb modes */
+ for(i4 = 0; i4 < 16; i4++)
+ {
+ byte = 0;
+
+ if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
+ ps_proc->au1_intra_luma_mb_4x4_modes[i4])
+ {
+ byte |= 1;
+ }
+ else
+ {
+ if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
+ ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
+ {
+ byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
+ }
+ else
+ {
+ byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
+ }
+ }
+
+ i4++;
+
+ if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
+ ps_proc->au1_intra_luma_mb_4x4_modes[i4])
+ {
+ byte |= 16;
+ }
+ else
+ {
+ if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
+ ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
+ {
+ byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
+ }
+ else
+ {
+ byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
+ }
+ }
+
+ ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] = byte;
+ }
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_i4x4_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == I16x16)
+ {
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_i16x16_t *ps_mb_hdr = (isvce_mb_hdr_i16x16_t *) ps_proc->pv_mb_header_data;
+
+ /* mb type plus mode */
+ ps_mb_hdr->common.u1_mb_type_mode =
+ (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
+
+ /* cbp */
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ /* mb qp delta */
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_i16x16_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == P16x16)
+ {
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_p16x16_t *ps_mb_hdr = (isvce_mb_hdr_p16x16_t *) ps_proc->pv_mb_header_data;
+
+ /* mb type */
+ ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
+
+ /* cbp */
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ /* mb qp delta */
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ ps_mb_hdr->u1_mvp_idx = ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0];
+
+ if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0])
+ {
+ ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
+ ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
+ ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
+ ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
+ ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvx;
+ ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
+ ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvy;
+ }
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_p16x16_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == PSKIP)
+ {
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_pskip_t *ps_mb_hdr = (isvce_mb_hdr_pskip_t *) ps_proc->pv_mb_header_data;
+
+ /* mb type */
+ ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_pskip_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == B16x16)
+ {
+ WORD32 i;
+
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_b16x16_t *ps_mb_hdr = (isvce_mb_hdr_b16x16_t *) ps_proc->pv_mb_header_data;
+
+ UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
+
+ /* mb type plus mode */
+ ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
+
+ /* cbp */
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ /* mb qp delta */
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ for(i = 0; i < NUM_PRED_DIRS; i++)
+ {
+ PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
+ PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
+
+ if(u4_pred_mode != e_pred_mode)
+ {
+ ps_mb_hdr->au1_mvp_idx[e_cmpl_pred_mode] =
+ ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode];
+
+ if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode])
+ {
+ ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
+ ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
+ ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvx;
+ ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
+ ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
+ ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvy;
+ }
+ else
+ {
+ ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
+ ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
+ ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvx;
+ ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
+ ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
+ ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvy;
+ }
+ }
+ }
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_b16x16_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == BDIRECT)
+ {
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_bdirect_t *ps_mb_hdr = (isvce_mb_hdr_bdirect_t *) ps_proc->pv_mb_header_data;
+
+ /* mb type plus mode */
+ ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
+
+ /* cbp */
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ /* mb qp delta */
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_bdirect_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == BSKIP)
+ {
+ UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
+
+ /* pointer to mb header storage space */
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+ isvce_mb_hdr_bskip_t *ps_mb_hdr = (isvce_mb_hdr_bskip_t *) ps_proc->pv_mb_header_data;
+
+ /* mb type plus mode */
+ ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ /* end of mb layer */
+ pu1_ptr += sizeof(isvce_mb_hdr_bskip_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+ else if(u4_mb_type == BASE_MODE)
+ {
+ isvce_mb_hdr_base_mode_t *ps_mb_hdr =
+ (isvce_mb_hdr_base_mode_t *) ps_proc->pv_mb_header_data;
+
+ UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
+
+ ASSERT(ps_proc->ps_mb_info->u1_base_mode_flag == 1);
+
+ ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
+
+ ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
+
+ ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
+
+ ps_mb_hdr->common.u1_residual_prediction_flag =
+ ps_proc->ps_mb_info->u1_residual_prediction_flag;
+
+ ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
+
+ pu1_ptr += sizeof(isvce_mb_hdr_base_mode_t);
+ ps_proc->pv_mb_header_data = pu1_ptr;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief update process context after encoding an mb. This involves preserving
+* the current mb information for later use, initialize the proc ctxt elements to
+* encode next mb.
+*
+* @par Description:
+* This function performs house keeping tasks after encoding an mb.
+* After encoding an mb, various elements of the process context needs to be
+* updated to encode the next mb. For instance, the source, recon and reference
+* pointers, mb indices have to be adjusted to the next mb. The slice index of
+* the current mb needs to be updated. If mb qp modulation is enabled, then if
+* the qp changes the quant param structure needs to be updated. Also to
+*encoding the next mb, the current mb info is used as part of mode prediction or
+*mv prediction. Hence the current mb info has to preserved at top/top left/left
+* locations.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+WORD32 isvce_update_proc_ctxt(isvce_process_ctxt_t *ps_proc)
+{
+ /* error status */
+ WORD32 error_status = IH264_SUCCESS;
+
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* curr mb indices */
+ WORD32 i4_mb_x = ps_proc->i4_mb_x;
+ WORD32 i4_mb_y = ps_proc->i4_mb_y;
+
+ /* mb syntax elements of neighbors */
+ isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
+ isvce_mb_info_t *ps_top_syn =
+ ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
+ .ps_top_row_mb_info +
+ i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs;
+
+ /* curr mb type */
+ UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
+
+ /* curr mb type */
+ UWORD32 u4_is_intra = ps_proc->ps_mb_info->u1_is_intra;
+
+ /* width in mbs */
+ WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
+
+ /*height in mbs*/
+ WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
+
+ /* proc map */
+ UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
+
+ /* deblk context */
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+
+ /* deblk bs context */
+ isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
+
+ /* sub mb modes */
+ UWORD8 *pu1_top_mb_intra_modes =
+ (ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
+ .ps_top_mb_intra_modes +
+ i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs)
+ ->au1_intra_modes;
+
+ /*************************************************************/
+ /* During MV prediction, when top right mb is not available, */
+ /* top left mb info. is used for prediction. Hence the curr */
+ /* top, which will be top left for the next mb needs to be */
+ /* preserved before updating it with curr mb info. */
+ /*************************************************************/
+
+ /*************************************************/
+ /* update top and left with curr mb info results */
+ /*************************************************/
+ ps_left_syn[0] = ps_top_syn[0] = ps_proc->ps_mb_info[0];
+ ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
+ ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
+
+ if(u4_is_intra)
+ {
+ /* mb / sub mb modes */
+ if(I16x16 == u4_mb_type)
+ {
+ pu1_top_mb_intra_modes[0] =
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[0] =
+ ps_proc->u1_l_i16_mode;
+ }
+ else if(I4x4 == u4_mb_type)
+ {
+ ps_mem_fxns->pf_mem_cpy_mul8(
+ ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
+ ps_proc->au1_intra_luma_mb_4x4_modes, 16);
+ ps_mem_fxns->pf_mem_cpy_mul8(pu1_top_mb_intra_modes,
+ ps_proc->au1_intra_luma_mb_4x4_modes, 16);
+ }
+ else if(I8x8 == u4_mb_type)
+ {
+ memcpy(ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
+ ps_proc->au1_intra_luma_mb_8x8_modes, 4);
+ memcpy(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
+ }
+
+ *ps_proc->pu4_mb_pu_cnt = 1;
+ }
+
+ /*
+ * Mark that the MB has been coded intra
+ * So that future AIRs can skip it
+ */
+ ps_proc->pu1_is_intra_coded[i4_mb_x + (i4_mb_y * i4_wd_mbs)] = u4_is_intra;
+
+ /**************************************************/
+ /* pack mb header info. for entropy coding */
+ /**************************************************/
+ isvce_pack_header_data(ps_proc);
+
+ /*
+ * We need to sync the cache to make sure that the nmv content of proc
+ * is updated to cache properly
+ */
+ DATA_SYNC();
+
+ /* Just before finishing the row, enqueue the job in to entropy queue.
+ * The master thread depending on its convenience shall dequeue it and
+ * performs entropy.
+ *
+ * WARN !! Placing this block post proc map update can cause queuing of
+ * entropy jobs in out of order.
+ */
+ if(i4_mb_x == i4_wd_mbs - 1)
+ {
+ /* job structures */
+ job_t s_job;
+
+ /* job class */
+ s_job.i4_cmd = CMD_ENTROPY;
+
+ /* number of mbs to be processed in the current job */
+ s_job.i2_mb_cnt = ps_proc->i4_wd_mbs;
+
+ /* job start index x */
+ s_job.i2_mb_x = 0;
+
+ /* job start index y */
+ s_job.i2_mb_y = ps_proc->i4_mb_y;
+
+ /* queue the job */
+ error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
+
+ if(error_status != IH264_SUCCESS)
+ {
+ return error_status;
+ }
+
+ if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
+ {
+ ih264_list_terminate(ps_codec->pv_entropy_jobq);
+ }
+ }
+
+ /* update proc map */
+ pu1_proc_map[i4_mb_x] = 1;
+ ASSERT(i4_mb_x < i4_wd_mbs);
+
+ /**************************************************/
+ /* update proc ctxt elements for encoding next mb */
+ /**************************************************/
+ /* update indices */
+ i4_mb_x++;
+ ps_proc->i4_mb_x = i4_mb_x;
+
+ if(ps_proc->i4_mb_x == i4_wd_mbs)
+ {
+ ps_proc->i4_mb_y++;
+ ps_proc->i4_mb_x = 0;
+ }
+
+ /* update slice index */
+ ps_proc->i4_cur_slice_idx =
+ ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
+
+ /* update buffers pointers */
+ ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) + MB_SIZE;
+
+ /*
+ * Note: Although chroma mb size is 8, as the chroma buffers are
+ * interleaved, the stride per MB is MB_SIZE
+ */
+ ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
+ ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
+
+ /* Reset cost, distortion params */
+ ps_proc->i4_mb_cost = INT_MAX;
+ ps_proc->i4_mb_distortion = SHRT_MAX;
+
+ ps_proc->ps_mb_info++;
+ ps_proc->pu4_mb_pu_cnt++;
+
+ /* Update colocated pu */
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ ps_proc->ps_col_mb++;
+ }
+
+ if(ps_proc->u4_disable_deblock_level != 1)
+ {
+ ps_bs->i4_mb_x = ps_proc->i4_mb_x;
+ ps_bs->i4_mb_y = ps_proc->i4_mb_y;
+
+#ifndef N_MB_ENABLE /* For N MB processing update take place inside deblocking \
+ function */
+ ASSERT(0);
+ ps_deblk->i4_mb_x++;
+
+ ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].pv_data) += MB_SIZE;
+ /*
+ * Note: Although chroma mb size is 8, as the chroma buffers are
+ * interleaved, the stride per MB is MB_SIZE
+ */
+ ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].pv_data) += MB_SIZE;
+#endif
+ }
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs luma & chroma padding
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @param[in] pu1_curr_pic_luma
+* Pointer to luma buffer
+*
+* @param[in] pu1_curr_pic_chroma
+* Pointer to chroma buffer
+*
+* @param[in] i4_mb_x
+* mb index x
+*
+* @param[in] i4_mb_y
+* mb index y
+*
+* @param[in] i4_pad_ht
+* number of rows to be padded
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_pad_recon_buffer(isvce_process_ctxt_t *ps_proc, UWORD8 *pu1_curr_pic_luma,
+ WORD32 i4_luma_stride, UWORD8 *pu1_curr_pic_chroma,
+ WORD32 i4_chroma_stride, WORD32 i4_mb_x, WORD32 i4_mb_y,
+ WORD32 i4_pad_ht)
+{
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ if(i4_mb_x == 0)
+ {
+ /* padding left luma */
+ ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_luma_stride, i4_pad_ht, PAD_LEFT);
+
+ /* padding left chroma */
+ ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_chroma_stride, i4_pad_ht >> 1,
+ PAD_LEFT);
+ }
+ if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
+ {
+ /* padding right luma */
+ ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_luma_stride, i4_pad_ht,
+ PAD_RIGHT);
+
+ /* padding right chroma */
+ ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_chroma_stride,
+ i4_pad_ht >> 1, PAD_RIGHT);
+
+ if(i4_mb_y == ps_proc->i4_ht_mbs - 1)
+ {
+ UWORD8 *pu1_rec_luma =
+ pu1_curr_pic_luma + MB_SIZE + PAD_RIGHT + ((i4_pad_ht - 1) * i4_luma_stride);
+ UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma + MB_SIZE + PAD_RIGHT +
+ (((i4_pad_ht >> 1) - 1) * i4_chroma_stride);
+
+ /* padding bottom luma */
+ ps_codec->pf_pad_bottom(pu1_rec_luma, i4_luma_stride, i4_luma_stride, PAD_BOT);
+
+ /* padding bottom chroma */
+ ps_codec->pf_pad_bottom(pu1_rec_chroma, i4_chroma_stride, i4_chroma_stride,
+ (PAD_BOT >> 1));
+ }
+ }
+
+ if(i4_mb_y == 0)
+ {
+ UWORD8 *pu1_rec_luma = pu1_curr_pic_luma;
+ UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma;
+ WORD32 wd = MB_SIZE;
+
+ if(i4_mb_x == 0)
+ {
+ pu1_rec_luma -= PAD_LEFT;
+ pu1_rec_chroma -= PAD_LEFT;
+
+ wd += PAD_LEFT;
+ }
+ if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
+ {
+ wd += PAD_RIGHT;
+ }
+
+ /* padding top luma */
+ ps_codec->pf_pad_top(pu1_rec_luma, i4_luma_stride, wd, PAD_TOP);
+
+ /* padding top chroma */
+ ps_codec->pf_pad_top(pu1_rec_chroma, i4_chroma_stride, wd, (PAD_TOP >> 1));
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs deblocking
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IH264E_ERROR_T isvce_dblk_n_mbs(isvce_process_ctxt_t *ps_proc,
+ UWORD8 u1_inter_layer_deblk_flag)
+{
+ WORD32 i;
+ WORD32 row, col;
+
+ n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+
+ UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
+ UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
+ WORD32 u4_deblk_prev_row = 0;
+ WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
+ WORD32 i4_n_mb_process_count = 0;
+ WORD32 i4_mb_x = ps_proc->i4_mb_x;
+ WORD32 i4_mb_y = ps_proc->i4_mb_y;
+
+ ASSERT(i4_n_mbs == ps_proc->i4_wd_mbs);
+
+ if(ps_proc->u4_disable_deblock_level != 1)
+ {
+ if((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
+ {
+ /* if number of mb's to be processed are less than 'N', go back.
+ * exception to the above clause is end of row */
+ if(((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) &&
+ (i4_mb_x < (ps_proc->i4_wd_mbs - 1)))
+ {
+ return IH264E_SUCCESS;
+ }
+ else
+ {
+ WORD32 i4_num_deblk_rows = 1;
+
+ if(i4_mb_y == (ps_proc->i4_ht_mbs - 1))
+ {
+ i4_num_deblk_rows += (ps_proc->i4_ht_mbs > 1);
+ }
+
+ if(1 == ps_proc->i4_ht_mbs)
+ {
+ ps_deblk->i4_mb_y = 0;
+ pu1_deblk_map_prev_row = pu1_deblk_map;
+ }
+
+ for(i = 0; i < i4_num_deblk_rows; i++)
+ {
+ if(i == 1)
+ {
+ /* Deblock last row */
+ ps_n_mb_ctxt->i4_mb_x = 0;
+ ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
+ ps_deblk->i4_mb_x = 0;
+ ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
+ pu1_deblk_map_prev_row = pu1_deblk_map;
+ pu1_deblk_map += ps_proc->i4_wd_mbs;
+ }
+
+ i4_n_mb_process_count = MIN(i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1), i4_n_mbs);
+
+ /* performing deblocking for required number of MBs */
+ u4_deblk_prev_row = 1;
+
+ /* checking whether the top rows are deblocked */
+ for(col = 0; col < i4_n_mb_process_count; col++)
+ {
+ u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
+ }
+
+ /* checking whether the top right MB is deblocked */
+ if((ps_deblk->i4_mb_x + i4_n_mb_process_count) != ps_proc->i4_wd_mbs)
+ {
+ u4_deblk_prev_row &=
+ pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + i4_n_mb_process_count];
+ }
+
+ /* Top or Top right MBs not deblocked */
+ if((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
+ {
+ return IH264E_SUCCESS;
+ }
+
+ for(row = 0; row < i4_n_mb_process_count; row++)
+ {
+ isvce_deblock_mb(ps_proc, ps_deblk, u1_inter_layer_deblk_flag);
+
+ pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
+
+ ps_deblk->i4_mb_x++;
+ }
+ }
+ }
+ }
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs 'intra base' deblocking
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static IH264E_ERROR_T isvce_intra_base_dblk(isvce_process_ctxt_t *ps_proc)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+
+ IH264E_ERROR_T e_ret = IH264E_SUCCESS;
+
+ if(ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
+ {
+ ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
+ ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
+
+ ps_deblk->s_rec_pic_buf_props =
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id];
+
+ e_ret = isvce_dblk_n_mbs(ps_proc, 1);
+
+ ps_deblk->s_rec_pic_buf_props = ps_proc->s_rec_pic_buf_props;
+ }
+
+ return e_ret;
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function performs luma & chroma core coding for a set of mb's.
+*
+* @par Description:
+* The mb to be coded is taken and is evaluated over a predefined set of modes
+* (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least
+*cost is selected and using intra/inter prediction filters, prediction is
+*carried out. The deviation between src and pred signal constitutes error
+*signal. This error signal is transformed (hierarchical transform if necessary)
+*and quantized. The quantized residue is packed in to entropy buffer for entropy
+*coding. This is repeated for all the mb's enlisted under the job.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+WORD32 isvce_process(isvce_process_ctxt_t *ps_proc)
+{
+ UWORD32 u4_cbp_l, u4_cbp_c;
+ WORD32 i4_mb_idx;
+ WORD32 luma_idx, chroma_idx, is_intra;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+
+ WORD32 error_status = IH264_SUCCESS;
+ WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
+ WORD32 i4_mb_cnt = ps_proc->i4_mb_cnt;
+ UWORD32 u4_valid_modes = 0;
+ WORD32 i4_gate_threshold = 0;
+ WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+ bool b_enable_intra4x4_eval = true;
+
+ /*
+ * list of modes for evaluation
+ * -------------------------------------------------------------------------
+ * Note on enabling I4x4 and I16x16
+ * At very low QP's the hadamard transform in I16x16 will push up the maximum
+ * coeff value very high. CAVLC may not be able to represent the value and
+ * hence the stream may not be decodable in some clips.
+ * Hence at low QPs, we will enable I4x4 and disable I16x16 irrespective of
+ * preset.
+ */
+ if(ps_proc->i4_slice_type == ISLICE)
+ {
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
+
+ /* enable intra 8x8 */
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
+
+ /* enable intra 4x4 */
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
+ u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
+ }
+ else if(ps_proc->i4_slice_type == PSLICE)
+ {
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
+
+ /* enable intra 4x4 */
+ if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
+ {
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
+ }
+ u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
+
+ /* enable inter P16x16 */
+ u4_valid_modes |= (1 << P16x16);
+ }
+ else if(ps_proc->i4_slice_type == BSLICE)
+ {
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
+
+ /* enable intra 4x4 */
+ if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
+ {
+ u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
+ }
+ u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
+
+ /* enable inter B16x16 */
+ u4_valid_modes |= (1 << B16x16);
+ }
+
+ ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
+ ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
+ ps_proc->s_entropy.i4_mb_cnt = MIN(ps_proc->i4_nmb_ntrpy, i4_wd_mbs - ps_proc->i4_mb_x);
+
+ /* compute recon when :
+ * 1. current frame is to be used as a reference
+ * 2. dump recon for bit stream sanity check
+ */
+ ps_proc->u4_compute_recon = ((ps_proc->s_svc_params.u1_num_spatial_layers > 1) &&
+ (ENABLE_RESIDUAL_PREDICTION || ENABLE_IBL_MODE)) ||
+ ps_codec->u4_is_curr_frm_ref || ps_codec->s_cfg.u4_enable_recon;
+
+ for(i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx++)
+ {
+ /* since we have not yet found sad, we have not yet got min sad */
+ /* we need to initialize these variables for each MB */
+ /* TODO how to get the min sad into the codec */
+ ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
+ ps_proc->u4_min_sad_reached = 0;
+
+ ps_proc->ps_mb_info->u1_mb_qp = ps_proc->u1_mb_qp;
+
+ /* wait until the proc of [top + 1] mb is computed.
+ * We wait till the proc dependencies are satisfied */
+ if(ps_proc->i4_mb_y > 0)
+ {
+ UWORD8 *pu1_proc_map_top;
+
+ pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
+
+ while(1)
+ {
+ volatile UWORD8 *pu1_buf;
+ WORD32 idx = MIN(i4_mb_cnt - 1, i4_mb_idx + 1);
+
+ idx = MIN(idx, ((WORD32) ps_codec->s_cfg.i4_wd_mbs - 1));
+ pu1_buf = pu1_proc_map_top + idx;
+ if(*pu1_buf) break;
+ ithread_yield();
+ }
+ }
+
+ if(ENABLE_ILP_MV && (ps_proc->u1_spatial_layer_id > 0) &&
+ (ps_proc->i4_slice_type != ISLICE))
+ {
+ svc_ilp_mv_ctxt_t *ps_svc_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt;
+ coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
+
+ ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
+ ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.s_mb_pos = s_mb_pos;
+ ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.u1_spatial_layer_id =
+ ps_proc->u1_spatial_layer_id;
+
+ isvce_get_mb_ilp_mv(ps_svc_ilp_mv_ctxt);
+
+ ps_proc->ps_ilp_mv = &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_mv;
+ ps_proc->s_me_ctxt.ps_ilp_me_cands =
+ &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_me_cands;
+ }
+ else
+ {
+ ps_proc->ps_ilp_mv = NULL;
+ ps_proc->s_me_ctxt.ps_ilp_me_cands = NULL;
+ }
+
+ ps_proc->ps_mb_info->u2_mb_type = INVALID_MB_TYPE;
+ ps_proc->i4_mb_distortion = SHRT_MAX;
+
+ {
+ WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
+
+ WORD32 i4_air_enable_inter =
+ (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
+ (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
+
+ if((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
+ {
+ if(ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
+ {
+ isvce_compute_me_nmb(
+ ps_proc, MIN((WORD32) ps_proc->u4_nmb_me, i4_wd_mbs - ps_proc->i4_mb_x));
+ }
+
+ {
+ UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me;
+
+ ps_proc->u4_min_sad_reached =
+ ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
+ ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
+
+ ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
+ ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
+ ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
+
+ ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
+
+ ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
+ ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
+ ps_proc->u4_min_sad_reached =
+ ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
+ ps_proc->ps_mb_info->u2_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
+
+ ps_proc->pu1_best_subpel_buf =
+ ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
+ ps_proc->u4_bst_spel_buf_strd =
+ ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
+ }
+
+ isvce_derive_nghbr_avbl_of_mbs(ps_proc);
+ }
+ else
+ {
+ ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
+
+ isvce_derive_nghbr_avbl_of_mbs(ps_proc);
+ }
+
+ /*
+ * If air says intra, we need to force the following code path to evaluate
+ * intra The easy way is just to say that the inter cost is too much
+ */
+ if(!i4_air_enable_inter)
+ {
+ ps_proc->u4_min_sad_reached = 0;
+ ps_proc->i4_mb_cost = INT_MAX;
+ ps_proc->i4_mb_distortion = INT_MAX;
+ }
+ else if(ps_proc->ps_mb_info->u2_mb_type == PSKIP)
+ {
+ ps_proc->ps_mb_info->u1_base_mode_flag = 0;
+ ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
+ goto UPDATE_MB_INFO;
+ }
+
+ /* If we already have the minimum sad, there is no point in searching for
+ * sad again */
+ if((ps_proc->u4_min_sad_reached == 0) ||
+ (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST))
+ {
+ /* intra gating in inter slices */
+ /* No need of gating if we want to force intra, we need to find the
+ * threshold only if inter is enabled by AIR*/
+ if((ps_proc->i4_slice_type != ISLICE) &&
+ (FORCE_DISTORTION_BASED_INTRA_4X4_GATING ||
+ (i4_air_enable_inter && ps_codec->u4_inter_gate)))
+ {
+ WORD32 i4_distortion[4];
+
+ if((ps_proc->i4_mb_x > 0) && (ps_proc->i4_mb_y > 0))
+ {
+ i4_distortion[0] = ps_proc->s_nbr_info.ps_left_mb_info->i4_mb_distortion;
+
+ i4_distortion[1] = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x]
+ .i4_mb_distortion;
+
+ i4_distortion[2] =
+ ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1]
+ .i4_mb_distortion;
+
+ i4_distortion[3] =
+ ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1]
+ .i4_mb_distortion;
+
+ i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] +
+ i4_distortion[2] + i4_distortion[3]) /
+ 4;
+ }
+ }
+
+ b_enable_intra4x4_eval = true;
+
+ if(ENABLE_IBL_MODE && (ps_proc->u1_spatial_layer_id > 0) &&
+ (ps_proc->s_svc_params.d_spatial_res_ratio == 2.) && !ps_proc->ps_ilp_mv)
+ {
+ isvce_evaluate_IBL_mode(ps_proc);
+ }
+ else
+ {
+ ps_proc->ps_mb_info->u1_base_mode_flag = 0;
+ }
+
+ if(u4_valid_modes & (1 << I16x16))
+ {
+ isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
+
+ if(ENABLE_INTRA16X16_BASED_INTRA4X4_GATING &&
+ (ps_proc->i4_slice_type != ISLICE) &&
+ (ps_proc->ps_mb_info->u2_mb_type == I16x16))
+ {
+ b_enable_intra4x4_eval = false;
+ }
+ }
+
+ if(u4_valid_modes & (1 << I8x8))
+ {
+ isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
+ }
+
+ if(ENABLE_ILP_BASED_INTRA4X4_GATING && (ps_proc->i4_slice_type != ISLICE))
+ {
+ b_enable_intra4x4_eval =
+ !(ps_proc->ps_ilp_mv && (INVALID_MB_TYPE != ps_proc->ps_ilp_mv->e_mb_type));
+ }
+
+ /* If we are going to force intra we need to evaluate intra irrespective
+ * of gating */
+ if((!i4_air_enable_inter) ||
+ ((i4_gate_threshold + 16 * ((WORD32) ps_proc->u4_lambda)) <
+ ps_proc->i4_mb_distortion))
+ {
+ if(b_enable_intra4x4_eval && (u4_valid_modes & (1 << I4x4)))
+ {
+ if(!FORCE_FAST_INTRA4X4 &&
+ (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST))
+ {
+ isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
+ }
+ else
+ {
+ isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
+ }
+ }
+ }
+ }
+ }
+
+ if(ps_proc->ps_mb_info->u2_mb_type == I4x4 || ps_proc->ps_mb_info->u2_mb_type == I16x16 ||
+ ps_proc->ps_mb_info->u2_mb_type == I8x8)
+ {
+ luma_idx = ps_proc->ps_mb_info->u2_mb_type;
+ chroma_idx = 0;
+ is_intra = 1;
+
+ isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
+ }
+ else if(ps_proc->ps_mb_info->u2_mb_type == BASE_MODE)
+ {
+ luma_idx = 3;
+ chroma_idx = 1;
+ is_intra = 1;
+ ps_proc->u4_min_sad_reached = 0;
+ }
+ else
+ {
+ luma_idx = 3;
+ chroma_idx = 1;
+ is_intra = 0;
+ }
+
+ ps_proc->ps_mb_info->u1_is_intra = is_intra;
+
+ if(is_intra)
+ {
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx = -1;
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx = 0;
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy = 0;
+
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1].i1_ref_idx = -1;
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx = 0;
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy = 0;
+ }
+ else
+ {
+ isvce_mv_pred(ps_proc, ps_proc->i4_slice_type);
+ }
+
+ if(ENABLE_RESIDUAL_PREDICTION && !is_intra && (ps_proc->u1_spatial_layer_id > 0) &&
+ (ps_proc->i4_slice_type == PSLICE) && (ps_proc->ps_mb_info->u2_mb_type != PSKIP))
+ {
+ svc_res_pred_ctxt_t *ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt;
+
+ UWORD32 u4_res_pred_sad;
+
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+ yuv_buf_props_t s_pred = ps_proc->s_src_buf_props;
+
+ if(!(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx % 4) &&
+ !(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy % 4))
+ {
+ s_pred.as_component_bufs[Y].pv_data =
+ ps_me_ctxt->apu1_ref_buf_luma[L0] +
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
+ (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) *
+ ps_me_ctxt->ai4_rec_strd[L0];
+ s_pred.as_component_bufs[Y].i4_data_stride = ps_me_ctxt->ai4_rec_strd[L0];
+ }
+ else
+ {
+ s_pred.as_component_bufs[Y].pv_data = ps_proc->pu1_best_subpel_buf;
+ s_pred.as_component_bufs[Y].i4_data_stride = ps_proc->u4_bst_spel_buf_strd;
+ }
+
+ s_pred.as_component_bufs[U].pv_data = s_pred.as_component_bufs[V].pv_data = NULL;
+
+ ps_res_pred_ctxt->s_res_pred_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
+ ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
+ ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
+ ps_res_pred_ctxt->s_res_pred_variables.u1_spatial_layer_id =
+ ps_proc->u1_spatial_layer_id;
+
+ if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.)
+ {
+ isvce_get_mb_residual_pred(ps_proc->ps_res_pred_ctxt);
+ }
+ else
+ {
+ isvce_get_mb_residual_pred_non_dyadic(ps_proc->ps_res_pred_ctxt);
+ }
+
+ isvce_residual_pred_eval(ps_proc->ps_res_pred_ctxt, &ps_proc->s_src_buf_props, &s_pred,
+ ps_proc->ps_mb_res_buf, &u4_res_pred_sad,
+ &ps_proc->ps_mb_info->u1_residual_prediction_flag,
+ ps_proc->i4_mb_distortion);
+
+ if(ps_proc->ps_mb_info->u1_residual_prediction_flag)
+ {
+ ps_proc->i4_mb_cost -= ps_proc->i4_mb_distortion;
+ ps_proc->i4_mb_cost += (WORD32) u4_res_pred_sad;
+ ps_proc->i4_mb_distortion = (WORD32) u4_res_pred_sad;
+ }
+ }
+ else
+ {
+ ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
+ }
+
+ if(isvce_is_ilp_mv_winning_mv(ps_proc->ps_mb_info, ps_proc->ps_ilp_mv))
+ {
+ ps_proc->ps_mb_info->as_pu->as_me_info[L0] = ps_proc->ps_ilp_mv->as_mv[0][L0];
+ ps_proc->ps_mb_info->as_pu->as_me_info[L1] = ps_proc->ps_ilp_mv->as_mv[0][L1];
+
+ ps_proc->ps_mb_info->u1_base_mode_flag = 1;
+ ps_proc->ps_mb_info->u2_mb_type = BASE_MODE;
+ }
+ else if(ps_proc->ps_mb_info->u2_mb_type != BASE_MODE)
+ {
+ ps_proc->ps_mb_info->u1_base_mode_flag = 0;
+ }
+
+ isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv, ps_proc->ps_ilp_mv->as_mv[0],
+ ps_proc->s_me_ctxt.pu1_mv_bits);
+
+ /* 8x8 Tx is not supported, and I8x8 is also unsupported */
+ ASSERT((luma_idx == 0) || (luma_idx == 1) || (luma_idx == 3));
+ ps_proc->ps_mb_info->u1_tx_size = 4;
+
+ /* Perform luma mb core coding */
+ u4_cbp_l = (ps_enc_loop_fxns->apf_luma_energy_compaction)[luma_idx](ps_proc);
+
+ /* Perform chroma mb core coding */
+ u4_cbp_c = (ps_enc_loop_fxns->apf_chroma_energy_compaction)[chroma_idx](ps_proc);
+
+ ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
+ ps_proc->ps_mb_info->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
+ ps_proc->ps_mb_info->u4_csbp = isvce_calculate_csbp(ps_proc);
+
+ if(ps_proc->ps_mb_info->u1_is_intra)
+ {
+ switch(ps_proc->ps_mb_info->u2_mb_type)
+ {
+ case I16x16:
+ {
+ ps_proc->ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode =
+ ps_proc->u1_l_i16_mode;
+
+ break;
+ }
+ case I4x4:
+ {
+ WORD32 i;
+
+ for(i = 0; i < MAX_TU_IN_MB; i++)
+ {
+ ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_mode =
+ ps_proc->au1_intra_luma_mb_4x4_modes[i];
+ ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_predicted_mode =
+ ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i];
+ }
+
+ break;
+ }
+ case BASE_MODE:
+ {
+ break;
+ }
+ default:
+ {
+ ASSERT(false);
+ }
+ }
+
+ ps_proc->ps_mb_info->s_intra_pu.u1_chroma_intra_mode = ps_proc->u1_c_i8_mode;
+ }
+
+ if(!ps_proc->ps_mb_info->u1_is_intra && !ps_proc->ps_mb_info->u1_residual_prediction_flag)
+ {
+ if(ps_proc->i4_slice_type == BSLICE)
+ {
+ if(isvce_find_bskip_params(ps_proc, L0))
+ {
+ ps_proc->ps_mb_info->u2_mb_type = (ps_proc->u4_cbp) ? BDIRECT : BSKIP;
+ }
+ }
+ else if(!ps_proc->u4_cbp)
+ {
+ if(isvce_find_pskip_params(ps_proc, L0))
+ {
+ ps_proc->ps_mb_info->u2_mb_type = PSKIP;
+ }
+ }
+ }
+
+ UPDATE_MB_INFO:
+ isvce_svc_ilp_buf_update(ps_proc);
+
+ isvce_update_ibl_info(
+ ps_proc->ps_intra_pred_ctxt, ps_proc->s_svc_params.u1_num_spatial_layers,
+ ps_proc->u1_spatial_layer_id, ps_proc->ps_mb_info->u2_mb_type, ps_proc->i4_mb_x,
+ ps_proc->i4_mb_y, ps_proc->ps_mb_info->u1_base_mode_flag);
+
+ isvce_update_res_pred_info(ps_proc);
+
+ /* Update mb sad, mb qp and intra mb cost. Will be used by rate control */
+ isvce_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
+
+ {
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
+ svc_sub_pic_rc_mb_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_mb_variables;
+
+ ps_sub_pic_rc_variables->ps_mb_info = ps_proc->ps_mb_info;
+ ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
+ ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
+ ps_sub_pic_rc_variables->u4_cbp = ps_proc->u4_cbp;
+ ps_sub_pic_rc_variables->aps_mvps[0] = ps_proc->ps_pred_mv;
+#if MAX_MVP_IDX == 1
+ ps_sub_pic_rc_variables->aps_mvps[1] = ps_proc->ps_ilp_mv->as_mv[0];
+#endif
+ ps_sub_pic_rc_variables->apu1_nnzs[Y] = (UWORD8 *) ps_proc->au4_nnz;
+ ps_sub_pic_rc_variables->apu1_nnzs[UV] = ps_proc->au1_chroma_nnz;
+
+ /* Quant coeffs are arranged TU by TU */
+ switch(ps_proc->ps_mb_info->u2_mb_type)
+ {
+ case I16x16:
+ case I4x4:
+ case P16x16:
+ case B16x16:
+ case BASE_MODE:
+ {
+ ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data =
+ ps_proc->pi2_res_buf_intra_4x4;
+ ps_sub_pic_rc_variables->as_quant_coeffs[Y].i4_data_stride =
+ ps_proc->i4_res_strd;
+ ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = ps_proc->pi2_res_buf;
+ ps_sub_pic_rc_variables->as_quant_coeffs[UV].i4_data_stride =
+ ps_proc->i4_res_strd;
+
+ break;
+ }
+ case PSKIP:
+ case BSKIP:
+ {
+ ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data = NULL;
+ ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = NULL;
+
+ break;
+ }
+ default:
+ {
+ ASSERT(false);
+
+ break;
+ }
+ }
+
+ isvce_sub_pic_rc_ctxt_update(ps_proc->ps_sub_pic_rc_ctxt);
+ }
+
+#if ENABLE_MODE_STAT_VISUALISER
+ if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
+ {
+ coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
+
+ isvce_msv_set_mode(ps_codec->ps_mode_stat_visualiser, ps_proc->ps_mb_info, &s_mb_pos);
+ }
+#endif
+
+ /**********************************************************************/
+ /* if disable deblock level is '0' this implies enable deblocking for */
+ /* all edges of all macroblocks with out any restrictions */
+ /* */
+ /* if disable deblock level is '1' this implies disable deblocking for*/
+ /* all edges of all macroblocks with out any restrictions */
+ /* */
+ /* if disable deblock level is '2' this implies enable deblocking for */
+ /* all edges of all macroblocks except edges overlapping with slice */
+ /* boundaries. This option is not currently supported by the encoder */
+ /* hence the slice map should be of no significance to perform debloc */
+ /* king */
+ /**********************************************************************/
+
+ if(ps_proc->u4_compute_recon)
+ {
+ /* compute blocking strength */
+ if(ps_proc->u4_disable_deblock_level != 1)
+ {
+ isvce_compute_bs(ps_proc, 0);
+
+ if(ENABLE_INTRA_BASE_DEBLOCK && (ps_proc->u1_spatial_layer_id <
+ (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
+ {
+ isvce_compute_bs(ps_proc, 1);
+ }
+ }
+ /* nmb deblocking and hpel and padding */
+ isvce_dblk_n_mbs(ps_proc, 0);
+
+ if(ENABLE_INTRA_BASE_DEBLOCK &&
+ (ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
+ {
+ isvce_intra_base_dblk(ps_proc);
+ }
+
+ if(ps_proc->i4_mb_x == (ps_proc->i4_wd_mbs - 1) &&
+ ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
+ {
+ isvce_svc_pad_frame(ps_proc);
+
+ isvce_pad_mb_mode_buf(ps_proc->ps_intra_pred_ctxt, ps_proc->u1_spatial_layer_id,
+ ps_proc->s_svc_params.u1_num_spatial_layers,
+ ps_proc->s_svc_params.d_spatial_res_ratio,
+ ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht);
+ }
+ }
+
+ /* update the context after for coding next mb */
+ error_status = isvce_update_proc_ctxt(ps_proc);
+
+ if(error_status != IH264E_SUCCESS)
+ {
+ return error_status;
+ }
+
+ {
+ UWORD8 u1_new_mb_qp;
+
+ u1_new_mb_qp =
+ isvce_sub_pic_rc_get_mb_qp(ps_proc->ps_sub_pic_rc_ctxt, ps_proc->u1_mb_qp);
+
+ if(u1_new_mb_qp != ps_proc->u1_mb_qp)
+ {
+ ps_proc->u1_mb_qp = u1_new_mb_qp;
+ ps_proc->u4_lambda = gu1_qp0[u1_new_mb_qp];
+
+ isvce_init_quant_params(ps_proc, ps_proc->u1_mb_qp);
+ }
+ }
+
+ /* Once the last row is processed, mark the buffer status appropriately */
+ if(ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
+ {
+ /* Pointer to current picture buffer structure */
+ svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
+
+ /* Pointer to current picture's mv buffer structure */
+ svc_au_data_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
+
+ /**********************************************************************/
+ /* if disable deblock level is '0' this implies enable deblocking for */
+ /* all edges of all macroblocks with out any restrictions */
+ /* */
+ /* if disable deblock level is '1' this implies disable deblocking for*/
+ /* all edges of all macroblocks with out any restrictions */
+ /* */
+ /* if disable deblock level is '2' this implies enable deblocking for */
+ /* all edges of all macroblocks except edges overlapping with slice */
+ /* boundaries. This option is not currently supported by the encoder */
+ /* hence the slice map should be of no significance to perform debloc */
+ /* king */
+ /**********************************************************************/
+ error_status = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
+ ps_cur_mv_buf->i4_buf_id, BUF_MGR_CODEC);
+ if(error_status != IH264E_SUCCESS)
+ {
+ return error_status;
+ }
+ error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
+ BUF_MGR_CODEC);
+ if(error_status != IH264E_SUCCESS)
+ {
+ return error_status;
+ }
+ if(ps_codec->s_cfg.u4_enable_recon)
+ {
+ /* pic cnt */
+ ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
+
+ /* rec buffers */
+ ps_codec->as_rec_buf[ctxt_sel].s_pic_buf = *ps_proc->ps_cur_pic;
+
+ /* is last? */
+ ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
+
+ /* frame time stamp */
+ ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high =
+ ps_proc->s_entropy.u4_timestamp_high;
+ ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low =
+ ps_proc->s_entropy.u4_timestamp_low;
+ }
+ }
+ }
+
+ DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* entry point of a spawned encoder thread
+*
+* @par Description:
+* The encoder thread dequeues a proc/entropy job from the encoder queue and
+* calls necessary routines.
+*
+* @param[in] pv_proc
+* Process context corresponding to the thread
+*
+* @returns error status
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_process_thread(void *pv_proc)
+{
+ job_t s_job;
+
+ isvce_process_ctxt_t *ps_proc = pv_proc;
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ IH264_ERROR_T ret = IH264_SUCCESS;
+
+ WORD32 error_status = IH264_SUCCESS;
+ WORD32 is_blocking = 0;
+
+ ps_proc->i4_error_code = IH264_SUCCESS;
+
+ while(1)
+ {
+ /* dequeue a job from the entropy queue */
+ {
+ WORD32 retval = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
+
+ /* codec context selector */
+ WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+
+ volatile UWORD32 *pu4_buf = &ps_codec->au4_entropy_thread_active[ctxt_sel];
+
+ /* have the lock */
+ if(retval == 0)
+ {
+ if(*pu4_buf == 0)
+ {
+ /* no entropy threads are active, try dequeuing a job from the entropy
+ * queue */
+ ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
+ if(IH264_SUCCESS == ret)
+ {
+ *pu4_buf = 1;
+ ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
+ goto WORKER;
+ }
+ else if(is_blocking)
+ {
+ ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
+ break;
+ }
+ }
+ ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
+ }
+ }
+
+ /* dequeue a job from the process queue */
+ ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
+ if(IH264_SUCCESS != ret)
+ {
+ if(ps_proc->i4_id)
+ break;
+ else
+ {
+ is_blocking = 1;
+ continue;
+ }
+ }
+
+ WORKER:
+ /* choose appropriate proc context based on proc_base_idx */
+ switch(s_job.i4_cmd)
+ {
+ case CMD_PROCESS:
+ {
+ ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
+ ps_proc->i4_mb_x = s_job.i2_mb_x;
+ ps_proc->i4_mb_y = s_job.i2_mb_y;
+
+ isvce_init_layer_proc_ctxt(ps_proc);
+
+ error_status = isvce_process(ps_proc);
+
+ if(error_status != IH264_SUCCESS)
+ {
+ ps_proc->i4_error_code = error_status;
+ return ret;
+ }
+
+ break;
+ }
+ case CMD_ENTROPY:
+ {
+ ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
+ ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
+ ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
+
+ isvce_init_entropy_ctxt(ps_proc);
+
+ error_status = isvce_entropy(ps_proc);
+
+ if(error_status != IH264_SUCCESS)
+ {
+ ps_proc->i4_error_code = error_status;
+ return ret;
+ }
+
+ break;
+ }
+ default:
+ {
+ ps_proc->i4_error_code = IH264_FAIL;
+ return ret;
+ }
+ }
+ }
+
+ return ret;
+}
diff --git a/encoder/svc/isvce_process.h b/encoder/svc/isvce_process.h
new file mode 100644
index 0000000..bacd324
--- /dev/null
+++ b/encoder/svc/isvce_process.h
@@ -0,0 +1,285 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_process.h
+*
+* @brief
+* Contains functions for codec thread
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_PROCESS_H_
+#define _ISVCE_PROCESS_H_
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief This function generates sps, pps set on request
+*
+* @par Description
+* When the encoder is set in header generation mode, the following function
+* is called. This generates sps and pps headers and returns the control back
+* to caller.
+*
+* @param[in] ps_codec
+* pointer to codec context
+*
+* @return success or failure error code
+*
+******************************************************************************
+*/
+IH264E_ERROR_T isvce_generate_sps_pps(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf);
+
+/**
+*******************************************************************************
+*
+* @brief initialize entropy context.
+*
+* @par Description:
+* Before invoking the call to perform to entropy coding the entropy context
+* associated with the job needs to be initialized. This involves the start
+* mb address, end mb address, slice index and the pointer to location at
+* which the mb residue info and mb header info are packed.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_init_entropy_ctxt(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief entry point for entropy coding
+*
+* @par Description
+* This function calls lower level functions to perform entropy coding for a
+* group (n rows) of mb's. After encoding 1 row of mb's, the function takes
+* back the control, updates the ctxt and calls lower level functions again.
+* This process is repeated till all the rows or group of mb's (which ever is
+* minimum) are coded
+*
+* @param[in] ps_proc
+* process context
+*
+* @returns error status
+*
+* @remarks
+* NOTE : It is assumed that this routine is invoked at the start of a slice,
+* so the slice header is generated by default.
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_entropy(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief Packs header information of a mb in to a buffer
+*
+* @par Description:
+* After the deciding the mode info of a macroblock, the syntax elements
+* associated with the mb are packed and stored. The entropy thread unpacks
+* this buffer and generates the end bit stream.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_pack_header_data(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief update process context after encoding an mb. This involves preserving
+* the current mb information for later use, initialize the proc ctxt elements to
+* encode next mb.
+*
+* @par Description:
+* This function performs house keeping tasks after encoding an mb.
+* After encoding an mb, various elements of the process context needs to be
+* updated to encode the next mb. For instance, the source, recon and reference
+* pointers, mb indices have to be adjusted to the next mb. The slice index of
+* the current mb needs to be updated. If mb qp modulation is enabled, then if
+* the qp changes the quant param structure needs to be updated. Also to
+*encoding the next mb, the current mb info is used as part of mode prediction or
+*mv prediction. Hence the current mb info has to preserved at top/top left/left
+* locations.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+WORD32 isvce_update_proc_ctxt(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief initialize process context.
+*
+* @par Description:
+* Before dispatching the current job to process thread, the process context
+* associated with the job is initialized. Usually every job aims to encode one
+* row of mb's. Basing on the row indices provided by the job, the process
+* context's buffer ptrs, slice indices and other elements that are necessary
+* during core-coding are initialized.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_init_proc_ctxt(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief This function performs luma & chroma padding
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @param[in] pu1_curr_pic_luma
+* Pointer to luma buffer
+*
+* @param[in] pu1_curr_pic_chroma
+* Pointer to chroma buffer
+*
+* @param[in] i4_mb_x
+* mb index x
+*
+* @param[in] i4_mb_y
+* mb index y
+*
+* @param[in] i4_pad_ht
+* number of rows to be padded
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_pad_recon_buffer(isvce_process_ctxt_t *ps_proc, UWORD8 *pu1_curr_pic_luma,
+ WORD32 i4_luma_stride, UWORD8 *pu1_curr_pic_chroma,
+ WORD32 i4_chroma_stride, WORD32 i4_mb_x, WORD32 i4_mb_y,
+ WORD32 i4_pad_ht);
+
+/**
+*******************************************************************************
+*
+* @brief This function performs luma half pel planes generation
+*
+* @par Description:
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_halfpel_generation(isvce_process_ctxt_t *ps_proc, UWORD8 *pu1_curr_pic_luma,
+ WORD32 i4_mb_x, WORD32 i4_mb_y);
+
+/**
+*******************************************************************************
+*
+* @brief This function performs luma & chroma core coding for a set of mb's.
+*
+* @par Description:
+* The mb to be coded is taken and is evaluated over a predefined set of modes
+* (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least
+*cost is selected and using intra/inter prediction filters, prediction is
+*carried out. The deviation between src and pred signal constitutes error
+*signal. This error signal is transformed (hierarchical transform if necessary)
+*and quantized. The quantized residue is packed in to entropy buffer for entropy
+*coding. This is repeated for all the mb's enlisted under the job.
+*
+* @param[in] ps_proc
+* Process context corresponding to the job
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+WORD32 isvce_process(isvce_process_ctxt_t *ps_proc);
+
+/**
+*******************************************************************************
+*
+* @brief
+* entry point of a spawned encoder thread
+*
+* @par Description:
+* The encoder thread dequeues a proc/entropy job from the encoder queue and
+* calls necessary routines.
+*
+* @param[in] pv_proc
+* Process context corresponding to the thread
+*
+* @returns error status
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_process_thread(void *pv_proc);
+
+#endif
diff --git a/encoder/svc/isvce_rate_control.c b/encoder/svc/isvce_rate_control.c
new file mode 100644
index 0000000..1562f08
--- /dev/null
+++ b/encoder/svc/isvce_rate_control.c
@@ -0,0 +1,716 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_rate_control.c
+*
+* @brief
+* Contains api function definitions for h264 rate control
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_rc_init()
+* - isvce_rc_get_picture_details()
+* - isvce_rc_pre_enc()
+* - isvce_update_rc_mb_info()
+* - isvce_rc_get_buffer_status()
+* - isvce_rc_post_enc()
+* - isvce_update_rc_bits_info()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+#include "ih264_typedefs.h"
+#include "irc_datatypes.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "isvc_defs.h"
+#include "isvc_macros.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_common_tables.h"
+#include "isvc_cabac_tables.h"
+#include "isvce_defs.h"
+#include "isvce_globals.h"
+#include "irc_mem_req_and_acq.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "irc_rate_control_api.h"
+#include "ih264e_time_stamp.h"
+#include "ih264e_modify_frm_rate.h"
+#include "isvce_rate_control.h"
+#include "ih264e_error.h"
+#include "ih264e_time_stamp.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_utils.h"
+#include "irc_trace_support.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function initializes rate control context and variables
+*
+* @par Description
+* This function initializes rate control type, source and target frame rate,
+* average and peak bitrate, intra-inter frame interval and initial
+* quantization parameter
+*
+* @param[in] pv_rc_api
+* Handle to rate control api
+*
+* @param[in] pv_frame_time
+* Handle to frame time context
+*
+* @param[in] pv_time_stamp
+* Handle to time stamp context
+*
+* @param[in] pv_pd_frm_rate
+* Handle to pull down frame time context
+*
+* @param[in] u4_max_frm_rate
+* Maximum frame rate
+*
+* @param[in] u4_src_frm_rate
+* Source frame rate
+*
+* @param[in] u4_tgt_frm_rate
+* Target frame rate
+*
+* @param[in] e_rate_control_type
+* Rate control type
+*
+* @param[in] u4_avg_bit_rate
+* Average bit rate
+*
+* @param[in] u4_peak_bit_rate
+* Peak bit rate
+*
+* @param[in] u4_max_delay
+* Maximum delay between frames
+*
+* @param[in] u4_intra_frame_interval
+* Intra frame interval
+*
+* @param[in] pu1_init_qp
+* Initial qp
+*
+* @param[in] i4_max_inter_frm_int
+* Maximum inter frame interval
+*
+* @param[in] pu1_min_max_qp
+* Array of min/max qp
+*
+* @param[in] u1_profile_level
+* Encoder profile level
+*
+* @returns none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_rc_init(void *pv_rc_api, void *pv_frame_time, void *pv_time_stamp, void *pv_pd_frm_rate,
+ UWORD32 u4_max_frm_rate, UWORD32 u4_src_frm_rate, UWORD32 u4_tgt_frm_rate,
+ rc_type_e e_rate_control_type, UWORD32 u4_avg_bit_rate, UWORD32 u4_peak_bit_rate,
+ UWORD32 u4_max_delay, UWORD32 u4_intra_frame_interval, WORD32 i4_inter_frm_int,
+ UWORD8 *pu1_init_qp, WORD32 i4_max_inter_frm_int, UWORD8 *pu1_min_max_qp,
+ UWORD8 u1_profile_level)
+{
+ // UWORD8 u1_is_mb_level_rc_on = 0;
+ UWORD32 au4_peak_bit_rate[2] = {0, 0};
+ UWORD32 u4_min_bit_rate = 0;
+ WORD32 i4_is_gop_closed = 1;
+ // WORD32 i4_use_est_intra_sad = 1;
+ UWORD32 u4_src_ticks = 0;
+ UWORD32 u4_tgt_ticks = 0;
+ UWORD8 u1_level_idx = ih264e_get_lvl_idx(u1_profile_level);
+ UWORD32 u4_max_cpb_size = 1200 * gas_isvc_lvl_tbl[u1_level_idx].u4_max_cpb_size;
+
+ /* Fill the params needed for the RC init */
+ if(e_rate_control_type == CBR_NLDRC)
+ {
+ au4_peak_bit_rate[0] = u4_avg_bit_rate;
+ au4_peak_bit_rate[1] = u4_avg_bit_rate;
+ }
+ else
+ {
+ au4_peak_bit_rate[0] = u4_peak_bit_rate;
+ au4_peak_bit_rate[1] = u4_peak_bit_rate;
+ }
+
+ /* Initialize frame time computation module*/
+ ih264e_init_frame_time(pv_frame_time, u4_src_frm_rate, /* u4_src_frm_rate */
+ u4_tgt_frm_rate); /* u4_tgt_frm_rate */
+
+ /* Initialize the pull_down frame rate */
+ ih264e_init_pd_frm_rate(pv_pd_frm_rate, u4_src_frm_rate); /* u4_input_frm_rate */
+
+ /* Initialize time stamp structure */
+ ih264e_init_time_stamp(pv_time_stamp, u4_max_frm_rate, /* u4_max_frm_rate */
+ u4_src_frm_rate); /* u4_src_frm_rate */
+
+ u4_src_ticks = ih264e_frame_time_get_src_ticks(pv_frame_time);
+ u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(pv_frame_time);
+
+ /* Init max_inter_frame int */
+ i4_max_inter_frm_int = (i4_inter_frm_int == 1) ? 2 : (i4_inter_frm_int + 2);
+
+ /* Initialize the rate control */
+ irc_initialise_rate_control(
+ pv_rc_api, /* RC handle */
+ e_rate_control_type, /* RC algo type */
+ 0, /* MB activity on/off */
+ u4_avg_bit_rate, /* Avg Bitrate */
+ au4_peak_bit_rate, /* Peak bitrate array[2]:[I][P] */
+ u4_min_bit_rate, /* Min Bitrate */
+ u4_src_frm_rate, /* Src frame_rate */
+ u4_max_delay, /* Max buffer delay */
+ u4_intra_frame_interval, /* Intra frm_interval */
+ i4_inter_frm_int, /* Inter frame interval */
+ pu1_init_qp, /* Init QP array[3]:[I][P][B] */
+ u4_max_cpb_size, /* Max VBV/CPB Buffer Size */
+ i4_max_inter_frm_int, /* Max inter frm_interval */
+ i4_is_gop_closed, /* Open/Closed GOP */
+ pu1_min_max_qp, /* Min-max QP
+ array[6]:[Imax][Imin][Pmax][Pmin][Bmax][Bmin] */
+ 0, /* How to calc the I-frame estimated_sad */
+ u4_src_ticks, /* Src_ticks = LCM(src_frm_rate,tgt_frm_rate)/src_frm_rate
+ */
+ u4_tgt_ticks); /* Tgt_ticks = LCM(src_frm_rate,tgt_frm_rate)/tgt_frm_rate
+ */
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get picture details
+*
+* @par Description
+* This function returns the Picture type(I/P/B)
+*
+* @param[in] pv_rc_api
+* Handle to Rate control api
+*
+* @returns
+* Picture type
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+picture_type_e isvce_rc_get_picture_details(void *pv_rc_api, WORD32 *pi4_pic_id,
+ WORD32 *pi4_pic_disp_order_no)
+{
+ picture_type_e e_rc_pic_type = P_PIC;
+
+ irc_get_picture_details(pv_rc_api, pi4_pic_id, pi4_pic_disp_order_no, &e_rc_pic_type);
+
+ return (e_rc_pic_type);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get rate control output before encoding
+*
+* @par Description
+* This function is called before queing the current frame. It decides if we
+*should skip the current iput buffer due to frame rate mismatch. It also updates
+*RC about the acehivble frame rate
+*
+* @param[in] ps_rate_control_api
+* Handle to rate control api
+*
+* @param[in] ps_pd_frm_rate
+* Handle to pull down frm rate context
+*
+* @param[in] ps_time_stamp
+* Handle to time stamp context
+*
+* @param[in] ps_frame_time
+* Handle to frame time context
+*
+* @param[in] i4_delta_time_stamp
+* Time stamp difference between frames
+*
+* @param[in] i4_total_mb_in_frame
+* Total Macro Blocks in frame
+*
+* @param[in/out] pe_vop_coding_type
+* Picture coding type(I/P/B)
+*
+* @param[in/out] pu1_frame_qp
+* QP for current frame
+*
+* @returns
+* Skip or queue the current frame
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_update_rc_framerates(void *ps_rate_control_api, void *ps_pd_frm_rate,
+ void *ps_time_stamp, void *ps_frame_time)
+{
+ WORD8 i4_skip_src = 0;
+ UWORD32 u4_src_not_skipped_for_dts = 0;
+
+ /* Update the time stamp for the current frame */
+ ih264e_update_time_stamp(ps_time_stamp);
+
+ /* Check if a src not needs to be skipped */
+ i4_skip_src = ih264e_should_src_be_skipped(ps_frame_time, 1, &u4_src_not_skipped_for_dts);
+
+ if(i4_skip_src)
+ {
+ /***********************************************************************
+ *Based on difference in source and target frame rate frames are skipped
+ ***********************************************************************/
+ /*update the missing frames frm_rate with 0 */
+ ih264e_update_pd_frm_rate(ps_pd_frm_rate, 0);
+ }
+ else
+ {
+ WORD32 i4_avg_frm_rate, i4_source_frame_rate;
+
+ i4_source_frame_rate = ih264e_frame_time_get_src_frame_rate(ps_frame_time);
+
+ /* Update the frame rate of the frame present with the tgt_frm_rate */
+ /* If the frm was not skipped due to delta_time_stamp, update the
+ frame_rate with double the tgt_frame_rate value, so that it makes
+ up for one of the frames skipped by the application */
+ ih264e_update_pd_frm_rate(ps_pd_frm_rate, i4_source_frame_rate);
+
+ /* Based on the update get the average frame rate */
+ i4_avg_frm_rate = ih264e_get_pd_avg_frm_rate(ps_pd_frm_rate);
+
+ /* Call the RC library function to change the frame_rate to the
+ actually achieved frm_rate */
+ irc_change_frm_rate_for_bit_alloc(ps_rate_control_api, i4_avg_frm_rate);
+ }
+
+ return (i4_skip_src);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update mb info for rate control context
+*
+* @par Description
+* After encoding a mb, information such as mb type, qp used, mb distortion
+* resulted in encoding the block and so on needs to be preserved for modeling
+* RC. This is preserved via this function call.
+*
+* @param[in] ps_frame_info
+* Handle Frame info context
+*
+* @param[in] ps_proc
+* Process context
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc)
+{
+ /* proc ctxt */
+ isvce_process_ctxt_t *ps_proc = pv_proc;
+
+ /* is intra or inter */
+ WORD32 mb_type = !ps_proc->ps_mb_info->u1_is_intra;
+
+ /* distortion */
+ ps_frame_info->tot_mb_sad[mb_type] += ps_proc->i4_mb_distortion;
+
+ /* qp */
+ ps_frame_info->qp_sum[mb_type] += gau1_h264_to_mpeg2_qmap[ps_proc->u1_mb_qp];
+
+ /* mb cnt */
+ ps_frame_info->num_mbs[mb_type]++;
+
+ /* cost */
+ if(ps_proc->ps_mb_info->u1_is_intra)
+ {
+ ps_frame_info->intra_mb_cost_sum += ps_proc->i4_mb_cost;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to get rate control buffer status
+*
+* @par Description
+* This function is used to get buffer status(underflow/overflow) by rate
+* control module
+*
+* @param[in] pv_rc_api
+* Handle to rate control api context
+*
+* @param[in] i4_total_frame_bits
+* Total frame bits
+*
+* @param[in] u1_pic_type
+* Picture type
+*
+* @param[in] pi4_num_bits_to_prevent_vbv_underflow
+* Number of bits to prevent underflow
+*
+* @param[out] pu1_is_enc_buf_overflow
+* Buffer overflow indication flag
+*
+* @param[out] pu1_is_enc_buf_underflow
+* Buffer underflow indication flag
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_rc_get_buffer_status(void *pv_rc_api, WORD32 i4_total_frame_bits,
+ picture_type_e e_pic_type,
+ WORD32 *pi4_num_bits_to_prevent_vbv_underflow,
+ UWORD8 *pu1_is_enc_buf_overflow, UWORD8 *pu1_is_enc_buf_underflow)
+{
+ vbv_buf_status_e e_vbv_buf_status = VBV_NORMAL;
+
+ e_vbv_buf_status = irc_get_buffer_status(pv_rc_api, i4_total_frame_bits, e_pic_type,
+ pi4_num_bits_to_prevent_vbv_underflow);
+
+ if(e_vbv_buf_status == VBV_OVERFLOW)
+ {
+ *pu1_is_enc_buf_underflow = 1;
+ *pu1_is_enc_buf_overflow = 0;
+ }
+ else if(e_vbv_buf_status == VBV_UNDERFLOW)
+ {
+ *pu1_is_enc_buf_underflow = 0;
+ *pu1_is_enc_buf_overflow = 1;
+ }
+ else
+ {
+ *pu1_is_enc_buf_underflow = 0;
+ *pu1_is_enc_buf_overflow = 0;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update rate control module after encoding
+*
+* @par Description
+* This function is used to update the rate control module after the current
+* frame encoding is done with details such as bits consumed, SAD for I/P/B,
+* intra cost ,mb type and other
+*
+* @param[in] ps_rate_control_api
+* Handle to rate control api context
+*
+* @param[in] ps_frame_info
+* Handle to frame info context
+*
+* @param[in] ps_pd_frm_rate
+* Handle to pull down frame rate context
+*
+* @param[in] ps_time_stamp
+* Handle to time stamp context
+*
+* @param[in] ps_frame_time
+* Handle to frame time context
+*
+* @param[in] i4_total_mb_in_frame
+* Total mb in frame
+*
+* @param[in] pe_vop_coding_type
+* Picture coding type
+*
+* @param[in] i4_is_first_frame
+* Is first frame
+*
+* @param[in] pi4_is_post_encode_skip
+* Post encoding skip flag
+*
+* @param[in] u1_frame_qp
+* Frame qp
+*
+* @param[in] pi4_num_intra_in_prev_frame
+* Numberf of intra mbs in previous frame
+*
+* @param[in] pi4_avg_activity
+* Average activity
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_rc_post_enc(void *ps_rate_control_api, frame_info_t *ps_frame_info,
+ void *ps_pd_frm_rate, void *ps_time_stamp, void *ps_frame_time,
+ WORD32 i4_total_mb_in_frame, picture_type_e *pe_vop_coding_type,
+ WORD32 i4_is_first_frame, WORD32 *pi4_is_post_encode_skip,
+ UWORD8 u1_frame_qp, WORD32 *pi4_num_intra_in_prev_frame,
+ WORD32 *pi4_avg_activity
+#if ENABLE_RE_ENC_AS_SKIP
+ ,
+ UWORD8 *u1_is_post_enc_skip
+#endif
+)
+{
+ /* Variables for the update_frm_level_info */
+ WORD32 ai4_tot_mb_in_type[MAX_MB_TYPE];
+ WORD32 ai4_tot_mb_type_qp[MAX_MB_TYPE] = {0, 0};
+ WORD32 ai4_mb_type_sad[MAX_MB_TYPE] = {0, 0};
+ WORD32 ai4_mb_type_tex_bits[MAX_MB_TYPE] = {0, 0};
+ WORD32 i4_total_frame_bits = 0;
+ WORD32 i4_total_hdr_bits = 0;
+ WORD32 i4_total_texturebits;
+ WORD32 i4_avg_mb_activity = 0;
+ WORD32 i4_intra_frm_cost = 0;
+ UWORD8 u1_is_scd = 0;
+ WORD32 i4_cbr_bits_to_stuff = 0;
+ UWORD32 u4_num_intra_in_prev_frame = *pi4_num_intra_in_prev_frame;
+
+ UNUSED(ps_pd_frm_rate);
+ UNUSED(ps_time_stamp);
+ UNUSED(ps_frame_time);
+ UNUSED(u1_frame_qp);
+ UNUSED(i4_is_first_frame);
+ /* Accumulate RC stats */
+ ai4_tot_mb_in_type[MB_TYPE_INTRA] = irc_fi_get_total_mb(ps_frame_info, MB_TYPE_INTRA);
+ ai4_tot_mb_in_type[MB_TYPE_INTER] = irc_fi_get_total_mb(ps_frame_info, MB_TYPE_INTER);
+ ai4_tot_mb_type_qp[MB_TYPE_INTRA] = irc_fi_get_total_mb_qp(ps_frame_info, MB_TYPE_INTRA);
+ ai4_tot_mb_type_qp[MB_TYPE_INTER] = irc_fi_get_total_mb_qp(ps_frame_info, MB_TYPE_INTER);
+ ai4_mb_type_sad[MB_TYPE_INTRA] = irc_fi_get_total_mb_sad(ps_frame_info, MB_TYPE_INTRA);
+ ai4_mb_type_sad[MB_TYPE_INTER] = irc_fi_get_total_mb_sad(ps_frame_info, MB_TYPE_INTER);
+ i4_intra_frm_cost = irc_fi_get_total_intra_mb_cost(ps_frame_info);
+ i4_avg_mb_activity = irc_fi_get_avg_activity(ps_frame_info);
+ i4_total_hdr_bits = irc_fi_get_total_header_bits(ps_frame_info);
+ i4_total_texturebits = irc_fi_get_total_mb_texture_bits(ps_frame_info, MB_TYPE_INTRA);
+ i4_total_texturebits += irc_fi_get_total_mb_texture_bits(ps_frame_info, MB_TYPE_INTER);
+ i4_total_frame_bits = i4_total_hdr_bits + i4_total_texturebits;
+
+ *pi4_avg_activity = i4_avg_mb_activity;
+
+ /* Texture bits are not accumulated. Hence subtracting hdr bits from total
+ * bits */
+ ai4_mb_type_tex_bits[MB_TYPE_INTRA] = 0;
+ ai4_mb_type_tex_bits[MB_TYPE_INTER] = i4_total_frame_bits - i4_total_hdr_bits;
+
+ /* Set post encode skip to zero */
+ pi4_is_post_encode_skip[0] = 0;
+
+ /* For NLDRC, get the buffer status for stuffing or skipping */
+ if(irc_get_rc_type(ps_rate_control_api) == CBR_NLDRC)
+ {
+ WORD32 i4_get_num_bit_to_prevent_vbv_overflow;
+ UWORD8 u1_enc_buf_overflow, u1_enc_buf_underflow;
+
+ /* Getting the buffer status */
+ isvce_rc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits, pe_vop_coding_type[0],
+ &i4_get_num_bit_to_prevent_vbv_overflow, &u1_enc_buf_overflow,
+ &u1_enc_buf_underflow);
+
+ /* We skip the frame if decoder buffer is underflowing. But we never skip
+ * first I frame */
+#if !DISABLE_POST_ENC_SKIP
+ if((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 1))
+ // if ((u1_enc_buf_overflow == 1) && (i4_is_first_frame != 0))
+ {
+ irc_post_encode_frame_skip(ps_rate_control_api, (picture_type_e) pe_vop_coding_type[0]);
+ // i4_total_frame_bits = imp4_write_skip_frame_header(ps_enc);
+ i4_total_frame_bits = 0;
+
+ *pi4_is_post_encode_skip = 1;
+
+ /* Adjust the GOP if in case we skipped an I-frame */
+ if(*pe_vop_coding_type == I_PIC) irc_force_I_frame(ps_rate_control_api);
+
+ /* Since this frame is skipped by writing 7 bytes header, we say this is a
+ * P frame */
+ // *pe_vop_coding_type = P;
+
+ /* Getting the buffer status again,to check if it underflows */
+ irc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits,
+ (picture_type_e) pe_vop_coding_type[0],
+ &i4_get_num_bit_to_prevent_vbv_overflow);
+ }
+#endif
+
+#if ENABLE_RE_ENC_AS_SKIP
+ /* Check for VBV constraints - post encode skip */
+ if(u1_enc_buf_overflow == 1 && (pe_vop_coding_type[0] != I_PIC))
+ {
+ *u1_is_post_enc_skip = 1;
+
+ ai4_tot_mb_in_type[MB_TYPE_INTER] += ai4_tot_mb_in_type[MB_TYPE_INTRA];
+ ai4_tot_mb_in_type[MB_TYPE_INTRA] = 0;
+ ai4_tot_mb_type_qp[MB_TYPE_INTER] += ai4_tot_mb_type_qp[MB_TYPE_INTRA];
+ ai4_tot_mb_type_qp[MB_TYPE_INTRA] = 0;
+
+ ai4_mb_type_sad[MB_TYPE_INTER] += ai4_mb_type_sad[MB_TYPE_INTRA];
+ ai4_mb_type_sad[MB_TYPE_INTRA] = 0;
+
+ i4_intra_frm_cost = 0;
+
+ i4_total_hdr_bits = 0;
+ i4_total_texturebits = 0;
+ i4_total_frame_bits = i4_total_hdr_bits + i4_total_texturebits;
+
+ ai4_mb_type_tex_bits[MB_TYPE_INTRA] = 0;
+ ai4_mb_type_tex_bits[MB_TYPE_INTER] = i4_total_frame_bits - i4_total_hdr_bits;
+
+ /* Getting the buffer status again,to check if it underflows */
+ irc_get_buffer_status(ps_rate_control_api, i4_total_frame_bits,
+ (picture_type_e) pe_vop_coding_type[0],
+ &i4_get_num_bit_to_prevent_vbv_overflow);
+ }
+#endif
+
+ /* In this case we stuff bytes as buffer is overflowing */
+ if(u1_enc_buf_underflow == 1)
+ {
+ /* The stuffing function is directly pulled out from split controller
+ workspace. encode_vop_data() function makes sure alignment data is
+ dumped at the end of a frame. Split controller was identifying this
+ alignment byte, overwriting it with the stuff data and then finally
+ aligning the buffer. Here every thing is inside the DSP. So, ideally
+ encode_vop_data needn't align, and we can start stuffing directly. But
+ in that case, it'll break the logic for a normal frame. Hence for
+ simplicity, not changing this part since it is ok to align and then
+ overwrite since stuffing is not done for every frame */
+ i4_cbr_bits_to_stuff = irc_get_bits_to_stuff(ps_rate_control_api, i4_total_frame_bits,
+ pe_vop_coding_type[0]);
+
+ /* Just add extra 32 bits to make sure we don't stuff lesser */
+ i4_cbr_bits_to_stuff += 32;
+
+ /* We can not stuff more than the outbuf size. So have a check here */
+ /* Add stuffed bits to total bits */
+ i4_total_frame_bits += i4_cbr_bits_to_stuff;
+ }
+ }
+
+ /* If number of intra MBs are more than 2/3rd of total MBs, assume it as a
+ * scene change */
+ if((ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((2 * i4_total_mb_in_frame) / 3)) &&
+ (*pe_vop_coding_type == P_PIC) &&
+ (ai4_tot_mb_in_type[MB_TYPE_INTRA] > ((11 * (WORD32) u4_num_intra_in_prev_frame) / 10)))
+ {
+ u1_is_scd = 1;
+ }
+
+ /* Update num intra mbs of this frame */
+ if(pi4_is_post_encode_skip[0] == 0)
+ {
+ *pi4_num_intra_in_prev_frame = ai4_tot_mb_in_type[MB_TYPE_INTRA];
+ }
+
+ /* Reset intra count to zero, if u encounter an I frame */
+ if(*pe_vop_coding_type == I_PIC)
+ {
+ *pi4_num_intra_in_prev_frame = 0;
+ }
+
+ /* Do an update of rate control after post encode */
+ irc_update_frame_level_info(ps_rate_control_api, /* RC state */
+ pe_vop_coding_type[0], /* PIC type */
+ ai4_mb_type_sad, /* SAD for [Intra/Inter] */
+ i4_total_frame_bits, /* Total frame bits */
+ i4_total_hdr_bits, /* header bits for */
+ ai4_mb_type_tex_bits, /* for MB[Intra/Inter] */
+ ai4_tot_mb_type_qp, /* for MB[Intra/Inter] */
+ ai4_tot_mb_in_type, /* for MB[Intra/Inter] */
+ i4_avg_mb_activity, /* Average mb activity in frame */
+ u1_is_scd, /* Is a scene change detected */
+ 0, /* Pre encode skip */
+ (WORD32) i4_intra_frm_cost, /* Intra cost for frame */
+ 0); /* Not done outside */
+
+ return (i4_cbr_bits_to_stuff >> 3);
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to update bits consumed info to rate control context
+*
+* @par Description
+* Function to update bits consume info to rate control context
+*
+* @param[in] ps_frame_info
+* Frame info context
+*
+* @param[in] ps_entropy
+* Entropy context
+*
+* @returns
+* total bits consumed by the frame
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_update_rc_bits_info(frame_info_t *ps_frame_info, void *pv_entropy)
+{
+ isvce_entropy_ctxt_t *ps_entropy = pv_entropy;
+
+ ps_frame_info->mb_header_bits[MB_TYPE_INTRA] += ps_entropy->u4_header_bits[MB_TYPE_INTRA];
+
+ ps_frame_info->mb_texture_bits[MB_TYPE_INTRA] += ps_entropy->u4_residue_bits[MB_TYPE_INTRA];
+
+ ps_frame_info->mb_header_bits[MB_TYPE_INTER] += ps_entropy->u4_header_bits[MB_TYPE_INTER];
+
+ ps_frame_info->mb_texture_bits[MB_TYPE_INTER] += ps_entropy->u4_residue_bits[MB_TYPE_INTER];
+
+ return;
+}
diff --git a/encoder/svc/isvce_rate_control.h b/encoder/svc/isvce_rate_control.h
new file mode 100644
index 0000000..26e0a98
--- /dev/null
+++ b/encoder/svc/isvce_rate_control.h
@@ -0,0 +1,330 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_rate_control.h
+*
+* @brief
+* This file contains function declarations of api functions for h264 rate
+* control
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_RATE_CONTROL_H_
+#define _ISVCE_RATE_CONTROL_H_
+
+#if ENABLE_RE_ENC_AS_SKIP
+#include "isvce_structs.h"
+#endif
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* This function initializes rate control context and variables
+*
+* @par Description
+* This function initializes rate control type, source and target frame rate,
+* average and peak bitrate, intra-inter frame interval and initial
+* quantization parameter
+*
+* @param[in] pv_rc_api
+* Handle to rate control api
+*
+* @param[in] pv_frame_time
+* Handle to frame time context
+*
+* @param[in] pv_time_stamp
+* Handle to time stamp context
+*
+* @param[in] pv_pd_frm_rate
+* Handle to pull down frame time context
+*
+* @param[in] u4_max_frm_rate
+* Maximum frame rate
+*
+* @param[in] u4_src_frm_rate
+* Source frame rate
+*
+* @param[in] u4_tgt_frm_rate
+* Target frame rate
+*
+* @param[in] e_rate_control_type
+* Rate control type
+*
+* @param[in] u4_avg_bit_rate
+* Average bit rate
+*
+* @param[in] u4_peak_bit_rate
+* Peak bit rate
+*
+* @param[in] u4_max_delay
+* Maximum delay between frames
+*
+* @param[in] u4_intra_frame_interval
+* Intra frame interval
+*
+* @param[in] i4_inter_frm_int
+* Inter frame interval
+*
+* @param[in] pu1_init_qp
+* Initial qp
+*
+* @param[in] i4_max_inter_frm_int
+* Maximum inter frame interval
+*
+* @param[in] pu1_min_max_qp
+* Array of min/max qp
+*
+* @param[in] u1_profile_level
+* Encoder profile level
+*
+* @returns none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_rc_init(void *pv_rc_api, void *pv_frame_time, void *pv_time_stamp, void *pv_pd_frm_rate,
+ UWORD32 u4_max_frm_rate, UWORD32 u4_src_frm_rate, UWORD32 u4_tgt_frm_rate,
+ rc_type_e e_rate_control_type, UWORD32 u4_avg_bit_rate, UWORD32 u4_peak_bit_rate,
+ UWORD32 u4_max_delay, UWORD32 u4_intra_frame_interval, WORD32 i4_inter_frm_int,
+ UWORD8 *pu1_init_qp, WORD32 i4_max_inter_frm_int, UWORD8 *pu1_min_max_qp,
+ UWORD8 u1_profile_level);
+
+/**
+*******************************************************************************
+*
+* @brief Function to get picture details
+*
+* @par Description
+* This function returns the Picture type(I/P/B)
+*
+* @param[in] pv_rc_api
+* Handle to Rate control api
+*
+* @returns
+* Picture type
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+picture_type_e isvce_rc_get_picture_details(void *pv_rc_api, WORD32 *pi4_pic_id,
+ WORD32 *pi4_pic_disp_order_no);
+
+/**
+*******************************************************************************
+*
+* @brief Function to set frame rate inside RC.
+*
+* @par Description
+* This function is called before encoding the current frame and gets the qp
+* for the current frame from rate control module
+*
+* @param[in] ps_rate_control_api
+* Handle to rate control api
+*
+* @param[in] ps_pd_frm_rate
+* Handle to pull down frm rate context
+*
+* @param[in] ps_time_stamp
+* Handle to time stamp context
+*
+* @param[in] ps_frame_time
+* Handle to frame time context
+*
+* @returns
+* Skip or encode the current frame
+*
+* @remarks
+*
+*******************************************************************************
+*/
+WORD32 isvce_update_rc_framerates(void *ps_rate_control_api, void *ps_pd_frm_rate,
+ void *ps_time_stamp, void *ps_frame_time);
+
+/**
+*******************************************************************************
+*
+* @brief Function to update mb info for rate control context
+*
+* @par Description
+* After encoding a mb, information such as mb type, qp used, mb distortion
+* resulted in encoding the block and so on needs to be preserved for modelling
+* RC. This is preserved via this function call.
+*
+* @param[in] ps_frame_info
+* Handle Frame info context
+*
+* @param[in] ps_proc
+* Process context
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_update_rc_mb_info(frame_info_t *ps_frame_info, void *pv_proc);
+
+/**
+*******************************************************************************
+*
+* @brief Function to get rate control buffer status
+*
+* @par Description
+* This function is used to get buffer status(underflow/overflow) by rate
+* control module
+*
+* @param[in] pv_rc_api
+* Handle to rate control api context
+*
+* @param[in] i4_total_frame_bits
+* Total frame bits
+*
+* @param[in] u1_pic_type
+* Picture type
+*
+* @param[in] pi4_num_bits_to_prevent_vbv_underflow
+* Number of bits to prevent underflow
+*
+* @param[out] pu1_is_enc_buf_overflow
+* Buffer overflow indication flag
+*
+* @param[out] pu1_is_enc_buf_underflow
+* Buffer underflow indication flag
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_rc_get_buffer_status(void *pv_rc_api, WORD32 i4_total_frame_bits,
+ picture_type_e e_pic_type,
+ WORD32 *pi4_num_bits_to_prevent_vbv_underflow,
+ UWORD8 *pu1_is_enc_buf_overflow, UWORD8 *pu1_is_enc_buf_underflow);
+
+/**
+*******************************************************************************
+*
+* @brief Function to update rate control module after encoding
+*
+* @par Description
+* This function is used to update the rate control module after the current
+* frame encoding is done with details such as bits consumed, SAD for I/P/B,
+* intra cost ,mb type and other
+*
+* @param[in] ps_rate_control_api
+* Handle to rate control api context
+*
+* @param[in] ps_frame_info
+* Handle to frame info context
+*
+* @param[in] ps_pd_frm_rate
+* Handle to pull down frame rate context
+*
+* @param[in] ps_time_stamp
+* Handle to time stamp context
+*
+* @param[in] ps_frame_time
+* Handle to frame time context
+*
+* @param[in] i4_total_mb_in_frame
+* Total mb in frame
+*
+* @param[in] pe_vop_coding_type
+* Picture coding type
+*
+* @param[in] i4_is_first_frame
+* Is first frame
+*
+* @param[in] pi4_is_post_encode_skip
+* Post encoding skip flag
+*
+* @param[in] u1_frame_qp
+* Frame qp
+*
+* @param[in] pi4_num_intra_in_prev_frame
+* Number of intra mbs in previous frame
+*
+* @param[in] pi4_avg_activity
+* Average activity
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+#if ENABLE_RE_ENC_AS_SKIP
+WORD32 isvce_rc_post_enc(void *ps_rate_control_api, frame_info_t *ps_frame_info,
+ void *ps_pd_frm_rate, void *ps_time_stamp, void *ps_frame_time,
+ WORD32 i4_total_mb_in_frame, picture_type_e *pe_vop_coding_type,
+ WORD32 i4_is_first_frame, WORD32 *pi4_is_post_encode_skip,
+ UWORD8 u1_frame_qp, WORD32 *pi4_num_intra_in_prev_frame,
+ WORD32 *pi4_avg_activity, UWORD8 *u1_is_post_enc_skip);
+#else
+WORD32 isvce_rc_post_enc(void *ps_rate_control_api, frame_info_t *ps_frame_info,
+ void *ps_pd_frm_rate, void *ps_time_stamp, void *ps_frame_time,
+ WORD32 i4_total_mb_in_frame, picture_type_e *pe_vop_coding_type,
+ WORD32 i4_is_first_frame, WORD32 *pi4_is_post_encode_skip,
+ UWORD8 u1_frame_qp, WORD32 *pi4_num_intra_in_prev_frame,
+ WORD32 *pi4_avg_activity);
+
+#endif
+/**
+*******************************************************************************
+*
+* @brief Function to update bits consumed info to rate control context
+*
+* @par Description
+* Function to update bits consume info to rate control context
+*
+* @param[in] ps_frame_info
+* Frame info context
+*
+* @param[in] ps_entropy
+* Entropy context
+*
+* @returns
+* total bits consumed by the frame
+*
+* @remarks
+*
+*******************************************************************************
+*/
+void isvce_update_rc_bits_info(frame_info_t *ps_frame_info, void *pv_entropy);
+
+#endif
diff --git a/encoder/svc/isvce_rc_mem_interface.c b/encoder/svc/isvce_rc_mem_interface.c
new file mode 100644
index 0000000..b021781
--- /dev/null
+++ b/encoder/svc/isvce_rc_mem_interface.c
@@ -0,0 +1,325 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_rc_mem_interface.c
+*
+* @brief
+* This file contains api function definitions for rate control memtabs
+*
+* @author
+* ittiam
+*
+* List of Functions
+* - fill_memtab()
+* - use_or_fill_base()
+* - isvce_map_rc_mem_recs_to_itt_api()
+* - isvce_map_itt_mem_rec_to_rc_mem_rec()
+* - isvce_get_rate_control_mem_tab()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <math.h>
+
+/* User Include Files */
+#include "ih264e_config.h"
+#include "ih264_typedefs.h"
+#include "ih264_size_defs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "isvce.h"
+#include "ithread.h"
+#include "isvc_defs.h"
+#include "ih264_debug.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_common_tables.h"
+#include "ih264_list.h"
+#include "isvc_cabac_tables.h"
+#include "ih264e_error.h"
+#include "isvce_defs.h"
+#include "ih264e_bitstream.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_master.h"
+#include "ih264_buf_mgr.h"
+#include "ih264_dpb_mgr.h"
+#include "isvce_utils.h"
+#include "ih264e_platform_macros.h"
+#include "ih264_cavlc_tables.h"
+#include "ih264e_statistics.h"
+#include "ih264e_trace.h"
+#include "ih264e_fmt_conv.h"
+#include "isvce_cavlc.h"
+#include "ih264e_rc_mem_interface.h"
+#include "isvce_rc_mem_interface.h"
+#include "ih264e_time_stamp.h"
+#include "irc_common.h"
+#include "irc_rd_model.h"
+#include "irc_est_sad.h"
+#include "irc_fixed_point_error_bits.h"
+#include "irc_vbr_storage_vbv.h"
+#include "irc_picture_type.h"
+#include "irc_bit_allocation.h"
+#include "irc_mb_model_based.h"
+#include "irc_cbr_buffer_control.h"
+#include "irc_vbr_str_prms.h"
+#include "irc_rate_control_api.h"
+#include "irc_rate_control_api_structs.h"
+#include "ih264e_modify_frm_rate.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+******************************************************************************
+*
+* @brief This function maps rc mem records structure to encoder lib mem records
+* structure
+*
+* @par Description
+* This function maps rc mem records structure to encoder lib mem records
+* structure
+*
+* @param[in] ps_mem
+* pointer to encoder lib mem records
+*
+* @param[in] rc_memtab
+* pointer to rc mem records
+*
+* @param[in] num_mem_recs
+* number of memory records
+*
+* @return void
+*
+******************************************************************************
+*/
+static void isvce_map_rc_mem_recs_to_itt_api(iv_mem_rec_t *ps_mem, itt_memtab_t *rc_memtab,
+ UWORD32 num_mem_recs)
+{
+ UWORD32 j;
+ UWORD32 Size, align;
+
+ for(j = 0; j < num_mem_recs; j++)
+ {
+ Size = rc_memtab->u4_size;
+ align = rc_memtab->i4_alignment;
+
+ /* we always ask for external persistent cacheable memory */
+ FILL_MEMTAB(ps_mem, j, Size, align, IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM);
+
+ rc_memtab++;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief This function maps encoder lib mem records structure to RC memory
+* records structure
+*
+* @par Description
+* This function maps encoder lib mem records structure to RC memory
+* records structure
+*
+* @param[in] ps_mem
+* pointer to encoder lib mem records
+*
+* @param[in] rc_memtab
+* pointer to rc mem records
+*
+* @param[in] num_mem_recs
+* Number of memory records
+
+* @returns none
+*
+* @remarks
+*
+*******************************************************************************
+*/
+static void isvce_map_itt_mem_rec_to_rc_mem_rec(iv_mem_rec_t *ps_mem, itt_memtab_t *rc_memtab,
+ UWORD32 num_mem_recs)
+{
+ UWORD32 i;
+
+ for(i = 0; i < num_mem_recs; i++)
+ {
+ rc_memtab->i4_alignment = ps_mem->u4_mem_alignment;
+ rc_memtab->u4_size = ps_mem->u4_mem_size;
+ rc_memtab->pv_base = ps_mem->pv_base;
+
+ /* only DDR memory is available */
+ rc_memtab->e_mem_region = DDR;
+ rc_memtab->e_usage = PERSISTENT;
+
+ rc_memtab++;
+ ps_mem++;
+ }
+}
+
+/**
+******************************************************************************
+*
+* @brief Get memtabs for rate control
+*
+* @par Description
+* This routine is used to Get/init memtabs for rate control
+*
+* @param[in] pv_rate_control
+* pointer to rate control context (handle)
+*
+* @param[in] ps_mem
+* pointer to encoder lib mem records
+*
+* @param[in] e_func_type
+* enum that dictates fill memory records or Init memory records
+*
+* @return total number of mem records
+*
+******************************************************************************
+*/
+WORD32 isvce_get_rate_control_mem_tab(void *pv_rate_control, iv_mem_rec_t *ps_mem,
+ ITT_FUNC_TYPE_E e_func_type)
+{
+ itt_memtab_t as_itt_memtab[NUM_SVCE_RC_MEMTABS];
+ WORD32 i4_num_memtab = 0, j = 0;
+ void *refptr2[RC_MEM_CNT];
+ void **refptr1[RC_MEM_CNT];
+ isvce_rate_control_ctxt_t *ps_rate_control = pv_rate_control;
+
+ for(j = 0; j < RC_MEM_CNT; j++) refptr1[j] = &(refptr2[j]);
+
+ j = 0;
+
+ if(e_func_type == USE_BASE || e_func_type == FILL_BASE)
+ {
+ refptr1[RC_MEM_FRAME_TIME] = &ps_rate_control->pps_frame_time;
+ refptr1[RC_MEM_TIME_STAMP] = &ps_rate_control->pps_time_stamp;
+ refptr1[RC_MEM_FRAME_RATE] = &ps_rate_control->pps_pd_frm_rate;
+ refptr1[RC_MEM_API_L0] = &ps_rate_control->apps_rate_control_api[0];
+ refptr1[RC_MEM_API_L1] = &ps_rate_control->apps_rate_control_api[1];
+ refptr1[RC_MEM_API_L2] = &ps_rate_control->apps_rate_control_api[2];
+ }
+
+ /* Get the total number of memtabs used by Frame time Module */
+ i4_num_memtab = ih264e_frame_time_get_init_free_memtab(
+ (frame_time_t **) refptr1[RC_MEM_FRAME_TIME], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Frame time Module */
+ i4_num_memtab = ih264e_frame_time_get_init_free_memtab(
+ (frame_time_t **) refptr1[RC_MEM_FRAME_TIME], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ /* Get the total number of memtabs used by Time stamp Module */
+ i4_num_memtab = ih264e_time_stamp_get_init_free_memtab(
+ (time_stamp_t **) refptr1[RC_MEM_TIME_STAMP], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Time Stamp Module */
+ i4_num_memtab = ih264e_time_stamp_get_init_free_memtab(
+ (time_stamp_t **) refptr1[RC_MEM_TIME_STAMP], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ /* Get the total number of memtabs used by Frame rate Module */
+ i4_num_memtab = ih264e_pd_frm_rate_get_init_free_memtab(
+ (pd_frm_rate_t **) refptr1[RC_MEM_FRAME_RATE], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Frame Rate Module */
+ i4_num_memtab = ih264e_pd_frm_rate_get_init_free_memtab(
+ (pd_frm_rate_t **) refptr1[RC_MEM_FRAME_RATE], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ /* Get the total number of memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L0], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L0], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ /* Get the total number of memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L1], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L1], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ /* Get the total number of memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L2], NULL, GET_NUM_MEMTAB);
+ /* Few extra steps during init */
+ isvce_map_itt_mem_rec_to_rc_mem_rec((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ /* Fill the memtabs used by Rate Controller */
+ i4_num_memtab = irc_rate_control_num_fill_use_free_memtab(
+ (rate_control_api_t **) refptr1[RC_MEM_API_L2], as_itt_memtab + j, e_func_type);
+ /* Mapping ittiam memtabs to App. memtabs */
+ isvce_map_rc_mem_recs_to_itt_api((&ps_mem[j]), as_itt_memtab + j, i4_num_memtab);
+ j += i4_num_memtab;
+
+ return j; /* Total MemTabs Needed by Rate Control Module */
+}
diff --git a/encoder/svc/isvce_rc_mem_interface.h b/encoder/svc/isvce_rc_mem_interface.h
new file mode 100644
index 0000000..ff7a475
--- /dev/null
+++ b/encoder/svc/isvce_rc_mem_interface.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file
+* isvce_rc_mem_interface.h
+*
+* @brief
+* This file contains function declaration and structures for rate control
+* memtabs
+*
+* @author
+* ittiam
+*
+* @remarks
+* The rate control library is a global library across various codecs. It
+* anticipates certain structures definitions. Those definitions are to be
+* imported from global workspace. Instead of that, the structures needed for
+* rc library are copied in to this file and exported to rc library. If the
+* structures / enums / ... in the global workspace change, this file also needs
+* to be modified accordingly.
+*
+******************************************************************************
+*/
+#ifndef _ISVCE_RC_MEM_INTERFACE_H_
+#define _ISVCE_RC_MEM_INTERFACE_H_
+
+#include "ih264e_rc_mem_interface.h"
+
+/**
+ ***************************************************************************
+ * Enum to hold mem records in RC
+ ****************************************************************************
+ */
+typedef enum RC_MEM_TYPES_T
+{
+ RC_MEM_FRAME_TIME,
+
+ RC_MEM_TIME_STAMP,
+
+ RC_MEM_FRAME_RATE,
+
+ RC_MEM_API_L0,
+
+ RC_MEM_API_L1,
+
+ RC_MEM_API_L2,
+
+ RC_MEM_CNT
+
+ /*
+ * Do not add anything below
+ */
+} RC_MEM_TYPES_T;
+
+extern WORD32 isvce_get_rate_control_mem_tab(void *pv_rate_control, iv_mem_rec_t *ps_mem,
+ ITT_FUNC_TYPE_E e_func_type);
+
+#endif
diff --git a/encoder/svc/isvce_rc_utils.c b/encoder/svc/isvce_rc_utils.c
new file mode 100644
index 0000000..a7bb090
--- /dev/null
+++ b/encoder/svc/isvce_rc_utils.c
@@ -0,0 +1,286 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_rc_utils.c
+*
+* @brief
+* Contains get gpp function required by the SVC encoder
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_get_gpp()
+* - isvce_rc_utils_init()
+* - isvce_get_rc_utils_data_size()
+* - isvce_compute_gpp()
+* - isvce_get_gpp_function_selector()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "isvc_structs.h"
+#include "isvce_rc_utils.h"
+#include "isvce_rc_utils_private_defs.h"
+
+/**
+*******************************************************************************
+*
+* @brief
+* get gpp function
+*
+* @par Description:
+* computes gradient per pixel value for a given frame
+*
+* @param[in] ps_input_buf
+* pointer to yuv buffer properties
+*
+* @returns
+* calculated gpp value
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+static DOUBLE isvce_get_gpp(yuv_buf_props_t *ps_input_buf)
+{
+ UWORD32 i, j;
+
+ DOUBLE d_gpp_y = 0;
+ DOUBLE d_gpp_u = 0;
+ DOUBLE d_gpp_v = 0;
+
+ DOUBLE d_gpp = 0;
+
+ UWORD32 u4_width = ps_input_buf->u4_width;
+ UWORD32 u4_height = ps_input_buf->u4_height;
+
+ UWORD8 *pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[0].pv_data;
+ WORD32 i4_input_stride = ps_input_buf->as_component_bufs[0].i4_data_stride;
+
+ for(i = 0; i < u4_height - 1; i++)
+ {
+ for(j = 0; j < u4_width - 1; j++)
+ {
+ UWORD8 u1_cur_pix = pu1_input_buf[j];
+ UWORD8 u1_bot_pix = pu1_input_buf[i4_input_stride + j];
+ UWORD8 u1_right_pix = pu1_input_buf[j + 1];
+
+ d_gpp_y += (ABS(u1_cur_pix - u1_bot_pix) + ABS(u1_cur_pix - u1_right_pix));
+ }
+ pu1_input_buf += i4_input_stride;
+ }
+
+ pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[1].pv_data;
+ i4_input_stride = ps_input_buf->as_component_bufs[1].i4_data_stride;
+
+ for(i = 0; i < (u4_height >> 1) - 1; i++)
+ {
+ for(j = 0; j < u4_width - 2; j += 2)
+ {
+ UWORD8 u1_cur_pix = pu1_input_buf[j];
+ UWORD8 u1_bot_pix = pu1_input_buf[i4_input_stride + j];
+ UWORD8 u1_right_pix = pu1_input_buf[j + 2];
+
+ d_gpp_u += (ABS(u1_cur_pix - u1_bot_pix) + ABS(u1_cur_pix - u1_right_pix));
+
+ u1_cur_pix = pu1_input_buf[j + 1];
+ u1_bot_pix = pu1_input_buf[i4_input_stride + j + 1];
+ u1_right_pix = pu1_input_buf[j + 2 + 1];
+
+ d_gpp_v += (ABS(u1_cur_pix - u1_bot_pix) + ABS(u1_cur_pix - u1_right_pix));
+ }
+ pu1_input_buf += i4_input_stride;
+ }
+
+ d_gpp_y /= (u4_width * u4_height);
+ d_gpp_u /= ((u4_width >> 1) * (u4_height >> 1));
+ d_gpp_v /= ((u4_width >> 1) * (u4_height >> 1));
+
+ d_gpp = (DOUBLE) ((4 * d_gpp_y) + d_gpp_u + d_gpp_v) / 6;
+
+ return d_gpp;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the memory size required for compute gpp
+*
+* @par Description:
+* returns the memory required by the rc utils context and state structs
+* for allocation.
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+UWORD32 isvce_get_rc_utils_data_size() { return sizeof(svc_rc_utils_state_t); }
+
+/**
+*******************************************************************************
+*
+* @brief
+* compute gpp process
+*
+* @par Description:
+* calls the function to compute gpp
+*
+* @param[in] ps_svc_rc_utils_ctxt
+* pointer to svc rc utils context
+*
+* @param[in] ps_input_buf
+* pointer to yuv buffer properties
+*
+* @returns
+* calculated gpp value
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+DOUBLE isvce_compute_gpp(svc_rc_utils_ctxt_t *ps_svc_rc_utils_ctxt, yuv_buf_props_t *ps_input_buf)
+{
+ svc_rc_utils_state_t *ps_rc_utils_state =
+ (svc_rc_utils_state_t *) ps_svc_rc_utils_ctxt->pv_rc_utils_state;
+
+ return ps_rc_utils_state->pf_get_gpp(ps_input_buf);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* selects which function to call for get gpp based on e_arch
+*
+* @par Description:
+*
+* @param[in] ps_rc_utils_state
+* pointer to svc rc utils state
+*
+* @param[in] e_arch
+* architecure type
+*
+* @returns
+*
+* @remarks
+*
+*******************************************************************************
+*/
+
+static void isvce_get_gpp_function_selector(svc_rc_utils_state_t *ps_rc_utils_state,
+ IV_ARCH_T e_arch)
+{
+ switch(e_arch)
+ {
+#if defined(X86)
+ case ARCH_X86_SSE42:
+ {
+ ps_rc_utils_state->pf_get_gpp = isvce_get_gpp_sse42;
+
+ break;
+ }
+#elif defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ {
+ ps_rc_utils_state->pf_get_gpp = isvce_get_gpp_neon;
+
+ break;
+ }
+#elif defined(ARM) && !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ {
+ ps_rc_utils_state->pf_get_gpp = isvce_get_gpp_neon;
+
+ break;
+ }
+#endif
+ default:
+ {
+ ps_rc_utils_state->pf_get_gpp = isvce_get_gpp;
+
+ break;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* initializes the rc utils context
+*
+* @par Description:
+* initializes the rc utils context
+*
+* @param[in] ps_svc_rc_utils_ctxt
+* pointer to svc rc utils context
+*
+* @param[in] ps_mem_rec
+* pointer to memory allocated to compute gpp process
+*
+* @param[in] e_arch
+* architecure type
+*
+* @returns
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+void isvce_rc_utils_init(svc_rc_utils_ctxt_t *ps_svc_rc_utils_ctxt, iv_mem_rec_t *ps_mem_rec,
+ IV_ARCH_T e_arch)
+{
+ svc_rc_utils_state_t *ps_rc_utils_state;
+
+ UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
+
+ ps_rc_utils_state = (svc_rc_utils_state_t *) pu1_buf;
+
+ ps_svc_rc_utils_ctxt->pv_rc_utils_state = ps_rc_utils_state;
+
+ isvce_get_gpp_function_selector(ps_rc_utils_state, e_arch);
+}
diff --git a/encoder/svc/isvce_rc_utils.h b/encoder/svc/isvce_rc_utils.h
new file mode 100644
index 0000000..f2f6451
--- /dev/null
+++ b/encoder/svc/isvce_rc_utils.h
@@ -0,0 +1,134 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_rc_utils.h
+*
+* @brief
+* Contains get gpp function required by the SVC encoder
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - isvce_rc_utils_init()
+* - isvce_get_rc_utils_data_size()
+* - isvce_compute_gpp()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_RC_UTILS_H_
+#define _ISVCE_RC_UTILS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_structs.h"
+
+typedef struct
+{
+ /**
+ * pointer to the state of rc utils
+ */
+ void *pv_rc_utils_state;
+
+} svc_rc_utils_ctxt_t;
+
+/**
+*******************************************************************************
+*
+* @brief
+* initializes the rc utils context
+*
+* @par Description:
+* initializes the rc utils context
+*
+* @param[in] ps_svc_rc_utils_ctxt
+* pointer to svc rc utils context
+*
+* @param[in] ps_mem_rec
+* pointer to memory allocated to compute gpp process
+*
+* @param[in] e_arch
+* architecure type
+*
+* @returns
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+extern void isvce_rc_utils_init(svc_rc_utils_ctxt_t *ps_svc_rc_utils_ctxt, iv_mem_rec_t *ps_mem_rec,
+ IV_ARCH_T e_arch);
+
+/**
+*******************************************************************************
+*
+* @brief
+* gets the memory size required for compute gpp
+*
+* @par Description:
+* returns the memory required by the rc utils context and state structs
+* for allocation.
+*
+* @returns
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+
+extern UWORD32 isvce_get_rc_utils_data_size();
+
+/**
+*******************************************************************************
+*
+* @brief
+* compute gpp process
+*
+* @par Description:
+* calls the function to compute gpp
+*
+* @param[in] ps_svc_rc_utils_ctxt
+* pointer to svc rc utils context
+*
+* @param[in] ps_input_buf
+* pointer to yuv buffer properties
+*
+* @returns
+* calculated gpp value
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+extern DOUBLE isvce_compute_gpp(svc_rc_utils_ctxt_t *ps_svc_rc_utils_ctxt,
+ yuv_buf_props_t *ps_input_buf);
+
+#endif
diff --git a/encoder/svc/isvce_rc_utils_private_defs.h b/encoder/svc/isvce_rc_utils_private_defs.h
new file mode 100644
index 0000000..cf2d7eb
--- /dev/null
+++ b/encoder/svc/isvce_rc_utils_private_defs.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef _ISVCE_RC_UTILS_PRIVATE_DEFS_H_
+#define _ISVCE_RC_UTILS_PRIVATE_DEFS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_structs.h"
+#include "isvce_rc_utils.h"
+
+/* Macros */
+#define WT_LUMA_GPP 4
+
+#define WT_TOTAL_GPP 6
+
+/* Typedefs */
+typedef DOUBLE FT_GET_GPP(yuv_buf_props_t *ps_input_buf);
+
+/* Structs */
+typedef struct
+{
+ /**
+ * function pointer to the leaf level function for get gpp
+ */
+ FT_GET_GPP *pf_get_gpp;
+
+} svc_rc_utils_state_t;
+
+/* SSE42 Declarations */
+extern FT_GET_GPP isvce_get_gpp_sse42;
+
+/* NEON Declarations */
+extern FT_GET_GPP isvce_get_gpp_neon;
+
+#endif
diff --git a/encoder/svc/isvce_res_pred_private_defs.h b/encoder/svc/isvce_res_pred_private_defs.h
new file mode 100644
index 0000000..768be5b
--- /dev/null
+++ b/encoder/svc/isvce_res_pred_private_defs.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvc_res_pred_private_defs.h
+*
+* @brief
+* Contains datatype and macro definitions used exclusively in
+* residual prediction
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_RES_PRED_PRIVATE_DEFS_H_
+#define _ISVCE_RES_PRED_PRIVATE_DEFS_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+
+#define REF_ARRAY_MAX_WIDTH (MB_SIZE + 6)
+
+#define REF_ARRAY_MAX_HEIGHT (MB_SIZE + 6)
+
+typedef UWORD32 FT_GET_SAD_WITH_RES_PRED(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res, UWORD32 u4_mb_wd,
+ UWORD32 u4_mb_ht);
+
+typedef void FT_RESIDUAL_SAMPLER(coordinates_t *ps_ref_array_positions,
+ coordinates_t *ps_ref_array_phases, buffer_container_t *ps_inp,
+ buffer_container_t *ps_out, buffer_container_t *ps_scratch,
+ UWORD32 u4_ref_nnz, UWORD8 u1_ref_tx_size);
+
+/* Structs */
+/* Offsets, etc used for residual upsampling and interpolation */
+/* Derived as per 'G.8.6.3.2', and 'G.8.6.3.3' for all MB's once during init */
+typedef struct res_pred_mb_state_t
+{
+ coordinates_t s_offsets;
+
+ coordinates_t s_ref_array_dims;
+
+ coordinates_t *ps_ref_array_positions;
+
+ coordinates_t *ps_ref_array_phases;
+} res_pred_mb_state_t;
+
+typedef struct res_pred_layer_state_t
+{
+ layer_resampler_props_t *ps_luma_props;
+
+ layer_resampler_props_t *ps_chroma_props;
+
+ res_pred_mb_state_t *ps_luma_mb_states;
+
+ res_pred_mb_state_t *ps_chroma_mb_states;
+
+ WORD8 *pi1_mb_mode;
+
+ WORD32 i4_mb_mode_stride;
+
+} res_pred_layer_state_t;
+
+typedef struct res_pred_mem_store_t
+{
+ buffer_container_t s_scratch;
+
+} res_pred_mem_store_t;
+
+typedef struct res_pred_state_t
+{
+ /* Array of size numSpatialLayers */
+ res_pred_layer_state_t *ps_layer_state;
+
+ res_pred_mem_store_t s_mem_store;
+
+ FT_RESIDUAL_SAMPLER *apf_residual_samplers[NUM_COMPONENTS];
+
+ FT_GET_SAD_WITH_RES_PRED *pf_get_sad_with_residual_pred;
+
+ UWORD8 *pu1_ref_x_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+ UWORD8 *pu1_ref_y_ptr_incr; /*!< buffer to store the reference
+ array ptr increments for
+ operand 2 of interpolation
+ */
+
+} res_pred_state_t;
+
+/* C declarations */
+extern FT_RESIDUAL_SAMPLER isvce_luma_residual_sampler_2x;
+extern FT_RESIDUAL_SAMPLER isvce_chroma_residual_sampler_2x;
+extern FT_GET_SAD_WITH_RES_PRED isvce_get_sad_with_residual_pred;
+
+/* SSE42 declarations */
+extern FT_RESIDUAL_SAMPLER isvce_luma_residual_sampler_2x_sse42;
+extern FT_GET_SAD_WITH_RES_PRED isvce_get_sad_with_residual_pred_sse42;
+
+/* NEON declarations */
+extern FT_RESIDUAL_SAMPLER isvce_luma_residual_sampler_2x_neon;
+extern FT_GET_SAD_WITH_RES_PRED isvce_get_sad_with_residual_pred_neon;
+
+#endif
diff --git a/encoder/svc/isvce_residual_pred.c b/encoder/svc/isvce_residual_pred.c
new file mode 100644
index 0000000..68bd9ff
--- /dev/null
+++ b/encoder/svc/isvce_residual_pred.c
@@ -0,0 +1,1950 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_residual_pred.c
+*
+* @brief
+* Contains functions used for SVC residual prediction
+*
+*******************************************************************************
+*/
+#include <stdint.h>
+#include <math.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_defs.h"
+#include "isvce_structs.h"
+#include "isvce_res_pred_private_defs.h"
+#include "isvce_residual_pred.h"
+#include "isvce_utils.h"
+#include "isvc_defs.h"
+
+void isvce_chroma_residual_sampler_2x(coordinates_t *ps_ref_array_positions,
+ coordinates_t *ps_ref_array_phases,
+ buffer_container_t *ps_inp, buffer_container_t *ps_out,
+ buffer_container_t *ps_scratch, UWORD32 u4_ref_nnz,
+ UWORD8 u1_ref_tx_size)
+{
+ WORD32 i4_i;
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_phase1, i4_phase2;
+
+ WORD16 *pi2_inp_data = ps_inp->pv_data;
+ WORD16 *pi2_out_res = ps_out->pv_data;
+ WORD32 i4_inp_data_stride = ps_inp->i4_data_stride;
+ WORD32 i4_out_res_stride = ps_out->i4_data_stride;
+
+ UNUSED(u4_ref_nnz);
+
+ UNUSED(ps_ref_array_positions);
+ UNUSED(u1_ref_tx_size);
+
+ /* For 2x scaling, offsets always point to TL pixel outside MB */
+ /* Hence, refTransBlkIdc will be different and since phase */
+ /* for first refArray pos for horiz filtering samples > 8, */
+ /* first row and first column from the refArray is never used */
+ pi2_inp_data += 2 + i4_inp_data_stride;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ i4_phase1 = ps_ref_array_phases[0].i4_abscissa;
+ i4_phase2 = ps_ref_array_phases[1].i4_abscissa;
+
+ ASSERT(i4_phase1 >= 8);
+
+ pi4_ref_array = (WORD32 *) ps_scratch->pv_data;
+
+ for(i4_i = 0; i4_i < BLK_SIZE; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[0]);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 4;
+
+ {
+ /* unroll count 1 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[2]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 2 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+
+ /* unroll count 3 */
+ i2_coeff1 = (WORD16) (pi2_ref_data_byte[4]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff2 + i4_phase2 * i2_coeff1);
+
+ /* unroll count 4 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff2 + i4_phase1 * i2_coeff1);
+
+ /* unroll count 5 */
+ i2_coeff2 = (WORD16) (pi2_ref_data_byte[6]);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((16 - i4_phase2) * i2_coeff1 + i4_phase2 * i2_coeff2);
+
+ /* unroll count 6 */
+ *pi4_ref_array++ = ((16 - i4_phase1) * i2_coeff1 + i4_phase1 * i2_coeff2);
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 4;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) ps_scratch->pv_data;
+
+ i4_phase1 = ps_ref_array_phases[0].i4_ordinate;
+ i4_phase2 = ps_ref_array_phases[2].i4_ordinate;
+
+ for(i4_i = 0; i4_i < BLK8x8SIZE; i4_i++)
+ {
+ WORD16 *pi2_out;
+ WORD32 *pi4_ref_array_temp;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+ pi2_out = pi2_out_res;
+ pi4_ref_array_temp = pi4_ref_array;
+
+ /* populate the first inter sample */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLK8x8SIZE;
+ *pi2_out = (i4_horz_samp_1 + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ {
+ /* unroll count 1 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLK8x8SIZE;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 2 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 3 */
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+ pi4_ref_array_temp += BLK8x8SIZE;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_2 + i4_phase2 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 4 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_2 + i4_phase1 * i4_horz_samp_1 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 5 */
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((16 - i4_phase2) * i4_horz_samp_1 + i4_phase2 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll count 6 */
+ *pi2_out = ((16 - i4_phase1) * i4_horz_samp_1 + i4_phase1 * i4_horz_samp_2 + 128) >> 8;
+ pi2_out += i4_out_res_stride;
+ }
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 8) >> 4;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res += 2;
+ }
+}
+
+void isvce_luma_residual_sampler_2x(coordinates_t *ps_ref_array_positions,
+ coordinates_t *ps_ref_array_phases, buffer_container_t *ps_inp,
+ buffer_container_t *ps_out, buffer_container_t *ps_scratch,
+ UWORD32 u4_ref_nnz, UWORD8 u1_ref_tx_size)
+{
+ WORD16 *pi2_inp_data = ps_inp->pv_data;
+ WORD16 *pi2_out_res = ps_out->pv_data;
+ WORD32 i4_inp_data_stride = ps_inp->i4_data_stride;
+ WORD32 i4_out_res_stride = ps_out->i4_data_stride;
+ WORD16 *pi2_refarray_buffer = ps_scratch->pv_data;
+ WORD32 i4_blk_ctr;
+
+ UNUSED(ps_ref_array_positions);
+ UNUSED(ps_ref_array_phases);
+
+ /* For 2x scaling, offsets always point to TL pixel outside MB */
+ /* Hence, refTransBlkIdc will be different and since phase */
+ /* for first refArray pos for horiz filtering samples > 8, */
+ /* first row and first column from the refArray is never used */
+ pi2_inp_data += 1 + i4_inp_data_stride;
+
+ if((u1_ref_tx_size) && (0 != u4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i, i4_j;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLK8x8SIZE; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i2_coeff1 = i2_coeff2;
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < MB_SIZE; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi4_ref_array_temp += MB_SIZE;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out = ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out = ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_1 = i4_horz_samp_2;
+ }
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < BLK_SIZE; i4_blk_ctr++)
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 *pi4_ref_array;
+ WORD32 i4_i;
+
+ /* if reference layer is not coded then no processing */
+ if(0 != (u4_ref_nnz & 0x1))
+ {
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLK_SIZE; i4_i++)
+ {
+ WORD16 i2_coeff1, i2_coeff2;
+
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate the first inter sample */
+ *pi4_ref_array++ = i2_coeff1 << 2;
+
+ {
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ i2_coeff1 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ i2_coeff2 = (WORD16) (*pi2_ref_data_byte++);
+
+ /* populate 2 samples based on current coeffs */
+ *pi4_ref_array++ = ((i2_coeff1 << 1) + (i2_coeff1) + (i2_coeff2));
+
+ *pi4_ref_array++ = ((i2_coeff2 << 1) + (i2_coeff2) + (i2_coeff1));
+ }
+
+ /* populate the last inter sample */
+ *pi4_ref_array++ = i2_coeff2 << 2;
+
+ /* vertical loop uopdates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 1) * i4_inp_data_stride);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi4_ref_array = (WORD32 *) pi2_refarray_buffer;
+
+ for(i4_i = 0; i4_i < BLK8x8SIZE; i4_i++)
+ {
+ WORD32 *pi4_ref_array_temp;
+ WORD16 *pi2_out;
+ WORD32 i4_horz_samp_1, i4_horz_samp_2;
+
+ pi4_ref_array_temp = pi4_ref_array;
+ pi2_out = pi2_out_res;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate the first inter sample */
+ *pi2_out = (i4_horz_samp_1 + 2) >> 2;
+ pi2_out += i4_out_res_stride;
+
+ {
+ /* unroll loop count 1 */
+ pi4_ref_array_temp += BLK8x8SIZE;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 2 */
+ pi4_ref_array_temp += BLK8x8SIZE;
+ i4_horz_samp_1 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ /* unroll loop count 3 */
+ pi4_ref_array_temp += BLK8x8SIZE;
+ i4_horz_samp_2 = *pi4_ref_array_temp;
+
+ /* populate 2 samples based on current coeffs */
+ *pi2_out =
+ ((i4_horz_samp_1 << 1) + (i4_horz_samp_1) + (i4_horz_samp_2) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+
+ *pi2_out =
+ ((i4_horz_samp_2 << 1) + (i4_horz_samp_2) + (i4_horz_samp_1) + 8) >> 4;
+ pi2_out += i4_out_res_stride;
+ }
+
+ /* populate the last inter sample */
+ *pi2_out = (i4_horz_samp_2 + 2) >> 2;
+
+ /* horizontal loop updates */
+ pi4_ref_array++;
+ pi2_out_res++;
+ }
+ }
+ else
+ {
+ pi2_out_res += BLK8x8SIZE;
+ }
+
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= BLK_SIZE;
+ pi2_inp_data += (i4_inp_data_stride * BLK_SIZE);
+ pi2_out_res -= MB_SIZE;
+ pi2_out_res += (i4_out_res_stride * BLK8x8SIZE);
+ u4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += BLK_SIZE;
+ }
+
+ u4_ref_nnz >>= 1;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing residual pred ctxt
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @param[in] u4_ht
+* Input Height
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_svc_res_pred_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 u4_size = 0;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ WORD32 i;
+
+ u4_size += MAX_PROCESS_CTXT * sizeof(svc_res_pred_ctxt_t);
+ u4_size += MAX_PROCESS_CTXT * sizeof(res_pred_state_t);
+
+ /* Mem for storing pred */
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * MB_SIZE * sizeof(WORD16);
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * (MB_SIZE / 2) * sizeof(WORD16);
+
+ /* Mem for storing intermediates */
+ u4_size += MAX_PROCESS_CTXT * REF_ARRAY_MAX_WIDTH * REF_ARRAY_MAX_HEIGHT * sizeof(WORD16);
+
+ /* Mem for pu1_ref_x_ptr_incr and pu1_ref_y_ptr_incr*/
+ u4_size +=
+ 2 * MAX_PROCESS_CTXT * REF_ARRAY_MAX_WIDTH * REF_ARRAY_MAX_HEIGHT * sizeof(UWORD8);
+
+ u4_size += MAX_PROCESS_CTXT * u1_num_spatial_layers * sizeof(res_pred_layer_state_t);
+
+ for(i = u1_num_spatial_layers - 1; i >= 1; i--)
+ {
+ WORD32 i4_layer_luma_wd =
+ (WORD32) ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_mbs = (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
+ WORD32 i4_layer_u_wd = i4_layer_luma_wd / 2.0 + 0.99;
+ WORD32 i4_layer_u_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_u_mbs =
+ (i4_layer_u_wd / (MB_SIZE / 2)) * (i4_layer_u_ht / (MB_SIZE / 2));
+
+ /* ps_luma_mb_states */
+ {
+ u4_size += i4_layer_luma_mbs * sizeof(res_pred_mb_state_t);
+
+ /* ps_ref_array_positions */
+ u4_size +=
+ ((1.5 == d_spatial_res_ratio) ? (i4_layer_luma_mbs * MB_SIZE * MB_SIZE) : 0) *
+ sizeof(coordinates_t);
+
+ /* ps_ref_array_phases */
+ u4_size += ((1.5 == d_spatial_res_ratio) ? (i4_layer_luma_mbs * 5) : 0) *
+ sizeof(coordinates_t);
+ }
+
+ /* ps_chroma_mb_states */
+ {
+ u4_size += i4_layer_u_mbs * sizeof(res_pred_mb_state_t);
+
+ /* ps_ref_array_positions */
+ u4_size +=
+ ((1.5 == d_spatial_res_ratio) ? (i4_layer_u_mbs * (MB_SIZE / 2) * (MB_SIZE / 2))
+ : 0) *
+ sizeof(coordinates_t);
+
+ /* ps_ref_array_phases */
+ u4_size += ((1.5 == d_spatial_res_ratio) ? (i4_layer_u_mbs * 5) : 3) *
+ sizeof(coordinates_t);
+ }
+ }
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ WORD32 i4_layer_luma_wd =
+ (WORD32) ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_mbs =
+ ((i4_layer_luma_wd / MB_SIZE) + 2) * ((i4_layer_luma_ht / MB_SIZE) + 2);
+
+ /* pi1_mb_mode */
+ u4_size += i4_layer_luma_mbs * sizeof(WORD8);
+ }
+ }
+ else
+ {
+ u4_size += MAX_PROCESS_CTXT * sizeof(yuv_buf_props_t);
+
+ /* Mem for storing pred */
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * MB_SIZE * sizeof(WORD16);
+ u4_size += MAX_PROCESS_CTXT * MB_SIZE * (MB_SIZE / 2) * sizeof(WORD16);
+ }
+
+ return u4_size;
+}
+
+static FORCEINLINE WORD32 isvce_get_scaled_pixel_pos(layer_resampler_props_t *ps_layer_props,
+ WORD32 i4_pixel_pos, UWORD8 u1_dim_id)
+{
+ if(1 == u1_dim_id)
+ {
+ return (((i4_pixel_pos - ps_layer_props->i4_offset_y) *
+ ((WORD64) ps_layer_props->u4_scale_y) +
+ ps_layer_props->i4_add_y) >>
+ (ps_layer_props->u4_shift_y - 4)) -
+ ps_layer_props->i4_delta_y;
+ }
+ else
+ {
+ return (((i4_pixel_pos - ps_layer_props->i4_offset_x) *
+ ((WORD64) ps_layer_props->u4_scale_x) +
+ ps_layer_props->i4_add_x) >>
+ (ps_layer_props->u4_shift_x - 4)) -
+ ps_layer_props->i4_delta_x;
+ }
+}
+
+static FORCEINLINE void isvce_ref_array_pos_and_phase_init_dyadic(
+ layer_resampler_props_t *ps_layer_props, res_pred_mb_state_t *ps_mb_state,
+ coordinates_t *ps_mb_pos, UWORD8 u1_frame_mbs_only_flag, UWORD8 u1_field_mb_flag,
+ UWORD8 u1_ref_layer_frame_mbs_only_flag)
+{
+ UWORD32 i, j;
+
+ coordinates_t *ps_ref_array_phases = ps_mb_state->ps_ref_array_phases;
+
+ WORD32 i4_x_offset = ps_mb_state->s_offsets.i4_abscissa;
+ WORD32 i4_y_offset = ps_mb_state->s_offsets.i4_ordinate;
+
+ for(i = 0; i < 2; i++)
+ {
+ WORD32 i4_y_ref16;
+
+ WORD32 i4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + i;
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - u1_field_mb_flag);
+ }
+
+ i4_y_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_yc, 1);
+
+ for(j = 0; j < ((0 == i) ? 2 : 1); j++)
+ {
+ WORD32 i4_x_ref16;
+
+ WORD32 i4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + j;
+
+ i4_x_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_xc, 0);
+
+ ps_ref_array_phases[j + i * 2].i4_abscissa = (i4_x_ref16 - (16 * i4_x_offset)) & 15;
+ ps_ref_array_phases[j + i * 2].i4_ordinate = (i4_y_ref16 - (16 * i4_y_offset)) & 15;
+ }
+ }
+}
+
+static FORCEINLINE void isvce_ref_array_pos_and_phase_init(layer_resampler_props_t *ps_layer_props,
+ res_pred_mb_state_t *ps_mb_state,
+ coordinates_t *ps_mb_pos,
+ UWORD8 u1_frame_mbs_only_flag,
+ UWORD8 u1_field_mb_flag,
+ UWORD8 u1_ref_layer_frame_mbs_only_flag)
+{
+ UWORD32 i, j;
+
+ coordinates_t *ps_ref_array_positions = ps_mb_state->ps_ref_array_positions;
+ coordinates_t *ps_ref_array_phases = ps_mb_state->ps_ref_array_phases;
+
+ WORD32 i4_x_offset = ps_mb_state->s_offsets.i4_abscissa;
+ WORD32 i4_y_offset = ps_mb_state->s_offsets.i4_ordinate;
+ UWORD32 u4_phase_array_idx = 0;
+
+ for(i = 0; i < ps_layer_props->u4_mb_ht; i++)
+ {
+ WORD32 i4_y_ref16;
+
+ WORD32 i4_yc = ps_mb_pos->i4_ordinate * ps_layer_props->u4_mb_ht + i;
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ i4_yc = i4_yc >> (1 - u1_field_mb_flag);
+ }
+
+ i4_y_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_yc, 1);
+
+ for(j = 0; j < ps_layer_props->u4_mb_wd; j++)
+ {
+ WORD32 i4_x_ref16;
+
+ WORD32 i4_xc = ps_mb_pos->i4_abscissa * ps_layer_props->u4_mb_wd + j;
+
+ i4_x_ref16 = isvce_get_scaled_pixel_pos(ps_layer_props, i4_xc, 0);
+
+ ps_ref_array_positions[j + i * ps_layer_props->u4_mb_wd].i4_abscissa =
+ (i4_x_ref16 >> 4) - i4_x_offset;
+ ps_ref_array_positions[j + i * ps_layer_props->u4_mb_wd].i4_ordinate =
+ (i4_y_ref16 >> 4) - i4_y_offset;
+
+ if(((0 == i) && (j < 3)) || ((0 == j) && (i < 3)))
+ {
+ ps_ref_array_phases[u4_phase_array_idx].i4_abscissa =
+ (i4_x_ref16 - (16 * i4_x_offset)) & 15;
+ ps_ref_array_phases[u4_phase_array_idx].i4_ordinate =
+ (i4_y_ref16 - (16 * i4_y_offset)) & 15;
+
+ u4_phase_array_idx++;
+ }
+ }
+ }
+}
+
+static void isvce_res_pred_layer_state_init(res_pred_layer_state_t *ps_layer_state,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht, IV_COLOR_FORMAT_T e_color_format)
+{
+ UWORD32 i, j, k;
+
+ const UWORD8 u1_ref_layer_field_pic_flag = 0;
+ const UWORD8 u1_field_pic_flag = 0;
+ const UWORD8 u1_frame_mbs_only_flag = 1;
+ const UWORD8 u1_ref_layer_frame_mbs_only_flag = 1;
+ const UWORD8 u1_field_mb_flag = 0;
+
+ ASSERT((IV_YUV_420P == e_color_format) || (IV_YUV_420SP_UV == e_color_format));
+
+ UNUSED(e_color_format);
+
+ for(i = 0; i < 2; i++)
+ {
+ res_pred_mb_state_t *ps_mb_states;
+ layer_resampler_props_t *ps_layer_props;
+
+ UWORD32 u4_wd_in_mbs;
+ UWORD32 u4_ht_in_mbs;
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+ UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
+ UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
+ UWORD32 u4_scaled_wd = u4_wd;
+ UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
+
+ ps_mb_states =
+ u1_is_chroma ? ps_layer_state->ps_chroma_mb_states : ps_layer_state->ps_luma_mb_states;
+ ps_layer_props =
+ u1_is_chroma ? ps_layer_state->ps_chroma_props : ps_layer_state->ps_luma_props;
+
+ u4_ref_wd = u4_ref_wd >> u1_is_chroma;
+ u4_ref_ht = u4_ref_ht >> u1_is_chroma;
+ u4_scaled_wd = u4_scaled_wd >> u1_is_chroma;
+ u4_scaled_ht = u4_scaled_ht >> u1_is_chroma;
+
+ u4_wd_in_mbs = u4_scaled_wd / ps_layer_props->u4_mb_wd;
+ u4_ht_in_mbs = u4_scaled_ht / ps_layer_props->u4_mb_ht;
+
+ for(j = 0; j < u4_ht_in_mbs; j++)
+ {
+ WORD32 i4_y_refmin16;
+ WORD32 i4_y_refmax16;
+ WORD32 i4_y_offset;
+
+ i4_y_refmin16 =
+ isvce_get_scaled_pixel_pos(ps_layer_props, j * ps_layer_props->u4_mb_ht, 1);
+ i4_y_refmax16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props, j * ps_layer_props->u4_mb_ht + ps_layer_props->u4_mb_ht - 1, 1);
+ i4_y_offset = i4_y_refmin16 >> 4;
+
+ for(k = 0; k < u4_wd_in_mbs; k++)
+ {
+ WORD32 i4_x_refmin16;
+ WORD32 i4_x_refmax16;
+ WORD32 i4_x_offset;
+
+ coordinates_t s_mb_pos = {k, j};
+
+ i4_x_refmin16 =
+ isvce_get_scaled_pixel_pos(ps_layer_props, k * ps_layer_props->u4_mb_wd, 0);
+ i4_x_refmax16 = isvce_get_scaled_pixel_pos(
+ ps_layer_props, k * ps_layer_props->u4_mb_wd + ps_layer_props->u4_mb_wd - 1, 0);
+ i4_x_offset = i4_x_refmin16 >> 4;
+
+ ps_mb_states[k + j * u4_wd_in_mbs].s_offsets.i4_abscissa = i4_x_offset;
+ ps_mb_states[k + j * u4_wd_in_mbs].s_offsets.i4_ordinate = i4_y_offset;
+ ps_mb_states[k + j * u4_wd_in_mbs].s_ref_array_dims.i4_abscissa =
+ (i4_x_refmax16 >> 4) - i4_x_offset + 2;
+ ps_mb_states[k + j * u4_wd_in_mbs].s_ref_array_dims.i4_ordinate =
+ (i4_y_refmax16 >> 4) - i4_y_offset + 2;
+
+ if((0 == k) && (0 == j) && (2 == d_spatial_res_ratio) && u1_is_chroma)
+ {
+ isvce_ref_array_pos_and_phase_init_dyadic(
+ ps_layer_props, &ps_mb_states[k + j * u4_wd_in_mbs], &s_mb_pos,
+ u1_frame_mbs_only_flag, u1_field_mb_flag, u1_ref_layer_frame_mbs_only_flag);
+ }
+ else if(1.5 == d_spatial_res_ratio)
+ {
+ isvce_ref_array_pos_and_phase_init(
+ ps_layer_props, &ps_mb_states[k + j * u4_wd_in_mbs], &s_mb_pos,
+ u1_frame_mbs_only_flag, u1_field_mb_flag, u1_ref_layer_frame_mbs_only_flag);
+ }
+ }
+ }
+ }
+}
+
+void isvce_svc_residual_sampling_function_selector(res_pred_state_t *ps_res_pred_state,
+ DOUBLE d_spatial_res_ratio, IV_ARCH_T e_arch)
+{
+ if(2. == d_spatial_res_ratio)
+ {
+ ps_res_pred_state->apf_residual_samplers[U] = isvce_chroma_residual_sampler_2x;
+ ps_res_pred_state->apf_residual_samplers[V] = isvce_chroma_residual_sampler_2x;
+
+ switch(e_arch)
+ {
+#if defined(X86)
+ case ARCH_X86_SSE42:
+ {
+ ps_res_pred_state->apf_residual_samplers[Y] = isvce_luma_residual_sampler_2x_sse42;
+
+ break;
+ }
+#elif defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ {
+ ps_res_pred_state->apf_residual_samplers[Y] = isvce_luma_residual_sampler_2x_neon;
+
+ break;
+ }
+#elif defined(ARM) && !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ {
+ ps_res_pred_state->apf_residual_samplers[Y] = isvce_luma_residual_sampler_2x_neon;
+
+ break;
+ }
+#endif
+ default:
+ {
+ ps_res_pred_state->apf_residual_samplers[Y] = isvce_luma_residual_sampler_2x;
+
+ break;
+ }
+ }
+ }
+
+ switch(e_arch)
+ {
+#if defined(X86)
+ case ARCH_X86_SSE42:
+ {
+ ps_res_pred_state->pf_get_sad_with_residual_pred =
+ isvce_get_sad_with_residual_pred_sse42;
+
+ break;
+ }
+#elif defined(ARMV8)
+ case ARCH_ARM_A53:
+ case ARCH_ARM_A57:
+ case ARCH_ARM_V8_NEON:
+ {
+ ps_res_pred_state->pf_get_sad_with_residual_pred =
+ isvce_get_sad_with_residual_pred_neon;
+
+ break;
+ }
+#elif defined(ARM) && !defined(DISABLE_NEON)
+ case ARCH_ARM_A9Q:
+ case ARCH_ARM_A9A:
+ case ARCH_ARM_A9:
+ case ARCH_ARM_A7:
+ case ARCH_ARM_A5:
+ case ARCH_ARM_A15:
+ {
+ ps_res_pred_state->pf_get_sad_with_residual_pred =
+ isvce_get_sad_with_residual_pred_neon;
+
+ break;
+ }
+#endif
+ default:
+ {
+ ps_res_pred_state->pf_get_sad_with_residual_pred = isvce_get_sad_with_residual_pred;
+
+ break;
+ }
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc ilp buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_svc_res_pred_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ WORD32 i, j, k;
+
+ const WORD32 i4_num_proc_ctxts = sizeof(ps_codec->as_process) / sizeof(ps_codec->as_process[0]);
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_svc_res_pred_ctxt_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ if(u1_num_spatial_layers > 1)
+ {
+ res_pred_mb_state_t *aps_luma_mb_states[MAX_NUM_SPATIAL_LAYERS];
+ res_pred_mb_state_t *aps_chroma_mb_states[MAX_NUM_SPATIAL_LAYERS];
+
+ WORD8 *api1_mb_mode[MAX_NUM_SPATIAL_LAYERS];
+ WORD32 ai4_mb_mode_stride[MAX_NUM_SPATIAL_LAYERS];
+
+ WORD32 i4_size;
+
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ res_pred_state_t *ps_res_pred_state;
+ svc_res_pred_ctxt_t *ps_res_pred_ctxt;
+ yuv_buf_props_t *ps_mb_res_buf;
+ res_pred_mem_store_t *ps_mem_store;
+
+ isvce_process_ctxt_t *ps_proc = ps_codec->as_process + i;
+
+ ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt = (svc_res_pred_ctxt_t *) pu1_buf;
+ pu1_buf += sizeof(svc_res_pred_ctxt_t);
+ i8_alloc_mem_size -= sizeof(svc_res_pred_ctxt_t);
+
+ ps_res_pred_ctxt->s_res_pred_constants.pv_state = pu1_buf;
+ ps_res_pred_state = (res_pred_state_t *) pu1_buf;
+ pu1_buf += sizeof(res_pred_state_t);
+ i8_alloc_mem_size -= sizeof(res_pred_state_t);
+
+ ps_res_pred_state->ps_layer_state = (res_pred_layer_state_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_res_pred_state->ps_layer_state[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_res_pred_state->ps_layer_state[0]);
+
+ i4_size = REF_ARRAY_MAX_WIDTH * REF_ARRAY_MAX_HEIGHT * sizeof(UWORD8);
+ ps_res_pred_state->pu1_ref_x_ptr_incr = (UWORD8 *) pu1_buf;
+ pu1_buf += i4_size;
+ ps_res_pred_state->pu1_ref_y_ptr_incr = (UWORD8 *) pu1_buf;
+ pu1_buf += i4_size;
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ if(0 == i)
+ {
+ UWORD32 au4_ref_pos_array_size[NUM_SP_COMPONENTS];
+ UWORD32 au4_ref_phase_array_size[NUM_SP_COMPONENTS];
+
+ if(1.5 == d_spatial_res_ratio)
+ {
+ au4_ref_pos_array_size[Y] = MB_SIZE * MB_SIZE;
+ au4_ref_phase_array_size[Y] = 5;
+ au4_ref_pos_array_size[U] = (MB_SIZE / 2) * (MB_SIZE / 2);
+ au4_ref_phase_array_size[U] = 5;
+ }
+ else
+ {
+ au4_ref_pos_array_size[Y] = au4_ref_pos_array_size[U] = 0;
+ au4_ref_phase_array_size[Y] = 0;
+ au4_ref_phase_array_size[U] = 3;
+ }
+
+ for(j = u1_num_spatial_layers - 1; j >= 1; j--)
+ {
+ res_pred_layer_state_t *ps_layer = &ps_res_pred_state->ps_layer_state[j];
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_mbs =
+ (i4_layer_luma_wd / MB_SIZE) * (i4_layer_luma_ht / MB_SIZE);
+ WORD32 i4_layer_u_wd = i4_layer_luma_wd / 2.0 + 0.99;
+ WORD32 i4_layer_u_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_u_mbs =
+ (i4_layer_u_wd / (MB_SIZE / 2)) * (i4_layer_u_ht / (MB_SIZE / 2));
+
+ ps_layer->ps_luma_mb_states = (res_pred_mb_state_t *) pu1_buf;
+ aps_luma_mb_states[j] = ps_layer->ps_luma_mb_states;
+ pu1_buf += i4_layer_luma_mbs * sizeof(ps_layer->ps_luma_mb_states[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_layer->ps_luma_mb_states[0]);
+
+ ps_layer->ps_chroma_mb_states = (res_pred_mb_state_t *) pu1_buf;
+ aps_chroma_mb_states[j] = ps_layer->ps_chroma_mb_states;
+ pu1_buf += i4_layer_u_mbs * sizeof(ps_layer->ps_chroma_mb_states[0]);
+ i8_alloc_mem_size -= i4_layer_u_mbs * sizeof(ps_layer->ps_chroma_mb_states[0]);
+
+ if(1.5 == d_spatial_res_ratio)
+ {
+ coordinates_t *ps_ref_array_pos = (coordinates_t *) pu1_buf;
+ coordinates_t *ps_ref_array_phases =
+ ps_ref_array_pos + i4_layer_luma_mbs * au4_ref_pos_array_size[Y];
+
+ for(k = 0; k < i4_layer_luma_mbs; k++)
+ {
+ ps_layer->ps_luma_mb_states[k].ps_ref_array_positions =
+ ps_ref_array_pos + k * au4_ref_pos_array_size[Y];
+ ps_layer->ps_luma_mb_states[k].ps_ref_array_phases =
+ ps_ref_array_phases + k * au4_ref_phase_array_size[Y];
+ pu1_buf += au4_ref_pos_array_size[Y] * sizeof(ps_ref_array_pos[0]);
+ i8_alloc_mem_size -=
+ au4_ref_pos_array_size[Y] * sizeof(ps_ref_array_pos[0]);
+ pu1_buf += au4_ref_phase_array_size[Y] * sizeof(ps_ref_array_phases[0]);
+ i8_alloc_mem_size -=
+ au4_ref_phase_array_size[Y] * sizeof(ps_ref_array_phases[0]);
+ }
+
+ ps_ref_array_pos = (coordinates_t *) pu1_buf;
+ ps_ref_array_phases =
+ ps_ref_array_pos + i4_layer_u_mbs * au4_ref_pos_array_size[U];
+
+ for(k = 0; k < i4_layer_u_mbs; k++)
+ {
+ ps_layer->ps_chroma_mb_states[k].ps_ref_array_positions =
+ ps_ref_array_pos + k * au4_ref_pos_array_size[U];
+ ps_layer->ps_chroma_mb_states[k].ps_ref_array_phases =
+ ps_ref_array_phases + k * au4_ref_phase_array_size[U];
+ pu1_buf += au4_ref_pos_array_size[U] * sizeof(ps_ref_array_pos[0]);
+ i8_alloc_mem_size -=
+ au4_ref_pos_array_size[U] * sizeof(ps_ref_array_pos[0]);
+ pu1_buf += au4_ref_phase_array_size[U] * sizeof(ps_ref_array_phases[0]);
+ i8_alloc_mem_size -=
+ au4_ref_phase_array_size[U] * sizeof(ps_ref_array_phases[0]);
+ }
+ }
+ else
+ {
+ coordinates_t *ps_ref_array_pos = NULL;
+ coordinates_t *ps_ref_array_phases = NULL;
+
+ for(k = 0; k < i4_layer_luma_mbs; k++)
+ {
+ ps_layer->ps_luma_mb_states[k].ps_ref_array_positions =
+ ps_ref_array_pos;
+ ps_layer->ps_luma_mb_states[k].ps_ref_array_phases =
+ ps_ref_array_phases;
+ }
+
+ ps_ref_array_pos = NULL;
+ ps_ref_array_phases = (coordinates_t *) pu1_buf;
+
+ for(k = 0; k < i4_layer_u_mbs; k++)
+ {
+ ps_layer->ps_chroma_mb_states[k].ps_ref_array_positions =
+ ps_ref_array_pos;
+ ps_layer->ps_chroma_mb_states[k].ps_ref_array_phases =
+ ps_ref_array_phases;
+ }
+
+ pu1_buf += au4_ref_phase_array_size[U] * sizeof(ps_ref_array_pos[0]);
+ i8_alloc_mem_size -=
+ au4_ref_phase_array_size[U] * sizeof(ps_ref_array_phases[0]);
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ /* Asserts below verify that
+ * 'ps_codec->s_svc_ilp_data.aps_layer_resampler_props' is initialised
+ */
+ ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j].u4_mb_wd ==
+ MB_SIZE);
+ ASSERT(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][j].u4_mb_wd ==
+ (MB_SIZE / 2));
+
+ ps_layer->ps_luma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
+ ps_layer->ps_chroma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][j];
+
+ isvce_res_pred_layer_state_init(ps_layer, d_spatial_res_ratio, i4_layer_luma_wd,
+ i4_layer_luma_ht,
+ ps_codec->s_cfg.e_inp_color_fmt);
+ }
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ res_pred_layer_state_t *ps_layer = &ps_res_pred_state->ps_layer_state[j];
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_mbs =
+ ((i4_layer_luma_wd / MB_SIZE) + 2) * ((i4_layer_luma_ht / MB_SIZE) + 2);
+
+ ps_layer->pi1_mb_mode = (WORD8 *) pu1_buf;
+ pu1_buf += i4_layer_luma_mbs * sizeof(WORD8);
+ memset(ps_layer->pi1_mb_mode, -1, i4_layer_luma_mbs);
+
+ ps_layer->i4_mb_mode_stride = ai4_mb_mode_stride[j] =
+ (i4_layer_luma_wd / MB_SIZE) + 2;
+ ps_layer->pi1_mb_mode += 1 + ps_layer->i4_mb_mode_stride;
+ api1_mb_mode[j] = ps_layer->pi1_mb_mode;
+ }
+ }
+ else
+ {
+ for(j = u1_num_spatial_layers - 1; j >= 1; j--)
+ {
+ res_pred_layer_state_t *ps_layer = &ps_res_pred_state->ps_layer_state[j];
+
+ ps_layer->ps_luma_mb_states = aps_luma_mb_states[j];
+ ps_layer->ps_chroma_mb_states = aps_chroma_mb_states[j];
+
+ ps_layer->ps_luma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[Y][j];
+ ps_layer->ps_chroma_props =
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[UV][j];
+ }
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ res_pred_layer_state_t *ps_layer = &ps_res_pred_state->ps_layer_state[j];
+
+ ps_layer->pi1_mb_mode = api1_mb_mode[j];
+ ps_layer->i4_mb_mode_stride = ai4_mb_mode_stride[j];
+ }
+ }
+
+ ps_mb_res_buf = &ps_res_pred_ctxt->s_res_pred_outputs.s_res_pred;
+ ps_mem_store = &ps_res_pred_state->s_mem_store;
+ ps_proc->ps_mb_res_buf = ps_mb_res_buf;
+
+ for(j = 0; j < NUM_SP_COMPONENTS; j++)
+ {
+ buffer_container_t *ps_comp_buf = &ps_mb_res_buf->as_component_bufs[j];
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) j));
+
+ ps_comp_buf->pv_data = pu1_buf;
+ ps_comp_buf->i4_data_stride = MB_SIZE;
+ pu1_buf += MB_SIZE * (MB_SIZE >> u1_is_chroma) * sizeof(WORD16);
+ i8_alloc_mem_size -= MB_SIZE * (MB_SIZE >> u1_is_chroma) * sizeof(WORD16);
+ }
+
+ ps_mem_store->s_scratch.pv_data = pu1_buf;
+ ps_mem_store->s_scratch.i4_data_stride = REF_ARRAY_MAX_WIDTH;
+ pu1_buf += REF_ARRAY_MAX_WIDTH * REF_ARRAY_MAX_HEIGHT * sizeof(WORD16);
+ i8_alloc_mem_size -= REF_ARRAY_MAX_WIDTH * REF_ARRAY_MAX_HEIGHT * sizeof(WORD16);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ ps_mb_res_buf->as_component_bufs[V].pv_data = NULL;
+ ps_mb_res_buf->e_color_format = IV_YUV_420SP_UV;
+ ps_mb_res_buf->u1_bit_depth = 10;
+ ps_mb_res_buf->u4_width = MB_SIZE;
+ ps_mb_res_buf->u4_height = MB_SIZE;
+
+ isvce_svc_residual_sampling_function_selector(ps_res_pred_state, d_spatial_res_ratio,
+ ps_codec->s_cfg.e_arch);
+ }
+ }
+ else
+ {
+ for(i = 0; i < i4_num_proc_ctxts; i++)
+ {
+ isvce_process_ctxt_t *ps_proc = ps_codec->as_process + i;
+
+ ps_proc->ps_res_pred_ctxt = NULL;
+
+ ps_proc->ps_mb_res_buf = (yuv_buf_props_t *) pu1_buf;
+ pu1_buf += sizeof(yuv_buf_props_t);
+ i8_alloc_mem_size -= sizeof(yuv_buf_props_t);
+
+ for(j = 0; j < NUM_SP_COMPONENTS; j++)
+ {
+ buffer_container_t *ps_comp_buf = &ps_proc->ps_mb_res_buf->as_component_bufs[j];
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) j));
+
+ ps_comp_buf->pv_data = pu1_buf;
+ ps_comp_buf->i4_data_stride = MB_SIZE;
+ pu1_buf += MB_SIZE * (MB_SIZE >> u1_is_chroma) * sizeof(WORD16);
+ i8_alloc_mem_size -= MB_SIZE * (MB_SIZE >> u1_is_chroma) * sizeof(WORD16);
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+ }
+}
+
+void isvce_get_mb_residual_pred(svc_res_pred_ctxt_t *ps_res_pred_ctxt)
+{
+ buffer_container_t s_inp;
+ buffer_container_t s_out;
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+ coordinates_t s_ref_array_offsets;
+ svc_layer_data_t *ps_ref_layer_data;
+ res_pred_layer_state_t *ps_layer_state;
+ yuv_buf_props_t *ps_ref_residual_buf;
+ res_pred_mb_state_t *ps_luma_mb_state;
+ res_pred_mb_state_t *ps_chroma_mb_state;
+ isvce_mb_info_t *ps_ref_mb;
+
+ WORD32 i;
+
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_variables_t *ps_res_pred_variables = &ps_res_pred_ctxt->s_res_pred_variables;
+ res_pred_outputs_t *ps_res_pred_outputs = &ps_res_pred_ctxt->s_res_pred_outputs;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ res_pred_mem_store_t *ps_mem_store = &ps_res_pred_state->s_mem_store;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_res_pred_variables->ps_svc_ilp_data;
+ coordinates_t *ps_mb_pos = &ps_res_pred_variables->s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id = ps_res_pred_variables->u1_spatial_layer_id;
+
+ ASSERT(u1_spatial_layer_id > 0);
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_ref_layer_data =
+ &ps_svc_ilp_data->ps_svc_au_data->ps_svc_layer_data[u1_spatial_layer_id - 1];
+ ps_layer_state = &ps_res_pred_state->ps_layer_state[u1_spatial_layer_id];
+ ps_ref_residual_buf = &ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1];
+ ps_luma_mb_state = ps_layer_state->ps_luma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+ ps_chroma_mb_state = ps_layer_state->ps_chroma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+
+ for(i = 0; i < NUM_COMPONENTS; i++)
+ {
+ res_pred_mb_state_t *ps_mb_state;
+ layer_resampler_props_t *ps_layer_props;
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+
+ ps_mb_state = u1_is_chroma ? ps_chroma_mb_state : ps_luma_mb_state;
+ ps_layer_props =
+ u1_is_chroma ? ps_layer_state->ps_chroma_props : ps_layer_state->ps_luma_props;
+
+ /* Presence of appropriate padding is assumed */
+ s_ref_array_offsets = ps_mb_state->s_offsets;
+
+ s_inp = ps_ref_residual_buf->as_component_bufs[u1_is_chroma ? UV : Y];
+ s_inp.pv_data = ((WORD16 *) s_inp.pv_data) + (V == ((COMPONENT_TYPE) i)) +
+ (s_ref_array_offsets.i4_abscissa << u1_is_chroma) +
+ s_ref_array_offsets.i4_ordinate * s_inp.i4_data_stride;
+
+ s_out = ps_res_pred_outputs->s_res_pred.as_component_bufs[u1_is_chroma ? UV : Y];
+ s_out.pv_data = ((WORD16 *) s_out.pv_data) + (V == ((COMPONENT_TYPE) i));
+
+ ps_ref_mb =
+ ps_ref_layer_data->ps_mb_info +
+ ((s_ref_array_offsets.i4_abscissa + (ps_mb_state->s_ref_array_dims.i4_abscissa / 2)) /
+ ps_layer_props->u4_mb_wd) +
+ ((s_ref_array_offsets.i4_ordinate + (ps_mb_state->s_ref_array_dims.i4_ordinate / 2)) /
+ ps_layer_props->u4_mb_ht) *
+ (s_frame_dims_in_mbs.i4_abscissa / 2);
+
+ ps_res_pred_state->apf_residual_samplers[i](
+ ps_mb_state->ps_ref_array_positions, ps_mb_state->ps_ref_array_phases, &s_inp, &s_out,
+ &ps_mem_store->s_scratch, UINT32_MAX, ps_ref_mb->u1_tx_size == 8);
+ }
+}
+
+void isvce_get_ref_layer_mbtype_tx_size(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_x_ref, WORD32 i4_y_ref,
+ WORD32 *pi4_mb_type, WORD32 *pi4_tx_size,
+ WORD32 i4_chroma_flag)
+{
+ WORD32 i4_mb_wd_sft, i4_mb_ht_sft;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD8 i1_mb_mode;
+
+ if(i4_x_ref < 0)
+ {
+ i4_x_ref = 0;
+ }
+ if(i4_y_ref < 0)
+ {
+ i4_y_ref = 0;
+ }
+
+ i4_mb_wd_sft = (MB_WIDTH_SHIFT - i4_chroma_flag);
+ i4_mb_ht_sft = (MB_HEIGHT_SHIFT - i4_chroma_flag);
+ i4_mb_x = (i4_x_ref >> i4_mb_wd_sft);
+ i4_mb_y = (i4_y_ref >> i4_mb_ht_sft);
+
+ pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_element_size);
+ pi1_ref_mb_modes += (i4_mb_x * i4_element_size);
+ i1_mb_mode = *pi1_ref_mb_modes;
+ i1_mb_mode = (i1_mb_mode < 0) ? i1_mb_mode : SVC_EXTRACT_MB_MODE(*pi1_ref_mb_modes);
+
+ if(i1_mb_mode <= SVC_INTER_MB)
+ {
+ *pi4_mb_type = SVC_INTER_MB;
+ *pi4_tx_size = GET_BIT_TX_SIZE(*pi1_ref_mb_modes, 1);
+ }
+ else
+ {
+ *pi4_mb_type = SVC_INTRA_MB;
+ *pi4_tx_size = 1;
+ }
+}
+
+void isvce_ref_layer_ptr_incr(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
+ WORD32 i4_element_size, WORD32 i4_x_offset, WORD32 i4_y_offset,
+ WORD32 i4_refary_wd, WORD32 i4_refary_ht, UWORD8 *pu1_ref_x_ptr_incr,
+ UWORD8 *pu1_ref_y_ptr_incr, WORD32 i4_chroma_flag)
+{
+ WORD32 i4_x, i4_y;
+ WORD32 i4_x_idx, i4_y_idx;
+ WORD32 i4_prev_x, i4_prev_y;
+ WORD32 i4_const_val;
+ WORD32 i4_pos_x, i4_pos_y;
+ WORD32 i4_trans_size;
+ WORD32 i4_mb_type, i4_tx_size;
+ WORD32 i4_act_ary_wd, i4_act_ary_ht;
+ WORD32 i4_and_const;
+ UWORD8 *pu1_incr_x, *pu1_incr_y;
+
+ memset(pu1_ref_x_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
+ memset(pu1_ref_y_ptr_incr, 1, (i4_refary_wd * i4_refary_ht));
+
+ i4_act_ary_wd = i4_refary_wd;
+ i4_act_ary_ht = i4_refary_ht;
+
+ i4_x = 0;
+ i4_y = 0;
+ i4_prev_y = 0;
+
+ if(0 == i4_chroma_flag)
+ {
+ do
+ {
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_idx;
+ WORD32 i4_wd, i4_ht;
+ WORD32 i4_max_pos_x, i4_max_pos_y;
+
+ i4_prev_x = i4_x;
+
+ i4_x_ref = i4_x_offset + i4_x;
+ i4_y_ref = i4_y_offset + i4_y;
+
+ isvce_get_ref_layer_mbtype_tx_size(pi1_ref_mb_modes, i4_ref_mode_stride,
+ i4_element_size, i4_x_ref, i4_y_ref, &i4_mb_type,
+ &i4_tx_size, i4_chroma_flag);
+
+ i4_trans_size = ((i4_tx_size + 1) << 2);
+ i4_const_val = i4_trans_size - 1;
+ i4_and_const = i4_const_val;
+
+ /* Fill horizontal tx block edges of current reference mb with 0 */
+ pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
+ pu1_incr_x += (i4_y * i4_refary_wd);
+
+ i4_ht = (16 - (i4_y_ref & 0xF));
+ i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
+
+ i4_x_idx = i4_x;
+
+ i4_pos_x = i4_x_ref & 0xF;
+
+ i4_max_pos_x = 16;
+ i4_x += (16 - i4_pos_x);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_x & i4_and_const));
+
+ i4_x_idx += i4_idx;
+
+ while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_x + i4_idx;
+
+ for(i4_i = 0; i4_i < i4_ht; i4_i++)
+ { /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr += i4_refary_wd;
+ }
+
+ i4_pos_x += i4_trans_size;
+ pu1_incr_x += i4_trans_size;
+ i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
+ }
+
+ /* Fill vertical tx block edges of current reference mb with 0 */
+ pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
+ pu1_incr_y += (i4_y * i4_refary_wd);
+
+ i4_wd = (16 - (i4_x_ref & 0xF));
+ i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
+
+ i4_y_idx = i4_y;
+
+ i4_pos_y = i4_y_ref & 0xF;
+
+ i4_max_pos_y = 16;
+ i4_y += (16 - i4_pos_y);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_y & i4_and_const));
+
+ i4_y_idx += i4_idx;
+
+ while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
+
+ for(i4_i = 0; i4_i < i4_wd; i4_i++)
+ { /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr++;
+ }
+
+ i4_pos_y += i4_trans_size;
+ pu1_incr_y += i4_trans_size * i4_refary_wd;
+ i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
+ }
+
+ if(i4_x < i4_act_ary_wd)
+ {
+ i4_y = i4_prev_y;
+ }
+ else if(i4_y < i4_act_ary_ht)
+ {
+ i4_prev_y = i4_y;
+ i4_x = 0;
+ }
+ } while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
+ }
+ else
+ {
+ i4_trans_size = 4;
+ i4_const_val = 3;
+
+ do
+ {
+ WORD32 i4_x_ref, i4_y_ref;
+ WORD32 i4_idx;
+ WORD32 i4_wd, i4_ht;
+ WORD32 i4_max_pos_x, i4_max_pos_y;
+
+ i4_prev_x = i4_x;
+
+ i4_x_ref = i4_x_offset + i4_x;
+ i4_y_ref = i4_y_offset + i4_y;
+
+ /* Fill horizontal tx block edges of current reference mb with 0 */
+ pu1_incr_x = pu1_ref_x_ptr_incr + i4_x;
+ pu1_incr_x += (i4_y * i4_refary_wd);
+
+ i4_ht = (8 - (i4_y_ref & 0x7));
+ i4_ht = MIN((i4_act_ary_ht - i4_y), i4_ht);
+
+ i4_x_idx = i4_x;
+
+ i4_pos_x = i4_x_ref & 0x7;
+
+ i4_max_pos_x = 8;
+ i4_x += (8 - i4_pos_x);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_x & 0x3));
+
+ i4_x_idx += i4_idx;
+
+ while((i4_pos_x < i4_max_pos_x) && (i4_x_idx < i4_act_ary_wd))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_x + i4_idx;
+
+ for(i4_i = 0; i4_i < i4_ht; i4_i++)
+ { /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr += i4_refary_wd;
+ }
+
+ i4_pos_x += i4_trans_size;
+ pu1_incr_x += i4_trans_size;
+ i4_x_idx += MIN(i4_trans_size, (i4_act_ary_wd - i4_x_idx));
+ }
+
+ /* Fill vertical tx block edges of current reference mb with 0 */
+ pu1_incr_y = pu1_ref_y_ptr_incr + i4_prev_x;
+ pu1_incr_y += (i4_y * i4_refary_wd);
+
+ i4_wd = (8 - (i4_x_ref & 0x7));
+ i4_wd = MIN((i4_act_ary_wd - i4_prev_x), i4_wd);
+
+ i4_y_idx = i4_y;
+
+ i4_pos_y = i4_y_ref & 0x7;
+
+ i4_max_pos_y = 8;
+ i4_y += (8 - i4_pos_y);
+
+ /* Get the transform block edge pos */
+ i4_idx = (i4_const_val - (i4_pos_y & 0x3));
+
+ i4_y_idx += i4_idx;
+
+ while((i4_pos_y < i4_max_pos_y) && (i4_y_idx < i4_act_ary_ht))
+ {
+ WORD32 i4_i;
+ UWORD8 *pu1_incr;
+
+ pu1_incr = pu1_incr_y + i4_idx * i4_refary_wd;
+
+ for(i4_i = 0; i4_i < i4_wd; i4_i++)
+ { /* Fill the block edge with 0s */
+ *pu1_incr = 0;
+ pu1_incr++;
+ }
+
+ i4_pos_y += i4_trans_size;
+ pu1_incr_y += i4_trans_size * i4_refary_wd;
+ i4_y_idx += MIN(i4_trans_size, (i4_act_ary_ht - i4_y_idx));
+ }
+
+ if(i4_x < i4_act_ary_wd)
+ {
+ i4_y = i4_prev_y;
+ }
+ else if(i4_y < i4_act_ary_ht)
+ {
+ i4_prev_y = i4_y;
+ i4_x = 0;
+ }
+ } while((i4_y < i4_act_ary_ht) || (i4_x < i4_act_ary_wd));
+ }
+}
+
+void isvce_residual_reflayer_const(svc_res_pred_ctxt_t *ps_res_pred_ctxt, WORD16 *pi2_inp_data,
+ WORD32 i4_inp_data_stride, WORD8 *ps_ref_mb_mode,
+ WORD32 i4_ref_mb_mode_stride, WORD32 *pi4_refarr_wd,
+ WORD32 i4_chroma_flag)
+{
+ WORD8 *pi1_ref_mb_modes;
+ WORD32 i4_ref_mode_stride;
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_ref_wd;
+ WORD32 i4_ref_ht;
+ WORD32 i4_x_offset;
+ WORD32 i4_y_offset;
+ WORD32 i4_refarray_wd;
+ WORD32 i4_refarray_ht;
+
+ WORD16 *pi2_ref_array;
+
+ res_pred_mb_state_t *ps_mb_states;
+ res_pred_layer_state_t *ps_layer_state;
+
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_variables_t *ps_res_pred_variables = &ps_res_pred_ctxt->s_res_pred_variables;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ res_pred_mem_store_t *ps_mem_store = &ps_res_pred_state->s_mem_store;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_res_pred_variables->ps_svc_ilp_data;
+ coordinates_t *ps_mb_pos = &ps_res_pred_variables->s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id = ps_res_pred_variables->u1_spatial_layer_id;
+
+ ps_layer_state = &ps_res_pred_state->ps_layer_state[u1_spatial_layer_id];
+ pi2_ref_array = (WORD16 *) ps_mem_store->s_scratch.pv_data;
+
+ pi1_ref_mb_modes = (WORD8 *) ps_ref_mb_mode;
+ i4_ref_mode_stride = i4_ref_mb_mode_stride;
+
+ ASSERT(NULL != pi1_ref_mb_modes);
+
+ {
+ WORD32 i4_base_width;
+ WORD32 i4_base_height;
+
+ coordinates_t s_frame_dims, s_frame_dims_in_mbs;
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_mb_states = i4_chroma_flag ? ps_layer_state->ps_chroma_mb_states
+ : ps_layer_state->ps_luma_mb_states;
+
+ ps_mb_states +=
+ ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+
+ i4_base_width = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_width;
+ i4_base_height = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1].u4_height;
+
+ i4_ref_wd = i4_base_width >> i4_chroma_flag;
+ i4_ref_ht = i4_base_height >> i4_chroma_flag;
+
+ i4_x_offset = ps_mb_states->s_offsets.i4_abscissa;
+ i4_y_offset = ps_mb_states->s_offsets.i4_ordinate;
+ i4_refarray_wd = ps_mb_states->s_ref_array_dims.i4_abscissa;
+ i4_refarray_ht = ps_mb_states->s_ref_array_dims.i4_ordinate;
+ }
+
+ {
+ isvce_ref_layer_ptr_incr(pi1_ref_mb_modes, i4_ref_mode_stride, 1, i4_x_offset, i4_y_offset,
+ i4_refarray_wd, i4_refarray_ht,
+ ps_res_pred_state->pu1_ref_x_ptr_incr,
+ ps_res_pred_state->pu1_ref_y_ptr_incr, i4_chroma_flag);
+ }
+
+ for(i4_y = 0; i4_y < i4_refarray_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_refarray_wd; i4_x++)
+ {
+ WORD32 i4_x_ref;
+ WORD32 i4_y_ref;
+ WORD32 i4_ref_mb_type, i4_ref_tx_size;
+ WORD16 *pi2_ref_data_byte;
+ WORD16 *pi2_ref_array_temp;
+
+ i4_x_ref = MAX(0, MIN(i4_ref_wd - 1, i4_x + i4_x_offset));
+ i4_y_ref = MAX(0, MIN(i4_ref_ht - 1, i4_y + i4_y_offset));
+
+ isvce_get_ref_layer_mbtype_tx_size(pi1_ref_mb_modes, i4_ref_mode_stride, 1, i4_x_ref,
+ i4_y_ref, &i4_ref_mb_type, &i4_ref_tx_size,
+ i4_chroma_flag);
+
+ if(0 <= i4_x_offset)
+ {
+ i4_x_ref = i4_x_ref - i4_x_offset;
+ }
+
+ if(0 <= i4_y_offset)
+ {
+ i4_y_ref = i4_y_ref - i4_y_offset;
+ }
+
+ pi2_ref_array_temp = pi2_ref_array + i4_x;
+ pi2_ref_array_temp += i4_y * i4_refarray_wd;
+
+ if(SVC_INTER_MB == i4_ref_mb_type)
+ {
+ pi2_ref_data_byte = pi2_inp_data + (i4_x_ref << i4_chroma_flag);
+ pi2_ref_data_byte += i4_y_ref * i4_inp_data_stride;
+
+ *pi2_ref_array_temp = (WORD16) (*pi2_ref_data_byte);
+ }
+ else
+ {
+ *pi2_ref_array_temp = 0;
+ }
+ }
+ }
+ *pi4_refarr_wd = i4_refarray_wd;
+}
+
+void isvce_interpolate_residual(svc_res_pred_ctxt_t *ps_res_pred_ctxt, WORD16 *pi2_out,
+ WORD32 i4_out_stride, WORD32 i4_refarray_wd, WORD32 i4_chroma_flag,
+ coordinates_t *ps_mb_pos)
+{
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_variables_t *ps_res_pred_variables = &ps_res_pred_ctxt->s_res_pred_variables;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ res_pred_mem_store_t *ps_mem_store = &ps_res_pred_state->s_mem_store;
+
+ WORD32 i4_x, i4_y;
+ WORD32 i4_temp_array_ht;
+ WORD32 i4_mb_wd;
+ WORD32 i4_mb_ht;
+ WORD16 *pi2_ref_array;
+ UWORD8 *pu1_ref_x_ptr_incr, *pu1_ref_y_ptr_incr;
+
+ coordinates_t *ps_phase;
+ coordinates_t *ps_pos;
+ res_pred_mb_state_t *ps_mb_states;
+
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+
+ UWORD8 u1_spatial_layer_id = ps_res_pred_variables->u1_spatial_layer_id;
+
+ svc_ilp_data_t *ps_svc_ilp_data = ps_res_pred_variables->ps_svc_ilp_data;
+
+ res_pred_mb_state_t *ps_mb_state;
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+
+ pu1_ref_x_ptr_incr = ps_res_pred_state->pu1_ref_x_ptr_incr;
+ pu1_ref_y_ptr_incr = ps_res_pred_state->pu1_ref_y_ptr_incr;
+
+ ps_mb_states = i4_chroma_flag
+ ? ps_res_pred_state->ps_layer_state[u1_spatial_layer_id].ps_chroma_mb_states
+ : ps_res_pred_state->ps_layer_state[u1_spatial_layer_id].ps_luma_mb_states;
+
+ i4_mb_wd = MB_SIZE >> i4_chroma_flag;
+ i4_mb_ht = MB_SIZE >> i4_chroma_flag;
+
+ ps_mb_state = &ps_mb_states[ps_mb_pos->i4_abscissa +
+ (ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa)];
+
+ ps_phase = ps_mb_state->ps_ref_array_phases;
+ ps_pos = ps_mb_state->ps_ref_array_positions;
+
+ i4_temp_array_ht = i4_mb_ht;
+
+ pi2_ref_array = (WORD16 *) ps_mem_store->s_scratch.pv_data;
+
+ for(i4_y = 0; i4_y < i4_temp_array_ht; i4_y++)
+ {
+ for(i4_x = 0; i4_x < i4_mb_wd; i4_x++)
+ {
+ WORD32 i4_i;
+ WORD32 i4_y_ref;
+ WORD32 i4_y_phase;
+ WORD32 i4_x_ref;
+ WORD32 i4_x_phase;
+ WORD32 i4_x_ref_round;
+ WORD16 *pi2_out_curr;
+ WORD32 ai4_temp_pred[2];
+ UWORD8 *pu1_ref_y_ptr_incr_temp;
+ WORD32 *pi4_temp_pred;
+ UWORD8 u1_incr_y;
+ WORD16 i2_res;
+
+ pi2_out_curr = pi2_out + (i4_x << i4_chroma_flag) + (i4_y * i4_out_stride);
+
+ i4_y_ref = ps_pos[(i4_mb_wd * i4_y) + i4_x].i4_ordinate;
+ i4_y_phase = ps_phase[((i4_y % 3) > 0) * 2 + (i4_y % 3)].i4_ordinate;
+
+ i4_x_ref = ps_pos[(i4_mb_wd * i4_y) + i4_x].i4_abscissa;
+ i4_x_phase = ps_phase[i4_x % 3].i4_abscissa;
+
+ /* horizontal processing*/
+ for(i4_i = 0; i4_i < 2; i4_i++)
+ {
+ UWORD8 *pu1_ref_x_ptr_incr_temp;
+ UWORD8 u1_incr;
+ WORD16 *pi2_ref_array_1, *pi2_ref_array_2;
+
+ pu1_ref_x_ptr_incr_temp = pu1_ref_x_ptr_incr + i4_x_ref;
+ pu1_ref_x_ptr_incr_temp += ((i4_y_ref + i4_i) * i4_refarray_wd);
+ u1_incr = *pu1_ref_x_ptr_incr_temp;
+
+ pi2_ref_array_1 = pi2_ref_array + i4_x_ref;
+ pi2_ref_array_1 += ((i4_y_ref + i4_i) * i4_refarray_wd);
+
+ if(!u1_incr)
+ {
+ pi2_ref_array_1 += (i4_x_phase >> 3);
+ }
+
+ pi2_ref_array_2 = pi2_ref_array_1 + u1_incr;
+
+ ai4_temp_pred[i4_i] =
+ (16 - i4_x_phase) * (*pi2_ref_array_1) + i4_x_phase * (*pi2_ref_array_2);
+ }
+
+ /* vertical processing */
+ i4_x_ref_round = (i4_x_ref + (i4_x_phase >> 3));
+
+ pu1_ref_y_ptr_incr_temp =
+ pu1_ref_y_ptr_incr + i4_x_ref_round + (i4_y_ref * i4_refarray_wd);
+ u1_incr_y = *pu1_ref_y_ptr_incr_temp;
+
+ pi4_temp_pred = &ai4_temp_pred[0];
+ if(!u1_incr_y)
+ {
+ pi4_temp_pred += (i4_y_phase >> 3);
+ }
+ i2_res = (((16 - i4_y_phase) * pi4_temp_pred[0] +
+ i4_y_phase * pi4_temp_pred[u1_incr_y] + 128) >>
+ 8);
+ *pi2_out_curr = i2_res;
+ }
+ }
+}
+
+void isvce_get_mb_residual_pred_non_dyadic(svc_res_pred_ctxt_t *ps_res_pred_ctxt)
+{
+ buffer_container_t s_inp;
+ buffer_container_t s_out;
+ coordinates_t s_frame_dims;
+ coordinates_t s_frame_dims_in_mbs;
+ coordinates_t s_ref_array_offsets;
+ res_pred_layer_state_t *ps_layer_state, *ps_ref_layer_state;
+ yuv_buf_props_t *ps_ref_residual_buf;
+ res_pred_mb_state_t *ps_luma_mb_state;
+ res_pred_mb_state_t *ps_chroma_mb_state;
+
+ WORD16 *pi2_inp, *pi2_out;
+ WORD32 i4_inp_stride, i4_out_stride;
+
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_variables_t *ps_res_pred_variables = &ps_res_pred_ctxt->s_res_pred_variables;
+ res_pred_outputs_t *ps_res_pred_outputs = &ps_res_pred_ctxt->s_res_pred_outputs;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ svc_ilp_data_t *ps_svc_ilp_data = ps_res_pred_variables->ps_svc_ilp_data;
+ coordinates_t *ps_mb_pos = &ps_res_pred_variables->s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id = ps_res_pred_variables->u1_spatial_layer_id;
+
+ WORD32 i4_refarray_wd;
+
+ WORD32 i;
+
+ ASSERT(u1_spatial_layer_id > 0);
+
+ s_frame_dims.i4_abscissa = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_width;
+ s_frame_dims.i4_ordinate = ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id].u4_height;
+ s_frame_dims_in_mbs.i4_abscissa = s_frame_dims.i4_abscissa / MB_SIZE;
+ s_frame_dims_in_mbs.i4_ordinate = s_frame_dims.i4_ordinate / MB_SIZE;
+
+ ps_layer_state = &ps_res_pred_state->ps_layer_state[u1_spatial_layer_id];
+ ps_ref_layer_state = &ps_res_pred_state->ps_layer_state[u1_spatial_layer_id - 1];
+ ps_ref_residual_buf = &ps_svc_ilp_data->ps_residual_bufs[u1_spatial_layer_id - 1];
+ ps_luma_mb_state = ps_layer_state->ps_luma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+ ps_chroma_mb_state = ps_layer_state->ps_chroma_mb_states + ps_mb_pos->i4_abscissa +
+ ps_mb_pos->i4_ordinate * s_frame_dims_in_mbs.i4_abscissa;
+
+ for(i = 0; i < NUM_COMPONENTS; i++)
+ {
+ res_pred_mb_state_t *ps_mb_state;
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+
+ ps_mb_state = u1_is_chroma ? ps_chroma_mb_state : ps_luma_mb_state;
+
+ s_ref_array_offsets.i4_abscissa =
+ MAX(0, MIN(ps_mb_state->s_offsets.i4_abscissa,
+ (s_frame_dims.i4_abscissa >> u1_is_chroma) - 1));
+ s_ref_array_offsets.i4_ordinate =
+ MAX(0, MIN(ps_mb_state->s_offsets.i4_ordinate,
+ (s_frame_dims.i4_ordinate >> u1_is_chroma) - 1));
+
+ s_inp = ps_ref_residual_buf->as_component_bufs[u1_is_chroma ? UV : Y];
+ s_inp.pv_data = ((WORD16 *) s_inp.pv_data) + (V == ((COMPONENT_TYPE) i)) +
+ (s_ref_array_offsets.i4_abscissa << u1_is_chroma) +
+ s_ref_array_offsets.i4_ordinate * s_inp.i4_data_stride;
+
+ s_out = ps_res_pred_outputs->s_res_pred.as_component_bufs[u1_is_chroma ? UV : Y];
+ s_out.pv_data = ((WORD16 *) s_out.pv_data) + (V == ((COMPONENT_TYPE) i));
+
+ pi2_inp = (WORD16 *) s_inp.pv_data;
+ pi2_out = (WORD16 *) s_out.pv_data;
+
+ i4_inp_stride = s_inp.i4_data_stride;
+ i4_out_stride = s_out.i4_data_stride;
+
+ /* ------- Constructing refSampleArray ----------------------- */
+ isvce_residual_reflayer_const(
+ ps_res_pred_ctxt, pi2_inp, i4_inp_stride, ps_ref_layer_state->pi1_mb_mode,
+ ps_ref_layer_state->i4_mb_mode_stride, &i4_refarray_wd, u1_is_chroma);
+
+ /* ---- Interpolation process for Residual prediction ------ */
+ isvce_interpolate_residual(ps_res_pred_ctxt, pi2_out, i4_out_stride, i4_refarray_wd,
+ u1_is_chroma, ps_mb_pos);
+ }
+}
+
+UWORD32 isvce_get_sad_with_residual_pred(buffer_container_t *ps_src, buffer_container_t *ps_pred,
+ buffer_container_t *ps_res, UWORD32 u4_mb_wd,
+ UWORD32 u4_mb_ht)
+{
+ UWORD32 i, j;
+
+ UWORD32 u4_sad = 0;
+
+ for(i = 0; i < u4_mb_ht; i++)
+ {
+ for(j = 0; j < u4_mb_wd; j++)
+ {
+ WORD16 i2_src = ((UWORD8 *) ps_src->pv_data)[j + i * ps_src->i4_data_stride];
+ WORD16 i2_pred = ((UWORD8 *) ps_pred->pv_data)[j + i * ps_pred->i4_data_stride];
+ WORD16 i2_res = ((WORD16 *) ps_res->pv_data)[j + i * ps_res->i4_data_stride];
+
+ u4_sad += ABS(i2_src - i2_pred - i2_res);
+ }
+ }
+ return u4_sad;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to evaluate residual_prediction_flag
+*
+* @param[in] ps_src
+* Pointer to MB src buffers
+*
+* @param[in] ps_pred
+* Pointer to MB pred buffers
+*
+* @param[in] ps_res
+* Pointer to MB res buffers
+*
+* @param[out] pu4_res_pred_sad
+* Output variable for SAD
+*
+* @param[out] pu1_residual_prediction_flag
+* Output variable for residual_prediction_flag
+*
+* @param[in] u4_winning_sad
+* Winning mode's SAD
+*
+* @notes The algorithm currently uses only luma for evaluating
+* residual_prediction_flag.
+*
+*******************************************************************************
+*/
+void isvce_residual_pred_eval(svc_res_pred_ctxt_t *ps_res_pred_ctxt, yuv_buf_props_t *ps_src,
+ yuv_buf_props_t *ps_pred, yuv_buf_props_t *ps_res,
+ UWORD32 *pu4_res_pred_sad, UWORD8 *pu1_residual_prediction_flag,
+ UWORD32 u4_winning_sad)
+{
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ pu4_res_pred_sad[0] = ps_res_pred_state->pf_get_sad_with_residual_pred(
+ &ps_src->as_component_bufs[Y], &ps_pred->as_component_bufs[Y],
+ &ps_res->as_component_bufs[Y], MB_SIZE, MB_SIZE);
+
+ pu1_residual_prediction_flag[0] = pu4_res_pred_sad[0] < u4_winning_sad;
+}
+
+void isvce_update_res_pred_info(isvce_process_ctxt_t *ps_proc)
+{
+ if(ps_proc->s_svc_params.u1_num_spatial_layers > 1)
+ {
+ svc_res_pred_ctxt_t *ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt;
+ res_pred_constants_t *ps_res_pred_constants = &ps_res_pred_ctxt->s_res_pred_constants;
+ res_pred_state_t *ps_res_pred_state = (res_pred_state_t *) ps_res_pred_constants->pv_state;
+ res_pred_layer_state_t *ps_layer_state =
+ &ps_res_pred_state->ps_layer_state[ps_proc->u1_spatial_layer_id];
+
+ WORD8 i1_is_intra = ps_proc->ps_mb_info->u1_is_intra;
+
+ WORD8 *pi1_mb_mode =
+ &ps_layer_state->pi1_mb_mode[ps_proc->i4_mb_x +
+ (ps_proc->i4_mb_y * (ps_layer_state->i4_mb_mode_stride))];
+
+ if(ps_proc->ps_mb_info->u1_base_mode_flag == 1 && i1_is_intra)
+ {
+ *pi1_mb_mode = SVC_IBL_MB;
+ }
+ else
+ {
+ if(i1_is_intra)
+ {
+ *pi1_mb_mode = SVC_INTRA_MB;
+ }
+ else
+ {
+ *pi1_mb_mode = SVC_INTER_MB;
+ }
+ }
+ }
+}
diff --git a/encoder/svc/isvce_residual_pred.h b/encoder/svc/isvce_residual_pred.h
new file mode 100644
index 0000000..d0ef076
--- /dev/null
+++ b/encoder/svc/isvce_residual_pred.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_residual_pred.h
+*
+* @brief
+* Contains function declarations for function declared in
+*isvce_residual_pred.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_RESIDUAL_PRED_H_
+#define _ISVCE_RESIDUAL_PRED_H_
+
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_debug.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+#include "isvce_structs.h"
+
+/* Structs */
+typedef struct res_pred_constants_t
+{
+ void *pv_state;
+} res_pred_constants_t;
+
+typedef struct res_pred_outputs_t
+{
+ yuv_buf_props_t s_res_pred;
+} res_pred_outputs_t;
+
+typedef struct res_pred_variables_t
+{
+ svc_ilp_data_t *ps_svc_ilp_data;
+
+ coordinates_t s_mb_pos;
+
+ UWORD8 u1_spatial_layer_id;
+} res_pred_variables_t;
+
+typedef struct svc_res_pred_ctxt_t
+{
+ res_pred_constants_t s_res_pred_constants;
+
+ res_pred_variables_t s_res_pred_variables;
+
+ res_pred_outputs_t s_res_pred_outputs;
+
+} svc_res_pred_ctxt_t;
+
+extern UWORD32 isvce_get_svc_res_pred_ctxt_size(UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht);
+
+extern void isvce_svc_res_pred_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_get_mb_residual_pred(svc_res_pred_ctxt_t *ps_res_pred_ctxt);
+
+extern void isvce_get_mb_residual_pred_non_dyadic(svc_res_pred_ctxt_t *ps_res_pred_ctxt);
+
+extern void isvce_residual_pred_eval(svc_res_pred_ctxt_t *ps_res_pred_ctxt, yuv_buf_props_t *ps_src,
+ yuv_buf_props_t *ps_pred, yuv_buf_props_t *ps_res,
+ UWORD32 *pu4_res_pred_sad,
+ UWORD8 *pu1_residual_prediction_flag, UWORD32 u4_winning_sad);
+
+extern void isvce_update_res_pred_info(isvce_process_ctxt_t *ps_proc);
+
+#endif
diff --git a/encoder/svc/isvce_structs.h b/encoder/svc/isvce_structs.h
new file mode 100644
index 0000000..1acf2ed
--- /dev/null
+++ b/encoder/svc/isvce_structs.h
@@ -0,0 +1,2584 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_structs.h
+*
+* @brief
+* Contains struct definition used for SVC encoding
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_STRUCTS_H_
+#define _ISVCE_STRUCTS_H_
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_inter_pred_filters.h"
+#include "ithread.h"
+#include "isvc_defs.h"
+#include "isvc_mem_fns.h"
+#include "isvc_cabac_tables.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+
+/* Dependencies of ih264e_structs.h */
+#include "ih264e_error.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "ih264e_defs.h"
+#include "ime_structs.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+
+#include "ih264e_structs.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_defs.h"
+#include "isvce_downscaler.h"
+#include "isvce_interface_structs.h"
+#include "isvce_nalu_stat_aggregator.h"
+#include "isvce_pred_structs.h"
+#include "isvce_rc_utils.h"
+
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+
+typedef struct svc_params_t
+{
+ /**
+ * Num Temporal Layers
+ */
+ UWORD8 u1_num_temporal_layers;
+
+ /**
+ * Num Spatial Layers
+ */
+ UWORD8 u1_num_spatial_layers;
+
+ /**
+ * Resolution ration b/w spatial layers
+ */
+ DOUBLE d_spatial_res_ratio;
+
+} svc_params_t;
+
+typedef struct svc_layer_data_t
+{
+ /**
+ * Array of structs that contain mode_info per MB for every MB per layer
+ */
+ isvce_mb_info_t *ps_mb_info;
+
+ UWORD32 *pu4_num_pus_in_mb;
+
+} svc_layer_data_t;
+
+typedef struct svc_au_data_t
+{
+ /**
+ * Array of structs that contain layer-wise data used for svc prediction
+ */
+ svc_layer_data_t *ps_svc_layer_data;
+
+ /**
+ * Absolute POC for the current MV Bank
+ */
+ WORD32 i4_abs_poc;
+
+ /**
+ * Buffer Id
+ */
+ WORD32 i4_buf_id;
+
+} svc_au_data_t;
+
+typedef struct isvce_inp_buf_t
+{
+ /* App's buffer */
+ isvce_raw_inp_buf_t s_inp_props;
+
+ /* A copy of SVC parameters */
+ svc_params_t s_svc_params;
+
+ /**
+ * Array of structs that contain properties of the buffers used for storing
+ * layer-wise YUV data
+ */
+ yuv_buf_props_t as_layer_yuv_buf_props[MAX_NUM_SPATIAL_LAYERS];
+
+} isvce_inp_buf_t;
+
+typedef struct mb_intra_modes_t
+{
+ UWORD8 au1_intra_modes[MAX_PU_IN_MB];
+} mb_intra_modes_t;
+
+typedef struct nbr_info_t
+{
+ isvce_mb_info_t *ps_top_row_mb_info;
+
+ isvce_mb_info_t *ps_left_mb_info;
+
+ mb_intra_modes_t *ps_top_mb_intra_modes;
+
+ mb_intra_modes_t *ps_left_mb_intra_modes;
+
+} nbr_info_t;
+
+typedef struct svc_nbr_info_t
+{
+ /**
+ * Array of structs that contain properties of the buffers used for storing
+ * layer-wise neighbour info
+ */
+ nbr_info_t *ps_layer_nbr_info;
+} svc_nbr_info_t;
+
+typedef struct layer_resampler_props_t
+{
+ UWORD32 u4_shift_x;
+
+ UWORD32 u4_shift_y;
+
+ UWORD32 u4_scale_x;
+
+ UWORD32 u4_scale_y;
+
+ WORD32 i4_offset_x;
+
+ WORD32 i4_offset_y;
+
+ WORD32 i4_add_x;
+
+ WORD32 i4_add_y;
+
+ WORD32 i4_delta_x;
+
+ WORD32 i4_delta_y;
+
+ WORD32 i4_refphase_x;
+
+ WORD32 i4_refphase_y;
+
+ WORD32 i4_phase_x;
+
+ WORD32 i4_phase_y;
+
+ UWORD32 u4_sub_wd;
+
+ UWORD32 u4_sub_ht;
+
+ UWORD32 u4_mb_wd;
+
+ UWORD32 u4_mb_ht;
+
+} layer_resampler_props_t;
+
+typedef struct svc_ilp_data_t
+{
+ /* Pointer to current AU buf */
+ svc_au_data_t *ps_svc_au_data;
+
+ /* Array of bufs corresponding to numSpatialLayers */
+ layer_resampler_props_t *aps_layer_resampler_props[NUM_SP_COMPONENTS];
+
+ /* Array of bufs corresponding to numSpatialLayers */
+ yuv_buf_props_t *ps_intra_recon_bufs;
+
+ /* Array of bufs corresponding to numSpatialLayers */
+ yuv_buf_props_t *ps_residual_bufs;
+} svc_ilp_data_t;
+
+typedef struct ilp_mv_t
+{
+ isvce_enc_pu_mv_t as_mv[ENC_MAX_PU_IN_MB][NUM_PRED_DIRS];
+
+ MBTYPES_T e_mb_type;
+
+ PRED_MODE_T ae_pred_mode[ENC_MAX_PU_IN_MB];
+} ilp_mv_t;
+
+typedef struct ilp_me_cands_t
+{
+ isvce_enc_pu_mv_t as_mv[MAX_PU_IN_MB + MAX_ILP_MV_IN_NBR_RGN][NUM_PRED_DIRS];
+
+ MBTYPES_T e_mb_type[MAX_PU_IN_MB + MAX_ILP_MV_IN_NBR_RGN];
+
+ PRED_MODE_T ae_pred_mode[MAX_PU_IN_MB + MAX_ILP_MV_IN_NBR_RGN];
+
+ UWORD32 u4_num_ilp_mvs;
+
+ UWORD32 u4_num_ilp_mvs_incl_nbrs;
+} ilp_me_cands_t;
+
+typedef struct isvce_cfg_params_t
+{
+ /** maximum width for which codec should request memory requirements */
+ UWORD32 u4_max_wd;
+
+ /** maximum height for which codec should request memory requirements */
+ UWORD32 u4_max_ht;
+
+ /** Maximum number of reference frames */
+ UWORD32 u4_max_ref_cnt;
+
+ /** Maximum number of reorder frames */
+ UWORD32 u4_max_reorder_cnt;
+
+ /** Maximum level supported */
+ UWORD32 u4_max_level;
+
+ /** Input color format */
+ IV_COLOR_FORMAT_T e_inp_color_fmt;
+
+ /** Flag to enable/disable - To be used only for debugging/testing */
+ UWORD32 u4_enable_recon;
+
+ /** Recon color format */
+ IV_COLOR_FORMAT_T e_recon_color_fmt;
+
+ /** Encoder Speed preset - Value between 0 (slowest) and 100 (fastest) */
+ IVE_SPEED_CONFIG u4_enc_speed_preset;
+
+ /** Rate control mode */
+ IVE_RC_MODE_T e_rc_mode;
+
+ /** Maximum frame rate to be supported */
+ UWORD32 u4_max_framerate;
+
+ /** Maximum bitrate to be supported */
+ UWORD32 au4_max_bitrate[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Maximum number of consecutive B frames */
+ UWORD32 u4_num_bframes;
+
+ /** Content type Interlaced/Progressive */
+ IV_CONTENT_TYPE_T e_content_type;
+
+ /** Maximum search range to be used in X direction */
+ UWORD32 u4_max_srch_rng_x;
+
+ /** Maximum search range to be used in Y direction */
+ UWORD32 u4_max_srch_rng_y;
+
+ /** Slice Mode */
+ IVE_SLICE_MODE_T e_slice_mode;
+
+ /** Slice parameter */
+ UWORD32 u4_slice_param;
+
+ /** Processor architecture */
+ IV_ARCH_T e_arch;
+
+ /** SOC details */
+ IV_SOC_T e_soc;
+
+ /** Input width to be sent in bitstream */
+ UWORD32 u4_disp_wd;
+
+ /** Input height to be sent in bitstream */
+ UWORD32 u4_disp_ht;
+
+ /** Input width */
+ UWORD32 u4_wd;
+
+ /** Input height */
+ UWORD32 u4_ht;
+
+ /** Input stride */
+ UWORD32 u4_strd;
+
+ /** Source frame rate */
+ UWORD32 u4_src_frame_rate;
+
+ /** Target frame rate */
+ UWORD32 u4_tgt_frame_rate;
+
+ /** Target bitrate in kilobits per second */
+ UWORD32 au4_target_bitrate[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Force current frame type */
+ IV_PICTURE_CODING_TYPE_T e_frame_type;
+
+ /** Encoder mode */
+ IVE_ENC_MODE_T e_enc_mode;
+
+ /** Set initial Qp for I pictures */
+ UWORD32 au4_i_qp[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set initial Qp for P pictures */
+ UWORD32 au4_p_qp[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set initial Qp for B pictures */
+ UWORD32 au4_b_qp[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set minimum Qp for I pictures */
+ UWORD32 au4_i_qp_min[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set maximum Qp for I pictures */
+ UWORD32 au4_i_qp_max[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set minimum Qp for P pictures */
+ UWORD32 au4_p_qp_min[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set maximum Qp for P pictures */
+ UWORD32 au4_p_qp_max[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set minimum Qp for B pictures */
+ UWORD32 au4_b_qp_min[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Set maximum Qp for B pictures */
+ UWORD32 au4_b_qp_max[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Adaptive intra refresh mode */
+ IVE_AIR_MODE_T e_air_mode;
+
+ /** Adaptive intra refresh period in frames */
+ UWORD32 u4_air_refresh_period;
+
+ /** VBV buffer delay */
+ UWORD32 au4_vbv_buffer_delay[MAX_NUM_SPATIAL_LAYERS];
+
+ /** Number of cores to be used */
+ UWORD32 u4_num_cores;
+
+ /** ME speed preset - Value between 0 (slowest) and 100 (fastest) */
+ UWORD32 u4_me_speed_preset;
+
+ /** Flag to enable/disable half pel motion estimation */
+ UWORD32 u4_enable_hpel;
+
+ /** Flag to enable/disable quarter pel motion estimation */
+ UWORD32 u4_enable_qpel;
+
+ /** Flag to enable/disable intra 4x4 analysis */
+ UWORD32 u4_enable_intra_4x4;
+
+ /** Flag to enable/disable intra 8x8 analysis */
+ UWORD32 u4_enable_intra_8x8;
+
+ /** Flag to enable/disable intra 16x16 analysis */
+ UWORD32 u4_enable_intra_16x16;
+
+ /** Flag to enable/disable fast SAD approximation */
+ UWORD32 u4_enable_fast_sad;
+
+ /*flag to enable/disable alternate reference frames */
+ UWORD32 u4_enable_alt_ref;
+
+ /*Flag to enable/disable computation of SATDQ in ME*/
+ UWORD32 u4_enable_satqd;
+
+ /*Minimum SAD to search for*/
+ WORD32 i4_min_sad;
+
+ /** Maximum search range in X direction for farthest reference */
+ UWORD32 u4_srch_rng_x;
+
+ /** Maximum search range in Y direction for farthest reference */
+ UWORD32 u4_srch_rng_y;
+
+ /** I frame interval */
+ UWORD32 u4_i_frm_interval;
+
+ /** IDR frame interval */
+ UWORD32 u4_idr_frm_interval;
+
+ /** Disable deblock level (0: Enable completely, 3: Disable completely */
+ UWORD32 u4_disable_deblock_level;
+
+ /** Profile */
+ IV_PROFILE_T e_profile;
+
+ /** Lower 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_low;
+
+ /** Upper 32bits of time stamp corresponding to input buffer,
+ * from which this command takes effect */
+ UWORD32 u4_timestamp_high;
+
+ /** Flag to say if the current config parameter set is valid
+ * Will be zero to start with and will be set to 1, when configured
+ * Once encoder uses the parameter set, this will be set to zero */
+ UWORD32 u4_is_valid;
+
+ /** Command associated with this config param set */
+ ISVCE_CONTROL_API_COMMAND_TYPE_T e_cmd;
+
+ /** Input width in mbs */
+ UWORD32 i4_wd_mbs;
+
+ /** Input height in mbs */
+ UWORD32 i4_ht_mbs;
+
+ /** entropy coding mode flag */
+ UWORD32 u4_entropy_coding_mode;
+
+ /** enable weighted prediction */
+ UWORD32 u4_weighted_prediction;
+
+ /** Pic info type */
+ UWORD32 u4_pic_info_type;
+ /**
+ * MB info type
+ */
+ UWORD32 u4_isvce_mb_info_type;
+
+ /** VUI structure */
+ vui_t s_vui;
+
+ /** SEI structure */
+ sei_params_t s_sei;
+
+ /** Flag to enable/disable VUI from header */
+ UWORD32 u4_disable_vui;
+
+ /** SVC params */
+ svc_params_t s_svc_params;
+
+ bool b_nalu_info_export_enable;
+
+} isvce_cfg_params_t;
+
+typedef struct mb_qp_ctxt_t
+{
+ UWORD8 u1_cur_mb_qp;
+
+} mb_qp_ctxt_t;
+
+typedef struct isvce_entropy_ctxt_t
+{
+ /**
+ * Pointer to the cabac context
+ */
+ isvce_cabac_ctxt_t *ps_cabac;
+
+ mb_qp_ctxt_t *ps_mb_qp_ctxt;
+
+ /**
+ * start of frame / start of slice flag
+ */
+ WORD32 i4_sof;
+
+ /**
+ * end of frame / end of slice flag
+ */
+ WORD32 i4_eof;
+
+ /**
+ * generate header upon request
+ */
+ WORD32 i4_gen_header;
+
+ WORD32 i4_gen_subset_sps;
+
+ /**
+ * Pointer to base of sequence parameter set structure array
+ */
+ sps_t *ps_sps_base;
+
+ /**
+ * Pointer to base of Picture parameter set structure array
+ */
+ pps_t *ps_pps_base;
+
+ /**
+ * Current slice idx
+ */
+ WORD32 i4_cur_slice_idx;
+
+ /**
+ * Points to the array of slice indices which is used to identify the
+ * independent slice to which each MB in a frame belongs.
+ */
+ UWORD8 *pu1_slice_idx;
+
+ /**
+ * Pointer to base of svc_nalu_ext structure array
+ */
+ svc_nalu_ext_t *ps_svc_nalu_ext_base;
+
+ /**
+ * Pointer to base of subset sequence parameter set structure array
+ */
+ subset_sps_t *ps_subset_sps_base;
+
+ /**
+ * Pointer to base of slice header structure array
+ */
+ slice_header_t *ps_slice_hdr_base;
+
+ /**
+ * Pointer to base of SVC slice header structure array
+ */
+ svc_slice_header_t *ps_svc_slice_hdr_base;
+
+ /**
+ * entropy status
+ */
+ UWORD8 *pu1_entropy_map;
+
+ /**
+ * MB's x position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_x;
+
+ /**
+ * MB's y position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_y;
+
+ /**
+ * MB start address
+ */
+ WORD32 i4_mb_cnt;
+
+ /**
+ * MB start address
+ */
+ WORD32 i4_mb_start_add;
+
+ /**
+ * MB end address
+ */
+ WORD32 i4_mb_end_add;
+
+ /**
+ * Input width in mbs
+ */
+ WORD32 i4_wd_mbs;
+
+ /**
+ * Input height in mbs
+ */
+ WORD32 i4_ht_mbs;
+
+ /**
+ * Bitstream structure
+ */
+ bitstrm_t *ps_bitstrm;
+
+#if ENABLE_RE_ENC_AS_SKIP
+ bitstrm_t *ps_bitstrm_after_slice_hdr;
+#endif
+
+ /**
+ * transform_8x8_mode_flag
+ */
+ WORD8 i1_transform_8x8_mode_flag;
+
+ /**
+ * entropy_coding_mode_flag
+ */
+ WORD8 u1_entropy_coding_mode_flag;
+
+ /**
+ * Pointer to the top row nnz for luma
+ */
+ UWORD8 (*pu1_top_nnz_luma)[4];
+
+ /**
+ * left nnz for luma
+ */
+ UWORD32 u4_left_nnz_luma;
+
+ /**
+ * Pointer to zero runs before for the mb
+ */
+ UWORD8 au1_zero_run[16];
+
+ /**
+ * Pointer to the top row nnz for chroma
+ */
+ UWORD8 (*pu1_top_nnz_cbcr)[4];
+
+ /**
+ * left nnz for chroma
+ */
+ UWORD8 u4_left_nnz_cbcr;
+
+ /**
+ * Pointer frame level mb subblock coeff data
+ */
+ void *pv_pic_mb_coeff_data;
+
+ /**
+ * Pointer to mb subblock coeff data and number of subblocks and scan idx
+ * Incremented each time a coded subblock is processed
+ */
+ void *pv_mb_coeff_data;
+
+ /**
+ * Pointer frame level mb header data
+ */
+ void *pv_pic_mb_header_data;
+
+ /**
+ * Pointer to mb header data and
+ * incremented each time a coded mb is encoded
+ */
+ void *pv_mb_header_data;
+
+ /**
+ * Error code during parse stage
+ */
+ IH264E_ERROR_T i4_error_code;
+
+ /**
+ * Void pointer to job context
+ */
+ void *pv_proc_jobq, *pv_entropy_jobq;
+
+ /**
+ * Flag to signal end of frame
+ */
+ WORD32 i4_end_of_frame;
+
+ /**
+ * Abs POC count of the frame
+ */
+ WORD32 i4_abs_pic_order_cnt;
+
+ /**
+ * mb skip run
+ */
+ WORD32 *pi4_mb_skip_run;
+
+ /**
+ * Flag to signal end of sequence
+ */
+ UWORD32 u4_is_last;
+
+ /**
+ * Lower 32bits of time-stamp corresponding to the buffer being encoded
+ */
+ UWORD32 u4_timestamp_low;
+
+ /**
+ * Upper 32bits of time-stamp corresponding to the buffer being encoded
+ */
+ UWORD32 u4_timestamp_high;
+
+ /**
+ * Current Picture count - used for synchronization
+ */
+ WORD32 i4_pic_cnt;
+
+ /**
+ * Number of bits consumed by header for I and P mb types
+ */
+ UWORD32 u4_header_bits[MAX_MB_TYPE];
+
+ /**
+ * Number of bits consumed by residue for I and P mb types
+ */
+ UWORD32 u4_residue_bits[MAX_MB_TYPE];
+
+ UWORD8 u1_spatial_layer_id;
+
+} isvce_entropy_ctxt_t;
+
+/**
+ ******************************************************************************
+ * @brief Rate control related variables
+ ******************************************************************************
+ */
+typedef struct isvce_rate_control_ctxt_t
+{
+ void *apps_rate_control_api[MAX_NUM_SPATIAL_LAYERS];
+
+ void *pps_frame_time;
+
+ void *pps_time_stamp;
+
+ void *pps_pd_frm_rate;
+
+ /**
+ * frame rate pull down
+ */
+ WORD32 pre_encode_skip[MAX_CTXT_SETS];
+
+ /**
+ * skip frame (cbr)
+ */
+ WORD32 post_encode_skip[MAX_CTXT_SETS];
+
+ /**
+ * rate control type
+ */
+ rc_type_e e_rc_type;
+
+ /**
+ * pic type
+ */
+ picture_type_e e_pic_type;
+
+ /**
+ * rc utils context
+ */
+ svc_rc_utils_ctxt_t s_rc_utils;
+
+ /**
+ * intra cnt in previous frame
+ */
+ WORD32 ai4_num_intra_in_prev_frame[MAX_NUM_SPATIAL_LAYERS];
+
+ /**
+ * avg activity of prev frame
+ */
+ WORD32 ai4_avg_activity[MAX_NUM_SPATIAL_LAYERS];
+
+} isvce_rate_control_ctxt_t;
+
+typedef struct
+{
+ /**
+ * mb type and mode
+ */
+ UWORD8 u1_mb_type_mode;
+
+ /**
+ * CBP
+ */
+ UWORD8 u1_cbp;
+
+ /**
+ * MB qp delta
+ */
+ UWORD8 u1_mb_qp;
+
+ /**
+ * Element to align structure to 2 byte boundary
+ */
+ UWORD8 u1_pad;
+
+ UWORD8 u1_base_mode_flag;
+
+ UWORD8 u1_residual_prediction_flag;
+
+} isvce_mb_hdr_common_t;
+
+/**
+******************************************************************************
+* @brief macro block info for I4x4 MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+ /**
+ * Sub block modes, 2 modes per byte
+ */
+ UWORD8 au1_sub_blk_modes[8];
+} isvce_mb_hdr_i4x4_t;
+
+/**
+******************************************************************************
+* @brief macro block info for I8x8 MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+ /**
+ * Sub block modes, 2 modes per byte
+ */
+ UWORD8 au1_sub_blk_modes[2];
+} isvce_mb_hdr_i8x8_t;
+
+/**
+******************************************************************************
+* @brief macro block info for I16x16 MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+} isvce_mb_hdr_i16x16_t;
+
+/**
+******************************************************************************
+* @brief macro block info for P16x16 MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+ /**
+ * MV
+ */
+ WORD16 ai2_mvd[2];
+
+ UWORD8 u1_mvp_idx;
+} isvce_mb_hdr_p16x16_t;
+
+/**
+******************************************************************************
+* @brief macro block info for PSKIP MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+} isvce_mb_hdr_pskip_t;
+
+/**
+******************************************************************************
+* @brief macro block info for B16x16 MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+ /**
+ * MV
+ */
+ WORD16 ai2_mvd[NUM_PRED_DIRS][2];
+
+ UWORD8 au1_mvp_idx[NUM_PRED_DIRS];
+} isvce_mb_hdr_b16x16_t;
+
+/**
+******************************************************************************
+* @brief macro block info for BDIRECT MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+} isvce_mb_hdr_bdirect_t;
+
+/**
+******************************************************************************
+* @brief macro block info for PSKIP MB
+******************************************************************************
+*/
+typedef struct
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+} isvce_mb_hdr_bskip_t;
+
+/**
+******************************************************************************
+* @brief macro block info for IBL MB
+******************************************************************************
+*/
+typedef struct isvce_mb_hdr_base_mode_t
+{
+ /**
+ * Common MB header params
+ */
+ isvce_mb_hdr_common_t common;
+
+} isvce_mb_hdr_base_mode_t;
+
+/**
+******************************************************************************
+* @brief Union of mb_hdr structures for size calculation
+* and to access first few common elements
+******************************************************************************
+*/
+
+typedef union isvce_mb_hdr_t
+{
+ isvce_mb_hdr_i4x4_t mb_hdr_i4x4;
+ isvce_mb_hdr_i8x8_t mb_hdr_i8x8;
+ isvce_mb_hdr_i16x16_t mb_hdr_i16x16;
+ isvce_mb_hdr_p16x16_t mb_hdr_p16x16;
+ isvce_mb_hdr_pskip_t mb_hdr_pskip;
+ isvce_mb_hdr_b16x16_t mb_hdr_b16x16;
+ isvce_mb_hdr_bdirect_t mb_hdr_bdirect;
+ isvce_mb_hdr_bskip_t mb_hdr_bskip;
+ isvce_mb_hdr_base_mode_t mb_hdr_base_mode;
+} isvce_mb_hdr_t;
+
+typedef struct isvce_bs_ctxt_t
+{
+ /**
+ * MB's x position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_x;
+
+ /**
+ * MB's y position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_y;
+
+ /**
+ * MB's x position within a Slice in raster scan in MB units
+ */
+ WORD32 i4_mb_slice_x;
+
+ /**
+ * MB's y position within a Slice in raster scan in MB units
+ */
+ WORD32 i4_mb_slice_y;
+
+ /**
+ * Vertical strength, Two bits per edge.
+ * Stored in format. BS[15] | BS[14] | .. |BS[0]
+ */
+ UWORD32 *pu4_pic_vert_bs;
+
+ UWORD32 *pu4_intra_base_vert_bs;
+
+ /**
+ * Boundary strength, Two bits per edge.
+ * Stored in format. BS[15] | BS[14] | .. |BS[0]
+ */
+ UWORD32 *pu4_pic_horz_bs;
+
+ UWORD32 *pu4_intra_base_horz_bs;
+
+ /**
+ * Qp array stored for each mb
+ */
+ UWORD8 *pu1_pic_qp;
+
+} isvce_bs_ctxt_t;
+
+typedef struct isvce_deblk_ctxt_t
+{
+ /**
+ * MB's x position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_x;
+
+ /**
+ * MB's y position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_y;
+
+ /**
+ * structure that contains BS and QP frame level arrays
+ */
+ isvce_bs_ctxt_t s_bs_ctxt;
+
+ /*
+ * Recon Buffers
+ */
+ yuv_buf_props_t s_rec_pic_buf_props;
+
+ /**
+ * Points to the array of slice indices which is used to identify the slice
+ * to which each MB in a frame belongs.
+ */
+ UWORD8 *pu1_slice_idx;
+
+} isvce_deblk_ctxt_t;
+
+/**
+**************************************************************************
+* @brief isvce_me_ctxt_t
+*
+* Structure encapsulating the parameters used in the motion estimation
+* context
+**************************************************************************
+*/
+typedef struct isvce_me_ctxt_t
+{
+ /**
+ * Ref pointer to current MB luma for each ref list
+ */
+ UWORD8 *apu1_ref_buf_luma[MAX_NUM_REFLIST];
+
+ /**
+ * Src pointer to current MB luma
+ */
+ UWORD8 *pu1_src_buf_luma;
+
+ /**
+ * source stride
+ * (strides for luma and chroma are the same)
+ */
+ WORD32 i4_src_strd;
+
+ /**
+ * recon stride
+ * (strides for luma and chroma are the same)
+ */
+ WORD32 ai4_rec_strd[MAX_NUM_REFLIST];
+
+ /**
+ * Offset for half pel x plane from the pic buf
+ */
+ UWORD32 u4_half_x_offset;
+
+ /**
+ * Offset for half pel y plane from half x plane
+ */
+ UWORD32 u4_half_y_offset;
+
+ /**
+ * Offset for half pel xy plane from half y plane
+ */
+ UWORD32 u4_half_xy_offset;
+
+ /**
+ * Search range in the X, Y axis in terms of pixels
+ */
+ WORD32 ai2_srch_boundaries[2];
+
+ /**
+ * Search range in the north direction in terms of pixels
+ */
+ WORD32 i4_srch_range_n;
+
+ /**
+ * Search range in the south direction in terms of pixels
+ */
+ WORD32 i4_srch_range_s;
+
+ /**
+ * Search range in the east direction in terms of pixels
+ */
+ WORD32 i4_srch_range_e;
+
+ /**
+ * Search range in the west direction in terms of pixels
+ */
+ WORD32 i4_srch_range_w;
+
+ /**
+ * left mb motion vector
+ */
+ ime_mv_t s_left_mv;
+
+ /**
+ * top left mb motion vector
+ */
+ ime_mv_t s_top_left_mv;
+
+ /*
+ * ilp MVs for ME candidates *
+ */
+ ilp_me_cands_t *ps_ilp_me_cands;
+
+ /**
+ * Number of valid candidates for the Initial search position
+ */
+ UWORD32 u4_num_candidates[MAX_NUM_REFLIST + 1];
+
+ /**
+ * Motion vector predictors derived from neighboring
+ * blocks for each of the six block partitions
+ */
+ ime_mv_t as_mv_init_search[MAX_NUM_REFLIST + 1][MAX_FPEL_SEARCH_CANDIDATES];
+
+ /**
+ * mv bits
+ */
+ UWORD8 *pu1_mv_bits;
+
+ /**
+ * lambda (lagrange multiplier for cost computation)
+ */
+ UWORD32 u4_lambda_motion;
+
+ /**
+ * enabled fast sad computation
+ */
+ UWORD32 u4_enable_fast_sad;
+
+ /*
+ * Enable SKIP block prediction based on SATQD
+ */
+ UWORD32 u4_enable_stat_sad;
+
+ /*
+ * Minimum distortion to search for
+ * */
+ WORD32 i4_min_sad;
+
+ /*
+ * Signal that minimum sad has been reached in ME
+ * */
+ UWORD32 u4_min_sad_reached;
+
+ /**
+ * Flag to enable/disbale half pel motion estimation
+ */
+ UWORD32 u4_enable_hpel;
+
+ /**
+ * Diamond search Iteration Max Cnt
+ */
+ UWORD32 u4_num_layers;
+
+ /**
+ * encoder me speed
+ */
+ UWORD32 u4_me_speed_preset;
+
+ UWORD32 u4_left_is_intra;
+
+ UWORD32 u4_left_is_skip;
+
+ /* skip_type can be PREDL0, PREDL1 or BIPRED */
+ WORD32 i4_skip_type;
+
+ /* Biasing given for skip prediction */
+ WORD32 i4_skip_bias[2];
+
+ /**
+ * Structure to store the MB partition info
+ * We need 1(L0)+1(L1)+1(bi)
+ */
+ mb_part_ctxt as_mb_part[MAX_NUM_REFLIST + 1];
+ /*
+ * Threshold to compare the sad with
+ */
+ UWORD16 *pu2_sad_thrsh;
+
+ /**
+ * fn ptrs for compute sad routines
+ */
+ ime_compute_sad_ft *pf_ime_compute_sad_16x16[2];
+ ime_compute_sad_ft *pf_ime_compute_sad_16x8;
+ ime_compute_sad4_diamond *pf_ime_compute_sad4_diamond;
+ ime_compute_sad3_diamond *pf_ime_compute_sad3_diamond;
+ ime_compute_sad2_diamond *pf_ime_compute_sad2_diamond;
+ ime_sub_pel_compute_sad_16x16_ft *pf_ime_sub_pel_compute_sad_16x16;
+
+ /*
+ * Function poitners for SATQD
+ */
+ ime_compute_sad_stat *pf_ime_compute_sad_stat_luma_16x16;
+
+ /**
+ * Qp
+ */
+ UWORD8 u1_mb_qp;
+
+ /*
+ * Buffers for holding subpel and bipred temp buffers
+ */
+ UWORD8 *apu1_subpel_buffs[SUBPEL_BUFF_CNT];
+
+ WORD32 u4_subpel_buf_strd;
+
+ /*
+ * Buffers to store the best halfpel plane*
+ */
+ UWORD8 *pu1_hpel_buf;
+
+} isvce_me_ctxt_t;
+
+typedef struct isvce_mb_info_nmb_t
+{
+ UWORD32 u4_mb_type;
+ UWORD32 u4_min_sad;
+ UWORD32 u4_min_sad_reached;
+ WORD32 i4_mb_cost;
+ WORD32 i4_mb_distortion;
+
+ isvce_enc_pu_mv_t as_skip_mv[4];
+
+ isvce_enc_pu_mv_t as_pred_mv[2];
+
+ block_neighbors_t s_ngbr_avbl;
+
+ /*
+ * Buffer to hold best subpel buffer in each MB of NMB
+ */
+ UWORD8 *pu1_best_sub_pel_buf;
+
+ /*
+ * Stride for subpel buffer
+ */
+ UWORD32 u4_bst_spel_buf_strd;
+
+} isvce_mb_info_nmb_t;
+
+typedef struct isvce_process_ctxt_t
+{
+ svc_params_t s_svc_params;
+
+ /* Resolves circular dependency with svc_ilp_mv_ctxt_t */
+ void *ps_svc_ilp_mv_ctxt;
+
+ /* Resolves circular dependency with svc_res_pred_ctxt_t */
+ void *ps_res_pred_ctxt;
+
+ /* Resolves circular dependency with svc_intra_pred_ctxt_t */
+ void *ps_intra_pred_ctxt;
+
+ /* Resolves circular dependency with svc_sub_pic_rc_ctxt_t */
+ void *ps_sub_pic_rc_ctxt;
+
+ yuv_buf_props_t *ps_mb_pred_buf;
+
+ yuv_buf_props_t *ps_mb_res_buf;
+
+ ilp_mv_t *ps_ilp_mv;
+
+ /**
+ * entropy context
+ */
+ isvce_entropy_ctxt_t s_entropy;
+
+ /**
+ * me context
+ */
+ isvce_me_ctxt_t s_me_ctxt;
+
+ /* Resolves circular dependency with isvce_codec_t */
+ void *ps_codec;
+
+ /**
+ * N mb process contest
+ */
+ n_mb_process_ctxt_t s_n_mb_ctxt;
+
+ /*
+ * Src Buffers
+ */
+ yuv_buf_props_t s_src_buf_props;
+
+ /*
+ * Recon Buffers
+ */
+ yuv_buf_props_t s_rec_buf_props;
+
+ /*
+ * Reference Frame Buffers
+ */
+ yuv_buf_props_t as_ref_buf_props[MAX_REF_PIC_CNT];
+
+ /*
+ * Src Buffers
+ */
+ yuv_buf_props_t s_src_pic_buf_props;
+
+ /*
+ * Recon Buffers
+ */
+ yuv_buf_props_t s_rec_pic_buf_props;
+
+ /*
+ * Reference Frame Buffers
+ */
+ yuv_buf_props_t as_ref_pic_buf_props[MAX_REF_PIC_CNT];
+
+ /**
+ * Pointer to ME NMB info
+ */
+ isvce_mb_info_nmb_t *ps_nmb_info;
+
+ isvce_mb_info_nmb_t *ps_cur_mb;
+
+ /**
+ * Offset for half pel x plane from the pic buf
+ */
+ UWORD32 u4_half_x_offset;
+
+ /**
+ * Offset for half pel y plane from half x plane
+ */
+ UWORD32 u4_half_y_offset;
+
+ /**
+ * Offset for half pel xy plane from half y plane
+ */
+ UWORD32 u4_half_xy_offset;
+
+ /**
+ * pred buffer pointer (temp buffer 1)
+ */
+ UWORD8 *pu1_pred_mb;
+
+ /**
+ * pred buffer pointer (prediction buffer for intra 16x16
+ */
+ UWORD8 *pu1_pred_mb_intra_16x16;
+
+ /**
+ * pred buffer pointer (prediction buffer for intra 16x16_plane
+ */
+ UWORD8 *pu1_pred_mb_intra_16x16_plane;
+
+ /**
+ * pred buffer pointer (prediction buffer for intra chroma
+ */
+ UWORD8 *pu1_pred_mb_intra_chroma;
+
+ /**
+ * pred buffer pointer (prediction buffer for intra chroma plane
+ */
+ UWORD8 *pu1_pred_mb_intra_chroma_plane;
+
+ /**
+ * temp. reference buffer ptr for intra 4x4 when rdopt is on
+ */
+ UWORD8 *pu1_ref_mb_intra_4x4;
+
+ /**
+ * prediction buffer stride
+ */
+ WORD32 i4_pred_strd;
+
+ /**
+ * transform buffer pointer (temp buffer 2)
+ */
+ WORD16 *pi2_res_buf;
+
+ /**
+ * temp. transform buffer ptr for intra 4x4 when rdopt is on
+ */
+ WORD16 *pi2_res_buf_intra_4x4;
+
+ /**
+ * transform buffer stride
+ */
+ WORD32 i4_res_strd;
+
+ /**
+ * scratch buffer for inverse transform (temp buffer 3)
+ */
+ void *pv_scratch_buff;
+
+ /**
+ * frame num
+ */
+ WORD32 i4_frame_num;
+
+ /**
+ * start address of frame / sub-frame
+ */
+ WORD32 i4_frame_strt_add;
+
+ /**
+ * IDR pic
+ */
+ UWORD32 u4_is_idr;
+
+ /**
+ * idr_pic_id
+ */
+ UWORD32 u4_idr_pic_id;
+
+ /**
+ * Input width in mbs
+ */
+ WORD32 i4_wd_mbs;
+
+ /**
+ * Input height in mbs
+ */
+ WORD32 i4_ht_mbs;
+
+ /**
+ * slice_type
+ */
+ WORD32 i4_slice_type;
+
+ /**
+ * Current slice idx
+ */
+ WORD32 i4_cur_slice_idx;
+
+ /**
+ * MB's x position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_x;
+
+ /**
+ * MB's y position within a picture in raster scan in MB units
+ */
+ WORD32 i4_mb_y;
+
+ /**
+ * MB's x position within a Slice in raster scan in MB units
+ */
+ WORD32 i4_mb_slice_x;
+
+ /**
+ * MB's y position within a Slice in raster scan in MB units
+ */
+ WORD32 i4_mb_slice_y;
+
+ /**
+ * mb neighbor availability pointer
+ */
+ block_neighbors_t *ps_ngbr_avbl;
+
+ /**
+ * lambda (lagrange multiplier for cost computation)
+ */
+ UWORD32 u4_lambda;
+
+ /**
+ * mb distortion
+ */
+ WORD32 i4_mb_distortion;
+
+ /**
+ * mb cost
+ */
+ WORD32 i4_mb_cost;
+
+ /********************************************************************/
+ /* i4_ngbr_avbl_mb_16 - ngbr avbl of curr mb */
+ /* i4_ngbr_avbl_sb_8 - ngbr avbl of all 8x8 sub blocks of curr mb */
+ /* i4_ngbr_avbl_sb_4 - ngbr avbl of all 4x4 sub blocks of curr mb */
+ /* i4_ngbr_avbl_mb_c - chroma ngbr avbl of curr mb */
+ /********************************************************************/
+ WORD32 i4_ngbr_avbl_16x16_mb;
+ WORD32 ai4_neighbor_avail_8x8_subblks[4];
+ UWORD8 au1_ngbr_avbl_4x4_subblks[16];
+ WORD32 i4_chroma_neighbor_avail_8x8_mb;
+
+ /**
+ * array to store the mode of mb sub blocks
+ */
+ UWORD8 au1_intra_luma_mb_4x4_modes[16];
+
+ /**
+ * array to store the predicted mode of mb sub blks
+ */
+ UWORD8 au1_predicted_intra_luma_mb_4x4_modes[16];
+
+ /**
+ * macro block intra 16x16 mode
+ */
+ UWORD8 u1_l_i16_mode;
+
+ /**
+ * array to store the mode of the macro block intra 8x8 4 modes
+ */
+ UWORD8 au1_intra_luma_mb_8x8_modes[4];
+
+ /**
+ * intra chroma mb mode
+ */
+ UWORD8 u1_c_i8_mode;
+
+ /********************************************************************/
+ /* array to store pixels from the neighborhood for intra prediction */
+ /* i16 - 16 left pels + 1 top left pel + 16 top pels = 33 pels */
+ /* i8 - 8 lpels + 1 tlpels + 8 tpels + 8 tr pels = 25 pels */
+ /* i4 - 4 lpels + 1 tlpels + 4 tpels + 4 tr pels = 13 pels */
+ /* ic - 8 left pels + 1 top left pel + 8 top pels )*2 */
+ /********************************************************************/
+ UWORD8 au1_ngbr_pels[34];
+
+ /**
+ * array for 8x8 intra pels filtering (temp buff 4)
+ */
+ UWORD8 au1_neighbor_pels_i8x8_unfiltered[25];
+
+ /**
+ * Number of sub partitons in the inter pred MB
+ */
+ UWORD32 u4_num_sub_partitions;
+
+ /**
+ * Pointer to hold num PUs each MB in a picture
+ */
+ UWORD32 *pu4_mb_pu_cnt;
+
+ /**
+ * Pointer to the array of structures having motion vectors, size
+ * and position of sub partitions
+ */
+ isvce_mb_info_t *ps_mb_info;
+
+ /**
+ * Pointer to the pu of current co-located MB in list 1
+ */
+ isvce_mb_info_t *ps_col_mb;
+
+ /**
+ * predicted motion vector
+ */
+ isvce_enc_pu_mv_t *ps_skip_mv;
+
+ /**
+ * predicted motion vector
+ */
+ isvce_enc_pu_mv_t *ps_pred_mv;
+
+ /**
+ * top row mb syntax information base
+ * In normal working scenarios, for a given context set,
+ * the mb syntax info pointer is identical across all process threads.
+ * But when the hard bound on slices are enabled, in multi core, frame
+ * is partitioned in to sections equal to set number of cores and each
+ * partition is run independently. In this scenario, a ctxt set will alone
+ * appear to run multiple frames at a time. For this to occur, the common
+ * pointers across the proc ctxt should disappear.
+ *
+ * This is done by allocating MAX_PROCESS_THREADS memory and distributing
+ * across individual ctxts when byte bnd per slice is enabled.
+ */
+ svc_nbr_info_t s_nbr_info_base;
+
+ nbr_info_t s_nbr_info;
+
+ /**
+ * mb neighbor availability pointer
+ */
+ block_neighbors_t s_ngbr_avbl;
+
+ /**
+ * coded block pattern
+ */
+ UWORD32 u4_cbp;
+
+ /**
+ * number of non zero coeffs
+ */
+ UWORD32 au4_nnz[5];
+
+ UWORD8 au1_chroma_nnz[2 * (NUM_4x4_IN_8x8 + 1)];
+
+ /**
+ * number of non zero coeffs for intra 4x4 when rdopt is on
+ */
+ UWORD32 au4_nnz_intra_4x4[4];
+
+ /**
+ * frame qp & mb qp
+ */
+ UWORD8 u1_frame_qp;
+
+ UWORD8 u1_mb_qp;
+
+ /**
+ * quantization parameters for luma & chroma planes
+ */
+ quant_params_t *ps_qp_params[3];
+
+ /**
+ * Pointer frame level mb subblock coeff data
+ */
+ void *pv_pic_mb_coeff_data;
+
+ /**
+ * Pointer to mb subblock coeff data and number of subblocks and scan idx
+ * Incremented each time a coded subblock is processed
+ */
+ void *pv_mb_coeff_data;
+
+ /**
+ * Pointer frame level mb header data
+ */
+ void *pv_pic_mb_header_data;
+
+ /**
+ * Pointer to mb header data and
+ * incremented each time a coded mb is encoded
+ */
+ void *pv_mb_header_data;
+
+ /**
+ * Signal that pic_init is called first time
+ */
+ WORD32 i4_first_pic_init;
+
+ /**
+ * Current MV Bank's buffer ID
+ */
+ WORD32 i4_cur_mv_bank_buf_id;
+
+ /**
+ * Void pointer to job context
+ */
+ void *pv_proc_jobq, *pv_entropy_jobq;
+
+ /**
+ * Number of MBs to be processed in the current Job
+ */
+ WORD32 i4_mb_cnt;
+
+ /**
+ * ID for the current context - Used for debugging
+ */
+ WORD32 i4_id;
+
+ /**
+ * Pointer to current picture buffer structure
+ */
+ svc_au_buf_t *ps_cur_pic;
+
+ /**
+ * Pointer to current picture's mv buffer structure
+ */
+ svc_au_data_t *ps_cur_mv_buf;
+
+ /**
+ * Flag to indicate if ps_proc was initialized at least once in a frame.
+ * This is needed to handle cases where a core starts to handle format
+ * conversion jobs directly
+ */
+ WORD32 i4_init_done;
+
+ /**
+ * Process status: one byte per MB
+ */
+ UWORD8 *pu1_proc_map;
+
+ /**
+ * Deblk status: one byte per MB
+ */
+ UWORD8 *pu1_deblk_map;
+
+ /**
+ * Process status: one byte per MB
+ */
+ UWORD8 *pu1_me_map;
+
+ /*
+ * Intra refresh mask.
+ * Indicates if an Mb is coded in intra mode within the current AIR interval
+ * NOTE Refreshes after each AIR period
+ * NOTE The map is shared between process
+ */
+ UWORD8 *pu1_is_intra_coded;
+
+ /**
+ * Disable deblock level (0: Enable completely, 3: Disable completely
+ */
+ UWORD32 u4_disable_deblock_level;
+
+ /**
+ * Pointer to the structure that contains deblock context
+ */
+ isvce_deblk_ctxt_t s_deblk_ctxt;
+
+ /**
+ * Points to the array of slice indices which is used to identify the
+ * independent slice to which each MB in a frame belongs.
+ */
+ UWORD8 *pu1_slice_idx;
+
+ /**
+ * Pointer to base of svc_nalu_ext structure array
+ */
+ svc_nalu_ext_t *ps_svc_nalu_ext_base;
+
+ /**
+ * Pointer to base of subset sequence parameter set structure array
+ */
+ subset_sps_t *ps_subset_sps_base;
+
+ /**
+ * Pointer to base of slice header structure array
+ */
+ slice_header_t *ps_slice_hdr_base;
+
+ /**
+ * Pointer to base of SVC slice header structure array
+ */
+ svc_slice_header_t *ps_svc_slice_hdr_base;
+
+ /**
+ * Number of mb's to process in one loop
+ */
+ WORD32 i4_nmb_ntrpy;
+
+ /**
+ * Number of mb's to process in one loop
+ */
+ UWORD32 u4_nmb_me;
+
+ /**
+ * Structure for current input buffer
+ */
+ isvce_inp_buf_t s_inp_buf;
+
+ /**
+ * api call cnt
+ */
+ WORD32 i4_encode_api_call_cnt;
+
+ /**
+ * Current Picture count - used for synchronization
+ */
+ WORD32 i4_pic_cnt;
+
+ /**
+ * Intermediate buffer for interpred leaf level functions
+ */
+ WORD32 ai16_pred1[HP_BUFF_WD * HP_BUFF_HT];
+
+ /**
+ * Reference picture for the current picture
+ * TODO: Only 2 reference assumed currently
+ */
+ svc_au_buf_t *aps_ref_pic[MAX_REF_PIC_CNT];
+
+ /**
+ * Reference MV buff for the current picture
+ */
+ svc_au_data_t *aps_mv_buf[MAX_REF_PIC_CNT];
+
+ /**
+ * frame info used by RC
+ */
+ frame_info_t s_frame_info;
+
+ /*
+ * NOTE NOT PERSISTANT INSIDE FUNCTIONS
+ * Min sad for current MB
+ * will be populated initially
+ * Once a sad less than eq to u4_min_sad is reached, the value will be copied
+ * to the cariable
+ */
+ UWORD32 u4_min_sad;
+
+ /*
+ * indicates weather we have rached minimum sa or not
+ */
+ UWORD32 u4_min_sad_reached;
+
+ /**
+ * Current error code
+ */
+ WORD32 i4_error_code;
+
+ /*
+ * Enables or disables computation of recon
+ */
+ UWORD32 u4_compute_recon;
+
+ /*
+ * Temporary buffers to be used for subpel computation
+ */
+ UWORD8 *apu1_subpel_buffs[SUBPEL_BUFF_CNT];
+
+ /*
+ * Buffer holding best sub pel values
+ */
+ UWORD8 *pu1_best_subpel_buf;
+
+ /*
+ * Stride for buffer holding best sub pel
+ */
+ UWORD32 u4_bst_spel_buf_strd;
+
+ /*
+ * SVC spatial layer ID
+ */
+ UWORD8 u1_spatial_layer_id;
+} isvce_process_ctxt_t;
+
+typedef UWORD8 FT_CORE_CODING(isvce_process_ctxt_t *ps_proc);
+
+typedef WORD32 FT_FIND_SKIP_PARAMS(isvce_process_ctxt_t *, WORD32);
+
+typedef void FT_ME_ALGORITHM(isvce_process_ctxt_t *);
+
+typedef struct enc_loop_fxns_t
+{
+ /**
+ * luma core coding function pointer
+ */
+ FT_CORE_CODING *apf_luma_energy_compaction[MAX_MBTYPES];
+
+ /**
+ * chroma core coding function pointer
+ */
+ FT_CORE_CODING *apf_chroma_energy_compaction[2];
+
+ /**
+ * forward transform for intra blk of mb type 16x16
+ */
+ FT_LUMA_16X16_RESI_TRANS_DCTRANS_QUANT
+ *pf_resi_trans_dctrans_quant_16x16;
+
+ /**
+ * inverse transform for intra blk of mb type 16x16
+ */
+ FT_LUMA_16X16_IDCTRANS_IQUANT_ITRANS_RECON
+ *pf_idctrans_iquant_itrans_recon_16x16;
+
+ /**
+ * forward transform for 4x4 blk luma
+ */
+ FT_RESI_TRANS_QUANT *apf_resi_trans_quant_4x4[NUM_RESI_TRANS_QUANT_VARIANTS];
+
+ /**
+ * forward transform for 4x4 blk luma
+ */
+ FT_RESI_TRANS_QUANT
+ *apf_resi_trans_quant_chroma_4x4[NUM_RESI_TRANS_QUANT_VARIANTS];
+
+ /*
+ * hadamard transform and quant for a 4x4 block
+ */
+ FT_HADAMARD_QUANT *pf_hadamard_quant_4x4;
+
+ /*
+ * hadamard transform and quant for a 4x4 block
+ */
+ FT_HADAMARD_QUANT *pf_hadamard_quant_2x2_uv;
+
+ /**
+ * inverse transform for 4x4 blk
+ */
+ FT_IQ_IT_RECON *apf_iquant_itrans_recon_4x4[NUM_IQ_IT_RECON_VARIANTS];
+
+ /**
+ * inverse transform for chroma 4x4 blk
+ */
+ FT_IQ_IT_RECON *apf_iquant_itrans_recon_chroma_4x4[NUM_IQ_IT_RECON_VARIANTS];
+
+ /**
+ * inverse transform for 4x4 blk with only single dc coeff
+ */
+ FT_IQ_IT_RECON *apf_iquant_itrans_recon_4x4_dc[NUM_IQ_IT_RECON_VARIANTS];
+
+ /**
+ * inverse transform for chroma 4x4 blk with only single dc coeff
+ */
+ FT_IQ_IT_RECON
+ *apf_iquant_itrans_recon_chroma_4x4_dc[NUM_IQ_IT_RECON_VARIANTS];
+
+ /*
+ * Inverse hadamard transform and iquant for a 4x4 block
+ */
+ FT_IHADAMARD_SCALING *pf_ihadamard_scaling_4x4;
+
+ /*
+ * Inverse hadamard transform and iquant for a 4x4 block
+ */
+ FT_IHADAMARD_SCALING *pf_ihadamard_scaling_2x2_uv;
+
+ /**
+ * forward transform for 8x8 blk
+ */
+ FT_RESI_TRANS_QUANT *apf_resi_trans_quant_8x8[NUM_RESI_TRANS_QUANT_VARIANTS];
+
+ /**
+ * inverse transform for 8x8 blk
+ */
+ FT_IQ_IT_RECON *apf_iquant_itrans_recon_8x8[NUM_IQ_IT_RECON_VARIANTS];
+
+ FT_IQ_IT_RECON *pf_zcbf_iquant_itrans_recon_4x4;
+
+ FT_IQ_IT_RECON *pf_chroma_zcbf_iquant_itrans_recon_4x4;
+
+} enc_loop_fxns_t;
+
+typedef struct inter_pred_fxns_t
+{
+ FT_INTER_PRED_LUMA *pf_inter_pred_luma_copy;
+
+ FT_INTER_PRED_LUMA *pf_inter_pred_luma_horz;
+
+ FT_INTER_PRED_LUMA *pf_inter_pred_luma_vert;
+
+ FT_INTER_PRED_LUMA_BILINEAR *pf_inter_pred_luma_bilinear;
+
+ FT_INTER_PRED_CHROMA *pf_inter_pred_chroma;
+} inter_pred_fxns_t;
+
+typedef struct mem_fxns_t
+{
+ FT_MEMCPY *pf_mem_cpy;
+
+ FT_MEMSET *pf_mem_set;
+
+ FT_MEMCPY *pf_mem_cpy_mul8;
+
+ FT_MEMSET *pf_mem_set_mul8;
+
+ FT_COPY_2D *pf_copy_2d;
+
+ FT_MEMSET_2D *pf_memset_2d;
+
+ FT_16BIT_INTERLEAVED_COPY *pf_16bit_interleaved_copy;
+
+ FT_16BIT_INTERLEAVED_MEMSET *pf_16bit_interleaved_memset;
+
+ FT_NONZERO_CHECKER *pf_nonzero_checker;
+
+} mem_fxns_t;
+
+typedef struct isa_dependent_fxns_t
+{
+ enc_loop_fxns_t s_enc_loop_fxns;
+
+ inter_pred_fxns_t s_inter_pred_fxns;
+
+ mem_fxns_t s_mem_fxns;
+} isa_dependent_fxns_t;
+
+/**
+ * Reference set containing pointers to MV buf and pic buf
+ */
+typedef struct
+{
+ /** Picture count */
+ WORD32 i4_pic_cnt;
+
+ /** POC */
+ WORD32 i4_poc;
+
+ /** picture buffer */
+ svc_au_buf_t *ps_pic_buf;
+
+ /** mv buffer */
+ svc_au_data_t *ps_svc_au_data;
+
+} isvce_ref_set_t;
+
+typedef struct isvce_codec_t
+{
+ /**
+ * downscaler context
+ */
+ downscaler_ctxt_t s_scaler;
+
+ svc_ilp_data_t s_svc_ilp_data;
+
+ nalu_descriptors_t as_nalu_descriptors[MAX_NUM_SPATIAL_LAYERS];
+
+ isa_dependent_fxns_t s_isa_dependent_fxns;
+
+#if ENABLE_MODE_STAT_VISUALISER
+ /* Resolves circular dependency with mode_stat_visualiser_t */
+ void *ps_mode_stat_visualiser;
+#endif
+
+ /** enable constrained intra prediction */
+ UWORD32 au4_constrained_intra_pred[MAX_NUM_SPATIAL_LAYERS];
+
+ /**
+ * Id of current pic (input order)
+ */
+ WORD32 i4_poc;
+
+ /**
+ * Number of encode frame API calls made
+ * This variable must only be used for context selection [Read only]
+ */
+ WORD32 i4_encode_api_call_cnt;
+
+ /**
+ * Number of pictures encoded
+ */
+ WORD32 i4_pic_cnt;
+
+ /**
+ * Number of threads created
+ */
+ WORD32 i4_proc_thread_cnt;
+
+ /**
+ * Mutex used to keep the control calls thread-safe
+ */
+ void *pv_ctl_mutex;
+
+ /**
+ * Current active config parameters
+ */
+ isvce_cfg_params_t s_cfg;
+
+ /**
+ * Array containing the config parameter sets
+ */
+ isvce_cfg_params_t as_cfg[MAX_ACTIVE_CONFIG_PARAMS];
+
+ /**
+ * Color format used by encoder internally
+ */
+ IV_COLOR_FORMAT_T e_codec_color_format;
+
+ /**
+ * recon stride
+ * (strides for luma and chroma are the same)
+ */
+ WORD32 i4_rec_strd;
+
+ /**
+ * Flag to enable/disable deblocking of a frame
+ */
+ WORD32 u4_disable_deblock_level;
+
+ /**
+ * Number of continuous frames where deblocking was disabled
+ */
+ WORD32 u4_disable_deblock_level_cnt;
+
+ /**
+ * frame type
+ */
+ PIC_TYPE_T pic_type;
+
+ /**
+ * frame qp
+ */
+ UWORD32 au4_frame_qp[MAX_NUM_SPATIAL_LAYERS];
+
+ /**
+ * Enable inital QP calculation based on BPP and GPP
+ */
+ UWORD8 u1_enable_init_qp;
+
+ /**
+ * frame num
+ */
+ WORD32 i4_frame_num;
+
+ /**
+ * slice_type
+ */
+ WORD32 i4_slice_type;
+
+ /*
+ * Force current frame to specific type
+ */
+ IV_PICTURE_CODING_TYPE_T force_curr_frame_type;
+
+ /**
+ * IDR pic
+ */
+ UWORD32 u4_is_idr;
+
+ /**
+ * idr_pic_id
+ */
+ WORD32 i4_idr_pic_id;
+
+ /**
+ * Flush mode
+ */
+ WORD32 i4_flush_mode;
+
+ /**
+ * Encode header mode
+ */
+ WORD32 i4_header_mode;
+
+ /**
+ * Flag to indicate if header has already
+ * been generated when i4_api_call_cnt 0
+ */
+ UWORD32 u4_header_generated;
+
+ /**
+ * Encode generate header
+ */
+ WORD32 i4_gen_header;
+
+ /**
+ * To signal successful completion of init
+ */
+ WORD32 i4_init_done;
+
+ /**
+ * To signal that at least one picture was decoded
+ */
+ WORD32 i4_first_pic_done;
+
+ /**
+ * Reset flag - Codec is reset if this flag is set
+ */
+ WORD32 i4_reset_flag;
+
+ /**
+ * Current error code
+ */
+ WORD32 i4_error_code;
+
+ /**
+ * threshold residue
+ */
+ WORD32 u4_thres_resi;
+
+ /**
+ * disable intra inter gating
+ */
+ UWORD32 u4_inter_gate;
+
+ /**
+ * Holds mem records passed during init.
+ * This will be used to return the mem records during retrieve call
+ */
+ iv_mem_rec_t *ps_mem_rec_backup;
+
+ /**
+ * Flag to determine if the entropy thread is active
+ */
+ volatile UWORD32 au4_entropy_thread_active[MAX_CTXT_SETS];
+
+ /**
+ * Mutex used to keep the entropy calls thread-safe
+ */
+ void *pv_entropy_mutex;
+
+ /**
+ * Job queue buffer base
+ */
+ void *pv_proc_jobq_buf, *pv_entropy_jobq_buf;
+
+ /**
+ * Job Queue mem tab size
+ */
+ WORD32 i4_proc_jobq_buf_size, i4_entropy_jobq_buf_size;
+
+ /**
+ * Memory for svc_au_data buffer manager
+ */
+ void *pv_svc_au_data_store_mgr_base;
+
+ /**
+ * svc_au_data buffer manager
+ */
+ void *pv_svc_au_data_store_mgr;
+
+ /**
+ * Pointer to svc_au_data structure array
+ */
+ svc_au_data_t *ps_svc_au_data;
+
+ /**
+ * Base address for svc_au_data
+ */
+ svc_au_data_t *ps_svc_au_data_base;
+
+ /**
+ * svc_au_data size
+ */
+ WORD32 i4_svc_au_data_size;
+
+ /**
+ * Memory for Picture buffer manager for reference pictures
+ */
+ void *pv_ref_buf_mgr_base;
+
+ /**
+ * Picture buffer manager for reference pictures
+ */
+ void *pv_ref_buf_mgr;
+
+ /**
+ * Number of reference buffers added to the buffer manager
+ */
+ WORD32 i4_ref_buf_cnt;
+
+ /**
+ * Pointer to Pic Buf structure array
+ */
+ svc_au_buf_t *ps_pic_buf;
+
+ /**
+ * Base address for Picture buffer
+ */
+ svc_au_buf_t *ps_pic_buf_base;
+
+ /**
+ * Total pic buffer size allocated
+ */
+ WORD32 i4_total_pic_buf_size;
+
+ /**
+ * Memory for Buffer manager for output buffers
+ */
+ void *pv_out_buf_mgr_base;
+
+ /**
+ * Buffer manager for output buffers
+ */
+ void *pv_out_buf_mgr;
+
+ /**
+ * Current output buffer's buffer ID
+ */
+ WORD32 i4_out_buf_id;
+
+ /**
+ * Number of output buffers added to the buffer manager
+ */
+ WORD32 i4_out_buf_cnt;
+
+ /**
+ * Memory for Picture buffer manager for input buffers
+ */
+ void *pv_inp_buf_mgr_base;
+
+ /**
+ * Picture buffer manager for input buffers
+ */
+ void *pv_inp_buf_mgr;
+
+ /**
+ * Current input buffer's buffer ID
+ */
+ WORD32 i4_inp_buf_id;
+
+ /**
+ * Number of input buffers added to the buffer manager
+ */
+ WORD32 i4_inp_buf_cnt;
+
+ /**
+ * Pointer to dpb manager structure
+ */
+ void *pv_dpb_mgr;
+
+ /**
+ * Pointer to base of Sequence parameter set structure array
+ */
+ sps_t *ps_sps_base;
+
+ /**
+ * Pointer to base of Picture parameter set structure array
+ */
+ pps_t *ps_pps_base;
+
+ /**
+ * Pointer to base of svc_nalu_ext structure array
+ */
+ svc_nalu_ext_t *ps_svc_nalu_ext_base;
+
+ /**
+ * Pointer to base of subset sequence parameter set structure array
+ */
+ subset_sps_t *ps_subset_sps_base;
+
+ /**
+ * Pointer to base of slice header structure array
+ */
+ slice_header_t *ps_slice_hdr_base;
+
+ /**
+ * Pointer to base of SVC slice header structure array
+ */
+ svc_slice_header_t *ps_svc_slice_hdr_base;
+
+ /**
+ * packed residue coeff data size for 1 row of mbs
+ */
+ UWORD32 u4_size_coeff_data;
+
+ /**
+ * packed header data size for 1 row of mbs
+ */
+ UWORD32 u4_size_header_data;
+
+ /**
+ * Processing context - One for each processing thread
+ * Create two sets, each set used for alternate frames
+ */
+ isvce_process_ctxt_t as_process[MAX_PROCESS_CTXT];
+
+ /**
+ * Thread handle for each of the processing threads
+ */
+ void *apv_proc_thread_handle[MAX_PROCESS_THREADS];
+
+ /**
+ * Thread created flag for each of the processing threads
+ */
+ WORD32 ai4_process_thread_created[MAX_PROCESS_THREADS];
+
+ /**
+ * Void pointer to process job context
+ */
+ void *pv_proc_jobq, *pv_entropy_jobq;
+
+ /**
+ * Number of MBs processed together for better instruction cache handling
+ */
+ WORD32 i4_proc_nmb;
+
+ /**
+ * Previous POC lsb
+ */
+ WORD32 i4_prev_poc_lsb;
+
+ /**
+ * Previous POC msb
+ */
+ WORD32 i4_prev_poc_msb;
+
+ /**
+ * Max POC lsb that has arrived till now
+ */
+ WORD32 i4_max_prev_poc_lsb;
+
+ /**
+ * Context for format conversion
+ */
+ fmt_conv_t s_fmt_conv;
+
+ /**
+ * Absolute pic order count
+ */
+ WORD32 i4_abs_pic_order_cnt;
+
+ /**
+ * Pic order count of lsb
+ */
+ WORD32 i4_pic_order_cnt_lsb;
+
+ /**
+ * Array giving current picture being processed in each context set
+ */
+ WORD32 ai4_pic_cnt[MAX_CTXT_SETS];
+
+ /*
+ * Min sad to search for
+ */
+ UWORD32 u4_min_sad;
+
+ /**
+ * Reference picture set
+ */
+ isvce_ref_set_t as_ref_set[MAX_DPB_SIZE + MAX_CTXT_SETS];
+
+ /*
+ * Air pic cnt
+ * Contains the number of pictures that have been encoded with air
+ * This value is moudulo air refresh period
+ */
+ WORD32 i4_air_pic_cnt;
+
+ /*
+ * Intra refresh map
+ * Stores the frames at which intra refresh should occur for a MB
+ */
+ UWORD16 *pu2_intr_rfrsh_map;
+
+ /*
+ * Indicates if the current frame is used as a reference frame
+ */
+ UWORD32 u4_is_curr_frm_ref;
+
+ /*
+ * Indicates if there can be non reference frames in the stream
+ */
+ WORD32 i4_non_ref_frames_in_stream;
+
+ /*
+ * Memory for color space conversion for luma plane
+ */
+ UWORD8 *pu1_y_csc_buf_base;
+
+ /*
+ * Memory for color space conversion foe chroma plane
+ */
+ UWORD8 *pu1_uv_csc_buf_base;
+
+ /**
+ * Function pointers for intra pred leaf level functions luma
+ */
+ pf_intra_pred apf_intra_pred_16_l[MAX_I16x16];
+ pf_intra_pred apf_intra_pred_8_l[MAX_I8x8];
+ pf_intra_pred apf_intra_pred_4_l[MAX_I4x4];
+
+ /**
+ * Function pointers for intra pred leaf level functions chroma
+ */
+ pf_intra_pred apf_intra_pred_c[MAX_CH_I8x8];
+
+ /**
+ * deblock vertical luma edge with blocking strength 4
+ */
+ ih264_deblk_edge_bs4_ft *pf_deblk_luma_vert_bs4;
+
+ /**
+ * deblock vertical chroma edge with blocking strength 4
+ */
+ ih264_deblk_chroma_edge_bs4_ft *pf_deblk_chroma_vert_bs4;
+
+ /**
+ * deblock vertical luma edge with blocking strength less than 4
+ */
+ ih264_deblk_edge_bslt4_ft *pf_deblk_luma_vert_bslt4;
+
+ /**
+ * deblock vertical chroma edge with blocking strength less than 4
+ */
+ ih264_deblk_chroma_edge_bslt4_ft *pf_deblk_chroma_vert_bslt4;
+
+ /**
+ * deblock horizontal luma edge with blocking strength 4
+ */
+ ih264_deblk_edge_bs4_ft *pf_deblk_luma_horz_bs4;
+
+ /**
+ * deblock horizontal chroma edge with blocking strength 4
+ */
+ ih264_deblk_chroma_edge_bs4_ft *pf_deblk_chroma_horz_bs4;
+
+ /**
+ * deblock horizontal luma edge with blocking strength less than 4
+ */
+ ih264_deblk_edge_bslt4_ft *pf_deblk_luma_horz_bslt4;
+
+ /**
+ * deblock horizontal chroma edge with blocking strength less than 4
+ */
+ ih264_deblk_chroma_edge_bslt4_ft *pf_deblk_chroma_horz_bslt4;
+
+ /**
+ * functions for padding
+ */
+ pf_pad pf_pad_top;
+ pf_pad pf_pad_bottom;
+ pf_pad pf_pad_left_luma;
+ pf_pad pf_pad_left_chroma;
+ pf_pad pf_pad_right_luma;
+ pf_pad pf_pad_right_chroma;
+
+ /**
+ * fn ptrs for compute sad routines
+ */
+ ime_compute_sad_ft *apf_compute_sad_16x16[2];
+ ime_compute_sad_ft *pf_compute_sad_16x8;
+
+ /**
+ * Function pointer for computing ME
+ * 1 for PSLICE and 1 for BSLICE
+ */
+ FT_ME_ALGORITHM *apf_compute_me[2];
+
+ /**
+ * Function pointers for computing SKIP parameters
+ */
+ FT_FIND_SKIP_PARAMS *apf_find_skip_params_me[2];
+
+ /**
+ * intra mode eval -encoder level function
+ */
+ pf_evaluate_intra_modes pf_ih264e_evaluate_intra16x16_modes;
+ pf_evaluate_intra_modes pf_ih264e_evaluate_intra_chroma_modes;
+ pf_evaluate_intra_4x4_modes pf_ih264e_evaluate_intra_4x4_modes;
+
+ /* Half pel generation function - encoder level
+ *
+ */
+ pf_sixtapfilter_horz pf_ih264e_sixtapfilter_horz;
+ pf_sixtap_filter_2dvh_vert pf_ih264e_sixtap_filter_2dvh_vert;
+
+ /**
+ * color space conversion from YUV 420P to YUV 420Sp
+ */
+ pf_fmt_conv_420p_to_420sp pf_ih264e_conv_420p_to_420sp;
+
+ /**
+ * color space conversion from YUV 420P to YUV 420Sp
+ */
+ pf_fmt_conv_422ile_to_420sp pf_ih264e_fmt_conv_422i_to_420sp;
+
+ /**
+ * write mb layer for a given slice I, P, B
+ */
+ IH264E_ERROR_T (*pf_write_mb_syntax_layer[2][3])(isvce_entropy_ctxt_t *ps_ent_ctxt);
+
+ /**
+ * Output buffer
+ */
+ isvce_out_buf_t as_out_buf[MAX_CTXT_SETS];
+
+ /**
+ * recon buffer
+ */
+ isvce_rec_buf_t as_rec_buf[MAX_CTXT_SETS];
+
+ /**
+ * rate control context
+ */
+ isvce_rate_control_ctxt_t s_rate_control;
+
+ /**
+ * input buffer queue
+ */
+ isvce_inp_buf_t as_inp_list[SVC_MAX_NUM_INP_FRAMES];
+
+ /**
+ * Flag to indicate if any IDR requests are pending
+ */
+ WORD32 i4_pending_idr_flag;
+
+ /**
+ *Flag to indicate if we have recived the last input frame
+ */
+ WORD32 i4_last_inp_buff_received;
+
+ /*
+ * Max num reference frames to be signaled in SPS
+ */
+ WORD32 i4_max_num_reference_frames;
+
+ /**
+ * backup sei params for comparison
+ */
+ sei_params_t s_sei;
+} isvce_codec_t;
+
+#endif
diff --git a/encoder/svc/isvce_sub_pic_rc.c b/encoder/svc/isvce_sub_pic_rc.c
new file mode 100644
index 0000000..92a66b7
--- /dev/null
+++ b/encoder/svc/isvce_sub_pic_rc.c
@@ -0,0 +1,906 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_sub_pic_rc.c
+*
+* @brief
+* Contains functions used in sub-pic RC
+*
+*******************************************************************************
+*/
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_cavlc_tables.h"
+#include "ih264_platform_macros.h"
+#include "ithread.h"
+#include "isvc_defs.h"
+#include "isvc_structs.h"
+#include "isvce_structs.h"
+#include "isvce_defs.h"
+#include "isvce_sub_pic_rc.h"
+#include "isvce_sub_pic_rc_private_defs.h"
+
+/* Dependencies of 'irc_picture_type.h' */
+#include "irc_mem_req_and_acq.h"
+
+/* Dependencies of 'irc_rate_control_api_structs' */
+#include "irc_picture_type.h"
+#include "irc_rd_model.h"
+#include "irc_vbr_storage_vbv.h"
+#include "irc_est_sad.h"
+#include "irc_bit_allocation.h"
+#include "irc_mb_model_based.h"
+#include "irc_cbr_buffer_control.h"
+#include "irc_vbr_str_prms.h"
+#include "irc_common.h"
+
+#include "irc_rate_control_api_structs.h"
+#include "irc_rate_control_api.h"
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing subPicRC ctxt
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_sub_pic_rc_ctxt_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ WORD32 i;
+
+ UWORD32 u4_size = MAX_PROCESS_CTXT * sizeof(svc_sub_pic_rc_ctxt_t);
+
+ u4_size += sizeof(sub_pic_rc_state_t);
+ u4_size += ithread_get_mutex_struct_size();
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ WORD32 i4_layer_wd =
+ (WORD32) ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) +
+ 0.99;
+ WORD32 i4_layer_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_mbs = (i4_layer_wd / MB_SIZE) * (i4_layer_ht / MB_SIZE);
+
+ /* ps_mb_bits_info */
+ u4_size += i4_layer_mbs * sizeof(mb_bits_info_t);
+
+#if DUMP_SUB_PIC_RC_DATA
+ /* ps_mb_bits_actual */
+ u4_size += i4_layer_mbs * sizeof(mb_bits_info_t);
+#endif
+ }
+
+ return u4_size;
+}
+
+void isvce_sub_pic_rc_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ sub_pic_rc_state_t *ps_sub_pic_rc_state;
+
+ WORD32 i, j;
+
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_sub_pic_rc_ctxt_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_codec->as_process[i].ps_sub_pic_rc_ctxt =
+ (svc_sub_pic_rc_ctxt_t *) pu1_buf;
+
+ pu1_buf += sizeof(ps_sub_pic_rc_ctxt[0]);
+ i8_alloc_mem_size -= sizeof(ps_sub_pic_rc_ctxt[0]);
+
+ if(0 == i)
+ {
+ ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants.pv_state = ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) pu1_buf;
+ pu1_buf += sizeof(ps_sub_pic_rc_state[0]);
+ i8_alloc_mem_size -= sizeof(ps_sub_pic_rc_state[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ ASSERT(NULL != ps_codec->s_rate_control.apps_rate_control_api);
+ ASSERT(NULL != ps_codec->as_process->s_me_ctxt.pu1_mv_bits);
+
+ ps_sub_pic_rc_state->s_svc_params = ps_codec->s_cfg.s_svc_params;
+ ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map = gau1_uev_codeword_to_bits_map;
+ ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map =
+ ps_codec->as_process->s_me_ctxt.pu1_mv_bits;
+ ps_sub_pic_rc_state->e_rc_mode = ps_codec->s_cfg.e_rc_mode;
+
+ ps_sub_pic_rc_state->pv_bits_accumulator_mutex = (void *) pu1_buf;
+ pu1_buf += ithread_get_mutex_struct_size();
+ i8_alloc_mem_size -= ithread_get_mutex_struct_size();
+ ithread_mutex_init(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ sub_pic_rc_layer_state_t *ps_layer_state =
+ &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[j];
+
+ WORD32 i4_layer_wd =
+ (WORD32) ((DOUBLE) u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_mbs = (i4_layer_wd / MB_SIZE) * (i4_layer_ht / MB_SIZE);
+
+ ps_layer_state->i4_wd = i4_layer_wd;
+ ps_layer_state->i4_ht = i4_layer_ht;
+ ps_layer_state->i4_num_mbs = i4_layer_mbs;
+ ps_layer_state->pv_layer_rc_ctxt =
+ ps_codec->s_rate_control.apps_rate_control_api[j];
+ ps_layer_state->ps_mb_bits_info = (mb_bits_info_t *) pu1_buf;
+ pu1_buf += i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_info[0]);
+ i8_alloc_mem_size -= i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_info[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+#if DUMP_SUB_PIC_RC_DATA
+ ps_layer_state->ps_mb_bits_actual = (mb_bits_info_t *) pu1_buf;
+ pu1_buf += i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_actual[0]);
+ i8_alloc_mem_size -= i4_layer_mbs * sizeof(ps_layer_state->ps_mb_bits_actual[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ {
+ UWORD8 au1_file_path[MAX_SUB_PIC_RC_DUMP_FILE_PATH_LENGTH + 1];
+
+ sprintf((WORD8 *) au1_file_path, "%ssubPicRC%1d.txt", SUB_PIC_RC_DUMP_FILE_PATH,
+ j);
+
+ ps_layer_state->ps_data_dump_file = fopen(au1_file_path, "w");
+
+ ASSERT(NULL != ps_layer_state->ps_data_dump_file);
+ }
+#endif
+ }
+ }
+ else
+ {
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt_src =
+ ps_codec->as_process[0].ps_sub_pic_rc_ctxt;
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt_dst =
+ ps_codec->as_process[i].ps_sub_pic_rc_ctxt;
+ sub_pic_rc_state_t *ps_proc0_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_ctxt_src->s_sub_pic_rc_constants.pv_state;
+
+ ps_sub_pic_rc_ctxt_dst->s_sub_pic_rc_constants.pv_state = ps_proc0_state;
+ }
+ }
+}
+
+static FORCEINLINE void isvce_sub_pic_rc_qp_params_init(sub_pic_rc_qp_params_t *ps_qp_params,
+ UWORD8 u1_min_qp, UWORD8 u1_max_qp)
+{
+ ps_qp_params->u1_min_qp = u1_min_qp;
+ ps_qp_params->u1_max_qp = u1_max_qp;
+ ps_qp_params->pu4_qp_to_qscale_map = gau4_qp_to_qscale_map;
+ ps_qp_params->pu1_qscale_to_qp_map = gau1_qscale_to_qp_map;
+}
+
+void isvce_sub_pic_rc_ctxt_layer_init(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+ sub_pic_rc_layer_state_t *ps_layer_state;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+
+ memset(&ps_layer_state->s_cumulative_mb_bits, 0, sizeof(ps_layer_state->s_cumulative_mb_bits));
+ ps_layer_state->u4_num_mbs_sampled = 0;
+
+ /* Frames with frameNum=0 are usually IDR's. RC model will be reset for IDR's.
+ */
+ /* Hence, using VBVBufSize as a proxy for estimated bits */
+ if(0 == ps_sub_pic_rc_variables->s_layer_variables.i4_frame_num)
+ {
+ ps_layer_state->u4_allocated_bits =
+ irc_get_vbv_buf_size(ps_layer_state->pv_layer_rc_ctxt) / 10.;
+ }
+ else
+ {
+ ps_layer_state->u4_allocated_bits =
+ irc_get_prev_frm_est_bits(ps_layer_state->pv_layer_rc_ctxt);
+ }
+
+ isvce_sub_pic_rc_qp_params_init(&ps_layer_state->s_qp_params,
+ ps_sub_pic_rc_variables->s_layer_variables.u1_min_qp,
+ ps_sub_pic_rc_variables->s_layer_variables.u1_max_qp);
+}
+
+static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_res_pred_flag_bits(
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
+{
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UNUSED(ps_sub_pic_rc_state);
+
+ return (ENABLE_RESIDUAL_PREDICTION && !ps_mb_info->u1_is_intra);
+}
+
+static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_cbp_bits(
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
+{
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD32 u4_cbp = ps_sub_pic_rc_variables->s_mb_variables.u4_cbp;
+ bool b_use_inter_cbp_map = !ps_mb_info->u1_is_intra || ps_mb_info->u1_base_mode_flag;
+
+ return ps_sub_pic_rc_state
+ ->pu1_uev_codeword_to_bits_map[gu1_cbp_map_tables[u4_cbp][b_use_inter_cbp_map]];
+}
+
+static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_mb_type_bits(
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
+{
+ UWORD32 u4_mb_type;
+
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD32 u4_cbp = ps_sub_pic_rc_variables->s_mb_variables.u4_cbp;
+ UWORD32 au4_cbps[NUM_SP_COMPONENTS] = {u4_cbp & 15, u4_cbp >> 4};
+
+ switch(ps_mb_info->u2_mb_type)
+ {
+ case I16x16:
+ {
+ u4_mb_type = ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode + 1 +
+ (au4_cbps[UV] << 2) + (au4_cbps[Y] == 15) * 12;
+
+ break;
+ }
+ case I4x4:
+ {
+ u4_mb_type = 5 * (ps_sub_pic_rc_variables->s_layer_variables.i4_slice_type != ISLICE);
+
+ break;
+ }
+ case P16x16:
+ {
+ u4_mb_type = 0;
+
+ break;
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+
+ return ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map[u4_mb_type];
+}
+
+static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_mb_pred_bits(
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, sub_pic_rc_state_t *ps_sub_pic_rc_state)
+{
+ WORD32 i;
+
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD32 u4_bits = 0;
+
+ switch(ps_mb_info->u2_mb_type)
+ {
+ case I16x16:
+ {
+ /* intra_chroma_pred_mode */
+ u4_bits +=
+ ps_sub_pic_rc_state
+ ->pu1_uev_codeword_to_bits_map[ps_mb_info->s_intra_pu.u1_chroma_intra_mode];
+
+ break;
+ }
+ case I4x4:
+ {
+ intra4x4_mode_data_t *ps_i4x4_mode_data = ps_mb_info->s_intra_pu.as_i4x4_mode_data;
+
+ for(i = 0; i < MAX_TU_IN_MB; i++)
+ {
+ /* prev_intra4x4_pred_mode_flag */
+ u4_bits += 1;
+
+ /* rem_intra4x4_pred_mode */
+ u4_bits +=
+ 3 * (ps_i4x4_mode_data[i].u1_mode != ps_i4x4_mode_data[i].u1_predicted_mode);
+ }
+
+ /* intra_chroma_pred_mode */
+ u4_bits +=
+ ps_sub_pic_rc_state
+ ->pu1_uev_codeword_to_bits_map[ps_mb_info->s_intra_pu.u1_chroma_intra_mode];
+
+ break;
+ }
+ case P16x16:
+ {
+ mv_t s_mvd;
+
+ /* motion_prediction_flag_l0 */
+ u4_bits += USE_ILP_MV_AS_MVP;
+
+ /* ref_idx_l0 */
+ if(2 == ps_sub_pic_rc_variables->s_layer_variables.i4_max_num_reference_frames)
+ {
+ u4_bits += 1;
+ }
+ else if(2 < ps_sub_pic_rc_variables->s_layer_variables.i4_max_num_reference_frames)
+ {
+ u4_bits += ps_sub_pic_rc_state->pu1_uev_codeword_to_bits_map
+ [ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx];
+ }
+
+ /* mvd_l0 */
+ s_mvd.i2_mvx = ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
+ ps_sub_pic_rc_variables->s_mb_variables
+ .aps_mvps[ps_mb_info->as_pu->au1_mvp_idx[L0]]
+ ->s_mv.i2_mvx;
+ s_mvd.i2_mvy = ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
+ ps_sub_pic_rc_variables->s_mb_variables
+ .aps_mvps[ps_mb_info->as_pu->au1_mvp_idx[L0]]
+ ->s_mv.i2_mvy;
+ u4_bits += ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map[s_mvd.i2_mvx];
+ u4_bits += ps_sub_pic_rc_state->pu1_sev_codeword_to_bits_map[s_mvd.i2_mvy];
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return u4_bits;
+}
+
+static void ihevce_svc_sub_pic_rc_set_header_bits(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+ sub_pic_rc_layer_state_t *ps_layer_state;
+ mb_bits_info_t *ps_mb_bits_info;
+
+ UWORD32 u4_mb_idx;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+ u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
+ ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
+ (ps_layer_state->i4_wd / MB_SIZE);
+ ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
+
+ /* Hypotheses used for header bits estimation - */
+ /* 1. mb_skip_run, base_mode_flag, mb_type, mb_pred, residual_prediction_flag,
+ * and cbp */
+ /* are considered as contibuting to header bits. */
+ /* 2. mb_skip_run = 1 bit */
+ /* 3. base_mode_flag = 1 bit */
+ /* 4. mb_type = LUT mapping mbType to corresponding ue(v) */
+ /* 5. mb_pred.I4x4 = 1 bit for 16 'prev_intra4x4_pred_mode_flag'; */
+ /* 3 bits for each explicitly signaled
+ * 'rem_intra4x4_pred_mode' */
+ /* 6. mb_pred.Inter = 1 bit for 'motion_prediction_flag_l0' and
+ * 'motion_prediction_flag_l1', when necessary; */
+ /* mvbits LUT for 'mvd_l0' and 'mvd_l1' */
+ /* 7. mb_pred.intra_chroma_pred_mode = LUT mapping intra_chroma_pred_mode to
+ * corresponding ue(v) */
+ /* 8. residual_prediction_flag = 1 bit */
+ /* 9. coded_block_pattern = LUT mapping mbType to corresponding me(v) */
+
+ /* mb_skip_run is assumed to be either 0 or 1 */
+ ps_mb_bits_info->i8_header_bits += 1;
+
+ /* 'base_mode_flag' */
+ if((ENABLE_ILP_MV || ENABLE_IBL_MODE) && u1_spatial_layer_id)
+ {
+ ps_mb_bits_info->i8_header_bits += 1;
+
+ if(ps_mb_info->u1_base_mode_flag)
+ {
+ /* 'residual_prediction_flag' */
+ ps_mb_bits_info->i8_header_bits += isvce_sub_pic_rc_get_res_pred_flag_bits(
+ ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
+
+ /* 'coded_block_pattern' */
+ ps_mb_bits_info->i8_header_bits +=
+ isvce_sub_pic_rc_get_cbp_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
+
+ return;
+ }
+ }
+
+ /* 'mb_type' */
+ ps_mb_bits_info->i8_header_bits +=
+ isvce_sub_pic_rc_get_mb_type_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
+
+ if(PSKIP == ps_mb_info->u2_mb_type)
+ {
+ return;
+ }
+
+ /* 'mb_pred' */
+ ps_mb_bits_info->i8_header_bits +=
+ isvce_sub_pic_rc_get_mb_pred_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
+
+ /* 'residual_prediction_flag' */
+ ps_mb_bits_info->i8_header_bits +=
+ isvce_sub_pic_rc_get_res_pred_flag_bits(ps_sub_pic_rc_variables, ps_sub_pic_rc_state);
+}
+
+static FORCEINLINE UWORD32 isvce_sub_pic_rc_get_tu_residual_bits(
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables, WORD32 i4_coeff_start_idx,
+ UWORD8 u1_num_coded_coeffs, UWORD8 u1_num_coeffs, bool b_is_chroma)
+{
+ WORD32 i;
+ UWORD32 u4_num_bits;
+
+ UWORD32 u4_bits = 0;
+ WORD16 *pi2_coeff =
+ ((WORD16 *) ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[b_is_chroma ? UV : Y]
+ .pv_data) +
+ i4_coeff_start_idx;
+
+ if(0 == u1_num_coded_coeffs)
+ {
+ return 0;
+ }
+
+ GETRANGE(u4_num_bits, u1_num_coded_coeffs);
+ u4_bits += u4_num_bits;
+
+ for(i = 0; i < u1_num_coeffs; i++)
+ {
+ if(pi2_coeff[i])
+ {
+ GETRANGE(u4_num_bits, pi2_coeff[i]);
+ u4_bits += u4_num_bits;
+ }
+ }
+ return u4_bits;
+}
+
+static void ihevce_svc_sub_pic_rc_set_texture_bits(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+ sub_pic_rc_layer_state_t *ps_layer_state;
+ mb_bits_info_t *ps_mb_bits_info;
+
+ UWORD32 u4_mb_idx;
+ WORD32 i, j;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
+ UWORD32 au4_cbps[NUM_SP_COMPONENTS] = {ps_sub_pic_rc_variables->s_mb_variables.u4_cbp & 15,
+ ps_sub_pic_rc_variables->s_mb_variables.u4_cbp >> 4};
+
+ if(0 == ps_sub_pic_rc_variables->s_mb_variables.u4_cbp)
+ {
+ return;
+ }
+
+ if(MIN_TU_SIZE != ps_mb_info->u1_tx_size)
+ {
+ return;
+ }
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+ u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
+ ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
+ (ps_layer_state->i4_wd / MB_SIZE);
+ ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
+
+ /* Hypotheses used for texture bits estimation - */
+ /* 1. Only level information is considered. */
+ /* 2. nnz is used as a proxy for coeff_token. */
+ /* 3. Both of the above are assumed coded via i(n). */
+ if(au4_cbps[Y])
+ {
+ /* Y - DC */
+ if(I16x16 == ps_mb_info->u2_mb_type)
+ {
+ ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
+ ps_sub_pic_rc_variables, 0, ps_sub_pic_rc_variables->s_mb_variables.apu1_nnzs[Y][0],
+ NUM_COEFFS_IN_MIN_TU, false);
+ }
+
+ for(i = 0; i < MIN_TU_IN_MB; i++)
+ {
+ if(au4_cbps[Y] & (1 << i))
+ {
+ UWORD32 u4_csbp = (ps_mb_info->u4_csbp >> (4 * i)) & 15;
+
+ for(j = 0; j < NUM_4x4_IN_8x8; j++)
+ {
+ if(u4_csbp & (1 << j))
+ {
+ /* 1 added to account for DC TU */
+ UWORD8 u1_blk_id = 1 + gau4_tu_zscan_id_to_rasterscan_id_map[i][j];
+ UWORD8 u1_nnz =
+ ps_sub_pic_rc_variables->s_mb_variables.apu1_nnzs[Y][u1_blk_id];
+
+ if(u1_nnz && (I16x16 == ps_mb_info->u2_mb_type))
+ {
+ u1_nnz -= !!(((WORD16 *) (ps_sub_pic_rc_variables->s_mb_variables
+ .as_quant_coeffs[Y]
+ .pv_data))[u1_blk_id - 1]);
+
+ ps_mb_bits_info->i8_texture_bits +=
+ isvce_sub_pic_rc_get_tu_residual_bits(
+ ps_sub_pic_rc_variables,
+ u1_blk_id * ps_sub_pic_rc_variables->s_mb_variables
+ .as_quant_coeffs[Y]
+ .i4_data_stride +
+ (I16x16 == ps_mb_info->u2_mb_type),
+ u1_nnz,
+ NUM_COEFFS_IN_MIN_TU - (I16x16 == ps_mb_info->u2_mb_type),
+ false);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(au4_cbps[UV])
+ {
+ for(i = ((WORD32) U); i <= ((WORD32) V); i++)
+ {
+ bool b_is_v = (i == ((WORD32) V));
+
+ ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
+ ps_sub_pic_rc_variables, b_is_v * NUM_4x4_IN_8x8,
+ ps_sub_pic_rc_variables->s_mb_variables
+ .apu1_nnzs[UV][0 + b_is_v * (1 + NUM_4x4_IN_8x8)],
+ NUM_4x4_IN_8x8, true);
+
+ for(j = 0; j < NUM_4x4_IN_8x8; j++)
+ {
+ UWORD8 u1_nnz = ps_sub_pic_rc_variables->s_mb_variables
+ .apu1_nnzs[UV][j + b_is_v * (1 + NUM_4x4_IN_8x8) + 1];
+
+ if(u1_nnz)
+ {
+ u1_nnz -=
+ !!(((WORD16 *) (ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[UV]
+ .pv_data))[j + b_is_v * NUM_4x4_IN_8x8]);
+
+ ps_mb_bits_info->i8_texture_bits += isvce_sub_pic_rc_get_tu_residual_bits(
+ ps_sub_pic_rc_variables,
+ (j + b_is_v * NUM_4x4_IN_8x8 + 1) *
+ ps_sub_pic_rc_variables->s_mb_variables.as_quant_coeffs[UV]
+ .i4_data_stride +
+ 1,
+ u1_nnz, NUM_COEFFS_IN_MIN_TU - 1, true);
+ }
+ }
+ }
+ }
+}
+
+void isvce_sub_pic_rc_ctxt_update(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+ sub_pic_rc_layer_state_t *ps_layer_state;
+ mb_bits_info_t *ps_mb_bits_info;
+
+ UWORD32 u4_mb_idx;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+ isvce_mb_info_t *ps_mb_info = ps_sub_pic_rc_variables->s_mb_variables.ps_mb_info;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
+ bool b_is_skip_mb = (PSKIP == ps_mb_info->u2_mb_type) || (BSKIP == ps_mb_info->u2_mb_type);
+
+ if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
+ {
+ return;
+ }
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+ u4_mb_idx = ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_abscissa +
+ ps_sub_pic_rc_variables->s_mb_variables.s_mb_pos.i4_ordinate *
+ (ps_layer_state->i4_wd / MB_SIZE);
+ ps_mb_bits_info = &ps_layer_state->ps_mb_bits_info[u4_mb_idx];
+
+ memset(ps_mb_bits_info, 0, sizeof(ps_mb_bits_info[0]));
+
+ if(!b_is_skip_mb)
+ {
+ ihevce_svc_sub_pic_rc_set_header_bits(ps_sub_pic_rc_ctxt);
+
+ ihevce_svc_sub_pic_rc_set_texture_bits(ps_sub_pic_rc_ctxt);
+ }
+
+ ithread_mutex_lock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+ ps_layer_state->s_cumulative_mb_bits.i8_header_bits += ps_mb_bits_info->i8_header_bits;
+ ps_layer_state->s_cumulative_mb_bits.i8_texture_bits += ps_mb_bits_info->i8_texture_bits;
+ ps_layer_state->u4_num_mbs_sampled++;
+
+ ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+}
+
+UWORD8 isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt, UWORD8 u1_cur_mb_qp)
+{
+ sub_pic_rc_layer_state_t *ps_layer_state;
+
+ DOUBLE d_bit_consumption_ratio;
+ UWORD32 u4_frame_qscale;
+ UWORD8 u1_mb_qp;
+ UWORD32 u4_num_mbs_sampled;
+ WORD32 i4_cumulative_mb_bits;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->s_layer_variables.u1_spatial_layer_id;
+ UWORD8 u1_frame_qp = ps_sub_pic_rc_variables->s_layer_variables.u1_frame_qp;
+
+ if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
+ {
+ return u1_cur_mb_qp;
+ }
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+
+ ithread_mutex_lock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+ u4_num_mbs_sampled = ps_layer_state->u4_num_mbs_sampled;
+
+ if(u4_num_mbs_sampled < (MIN_SAMPLED_MB_RATIO * ps_layer_state->i4_num_mbs))
+ {
+ ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+ return u1_cur_mb_qp;
+ }
+
+ i4_cumulative_mb_bits = (WORD32) (ps_layer_state->s_cumulative_mb_bits.i8_header_bits +
+ ps_layer_state->s_cumulative_mb_bits.i8_texture_bits);
+
+ d_bit_consumption_ratio =
+ (((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs)) /
+ (((DOUBLE) ps_layer_state->u4_allocated_bits) * ((DOUBLE) u4_num_mbs_sampled));
+
+ ithread_mutex_unlock(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+ if((d_bit_consumption_ratio > BIT_RATIO_FOR_OVERCONSUMPTION) ||
+ (d_bit_consumption_ratio < BIT_RATIO_FOR_UNDERCONSUMPTION))
+ {
+ u4_frame_qscale = ps_layer_state->s_qp_params.pu4_qp_to_qscale_map[u1_frame_qp] *
+ d_bit_consumption_ratio +
+ 0.5;
+ u4_frame_qscale = CLIP3(ps_layer_state->s_qp_params.pu4_qp_to_qscale_map[0], MAX_SVC_QSCALE,
+ u4_frame_qscale);
+ u1_mb_qp = ps_layer_state->s_qp_params.pu1_qscale_to_qp_map[u4_frame_qscale];
+ u1_mb_qp = CLIP3(ps_layer_state->s_qp_params.u1_min_qp,
+ ps_layer_state->s_qp_params.u1_max_qp, u1_mb_qp);
+ u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_cur_mb_qp) - MAX_MB_QP_DECREMENT),
+ MIN(MAX_H264_QP, ((WORD16) u1_cur_mb_qp) + MAX_MB_QP_INCREMENT),
+ ((WORD16) u1_mb_qp));
+ /* This ensures mb_qp_delta stays within the interval [-26, 25] */
+ u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_frame_qp) - MAX_FRAME_QP_DECREMENT),
+ MIN(MAX_H264_QP, ((WORD16) u1_frame_qp) + MAX_FRAME_QP_INCREMENT),
+ ((WORD16) u1_mb_qp));
+ }
+ else
+ {
+ u1_mb_qp = u1_cur_mb_qp;
+ }
+
+ {
+ vbv_buf_status_e e_vbv_buf_status;
+ picture_type_e e_rc_pic_type;
+
+ DOUBLE d_est_frame_bits;
+
+ WORD32 i4_num_bits_to_prevent_vbv_underflow;
+
+ d_est_frame_bits = ((DOUBLE) i4_cumulative_mb_bits) * ((DOUBLE) ps_layer_state->i4_num_mbs);
+ d_est_frame_bits /= u4_num_mbs_sampled;
+
+ switch(ps_sub_pic_rc_variables->s_layer_variables.i4_slice_type)
+ {
+ case ISLICE:
+ {
+ e_rc_pic_type = I_PIC;
+ break;
+ }
+ case PSLICE:
+ {
+ e_rc_pic_type = P_PIC;
+ break;
+ }
+ default:
+ {
+ e_rc_pic_type = B_PIC;
+ break;
+ }
+ }
+
+ e_vbv_buf_status =
+ irc_get_buffer_status(ps_layer_state->pv_layer_rc_ctxt, (WORD32) d_est_frame_bits,
+ e_rc_pic_type, &i4_num_bits_to_prevent_vbv_underflow);
+
+ /* This models dec VBV buffer */
+ if(VBV_OVERFLOW == e_vbv_buf_status)
+ {
+ u1_mb_qp--;
+ }
+ else if(VBV_UNDERFLOW == e_vbv_buf_status)
+ {
+ u1_mb_qp++;
+ }
+
+ /* This ensures mb_qp_delta stays within the interval [-26, 25] */
+ u1_mb_qp = CLIP3(ps_layer_state->s_qp_params.u1_min_qp,
+ ps_layer_state->s_qp_params.u1_max_qp, u1_mb_qp);
+ u1_mb_qp = CLIP3(MAX(MIN_H264_QP, ((WORD16) u1_frame_qp) - MAX_FRAME_QP_DECREMENT),
+ MIN(MAX_H264_QP, ((WORD16) u1_frame_qp) + MAX_FRAME_QP_INCREMENT),
+ ((WORD16) u1_mb_qp));
+ }
+
+ return u1_mb_qp;
+}
+
+void isvce_sub_pic_rc_get_entropy_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+#if DUMP_SUB_PIC_RC_DATA
+ sub_pic_rc_layer_state_t *ps_layer_state;
+
+ UWORD32 u4_mb_idx;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+
+ UWORD8 u1_spatial_layer_id = ps_sub_pic_rc_variables->u1_spatial_layer_id;
+
+ if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
+ {
+ return;
+ }
+
+ ps_layer_state = &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[u1_spatial_layer_id];
+ u4_mb_idx = ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa +
+ ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate * (ps_layer_state->i4_wd / MB_SIZE);
+
+ ps_layer_state->ps_mb_bits_actual[u4_mb_idx] = ps_sub_pic_rc_variables->s_mb_bits;
+#else
+ UNUSED(ps_sub_pic_rc_ctxt);
+#endif
+}
+
+void isvce_sub_pic_rc_dump_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+#if DUMP_SUB_PIC_RC_DATA
+ WORD32 i, j, k;
+
+ svc_sub_pic_rc_constants_t *ps_sub_pic_rc_constants =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants;
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_constants->pv_state;
+
+ if(!ENABLE_IN_FRAME_RC || (IVE_RC_NONE == ps_sub_pic_rc_state->e_rc_mode))
+ {
+ return;
+ }
+
+ for(i = 0; i < ps_sub_pic_rc_state->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ sub_pic_rc_layer_state_t *ps_layer_state =
+ &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[i];
+
+ for(j = 0; j < (ps_layer_state->i4_ht / MB_SIZE); j++)
+ {
+ for(k = 0; k < (ps_layer_state->i4_wd / MB_SIZE); k++)
+ {
+ mb_bits_info_t *ps_mb_bits_est =
+ &ps_layer_state->ps_mb_bits_info[k + j * (ps_layer_state->i4_wd / MB_SIZE)];
+ mb_bits_info_t *ps_mb_bits_actual =
+ &ps_layer_state->ps_mb_bits_actual[k + j * (ps_layer_state->i4_wd / MB_SIZE)];
+
+ fprintf(ps_layer_state->ps_data_dump_file, "%ld,%ld,%ld,%ld,\n",
+ ps_mb_bits_est->i8_header_bits, ps_mb_bits_est->i8_texture_bits,
+ ps_mb_bits_actual->i8_header_bits, ps_mb_bits_actual->i8_texture_bits);
+ }
+ }
+ }
+#else
+ UNUSED(ps_sub_pic_rc_ctxt);
+#endif
+}
+
+void isvce_sub_pic_rc_ctxt_delete(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt)
+{
+ sub_pic_rc_state_t *ps_sub_pic_rc_state =
+ (sub_pic_rc_state_t *) ps_sub_pic_rc_ctxt->s_sub_pic_rc_constants.pv_state;
+
+ ithread_mutex_destroy(ps_sub_pic_rc_state->pv_bits_accumulator_mutex);
+
+#if DUMP_SUB_PIC_RC_DATA
+ {
+ WORD32 i;
+
+ UWORD8 u1_num_spatial_layers = ps_sub_pic_rc_state->s_svc_params.u1_num_spatial_layers;
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ sub_pic_rc_layer_state_t *ps_layer_state =
+ &ps_sub_pic_rc_state->as_sub_pic_rc_layer_states[i];
+
+ if(ps_layer_state->ps_data_dump_file)
+ {
+ fclose(ps_layer_state->ps_data_dump_file);
+ }
+
+ ps_layer_state->ps_data_dump_file = NULL;
+ }
+ }
+#endif
+}
diff --git a/encoder/svc/isvce_sub_pic_rc.h b/encoder/svc/isvce_sub_pic_rc.h
new file mode 100644
index 0000000..f51ded9
--- /dev/null
+++ b/encoder/svc/isvce_sub_pic_rc.h
@@ -0,0 +1,131 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_sub_pic_rc.h
+*
+* @brief
+* Contains typdefs and externs used for invoking sub-pic RC
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_SUB_PIC_RC_H_
+#define _ISVCE_SUB_PIC_RC_H_
+
+#include "ih264_typedefs.h"
+#include "isvce_pred_structs.h"
+#include "isvce_defs.h"
+
+/* Structs */
+typedef struct svc_sub_pic_rc_constants_t
+{
+ void *pv_state;
+
+} svc_sub_pic_rc_constants_t;
+
+typedef struct mb_bits_info_t
+{
+ WORD64 i8_header_bits;
+
+ WORD64 i8_texture_bits;
+} mb_bits_info_t;
+
+typedef struct svc_sub_pic_rc_entropy_variables_t
+{
+ coordinates_t s_mb_pos;
+
+ mb_bits_info_t s_mb_bits;
+
+ UWORD8 u1_spatial_layer_id;
+} svc_sub_pic_rc_entropy_variables_t;
+
+typedef struct svc_sub_pic_rc_layer_variables_t
+{
+ WORD32 i4_max_num_reference_frames;
+
+ WORD32 i4_slice_type;
+
+ WORD32 i4_frame_num;
+
+ UWORD8 u1_frame_qp;
+
+ UWORD8 u1_min_qp;
+
+ UWORD8 u1_max_qp;
+
+ UWORD8 u1_spatial_layer_id;
+} svc_sub_pic_rc_layer_variables_t;
+
+typedef struct svc_sub_pic_rc_mb_variables_t
+{
+ buffer_container_t as_quant_coeffs[NUM_SP_COMPONENTS];
+
+ isvce_enc_pu_mv_t *aps_mvps[MAX_MVP_IDX + 1];
+
+ coordinates_t s_mb_pos;
+
+ isvce_mb_info_t *ps_mb_info;
+
+ UWORD8 *apu1_nnzs[NUM_SP_COMPONENTS];
+
+ UWORD32 u4_cbp;
+} svc_sub_pic_rc_mb_variables_t;
+
+typedef struct svc_sub_pic_rc_variables_t
+{
+ svc_sub_pic_rc_layer_variables_t s_layer_variables;
+
+ svc_sub_pic_rc_mb_variables_t s_mb_variables;
+
+} svc_sub_pic_rc_variables_t;
+
+typedef struct svc_sub_pic_rc_ctxt_t
+{
+ svc_sub_pic_rc_constants_t s_sub_pic_rc_constants;
+
+ svc_sub_pic_rc_variables_t s_sub_pic_rc_variables;
+
+ svc_sub_pic_rc_entropy_variables_t s_sub_pic_rc_entropy_variables;
+} svc_sub_pic_rc_ctxt_t;
+
+/* Function declarations */
+extern UWORD32 isvce_get_sub_pic_rc_ctxt_size(UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht);
+
+extern void isvce_sub_pic_rc_ctxt_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_sub_pic_rc_ctxt_layer_init(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt);
+
+extern void isvce_sub_pic_rc_ctxt_delete(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt);
+
+extern void isvce_sub_pic_rc_ctxt_update(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt);
+
+extern UWORD8 isvce_sub_pic_rc_get_mb_qp(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt,
+ UWORD8 u1_cur_mb_qp);
+
+extern void isvce_sub_pic_rc_get_entropy_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt);
+
+extern void isvce_sub_pic_rc_dump_data(svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt);
+
+#endif
diff --git a/encoder/svc/isvce_sub_pic_rc_private_defs.h b/encoder/svc/isvce_sub_pic_rc_private_defs.h
new file mode 100644
index 0000000..14f77ba
--- /dev/null
+++ b/encoder/svc/isvce_sub_pic_rc_private_defs.h
@@ -0,0 +1,256 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_sub_pic_rc_private_defs.h
+*
+* @brief
+* Contains typdefs and externs used exclusively by sub-pic RC functions
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_SUB_PIC_RC_PRIVATE_DEFS_H_
+#define _ISVCE_SUB_PIC_RC_PRIVATE_DEFS_H_
+
+#include <stdio.h>
+
+#include "ih264_typedefs.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ithread.h"
+#include "isvce_structs.h"
+#include "isvce_sub_pic_rc.h"
+
+/* Macros */
+#define DUMP_SUB_PIC_RC_DATA 0
+
+#if DUMP_SUB_PIC_RC_DATA
+#ifdef WINDOWS
+#define SUB_PIC_RC_DUMP_FILE_PATH "D:\\H264\\"
+#else
+#define SUB_PIC_RC_DUMP_FILE_PATH "/mnt/d/H264/"
+#endif
+
+#define MAX_SUB_PIC_RC_DUMP_FILE_PATH_LENGTH 100
+#endif
+
+#define MAX_UEV_CODEWORD (1 << 6)
+
+#define SVC_QSCALE_Q_FACTOR 3
+
+/* (2 ^ ((MAX_H264_QP - 4) / 6)) * (2 ^ (SVC_QSCALE_Q_FACTOR)) */
+#define MAX_SVC_QSCALE 1824
+
+#define BIT_RATIO_FOR_OVERCONSUMPTION 1.2
+
+#define BIT_RATIO_FOR_UNDERCONSUMPTION 0.7
+
+#define MIN_SAMPLED_MB_RATIO 0.05
+
+#define MAX_MB_QP_DECREMENT 1
+
+#define MAX_MB_QP_INCREMENT 1
+
+#define MAX_FRAME_QP_DECREMENT 12
+
+#define MAX_FRAME_QP_INCREMENT 13
+
+#define ENABLE_IN_FRAME_RC 1
+
+/* Globals */
+static const UWORD8 gau1_uev_codeword_to_bits_map[MAX_UEV_CODEWORD + 1] = {
+ 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 13, 13,
+};
+
+static const UWORD32 gau4_tu_zscan_id_to_rasterscan_id_map[MIN_TU_IN_MB][NUM_4x4_IN_8x8] = {
+ {
+ 0,
+ 1,
+ 4,
+ 5,
+ },
+ {
+ 2,
+ 3,
+ 6,
+ 7,
+ },
+ {
+ 8,
+ 9,
+ 12,
+ 13,
+ },
+ {
+ 10,
+ 11,
+ 14,
+ 15,
+ },
+};
+
+static const UWORD32 gau4_qp_to_qscale_map[MAX_H264_QP + 1] = {
+ 5, 5, 6, 7, 8, 8, 10, 11, 12, 14, 16, 17, 20, 22, 25, 28, 32, 35,
+ 40, 45, 50, 57, 64, 71, 80, 90, 101, 114, 128, 143, 161, 181, 203, 228, 256, 287,
+ 322, 362, 406, 456, 512, 574, 645, 724, 812, 912, 1024, 1149, 1290, 1448, 1625, 1824,
+};
+
+static const UWORD8 gau1_qscale_to_qp_map[MAX_SVC_QSCALE + 1] = {
+ 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 11, 11, 11, 12, 12, 13, 13,
+ 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19,
+ 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51,
+};
+
+/* Structs */
+typedef struct sub_pic_rc_qp_params_t
+{
+ const UWORD32 *pu4_qp_to_qscale_map;
+
+ const UWORD8 *pu1_qscale_to_qp_map;
+
+ UWORD8 u1_min_qp;
+
+ UWORD8 u1_max_qp;
+
+} sub_pic_rc_qp_params_t;
+
+typedef struct sub_pic_rc_layer_state_t
+{
+ void *pv_layer_rc_ctxt;
+
+ sub_pic_rc_qp_params_t s_qp_params;
+
+ /* Array of size NumMB's */
+ mb_bits_info_t *ps_mb_bits_info;
+
+ mb_bits_info_t s_cumulative_mb_bits;
+
+ UWORD32 u4_allocated_bits;
+
+ UWORD32 u4_num_mbs_sampled;
+
+ WORD32 i4_wd;
+
+ WORD32 i4_ht;
+
+ WORD32 i4_num_mbs;
+
+#if DUMP_SUB_PIC_RC_DATA
+ FILE *ps_data_dump_file;
+
+ mb_bits_info_t *ps_mb_bits_actual;
+#endif
+} sub_pic_rc_layer_state_t;
+
+typedef struct sub_pic_rc_state_t
+{
+ sub_pic_rc_layer_state_t as_sub_pic_rc_layer_states[MAX_NUM_SPATIAL_LAYERS];
+
+ svc_params_t s_svc_params;
+
+ void *pv_bits_accumulator_mutex;
+
+ const UWORD8 *pu1_sev_codeword_to_bits_map;
+
+ const UWORD8 *pu1_uev_codeword_to_bits_map;
+
+ IVE_RC_MODE_T e_rc_mode;
+} sub_pic_rc_state_t;
+
+#endif
diff --git a/encoder/svc/isvce_utils.c b/encoder/svc/isvce_utils.c
new file mode 100644
index 0000000..904e4d3
--- /dev/null
+++ b/encoder/svc/isvce_utils.c
@@ -0,0 +1,4547 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* ih264e_svc_utils.c
+*
+* @brief
+* Contains utility functions used for SVC encoding
+*
+* @author
+* ittiam
+*
+* @par List of Functions:
+* - ih264e_svc_ref_list_refresh()
+* - ih264e_svc_inp_params_validate()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+#include <math.h>
+#include <limits.h>
+
+#include "ih264_typedefs.h"
+
+/* Dependencies of ih264_buf_mgr.h */
+/* Dependencies of ih264_list.h */
+#include "ih264_error.h"
+
+#include "ih264_buf_mgr.h"
+#include "ih264_list.h"
+#include "ih264_trans_data.h"
+#include "ih264_size_defs.h"
+
+/* Dependencies of ih264_common_tables.h */
+#include "ih264_defs.h"
+#include "ih264_structs.h"
+
+#include "ih264_common_tables.h"
+
+/* Dependencies of ih264e_bitstream.h */
+#include "ih264e_error.h"
+
+/* Dependencies of ih264e_cabac_structs.h */
+#include "ih264_cabac_tables.h"
+
+/* Dependencies of ime_structs.h */
+#include "ime_defs.h"
+#include "ime_distortion_metrics.h"
+
+/* Dependencies of ih264e_structs.h */
+#include "iv2.h"
+#include "ive2.h"
+#include "ih264_defs.h"
+#include "ih264_deblk_edge_filters.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_structs.h"
+#include "ih264_trans_quant_itrans_iquant.h"
+#include "ih264e_bitstream.h"
+#include "ih264e_cabac_structs.h"
+#include "ime_statistics.h"
+#include "ime_structs.h"
+/* Dependencies of 'irc_picture_type.h' */
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "irc_mem_req_and_acq.h"
+/* Dependencies of 'irc_rate_control_api_structs' */
+#include "irc_picture_type.h"
+#include "irc_rd_model.h"
+#include "irc_vbr_storage_vbv.h"
+#include "irc_est_sad.h"
+#include "irc_bit_allocation.h"
+#include "irc_mb_model_based.h"
+#include "irc_cbr_buffer_control.h"
+#include "irc_vbr_str_prms.h"
+#include "irc_common.h"
+#include "irc_rate_control_api_structs.h"
+#include "irc_rate_control_api.h"
+#include "irc_svc_rate_control_api.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_defs.h"
+#include "ih264e_structs.h"
+/* Dependencies of 'ih264e_utils.h' */
+#include "ih264e_rc_mem_interface.h"
+#include "ih264e_time_stamp.h"
+#include "ih264e_utils.h"
+#include "ime.h"
+#include "isvc_macros.h"
+#include "isvce_cabac.h"
+#include "isvce_core_coding.h"
+#include "isvce_defs.h"
+#include "isvce_error.h"
+#include "isvce_me.h"
+#include "isvce_utils.h"
+#include "isvce_downscaler.h"
+#include "isvce_encode_header.h"
+#include "isvce_rate_control.h"
+#include "isvce_sub_pic_rc.h"
+
+static const UWORD32 gu4_downscaler_blk_size = 96;
+
+static FORCEINLINE UWORD32 isvce_get_downscaler_blk_dims(UWORD32 u4_frame_dim, UWORD32 u4_blk_pos,
+ UWORD32 u4_default_blk_size)
+{
+ return ((u4_frame_dim - u4_blk_pos * u4_default_blk_size) < u4_default_blk_size)
+ ? (u4_frame_dim - u4_blk_pos * u4_default_blk_size)
+ : u4_default_blk_size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Reference and MV bank Buffer Manager for SVC
+*
+* @par Description:
+* Here we will
+* 1) Find the correct ref pics for the current frame
+* 2) Free the ref pics that are not going to be used anymore
+*
+* 1) Finding correct ref pic
+* All pics needed for future are arranged in a picture list called
+* ps_codec->as_ref_set. Each picture in this will have a pic buffer and
+* MV buffer that is marked appropriately as BUF_MGR_REF, BUF_MGR_IO or
+* BUF_MGR_CODEC. pic_cnt, poc, and temporal_id will also be present.
+* The strategy is to pick the closest references that belongs to the
+* same temporal_id or lesser. The closeness is measured via the
+* smallest absolute difference between ref and cur pocs.
+*
+* Note that i4_pic_cnt == -1 is used to filter uninitialised ref pics.
+* Now since we only have max two ref pics, we will always find max 2
+* ref pics.
+*
+* 2) Self explanatory
+*
+* @param[in] ps_codec
+* Pointer to codeec context
+*
+* @param[in] pps_ref_pics
+* Array of pointers to refPicBufs
+*
+* @param[in] pps_mv_bufs
+* Array of pointers to refMVBufs
+*
+* @param[in] e_pic_type
+* Picture type
+*
+* @returns Nothing
+*
+*******************************************************************************
+*/
+static WORD32 isvce_ref_list_refresh(isvce_codec_t *ps_codec, svc_au_buf_t **pps_ref_pics,
+ svc_au_data_t **pps_mv_bufs, WORD32 *pi4_ref_set_id,
+ PIC_TYPE_T e_pic_type)
+{
+ typedef struct
+ {
+ WORD32 i4_buf_id;
+
+ WORD32 i4_abs_poc_diff;
+
+ WORD8 i1_temporal_id;
+ } ref_pic_props_t;
+
+ ref_pic_props_t s_ref_pic_props = {0, 0, -1};
+
+ WORD32 i, buf_status;
+
+ WORD32 i4_cur_pic_poc = ps_codec->i4_poc;
+ WORD32 i4_cur_pic_temporal_id = isvce_svc_temporal_id_compute(
+ ps_codec->i4_poc, ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers, e_pic_type);
+
+ if(e_pic_type == PIC_B)
+ {
+ return IH264E_FAIL;
+ }
+
+ ASSERT(1 == MAX_LAYER_REFERENCE_PICS);
+
+ /* Pick a ref_pic for the current picture */
+ if(e_pic_type != PIC_IDR)
+ {
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ WORD32 i4_abs_poc_diff;
+ WORD8 i1_temporal_id;
+
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ {
+ continue;
+ }
+
+ buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if(buf_status & BUF_MGR_REF)
+ {
+ i4_abs_poc_diff = ABS(ps_codec->as_ref_set[i].i4_poc - i4_cur_pic_poc);
+ i1_temporal_id = ps_codec->as_ref_set[i].ps_pic_buf->i1_temporal_id;
+
+ if(s_ref_pic_props.i1_temporal_id > -1)
+ {
+ if((i1_temporal_id <= i4_cur_pic_temporal_id) &&
+ (s_ref_pic_props.i4_abs_poc_diff > i4_abs_poc_diff))
+ {
+ s_ref_pic_props.i4_abs_poc_diff = i4_abs_poc_diff;
+ s_ref_pic_props.i1_temporal_id = i1_temporal_id;
+ s_ref_pic_props.i4_buf_id = i;
+ }
+ }
+ else if(i1_temporal_id <= i4_cur_pic_temporal_id)
+ {
+ s_ref_pic_props.i4_abs_poc_diff = i4_abs_poc_diff;
+ s_ref_pic_props.i1_temporal_id = i1_temporal_id;
+ s_ref_pic_props.i4_buf_id = i;
+ }
+ }
+ }
+
+ if(s_ref_pic_props.i1_temporal_id < 0)
+ {
+ return IH264E_FAIL;
+ }
+
+ pps_ref_pics[0] = pps_ref_pics[1] =
+ ps_codec->as_ref_set[s_ref_pic_props.i4_buf_id].ps_pic_buf;
+ pps_mv_bufs[0] = pps_mv_bufs[1] =
+ ps_codec->as_ref_set[s_ref_pic_props.i4_buf_id].ps_svc_au_data;
+
+ /* Pick all ref pic_bufs to be freed. */
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ {
+ continue;
+ }
+
+ buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
+ {
+ ps_codec->as_ref_set[i].i4_pic_cnt = -1;
+ ps_codec->as_ref_set[i].i4_poc = 32768;
+
+ continue;
+ }
+
+ if(buf_status & BUF_MGR_REF)
+ {
+ if((i4_cur_pic_temporal_id <= ps_codec->as_ref_set[i].ps_pic_buf->i1_temporal_id) &&
+ (pps_ref_pics[0]->i4_frame_num !=
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_frame_num) &&
+ (pps_ref_pics[0]->i4_frame_num !=
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_frame_num))
+ {
+ ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id,
+ BUF_MGR_REF);
+
+ ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id,
+ BUF_MGR_REF);
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ {
+ continue;
+ }
+
+ buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
+ {
+ ps_codec->as_ref_set[i].i4_pic_cnt = -1;
+ ps_codec->as_ref_set[i].i4_poc = 32768;
+
+ continue;
+ }
+
+ if(buf_status & BUF_MGR_REF)
+ {
+ ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id, BUF_MGR_REF);
+
+ ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id, BUF_MGR_REF);
+ }
+ }
+ }
+
+ /*
+ * Mark all reference pic with unused buffers to be free
+ * We need this step since each one, ie ref, recon io etc only unset their
+ * respective flags. Hence we need to combine togather and mark the ref set
+ * accordingly
+ */
+ pi4_ref_set_id[0] = -1;
+
+ for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ {
+ pi4_ref_set_id[0] = i;
+ continue;
+ }
+
+ buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
+ {
+ ps_codec->as_ref_set[i].i4_pic_cnt = -1;
+ ps_codec->as_ref_set[i].i4_poc = 32768;
+
+ pi4_ref_set_id[0] = i;
+ }
+ }
+
+ /* An asssert failure here means we donot have any free buffs */
+ if(pi4_ref_set_id[0] < 0)
+ {
+ return IH264E_FAIL;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Validates SVC AU properties
+*
+* @param[in] ps_cfg
+* Cfg parameters
+*
+* @returns error code in conformance with 'IH264E_ERROR_T'
+*
+*******************************************************************************
+*/
+WORD32 isvce_svc_au_props_validate(svc_inp_params_t *ps_svc_inp_params, UWORD32 u4_inp_wd,
+ UWORD32 u4_inp_ht, UWORD32 u4_svc_comp_wd,
+ UWORD32 u4_svc_comp_ht)
+{
+ typedef struct
+ {
+ DOUBLE d_spatial_res_ratio;
+
+ UWORD8 u1_max_num_spatial_layers;
+ } spatial_layer_props_t;
+
+ UWORD8 i;
+ UWORD32 au4_svc_wd[MAX_NUM_SPATIAL_LAYERS];
+ UWORD32 au4_svc_ht[MAX_NUM_SPATIAL_LAYERS];
+
+ DOUBLE d_scaling_factor = ps_svc_inp_params->d_spatial_res_ratio;
+ UWORD8 u1_num_spatial_layers = ps_svc_inp_params->u1_num_spatial_layers;
+ const spatial_layer_props_t gas_valid_spatial_layer_props[] = {{1.5, 2}, {2, 3}};
+ UWORD32 u4_error_code = IV_SUCCESS;
+ const UWORD8 u1_min_num_temporal_layers = 1;
+ const UWORD8 u1_min_num_spatial_layers = 1;
+ const UWORD8 u1_max_num_temporal_layers = MAX_NUM_TEMPORAL_LAYERS;
+ const UWORD8 u1_max_num_spatial_layers = MAX_NUM_SPATIAL_LAYERS;
+ const UWORD8 u1_num_valid_spatial_layer_props =
+ sizeof(gas_valid_spatial_layer_props) / sizeof(gas_valid_spatial_layer_props[0]);
+
+ if((ps_svc_inp_params->u1_num_temporal_layers < u1_min_num_temporal_layers) ||
+ (ps_svc_inp_params->u1_num_temporal_layers > u1_max_num_temporal_layers))
+ {
+ u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_TEMPORAL_LAYERS;
+ }
+
+ if((ps_svc_inp_params->u1_num_spatial_layers < u1_min_num_spatial_layers) ||
+ (ps_svc_inp_params->u1_num_spatial_layers > u1_max_num_spatial_layers))
+ {
+ u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_SPATIAL_LAYERS;
+ }
+
+ {
+ UWORD8 u1_is_input_ratio_valid = 0;
+
+ for(i = 0; i < u1_num_valid_spatial_layer_props; i++)
+ {
+ if(ps_svc_inp_params->d_spatial_res_ratio ==
+ gas_valid_spatial_layer_props[i].d_spatial_res_ratio)
+ {
+ u1_is_input_ratio_valid = 1;
+
+ if(ps_svc_inp_params->u1_num_spatial_layers >
+ gas_valid_spatial_layer_props[i].u1_max_num_spatial_layers)
+ {
+ u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_SPATIAL_LAYERS;
+ }
+
+ break;
+ }
+ }
+
+ if(!u1_is_input_ratio_valid)
+ {
+ u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_SPATIAL_RES_RATIO;
+ }
+ }
+
+ if((u4_svc_comp_wd > SVCE_MAX_INP_DIM) || (u4_svc_comp_ht > SVCE_MAX_INP_DIM) ||
+ ((u4_svc_comp_wd * u4_svc_comp_ht) > SVCE_MAX_INP_FRAME_SIZE) ||
+ (u4_svc_comp_wd % 16 != 0) || (u4_svc_comp_ht % 16 != 0))
+ {
+ u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
+ }
+
+ /* Constraint from padding intrinsics */
+ if((u4_svc_comp_wd - u4_inp_wd) % 16)
+ {
+ u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
+ }
+
+ /* Constraint from 420p to 420sp conversion */
+ if((u4_svc_comp_ht - u4_inp_ht) % 4)
+ {
+ u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
+ }
+
+ au4_svc_wd[u1_num_spatial_layers - 1] = u4_svc_comp_wd;
+ au4_svc_ht[u1_num_spatial_layers - 1] = u4_svc_comp_ht;
+
+ for(i = (u1_num_spatial_layers - 1); i > 0; i--)
+ {
+ au4_svc_wd[i - 1] = au4_svc_wd[i] / d_scaling_factor;
+ au4_svc_ht[i - 1] = au4_svc_ht[i] / d_scaling_factor;
+
+ if((au4_svc_wd[i - 1] * d_scaling_factor != au4_svc_wd[i]) ||
+ (au4_svc_ht[i - 1] * d_scaling_factor != au4_svc_ht[i]) ||
+ (au4_svc_ht[i - 1] % 16 != 0) || (au4_svc_ht[i - 1] % 16 != 0))
+ {
+ u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
+ }
+ }
+
+ return u4_error_code;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Validates SVC input params
+*
+* @param[in] ps_cfg
+* Cfg parameters
+*
+* @returns error code in conformance with 'IH264E_ERROR_T'
+*
+*******************************************************************************
+*/
+WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t *ps_cfg)
+{
+ UWORD32 u4_error_code = isvce_svc_au_props_validate(&ps_ip->s_svc_inp_params, ps_ip->u4_wd,
+ ps_ip->u4_ht, ps_cfg->u4_wd, ps_cfg->u4_ht);
+
+ if(ps_cfg->u4_enable_alt_ref)
+ {
+ u4_error_code |= IH264E_INVALID_ALT_REF_OPTION;
+ }
+
+ if(ps_cfg->u4_num_bframes)
+ {
+ u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
+ }
+
+ if(ps_cfg->e_slice_mode != IVE_SLICE_MODE_NONE)
+ {
+ u4_error_code |= IH264E_SLICE_TYPE_INPUT_INVALID;
+ }
+
+ if(ps_cfg->e_content_type != IV_PROGRESSIVE)
+ {
+ u4_error_code |= IH264E_CONTENT_TYPE_NOT_SUPPORTED;
+ }
+
+ if(ps_cfg->u4_weighted_prediction)
+ {
+ u4_error_code |= IH264E_WEIGHTED_PRED_NOT_SUPPORTED;
+ }
+
+ return u4_error_code;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Used to get reference picture buffer size for a given level and
+* and padding used
+*
+* @param[in] ps_svc_inp_params
+* Struct containing SVC specific input params
+*
+* @param[in] i4_pic_size
+* Number of luma samples (Width * Height)
+*
+* @param[in] i4_level
+* Level
+*
+* @param[in] i4_horz_pad
+* Total padding used in horizontal direction
+*
+* @param[in] i4_vert_pad
+* Total padding used in vertical direction
+*
+* @param[in] i4_num_ref_frames
+* Num Reference Frames
+*
+* @param[in] i4_num_reorder_frames
+* Num Reorder Frames
+*
+* @returns Total picture buffer size
+*
+*******************************************************************************
+*/
+WORD32 isvce_get_total_svc_au_buf_size(svc_inp_params_t *ps_svc_inp_params, WORD32 i4_pic_size,
+ WORD32 i4_level, WORD32 i4_horz_pad, WORD32 i4_vert_pad,
+ WORD32 i4_num_ref_frames, WORD32 i4_num_reorder_frames)
+{
+ WORD32 i;
+ WORD32 size;
+ WORD32 num_luma_samples;
+ WORD32 lvl_idx;
+ WORD32 max_wd, min_ht;
+ WORD32 num_samples;
+ WORD32 max_num_bufs;
+
+ WORD32 pad = MAX(i4_horz_pad, i4_vert_pad);
+ DOUBLE d_svc_size_multiplier = 1;
+
+ for(i = 1; i < ps_svc_inp_params->u1_num_spatial_layers; i++)
+ {
+ d_svc_size_multiplier += 1. / pow(ps_svc_inp_params->d_spatial_res_ratio, i);
+ }
+
+ /*
+ * If i4_num_ref_frames and num_reorder_frmaes is specified
+ * Use minimum value
+ */
+ max_num_bufs = (i4_num_ref_frames + i4_num_reorder_frames + MAX_CTXT_SETS +
+ ps_svc_inp_params->u1_num_temporal_layers);
+
+ /* Get i4_level index */
+ lvl_idx = ih264e_get_lvl_idx(i4_level);
+
+ /* Maximum number of luma samples in a picture at given i4_level */
+ num_luma_samples = gai4_ih264_max_luma_pic_size[lvl_idx];
+ num_luma_samples = MAX(num_luma_samples, i4_pic_size);
+
+ /* Account for chroma */
+ num_samples = num_luma_samples * 3 / 2;
+
+ /* Maximum width of luma samples in a picture at given i4_level */
+ max_wd = gai4_ih264_max_wd_ht[lvl_idx];
+
+ /* Minimum height of luma samples in a picture at given i4_level */
+ min_ht = gai4_ih264_min_wd_ht[lvl_idx];
+
+ /* Allocation is required for
+ * (Wd + i4_horz_pad) * (Ht + i4_vert_pad) * (2 * max_dpb_size + 1)
+ *
+ * Above expanded as
+ * ((Wd * Ht) + (i4_horz_pad * i4_vert_pad) + Wd * i4_vert_pad + Ht *
+ * i4_horz_pad) * (2 * max_dpb_size + 1) (Wd * Ht) * (2 * max_dpb_size + 1) +
+ * ((i4_horz_pad * i4_vert_pad) + Wd * i4_vert_pad + Ht * i4_horz_pad) * (2 *
+ * max_dpb_size + 1) Now max_dpb_size increases with smaller Wd and Ht, but Wd
+ * * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht *
+ * dpb_size
+ *
+ * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by
+ * using num_samples * (2 * max_dpb_size + 1) below
+ *
+ * For the padded area use MAX(i4_horz_pad, i4_vert_pad) as pad
+ * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted
+ * from the above for padding
+ *
+ * Since Width and Height can change worst Wd + Ht is when One of the
+ * dimensions is max and other is min So use max_wd and min_ht
+ */
+
+ /* Number of bytes in reference pictures */
+ size = num_samples * max_num_bufs;
+
+ /* Account for Spatial Layers */
+ size = (WORD32) (size * d_svc_size_multiplier + 0.99);
+
+ /* Account for padding area */
+ size += ((pad * pad) + pad * (max_wd + min_ht)) * 3 / 2 * max_num_bufs *
+ ps_svc_inp_params->u1_num_spatial_layers;
+
+ size += ps_svc_inp_params->u1_num_spatial_layers * sizeof(yuv_buf_props_t);
+
+ return size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Used to get size of buffers used for storing prediction data
+*
+* @param[in] ps_svc_inp_params
+* Struct containing SVC specific input params
+*
+* @param[in] i4_num_luma_samples
+* Number of luma samples (Width * Height)
+*
+* @returns Size of buffers used for storing prediction data
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_total_svc_au_data_size(WORD32 i4_num_luma_samples, UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio)
+{
+ WORD32 i;
+
+ UWORD32 u4_svc_au_data_size = 0;
+
+ u4_svc_au_data_size += u1_num_spatial_layers * sizeof(svc_layer_data_t);
+
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ WORD32 i4_layer_luma_samples =
+ ((DOUBLE) i4_num_luma_samples) / pow(pow(d_spatial_res_ratio, i), 2) + 0.99;
+ WORD32 i4_num_mbs = i4_layer_luma_samples / (MB_SIZE * MB_SIZE);
+
+ /* isvce_mb_info_t */
+ u4_svc_au_data_size += i4_num_mbs * sizeof(isvce_mb_info_t);
+
+ /* pu4_num_pus_in_mb */
+ u4_svc_au_data_size += i4_num_mbs * sizeof(UWORD32);
+ }
+
+ return u4_svc_au_data_size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief Function to add buffers to SVC AU Data Store Manager
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @returns error status
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_svc_au_data_mgr_add_bufs(isvce_codec_t *ps_codec)
+{
+ IH264_ERROR_T ret;
+
+ WORD32 i, j;
+ UWORD8 *pu1_buf;
+
+ svc_au_data_t *ps_svc_au_data = ps_codec->ps_svc_au_data_base;
+
+ WORD32 i4_max_dpb_size = ps_codec->i4_ref_buf_cnt;
+ WORD64 i8_alloc_mem_size = ps_codec->i4_svc_au_data_size;
+ WORD32 i4_num_luma_samples = ALIGN16(ps_codec->s_cfg.u4_wd) * ALIGN16(ps_codec->s_cfg.u4_ht);
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+
+ ps_codec->ps_svc_au_data = ps_svc_au_data;
+ pu1_buf = (UWORD8 *) ps_svc_au_data;
+ pu1_buf += BUF_MGR_MAX_CNT * sizeof(ps_svc_au_data[0]);
+
+ i8_alloc_mem_size -= (BUF_MGR_MAX_CNT * sizeof(ps_svc_au_data[0]));
+
+ i = 0;
+
+ while(i < i4_max_dpb_size)
+ {
+ ps_svc_au_data->ps_svc_layer_data = (svc_layer_data_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_svc_au_data->ps_svc_layer_data[0]);
+ i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_svc_au_data->ps_svc_layer_data[0]);
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ WORD32 i4_layer_luma_samples =
+ ((DOUBLE) i4_num_luma_samples) /
+ pow(pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j), 2) +
+ 0.99;
+ WORD32 i4_num_mbs = i4_layer_luma_samples / (MB_SIZE * MB_SIZE);
+
+ ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb = (UWORD32 *) pu1_buf;
+ pu1_buf +=
+ i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb[0]);
+ i8_alloc_mem_size -=
+ i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb[0]);
+
+ ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info = (isvce_mb_info_t *) pu1_buf;
+ pu1_buf += i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info[0]);
+ i8_alloc_mem_size -=
+ i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+
+ if(i8_alloc_mem_size < 0)
+ {
+ ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_MVBANK;
+
+ return IH264E_INSUFFICIENT_MEM_MVBANK;
+ }
+
+ ret =
+ ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_svc_au_data_store_mgr, ps_svc_au_data, i);
+
+ if(IH264_SUCCESS != ret)
+ {
+ ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
+
+ return IH264E_BUF_MGR_ERROR;
+ }
+
+ ps_svc_au_data++;
+ i++;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc_au_buf_t structs add au buffers to
+* buffer manager in case of non-shared mode
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @returns error status
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_svc_au_buf_mgr_add_bufs(isvce_codec_t *ps_codec)
+{
+ WORD32 i, j;
+ WORD32 buf_ret;
+
+ svc_au_buf_t *ps_pic_buf = ps_codec->ps_pic_buf;
+
+ IH264E_ERROR_T ret = IH264E_SUCCESS;
+
+ WORD32 i4_max_dpb_size = ps_codec->i4_ref_buf_cnt;
+ WORD64 i8_alloc_mem_size =
+ ps_codec->i4_total_pic_buf_size - BUF_MGR_MAX_CNT * sizeof(ps_pic_buf[0]);
+ UWORD8 *pu1_buf = (UWORD8 *) ps_codec->ps_pic_buf;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+
+ pu1_buf += BUF_MGR_MAX_CNT * sizeof(svc_au_buf_t);
+
+ for(i = 0; i < i4_max_dpb_size; i++)
+ {
+ WORD32 i4_total_fpel_mem_size = 0;
+
+ ps_pic_buf->ps_layer_yuv_buf_props = (yuv_buf_props_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_pic_buf->ps_layer_yuv_buf_props[0]);
+ i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_pic_buf->ps_layer_yuv_buf_props[0]);
+
+ if(i8_alloc_mem_size < 0)
+ {
+ ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
+ return IH264E_INSUFFICIENT_MEM_PICBUF;
+ }
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ WORD32 i4_layer_luma_wd = ((DOUBLE) ps_codec->s_cfg.u4_wd /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_ht = ((DOUBLE) ps_codec->s_cfg.u4_ht /
+ pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
+ 0.99;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_uv_samples =
+ (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
+
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].i4_data_stride =
+ ALIGN16(i4_layer_luma_wd) + PAD_WD;
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].pv_data =
+ pu1_buf +
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].i4_data_stride *
+ PAD_TOP +
+ PAD_LEFT;
+
+ pu1_buf += i4_layer_luma_samples;
+
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].i4_data_stride =
+ ALIGN16(i4_layer_uv_wd) + PAD_WD;
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].pv_data =
+ pu1_buf +
+ ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].i4_data_stride *
+ (PAD_TOP / 2) +
+ PAD_LEFT;
+
+ pu1_buf += i4_layer_uv_samples;
+
+ ps_pic_buf->ps_layer_yuv_buf_props[j].u4_width = i4_layer_luma_wd;
+ ps_pic_buf->ps_layer_yuv_buf_props[j].u4_height = i4_layer_luma_ht;
+ ps_pic_buf->ps_layer_yuv_buf_props[j].u1_bit_depth = 8;
+ ps_pic_buf->ps_layer_yuv_buf_props[j].e_color_format = IV_YUV_420SP_UV;
+
+ i8_alloc_mem_size -= i4_layer_luma_samples + i4_layer_uv_samples;
+ i4_total_fpel_mem_size += i4_layer_luma_samples + i4_layer_uv_samples;
+
+ if(i8_alloc_mem_size < 0)
+ {
+ ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
+ return IH264E_INSUFFICIENT_MEM_PICBUF;
+ }
+ }
+
+ buf_ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_ref_buf_mgr, ps_pic_buf, i);
+
+ if(0 != buf_ret)
+ {
+ ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
+ return IH264E_BUF_MGR_ERROR;
+ }
+
+ pu1_buf += (HPEL_PLANES_CNT - 1) * i4_total_fpel_mem_size;
+ ps_pic_buf++;
+ }
+
+ return ret;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing SVC input data
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @param[in] u4_ht
+* Input Height
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_svc_inp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ padding_dims_t s_pad_dims;
+
+ UWORD32 i;
+ UWORD8 u1_filter_padding_size_x, u1_filter_padding_size_y;
+
+ UWORD32 u4_size = 0;
+
+ isvce_get_downscaler_padding_dims(&s_pad_dims);
+
+ u1_filter_padding_size_x = s_pad_dims.u1_left_pad_size + s_pad_dims.u1_right_pad_size;
+
+ u1_filter_padding_size_y = s_pad_dims.u1_top_pad_size + s_pad_dims.u1_bottom_pad_size;
+
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ WORD32 i4_layer_luma_wd = ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, i)) + 0.99;
+ WORD32 i4_layer_luma_ht = ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, i)) + 0.99;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x) *
+ (i4_layer_luma_ht + PAD_HT + u1_filter_padding_size_y);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ /* u1_filter_padding_size_x * 2 because U and V
+ both need same amount of padding */
+ WORD32 i4_layer_uv_samples =
+ (ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2) *
+ (i4_layer_uv_ht + PAD_HT + u1_filter_padding_size_y);
+
+ u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(UWORD8);
+ }
+
+ return SVC_MAX_NUM_INP_FRAMES * u4_size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc input buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_svc_inp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ padding_dims_t s_pad_dims;
+
+ WORD32 i, j;
+ UWORD8 u1_filter_padding_size_x, u1_filter_padding_size_y;
+
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_svc_inp_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ isvce_get_downscaler_padding_dims(&s_pad_dims);
+
+ u1_filter_padding_size_x = s_pad_dims.u1_left_pad_size + s_pad_dims.u1_right_pad_size;
+
+ u1_filter_padding_size_y = s_pad_dims.u1_top_pad_size + s_pad_dims.u1_bottom_pad_size;
+
+ for(i = 0; i < SVC_MAX_NUM_INP_FRAMES; i++)
+ {
+ ps_codec->as_inp_list[i].s_svc_params = ps_codec->s_cfg.s_svc_params;
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) + 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) + 0.99;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x) *
+ (i4_layer_luma_ht + PAD_HT + u1_filter_padding_size_y);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ /* u1_filter_padding_size_x * 2 because U and V
+ both need same amount of padding */
+ WORD32 i4_layer_uv_samples =
+ (ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2) *
+ (i4_layer_uv_ht + PAD_HT + u1_filter_padding_size_y);
+
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[Y].i4_data_stride =
+ ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x;
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[Y].pv_data =
+ pu1_buf +
+ ps_codec->as_inp_list[i]
+ .as_layer_yuv_buf_props[j]
+ .as_component_bufs[Y]
+ .i4_data_stride *
+ (PAD_TOP + s_pad_dims.u1_top_pad_size) +
+ (PAD_LEFT + s_pad_dims.u1_left_pad_size);
+ pu1_buf += i4_layer_luma_samples * sizeof(UWORD8);
+ i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(UWORD8);
+
+ ps_codec->as_inp_list[i]
+ .as_layer_yuv_buf_props[j]
+ .as_component_bufs[UV]
+ .i4_data_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2;
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[UV].pv_data =
+ pu1_buf +
+ ps_codec->as_inp_list[i]
+ .as_layer_yuv_buf_props[j]
+ .as_component_bufs[UV]
+ .i4_data_stride *
+ (PAD_TOP + s_pad_dims.u1_top_pad_size) +
+ (PAD_LEFT + s_pad_dims.u1_left_pad_size * 2);
+ pu1_buf += i4_layer_uv_samples * sizeof(UWORD8);
+ i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(UWORD8);
+
+ /* Chroma is always stored interleaved */
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[V].pv_data = NULL;
+
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u1_bit_depth = 8;
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].e_color_format = IV_YUV_420SP_UV;
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u4_width = i4_layer_luma_wd;
+ ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u4_height = i4_layer_luma_ht;
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+ }
+}
+
+void isvce_init_svc_dimension(isvce_inp_buf_t *ps_inp)
+{
+ WORD32 i;
+
+ UWORD8 u1_num_spatial_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio = ps_inp->s_svc_params.d_spatial_res_ratio;
+ UWORD32 u4_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[Y];
+ UWORD32 u4_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[Y];
+
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ ps_inp->as_layer_yuv_buf_props[i].u4_width =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ ps_inp->as_layer_yuv_buf_props[i].u4_height =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Pads input buf as assumed by the downscaler filter
+*
+* @param[in] ps_codec
+* Pointer to codec ctxt
+*
+* @param[in] ps_inp
+* Pointer to svc input buffer
+*
+* @param[in] u1_svc_layer_index
+* SVC layer index of the buffer
+*
+*******************************************************************************
+*/
+
+static void isvce_pad_buf_for_filtering(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp,
+ UWORD8 u1_svc_layer_index)
+{
+ padding_dims_t s_pad_dims;
+
+ UWORD8 *pu1_buf;
+ UWORD32 u4_buf_width, u4_buf_height;
+
+ UWORD8 u1_pad_left_size;
+ UWORD8 u1_pad_right_size;
+ UWORD8 u1_pad_top_size;
+ UWORD8 u1_pad_bottom_size;
+ UWORD8 u1_filter_padding_size_x;
+ UWORD8 u1_filter_padding_size_chroma_x;
+
+ ASSERT(ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].e_color_format == IV_YUV_420SP_UV);
+
+ isvce_get_downscaler_padding_dims(&s_pad_dims);
+
+ u1_pad_left_size = s_pad_dims.u1_left_pad_size;
+ u1_pad_right_size = s_pad_dims.u1_right_pad_size;
+ u1_pad_top_size = s_pad_dims.u1_top_pad_size;
+ u1_pad_bottom_size = s_pad_dims.u1_bottom_pad_size;
+ u1_filter_padding_size_x = u1_pad_left_size + u1_pad_right_size;
+ u1_filter_padding_size_chroma_x = u1_filter_padding_size_x * 2;
+
+ u4_buf_width = ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].u4_width;
+
+ u4_buf_height = ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].u4_height;
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[0]
+ .pv_data);
+
+ ps_codec->pf_pad_left_luma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
+ u4_buf_height, u1_pad_left_size);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[0]
+ .pv_data);
+
+ pu1_buf += u4_buf_width;
+
+ ps_codec->pf_pad_right_luma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
+ u4_buf_height, u1_pad_right_size);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[1]
+ .pv_data);
+
+ ps_codec->pf_pad_left_chroma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
+ u4_buf_height / 2, u1_pad_left_size * 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[1]
+ .pv_data);
+
+ pu1_buf += u4_buf_width;
+
+ ps_codec->pf_pad_right_chroma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
+ u4_buf_height / 2, u1_pad_right_size * 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[0]
+ .pv_data) -
+ u1_pad_left_size;
+
+ ps_codec->pf_pad_top(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
+ (u4_buf_width + u1_filter_padding_size_x), u1_pad_top_size);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[0]
+ .pv_data) -
+ u1_pad_left_size;
+
+ pu1_buf +=
+ (u4_buf_height *
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride);
+
+ ps_codec->pf_pad_bottom(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
+ (u4_buf_width + u1_filter_padding_size_x), u1_pad_bottom_size);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[1]
+ .pv_data) -
+ u1_pad_left_size * 2;
+
+ ps_codec->pf_pad_top(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
+ (u4_buf_width + u1_filter_padding_size_chroma_x), u1_pad_top_size);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
+ .as_component_bufs[1]
+ .pv_data) -
+ u1_pad_left_size * 2;
+
+ pu1_buf +=
+ ((u4_buf_height / 2) *
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride);
+
+ ps_codec->pf_pad_bottom(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
+ (u4_buf_width + u1_filter_padding_size_chroma_x), u1_pad_bottom_size);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Pads raw input to satisfy SVC compliant input dimensions
+*
+* @param[in] ps_codec
+* Pointer to codec ctxt
+*
+* @param[in] ps_inp
+* Pointer to svc input buffer
+*
+*******************************************************************************
+*/
+
+static void isvce_pad_input_to_svc_compliant_dims(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp)
+{
+ UWORD8 *pu1_buf;
+ UWORD32 u4_raw_input_wd, u4_raw_input_ht, u4_padded_width, u4_padded_height, u4_width_delta,
+ u4_height_delta;
+ UWORD8 u1_num_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
+
+ ASSERT(ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].e_color_format == IV_YUV_420SP_UV);
+
+ u4_padded_width = ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].u4_width;
+ u4_padded_height = ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].u4_height;
+ u4_raw_input_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
+ u4_raw_input_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
+ u4_width_delta = u4_padded_width - u4_raw_input_wd;
+ u4_height_delta = u4_padded_height - u4_raw_input_ht;
+
+ ASSERT(!(u4_width_delta & 1));
+ ASSERT(!(u4_height_delta & 1));
+
+ if(u4_width_delta)
+ {
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .pv_data);
+
+ pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride) *
+ (u4_height_delta / 2));
+
+ ps_codec->pf_pad_left_luma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
+ u4_padded_height, u4_width_delta / 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .pv_data);
+
+ pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride) *
+ (u4_height_delta / 2));
+
+ pu1_buf += u4_raw_input_wd;
+
+ ps_codec->pf_pad_right_luma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
+ u4_padded_height, u4_width_delta / 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .pv_data);
+
+ pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride) *
+ (u4_height_delta / 4));
+
+ ps_codec->pf_pad_left_chroma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
+ u4_padded_height / 2, u4_width_delta / 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .pv_data);
+
+ pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride) *
+ (u4_height_delta / 4));
+
+ pu1_buf += u4_raw_input_wd;
+
+ ps_codec->pf_pad_right_chroma(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
+ u4_padded_height / 2, u4_width_delta / 2);
+ }
+
+ if(u4_height_delta)
+ {
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .pv_data);
+
+ pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride) *
+ (u4_height_delta / 2));
+
+ ps_codec->pf_pad_top(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
+ u4_padded_width, u4_height_delta / 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .pv_data);
+
+ pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride) *
+ (u4_height_delta / 2));
+
+ pu1_buf +=
+ (u4_raw_input_ht *
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride);
+
+ ps_codec->pf_pad_bottom(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
+ u4_padded_width, u4_height_delta / 2);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .pv_data);
+
+ pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride) *
+ (u4_height_delta / 4));
+
+ ps_codec->pf_pad_top(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
+ u4_padded_width, u4_height_delta / 4);
+
+ pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .pv_data);
+
+ pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride) *
+ (u4_height_delta / 4));
+
+ pu1_buf +=
+ ((u4_raw_input_ht / 2) *
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride);
+
+ ps_codec->pf_pad_bottom(
+ pu1_buf,
+ ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
+ u4_padded_width, u4_height_delta / 4);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Format conversion and downsampling for deriving spatial layer inputs
+*
+* @param[in] ps_inp
+* Pointer to input buffer
+*
+*******************************************************************************
+*/
+void isvce_svc_inp_buf_populate(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp)
+{
+ yuv_buf_props_t s_src_buf_props, s_dst_buf_props;
+
+ UWORD32 i;
+ UWORD32 u4_blk_x, u4_blk_y;
+ UWORD8 *pu1_planar_y, *pu1_planar_u, *pu1_planar_v, *pu1_semi_planar_y, *pu1_semi_planar_uv;
+ UWORD8 *pu1_src_luma, *pu1_src_chroma, *pu1_dst_luma, *pu1_dst_chroma;
+ UWORD32 u4_num_blocks_x, u4_num_blocks_y;
+ UWORD32 u4_scaled_block_wd, u4_scaled_block_ht;
+ UWORD32 u4_blk_wd_luma, u4_blk_ht_luma;
+
+ downscaler_ctxt_t *ps_scaler = &ps_codec->s_scaler;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ const UWORD8 u1_num_yuv_components_420sp = NUM_SP_COMPONENTS;
+ UWORD8 u1_num_spatial_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
+ UWORD32 u4_padded_width = ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1].u4_width;
+ UWORD32 u4_padded_height = ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1].u4_height;
+ UWORD32 u4_raw_input_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
+ UWORD32 u4_raw_input_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
+ UWORD32 u4_width_delta = u4_padded_width - u4_raw_input_wd;
+ UWORD32 u4_height_delta = u4_padded_height - u4_raw_input_ht;
+
+ ASSERT(!(u4_width_delta & 1));
+ ASSERT(!(u4_height_delta & 1));
+
+ ASSERT((ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420P) ||
+ (ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420SP_UV));
+
+ /* Check is input is valid */
+ if(!(ps_inp->s_inp_props.s_raw_buf.apv_bufs[0]))
+ {
+ ASSERT(0);
+
+ return;
+ }
+
+ /* Convert the input into semi-planar in case of other formats */
+ if(ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420P)
+ {
+ pu1_planar_y = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[0];
+ pu1_planar_u = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[1];
+ pu1_planar_v = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[2];
+
+ pu1_semi_planar_y = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[0]
+ .pv_data;
+
+ pu1_semi_planar_uv = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[1]
+ .pv_data;
+
+ pu1_semi_planar_y +=
+ ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride) *
+ (u4_height_delta / 2));
+
+ pu1_semi_planar_uv +=
+ ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride) *
+ (u4_height_delta / 4));
+
+ ps_codec->pf_ih264e_conv_420p_to_420sp(
+ pu1_planar_y, pu1_planar_u, pu1_planar_v, pu1_semi_planar_y, pu1_semi_planar_uv,
+ ps_inp->s_inp_props.s_raw_buf.au4_ht[0], ps_inp->s_inp_props.s_raw_buf.au4_wd[0],
+ ps_inp->s_inp_props.s_raw_buf.au4_strd[0], ps_inp->s_inp_props.s_raw_buf.au4_strd[1],
+ ps_inp->s_inp_props.s_raw_buf.au4_strd[2],
+ ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[0]
+ .i4_data_stride,
+ ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[1]
+ .i4_data_stride,
+ 0);
+ }
+ else
+ {
+ UWORD32 u4_wd, u4_ht;
+ UWORD8 u1_comp;
+ UWORD32 au4_arr_dims[4];
+ UWORD8 *pu1_src, *pu1_dst;
+
+ au4_arr_dims[0] = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
+ au4_arr_dims[1] = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
+ au4_arr_dims[2] = ps_inp->s_inp_props.s_raw_buf.au4_wd[1];
+ au4_arr_dims[3] = ps_inp->s_inp_props.s_raw_buf.au4_ht[1];
+
+ for(u1_comp = 0; u1_comp < u1_num_yuv_components_420sp; u1_comp++)
+ {
+ u4_wd = au4_arr_dims[u1_comp * 2];
+ u4_ht = au4_arr_dims[(u1_comp * 2) + 1];
+
+ pu1_dst = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[u1_comp]
+ .pv_data;
+
+ pu1_dst +=
+ ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[u1_comp]
+ .i4_data_stride) *
+ ((u4_height_delta / 2) / (u1_comp + 1)));
+
+ pu1_src = ps_inp->s_inp_props.s_raw_buf.apv_bufs[u1_comp];
+
+ ps_mem_fxns->pf_copy_2d(pu1_dst,
+ ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
+ .as_component_bufs[u1_comp]
+ .i4_data_stride,
+ pu1_src, ps_inp->s_inp_props.s_raw_buf.au4_strd[u1_comp], u4_wd,
+ u4_ht);
+ }
+ }
+
+ /* Padding input to satisfy SVC constraints */
+ isvce_pad_input_to_svc_compliant_dims(ps_codec, ps_inp);
+
+ /* Downscaling */
+ for(i = u1_num_spatial_layers - 1; i > 0; i--)
+ {
+ const UWORD32 u4_default_scaled_blk_wd =
+ gu4_downscaler_blk_size / ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio + 0.5;
+ const UWORD32 u4_default_scaled_blk_ht =
+ gu4_downscaler_blk_size / ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio + 0.5;
+
+ isvce_pad_buf_for_filtering(ps_codec, ps_inp, i);
+
+ s_src_buf_props = ps_inp->as_layer_yuv_buf_props[i];
+ s_dst_buf_props = ps_inp->as_layer_yuv_buf_props[i - 1];
+
+ u4_num_blocks_x =
+ (s_src_buf_props.u4_width + (gu4_downscaler_blk_size - 1)) / gu4_downscaler_blk_size;
+
+ u4_num_blocks_y =
+ (s_src_buf_props.u4_height + (gu4_downscaler_blk_size - 1)) / gu4_downscaler_blk_size;
+
+ pu1_src_luma = (UWORD8 *) s_src_buf_props.as_component_bufs[Y].pv_data;
+ pu1_src_chroma = (UWORD8 *) s_src_buf_props.as_component_bufs[U].pv_data;
+ pu1_dst_luma = (UWORD8 *) s_dst_buf_props.as_component_bufs[Y].pv_data;
+ pu1_dst_chroma = (UWORD8 *) s_dst_buf_props.as_component_bufs[U].pv_data;
+
+ for(u4_blk_x = 0; u4_blk_x < u4_num_blocks_x; u4_blk_x++)
+ {
+ for(u4_blk_y = 0; u4_blk_y < u4_num_blocks_y; u4_blk_y++)
+ {
+ u4_blk_wd_luma = isvce_get_downscaler_blk_dims(s_src_buf_props.u4_width, u4_blk_x,
+ gu4_downscaler_blk_size);
+
+ u4_blk_ht_luma = isvce_get_downscaler_blk_dims(s_src_buf_props.u4_height, u4_blk_y,
+ gu4_downscaler_blk_size);
+
+ u4_scaled_block_wd = isvce_get_downscaler_blk_dims(
+ s_dst_buf_props.u4_width, u4_blk_x, u4_default_scaled_blk_wd);
+
+ u4_scaled_block_ht = isvce_get_downscaler_blk_dims(
+ s_dst_buf_props.u4_height, u4_blk_y, u4_default_scaled_blk_ht);
+
+ s_src_buf_props.as_component_bufs[Y].pv_data =
+ pu1_src_luma + (u4_blk_x * gu4_downscaler_blk_size +
+ u4_blk_y * gu4_downscaler_blk_size *
+ s_src_buf_props.as_component_bufs[Y].i4_data_stride);
+
+ s_src_buf_props.as_component_bufs[U].pv_data =
+ pu1_src_chroma + (u4_blk_x * gu4_downscaler_blk_size +
+ u4_blk_y * (gu4_downscaler_blk_size / 2) *
+ s_src_buf_props.as_component_bufs[U].i4_data_stride);
+
+ s_dst_buf_props.as_component_bufs[Y].pv_data =
+ pu1_dst_luma + (u4_blk_x * u4_default_scaled_blk_wd +
+ u4_blk_y * u4_default_scaled_blk_ht *
+ s_dst_buf_props.as_component_bufs[Y].i4_data_stride);
+
+ s_dst_buf_props.as_component_bufs[U].pv_data =
+ pu1_dst_chroma + (u4_blk_x * u4_default_scaled_blk_wd +
+ u4_blk_y * (u4_default_scaled_blk_ht / 2) *
+ s_dst_buf_props.as_component_bufs[U].i4_data_stride);
+
+ ASSERT(!(u4_scaled_block_wd & 1));
+ ASSERT(!(u4_scaled_block_ht & 1));
+
+ isvce_process_downscaler(ps_scaler, &s_src_buf_props, &s_dst_buf_props,
+ u4_blk_wd_luma, u4_blk_ht_luma);
+ }
+ }
+ }
+
+ UNUSED(u4_scaled_block_wd);
+ UNUSED(u4_scaled_block_ht);
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* calculates the greatest common divisor between the two parameters.
+*
+*******************************************************************************
+*/
+
+static DOUBLE isvce_get_GCD(DOUBLE a, DOUBLE b)
+{
+ if(b == 0)
+ {
+ return a;
+ }
+
+ return isvce_get_GCD(b, fmod(a, b));
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* calculates the least common multiple between the two parameters
+*
+*******************************************************************************
+*/
+
+static DOUBLE isvce_get_LCM(DOUBLE a, DOUBLE b) { return (a / isvce_get_GCD(a, b)) * b; }
+
+/**
+*******************************************************************************
+*
+* @brief
+* sets the width and height in config structure to SVC compliant width and
+* height
+*
+* @param[in] ps_cfg
+* Pointer to config struct
+*
+* @param[in] u4_app_wd
+* width of the YUV as read by the app
+*
+* @param[in] u4_app_ht
+* height of the YUV as read by the app
+*
+*******************************************************************************
+*/
+
+void isvce_get_svc_compliant_dimensions(UWORD8 u1_num_spatial_layers, DOUBLE d_scaling_factor,
+ UWORD32 u4_wd, UWORD32 u4_ht, UWORD32 *pu4_svc_comp_wd,
+ UWORD32 *pu4_svc_comp_ht)
+{
+ DOUBLE d_scaling_factor_power_num_layers_minus1 = 0;
+ UWORD32 u4_constraint_offset = 0;
+
+ d_scaling_factor_power_num_layers_minus1 = pow(d_scaling_factor, u1_num_spatial_layers - 1);
+
+ if(fmod(16, d_scaling_factor_power_num_layers_minus1))
+ {
+ u4_constraint_offset =
+ (UWORD32) isvce_get_LCM(16, d_scaling_factor_power_num_layers_minus1);
+ }
+ else
+ {
+ u4_constraint_offset = (UWORD32) (16 * d_scaling_factor_power_num_layers_minus1);
+ }
+
+ if(u4_wd % u4_constraint_offset)
+ {
+ *pu4_svc_comp_wd = u4_wd - ((u4_wd) % u4_constraint_offset) + u4_constraint_offset;
+ }
+ else
+ {
+ *pu4_svc_comp_wd = u4_wd;
+ }
+
+ if(u4_ht % u4_constraint_offset)
+ {
+ *pu4_svc_comp_ht = u4_ht - ((u4_ht) % u4_constraint_offset) + u4_constraint_offset;
+ }
+ else
+ {
+ *pu4_svc_comp_ht = u4_ht;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing SVC layer nbr info
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_svc_nbr_info_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ UWORD32 i;
+
+ UWORD32 u4_size = 0;
+
+ ASSERT(1 == MAX_CTXT_SETS);
+
+ u4_size += MAX_PROCESS_CTXT * u1_num_spatial_layers * sizeof(nbr_info_t);
+
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ WORD32 i4_layer_luma_wd = ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, i)) + 0.99;
+ WORD32 i4_layer_luma_ht = ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, i)) + 0.99;
+ WORD32 i4_num_mbs_in_row = i4_layer_luma_wd / MB_SIZE;
+ WORD32 i4_num_mbs_in_col = i4_layer_luma_ht / MB_SIZE;
+
+ /* ps_top_row_mb_info */
+ u4_size += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(isvce_mb_info_t);
+
+ /* ps_left_mb_info */
+ u4_size += MAX_PROCESS_CTXT * sizeof(isvce_mb_info_t);
+
+ /* ps_top_mb_intra_modes */
+ u4_size += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(mb_intra_modes_t);
+
+ /* ps_left_mb_intra_modes */
+ u4_size += MAX_PROCESS_CTXT * sizeof(mb_intra_modes_t);
+ }
+
+ return u4_size;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc nbr info buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_svc_nbr_info_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ WORD32 i, j;
+
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_svc_nbr_info_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ ASSERT(1 == MAX_CTXT_SETS);
+
+ for(i = 0; i < MAX_PROCESS_CTXT; i++)
+ {
+ ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info = (nbr_info_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers *
+ sizeof(ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[0]);
+ i8_alloc_mem_size -= u1_num_spatial_layers *
+ sizeof(ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[0]);
+
+ for(j = u1_num_spatial_layers - 1; j >= 0; j--)
+ {
+ ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[j].ps_left_mb_info =
+ (isvce_mb_info_t *) pu1_buf;
+ ps_codec->as_process[i].s_nbr_info.ps_left_mb_info = (isvce_mb_info_t *) pu1_buf;
+ pu1_buf += sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_info[0]);
+ i8_alloc_mem_size -= sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_info[0]);
+
+ ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[j].ps_left_mb_intra_modes =
+ (mb_intra_modes_t *) pu1_buf;
+ ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes =
+ (mb_intra_modes_t *) pu1_buf;
+ pu1_buf += sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes[0]);
+ i8_alloc_mem_size -=
+ sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes[0]);
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ isvce_mb_info_t *ps_top_mb_info;
+ mb_intra_modes_t *ps_top_intra_modes;
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_num_mbs_in_row = i4_layer_luma_wd / MB_SIZE;
+ WORD32 i4_num_mbs_in_col = i4_layer_luma_ht / MB_SIZE;
+
+ ps_top_mb_info = (isvce_mb_info_t *) pu1_buf;
+ pu1_buf += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_mb_info[0]);
+ i8_alloc_mem_size -=
+ (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_mb_info[0]);
+
+ ps_top_intra_modes = (mb_intra_modes_t *) pu1_buf;
+ pu1_buf += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_intra_modes[0]);
+ i8_alloc_mem_size -=
+ (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_intra_modes[0]);
+
+ for(j = 0; j < MAX_PROCESS_CTXT; j++)
+ {
+ ps_codec->as_process[j].s_nbr_info_base.ps_layer_nbr_info[i].ps_top_row_mb_info =
+ ps_top_mb_info;
+ ps_codec->as_process[j].s_nbr_info.ps_top_row_mb_info = NULL;
+
+ ps_codec->as_process[j].s_nbr_info_base.ps_layer_nbr_info[i].ps_top_mb_intra_modes =
+ ps_top_intra_modes;
+ ps_codec->as_process[j].s_nbr_info.ps_top_mb_intra_modes = NULL;
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* isvce_codec_t and proc_t initialisations for an Access Unit
+*
+* @par Description:
+* Before beginning to encode the frame, the current function initializes all
+* the ctxts (proc, entropy, me, ...) basing on the input configured params.
+* It locates space for storing recon in the encoder picture buffer set, fetches
+* reference frame from encoder picture buffer set. Calls RC pre-enc to get
+* qp and pic type for the current frame. Queues proc jobs so that
+* the other threads can begin encoding. In brief, this function sets up the
+* tone for the entire encoder.
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_inp_buf
+* Pointer to input buffer context
+*
+* @returns error_status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_svc_au_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf)
+{
+ svc_au_buf_t *ps_cur_pic;
+
+ WORD32 cur_mv_bank_buf_id;
+ WORD32 cur_pic_buf_id;
+ WORD32 ref_set_id;
+ WORD32 i, j;
+
+ svc_au_data_t *ps_mv_buf = NULL;
+ svc_au_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {NULL, NULL};
+ svc_au_data_t *aps_mv_buf[MAX_REF_PIC_CNT] = {NULL, NULL};
+
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+ PIC_TYPE_T *pic_type = &ps_codec->pic_type;
+
+ UWORD32 u4_timestamp_high = ps_inp_buf->s_inp_props.u4_timestamp_high;
+ UWORD32 u4_timestamp_low = ps_inp_buf->s_inp_props.u4_timestamp_low;
+ WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+ /* Diamond search Iteration Max Cnt */
+ UWORD32 u4_num_layers =
+ (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) ? (NUM_LAYERS >> 2) : NUM_LAYERS;
+ UWORD32 u4_enable_fast_sad = ps_codec->s_cfg.u4_enable_fast_sad;
+
+ if((PIC_I == *pic_type) || (PIC_IDR == *pic_type))
+ {
+ ps_codec->i4_slice_type = ISLICE;
+ }
+ else if(PIC_P == *pic_type)
+ {
+ ps_codec->i4_slice_type = PSLICE;
+ }
+ else if(PIC_B == *pic_type)
+ {
+ ps_codec->i4_slice_type = BSLICE;
+ }
+
+ ps_codec->u4_is_curr_frm_ref = 0;
+ ps_codec->u4_is_curr_frm_ref = (*pic_type != PIC_B);
+
+ if(ps_codec->s_cfg.u4_enable_alt_ref && (*pic_type == PIC_P) &&
+ (ps_codec->i4_pic_cnt % (ps_codec->s_cfg.u4_enable_alt_ref + 1)))
+ {
+ ps_codec->u4_is_curr_frm_ref = 0;
+ }
+
+ ps_codec->u4_is_idr = 0;
+
+ if(PIC_IDR == *pic_type)
+ {
+ ps_codec->u4_is_idr = 1;
+
+ ps_codec->i4_frame_num = 0;
+
+ ps_codec->i4_idr_pic_id++;
+ }
+
+ ps_codec->u4_disable_deblock_level = 1;
+
+ if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_0)
+ {
+ ps_codec->u4_disable_deblock_level = 0;
+ }
+ else if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_2)
+ {
+ if(ps_codec->u4_disable_deblock_level_cnt == DISABLE_DEBLOCK_INTERVAL ||
+ ps_codec->i4_slice_type == ISLICE)
+ {
+ ps_codec->u4_disable_deblock_level = 0;
+ }
+ }
+ else if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_3)
+ {
+ if(ps_codec->i4_slice_type == ISLICE)
+ {
+ ps_codec->u4_disable_deblock_level = 0;
+ }
+ }
+
+ if(ps_codec->u4_disable_deblock_level)
+ {
+ ps_codec->u4_disable_deblock_level_cnt++;
+ }
+ else
+ {
+ ps_codec->u4_disable_deblock_level_cnt = 0;
+ }
+
+ if(ps_codec->u4_disable_deblock_level == 0)
+ {
+ if(ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
+ {
+ ps_codec->i4_error_code = IH264E_SLICE_TYPE_INPUT_INVALID;
+
+ return IH264E_SLICE_TYPE_INPUT_INVALID;
+ }
+ }
+
+ ps_codec->i4_error_code = IH264E_SUCCESS;
+
+ if(ps_codec->i4_gen_header)
+ {
+ sps_t *ps_sps = NULL;
+ pps_t *ps_pps = NULL;
+ subset_sps_t *ps_subset_sps = NULL;
+ UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
+
+ if(ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS].u1_spatial_layer_id > 0)
+ {
+ u1_profile_idc = IH264_SCALABLE_BASELINE;
+ }
+
+ ps_sps = ps_codec->ps_sps_base;
+ isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
+
+ ps_pps = ps_codec->ps_pps_base;
+ isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
+
+ for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_subset_sps = ps_codec->ps_subset_sps_base + i;
+ isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
+
+ /* populate pps header */
+ ps_pps = ps_codec->ps_pps_base + i;
+ isvce_populate_pps(ps_codec, ps_pps, i, i, i);
+ }
+ }
+
+ if(IH264E_SUCCESS !=
+ isvce_ref_list_refresh(ps_codec, aps_ref_pic, aps_mv_buf, &ref_set_id, pic_type[0]))
+ {
+ ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
+
+ return IH264E_NO_FREE_PICBUF;
+ }
+
+ {
+ ps_mv_buf = (svc_au_data_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_codec->pv_svc_au_data_store_mgr, &cur_mv_bank_buf_id);
+
+ if(NULL == ps_mv_buf)
+ {
+ ps_codec->i4_error_code = IH264E_NO_FREE_MVBANK;
+
+ return IH264E_NO_FREE_MVBANK;
+ }
+
+ if(ps_codec->u4_is_curr_frm_ref)
+ {
+ ih264_buf_mgr_set_status(ps_codec->pv_svc_au_data_store_mgr, cur_mv_bank_buf_id,
+ BUF_MGR_REF);
+ }
+
+ ps_mv_buf->i4_abs_poc = ps_codec->i4_abs_pic_order_cnt;
+ ps_mv_buf->i4_buf_id = cur_mv_bank_buf_id;
+ }
+
+ {
+ ps_cur_pic = (svc_au_buf_t *) ih264_buf_mgr_get_next_free(
+ (buf_mgr_t *) ps_codec->pv_ref_buf_mgr, &cur_pic_buf_id);
+
+ if(NULL == ps_cur_pic)
+ {
+ ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
+
+ return IH264E_NO_FREE_PICBUF;
+ }
+
+ if(ps_codec->u4_is_curr_frm_ref)
+ {
+ ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id, BUF_MGR_REF);
+ }
+
+ if(1 == ps_codec->s_cfg.u4_enable_recon)
+ {
+ ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id, BUF_MGR_IO);
+ }
+
+ ps_cur_pic->u4_timestamp_high = ps_inp_buf->s_inp_props.u4_timestamp_high;
+ ps_cur_pic->u4_timestamp_low = ps_inp_buf->s_inp_props.u4_timestamp_low;
+
+ ps_cur_pic->i4_abs_poc = ps_codec->i4_poc;
+ ps_cur_pic->i4_poc_lsb = ps_codec->i4_pic_order_cnt_lsb;
+ ps_cur_pic->i4_frame_num = ps_codec->i4_frame_num;
+
+ ps_cur_pic->i4_buf_id = cur_pic_buf_id;
+
+ ps_cur_pic->i1_temporal_id = isvce_svc_temporal_id_compute(
+ ps_codec->i4_poc, ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers, pic_type[0]);
+ }
+
+ /*
+ * Add the current picture to ref list independent of the fact that it is used
+ * as reference or not. This is because, now recon is not in sync with output
+ * hence we may need the current recon after some delay. By adding it to ref
+ * list we can retrieve the recon any time we want. The information that it is
+ * used for ref can still be found by checking the buffer status of pic buf.
+ */
+ ps_codec->as_ref_set[ref_set_id].i4_pic_cnt = ps_codec->i4_pic_cnt;
+ ps_codec->as_ref_set[ref_set_id].i4_poc = ps_codec->i4_poc;
+ ps_codec->as_ref_set[ref_set_id].ps_svc_au_data = ps_mv_buf;
+ ps_codec->as_ref_set[ref_set_id].ps_pic_buf = ps_cur_pic;
+
+ ps_codec->s_svc_ilp_data.ps_svc_au_data = ps_mv_buf;
+
+ {
+ isvce_process_ctxt_t *ps_proc = NULL;
+
+ j = ctxt_sel * MAX_PROCESS_THREADS;
+
+ for(i = j; i < (j + MAX_PROCESS_THREADS); i++)
+ {
+ ps_proc = &ps_codec->as_process[i];
+
+ ps_proc->s_svc_params = ps_codec->s_cfg.s_svc_params;
+
+ ps_proc->i4_frame_num = ps_codec->i4_frame_num;
+ ps_proc->u4_is_idr = ps_codec->u4_is_idr;
+ ps_proc->u4_idr_pic_id = ps_codec->i4_idr_pic_id;
+ ps_proc->i4_slice_type = ps_codec->i4_slice_type;
+
+ ps_proc->u4_half_x_offset = 0;
+ ps_proc->u4_half_y_offset = 0;
+ ps_proc->u4_half_xy_offset = 0;
+
+ ps_proc->u4_disable_deblock_level = ps_codec->u4_disable_deblock_level;
+
+ ps_proc->i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
+ ps_proc->ps_cur_pic = ps_cur_pic;
+ ps_proc->ps_cur_mv_buf = ps_mv_buf;
+
+ /*
+ * pointer to ref picture
+ * 0 : Temporal back reference
+ * 1 : Temporal forward reference
+ */
+ ps_proc->aps_ref_pic[L0] = aps_ref_pic[L0];
+ ps_proc->aps_ref_pic[L1] = aps_ref_pic[L1];
+ if(ps_codec->pic_type == PIC_B)
+ {
+ ps_proc->aps_mv_buf[L0] = aps_mv_buf[L0];
+ ps_proc->aps_mv_buf[L1] = aps_mv_buf[L1];
+ }
+ else
+ {
+ /*
+ * Else is dummy since for non B pic we does not need this
+ * But an assignment here will help in not having a segfault
+ * when we calcualte colpic in P slices
+ */
+ ps_proc->aps_mv_buf[L0] = ps_mv_buf;
+ ps_proc->aps_mv_buf[L1] = ps_mv_buf;
+ }
+
+ ps_proc->s_inp_buf = ps_inp_buf[0];
+
+ ps_proc->i4_encode_api_call_cnt = ps_codec->i4_encode_api_call_cnt;
+
+ ps_proc->i4_pic_cnt = ps_codec->i4_pic_cnt;
+
+ ps_proc->i4_error_code = 0;
+
+ {
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+
+ ps_entropy->i4_sof = 0;
+ ps_entropy->i4_eof = 0;
+ ps_entropy->ps_sps_base = ps_codec->ps_sps_base;
+ ps_entropy->ps_pps_base = ps_codec->ps_pps_base;
+ ps_entropy->pu1_slice_idx = ps_proc->pu1_slice_idx;
+ ps_entropy->ps_svc_nalu_ext_base = ps_proc->ps_svc_nalu_ext_base;
+ ps_entropy->ps_subset_sps_base = ps_proc->ps_subset_sps_base;
+ ps_entropy->ps_slice_hdr_base = ps_proc->ps_slice_hdr_base;
+ ps_entropy->ps_svc_slice_hdr_base = ps_proc->ps_svc_slice_hdr_base;
+ ps_entropy->i4_abs_pic_order_cnt = ps_codec->i4_poc;
+
+ ps_entropy->i1_transform_8x8_mode_flag = 0;
+
+ ps_entropy->i4_error_code = IH264E_SUCCESS;
+ ps_proc->s_entropy.u4_is_last = ps_inp_buf->s_inp_props.u4_is_last;
+ ps_proc->s_entropy.i4_pic_cnt = ps_codec->i4_pic_cnt;
+
+ ps_entropy->u4_timestamp_low = u4_timestamp_low;
+ ps_entropy->u4_timestamp_high = u4_timestamp_high;
+ }
+
+ {
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+
+ ps_me_ctxt->ai2_srch_boundaries[0] = ps_codec->s_cfg.u4_srch_rng_x;
+ ps_me_ctxt->ai2_srch_boundaries[1] = ps_codec->s_cfg.u4_srch_rng_y;
+
+ ps_me_ctxt->u4_half_x_offset = ps_proc->u4_half_x_offset;
+ ps_me_ctxt->u4_half_y_offset = ps_proc->u4_half_y_offset;
+ ps_me_ctxt->u4_half_xy_offset = ps_proc->u4_half_xy_offset;
+
+ ps_me_ctxt->u4_enable_fast_sad = u4_enable_fast_sad;
+ ps_me_ctxt->u4_enable_hpel = ps_codec->s_cfg.u4_enable_hpel;
+ ps_me_ctxt->u4_num_layers = u4_num_layers;
+ ps_me_ctxt->u4_me_speed_preset = ps_codec->s_cfg.u4_me_speed_preset;
+
+ if((i == j) && (0 == ps_codec->i4_poc))
+ {
+ isvce_init_mv_bits(ps_me_ctxt);
+ }
+ }
+
+ ps_proc->ps_ngbr_avbl = &(ps_proc->s_ngbr_avbl);
+ }
+ }
+
+ return error_status;
+}
+
+void isvce_init_quant_params(isvce_process_ctxt_t *ps_proc, WORD32 qp)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ /* quant params */
+ quant_params_t *ps_qp_params;
+
+ /* ptr to forward quant threshold matrix */
+ const UWORD16 *pu2_thres_mat = NULL;
+
+ /* ptr to forward scale matrix */
+ const UWORD16 *pu2_scale_mat = gu2_quant_scale_matrix_4x4;
+
+ /* ptr to inverse scale matrix */
+ const UWORD16 *pu2_iscale_mat = gau2_ih264_iquant_scale_matrix_4x4;
+
+ /* temp var */
+ UWORD32 u4_qp[3], u4_qp_div6, u4_qp_mod6;
+ COMPONENT_TYPE plane;
+ WORD32 i;
+ UWORD32 u4_satdq_t;
+ const UWORD16 *pu2_smat;
+
+ /********************************************************************/
+ /* init quant params for all planes Y, U and V */
+ /********************************************************************/
+ /* luma qp */
+ u4_qp[Y] = qp;
+
+ /* chroma qp
+ * TODO_LATER : just in case if the chroma planes use different qp's this
+ * needs to be corrected accordingly.
+ */
+ u4_qp[U] = gu1_qpc_fqpi[qp];
+ u4_qp[V] = gu1_qpc_fqpi[qp];
+
+ plane = Y;
+ while(plane <= V)
+ {
+ u4_qp_div6 = (u4_qp[plane] / 6);
+ u4_qp_mod6 = (u4_qp[plane] % 6);
+
+ ps_qp_params = ps_proc->ps_qp_params[plane];
+
+ /* mb qp */
+ ps_qp_params->u1_mb_qp = u4_qp[plane];
+
+ /* mb qp / 6 */
+ ps_qp_params->u1_qp_div = u4_qp_div6;
+
+ /* mb qp % 6 */
+ ps_qp_params->u1_qp_rem = u4_qp_mod6;
+
+ /* QP bits */
+ ps_qp_params->u1_qbits = QP_BITS_h264_4x4 + u4_qp_div6;
+
+ /* forward scale matrix */
+ ps_qp_params->pu2_scale_mat = pu2_scale_mat + (u4_qp_mod6 * 16);
+
+ /* threshold matrix & weight for quantization */
+ pu2_thres_mat = gu2_forward_quant_threshold_4x4 + (u4_qp_mod6 * 16);
+ for(i = 0; i < 16; i++)
+ {
+ ps_qp_params->pu2_thres_mat[i] = pu2_thres_mat[i] >> (8 - u4_qp_div6);
+ ps_qp_params->pu2_weigh_mat[i] = 16;
+ }
+
+ /* qp dependent rounding constant */
+ ps_qp_params->u4_dead_zone = gu4_forward_quant_round_factor_4x4[u4_qp_div6];
+
+ /* slice dependent rounding constant */
+ if(ps_proc->i4_slice_type != ISLICE && ps_proc->i4_slice_type != SISLICE)
+ {
+ ps_qp_params->u4_dead_zone >>= 1;
+ }
+
+ /* SATQD threshold for zero block prediction */
+ if(ps_codec->s_cfg.u4_enable_satqd)
+ {
+ pu2_smat = ps_qp_params->pu2_scale_mat;
+
+ u4_satdq_t = ((1 << (ps_qp_params->u1_qbits)) - ps_qp_params->u4_dead_zone);
+
+ ps_qp_params->pu2_sad_thrsh[0] = u4_satdq_t / MAX(pu2_smat[3], pu2_smat[11]);
+ ps_qp_params->pu2_sad_thrsh[1] = u4_satdq_t / MAX(pu2_smat[1], pu2_smat[9]);
+ ps_qp_params->pu2_sad_thrsh[2] = u4_satdq_t / pu2_smat[15];
+ ps_qp_params->pu2_sad_thrsh[3] = u4_satdq_t / pu2_smat[7];
+ ps_qp_params->pu2_sad_thrsh[4] = u4_satdq_t / MAX(pu2_smat[12], pu2_smat[14]);
+ ps_qp_params->pu2_sad_thrsh[5] = u4_satdq_t / MAX(pu2_smat[4], pu2_smat[6]);
+ ps_qp_params->pu2_sad_thrsh[6] = u4_satdq_t / pu2_smat[13];
+ ps_qp_params->pu2_sad_thrsh[7] = u4_satdq_t / pu2_smat[5];
+ ps_qp_params->pu2_sad_thrsh[8] =
+ u4_satdq_t / MAX(MAX3(pu2_smat[0], pu2_smat[2], pu2_smat[8]), pu2_smat[10]);
+ }
+
+ /* inverse scale matrix */
+ ps_qp_params->pu2_iscale_mat = pu2_iscale_mat + (u4_qp_mod6 * 16);
+
+ plane += 1;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* isvce_codec_t and proc_t initialisations for an Access Unit
+*
+* @par Description:
+* Before beginning to encode the frame, the current function initializes all
+* the ctxts (proc, entropy, me, ...) basing on the input configured params.
+* It locates space for storing recon in the encoder picture buffer set, fetches
+* reference frame from encoder picture buffer set. Calls RC pre-enc to get
+* qp and pic type for the current frame. Queues proc jobs so that
+* the other threads can begin encoding. In brief, this function sets up the
+* tone for the entire encoder.
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_inp_buf
+* Pointer to input buffer context
+*
+* @param[in] u1_spatial_layer_id
+* Spatial Layer IDl 0 => Base layer
+*
+* @returns error_status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_svc_layer_pic_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id)
+{
+ WORD32 i;
+
+ IH264E_ERROR_T error_status = IH264E_SUCCESS;
+ IH264_ERROR_T ret = IH264_SUCCESS;
+ PIC_TYPE_T e_pic_type = ps_codec->pic_type;
+
+ ASSERT(MAX_CTXT_SETS == 1);
+
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
+ {
+ isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i];
+ isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+ isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
+ svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
+ svc_au_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {ps_proc->aps_ref_pic[L0],
+ ps_proc->aps_ref_pic[L1]};
+
+ ps_proc->u1_spatial_layer_id = u1_spatial_layer_id;
+
+ ps_proc->s_src_pic_buf_props = ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id];
+
+ ps_proc->s_rec_pic_buf_props = ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id];
+
+ ASSERT(0 == (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width % MB_SIZE));
+ ASSERT(0 == (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height % MB_SIZE));
+
+ ps_proc->i4_wd_mbs =
+ ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width / MB_SIZE;
+ ps_proc->i4_ht_mbs =
+ ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height / MB_SIZE;
+
+ ps_proc->u1_frame_qp = ps_codec->au4_frame_qp[u1_spatial_layer_id];
+
+ ps_proc->u1_mb_qp = ps_proc->u1_frame_qp;
+ ps_entropy->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_proc->u1_frame_qp;
+
+ isvce_init_quant_params(ps_proc, ps_proc->u1_frame_qp);
+
+ memset(&ps_proc->s_frame_info, 0, sizeof(frame_info_t));
+
+ /* row '-1' */
+ memset(ps_proc->pu1_proc_map - ps_proc->i4_wd_mbs, 1,
+ ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_proc_map[0]));
+
+ /* row 0 to ht in mbs */
+ memset(ps_proc->pu1_proc_map, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_proc_map[0]));
+
+ /* row '-1' */
+ memset(ps_proc->pu1_deblk_map - ps_proc->i4_wd_mbs, 1,
+ ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_deblk_map[0]));
+
+ /* row 0 to ht in mbs */
+ memset(ps_proc->pu1_deblk_map, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_deblk_map[0]));
+
+ /* row '-1' */
+ memset(ps_proc->pu1_me_map - ps_proc->i4_wd_mbs, 1,
+ ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_me_map[0]));
+
+ /* row 0 to ht in mbs */
+ memset(ps_proc->pu1_me_map, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_me_map[0]));
+
+ if(IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
+ {
+ ps_codec->i4_air_pic_cnt =
+ (ps_codec->i4_air_pic_cnt + 1) % ps_codec->s_cfg.u4_air_refresh_period;
+
+ if(!ps_codec->i4_air_pic_cnt)
+ {
+ memset(ps_proc->pu1_is_intra_coded, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs *
+ sizeof(ps_proc->pu1_is_intra_coded[0]));
+ }
+ }
+
+ if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_NONE)
+ {
+ memset(ps_proc->pu1_slice_idx, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_slice_idx[0]));
+ }
+ else if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
+ {
+ UWORD8 *pu1_slice_idx = ps_proc->pu1_slice_idx;
+ WORD32 i4_mb_y = 0, slice_idx = 0, cnt;
+
+ while(i4_mb_y < ps_proc->i4_ht_mbs)
+ {
+ if(i4_mb_y + (WORD32) ps_codec->s_cfg.u4_slice_param < ps_proc->i4_ht_mbs)
+ {
+ cnt = ps_codec->s_cfg.u4_slice_param * ps_proc->i4_wd_mbs;
+ i4_mb_y += ps_codec->s_cfg.u4_slice_param;
+ }
+ else
+ {
+ cnt = (ps_proc->i4_ht_mbs - i4_mb_y) * ps_proc->i4_wd_mbs;
+ i4_mb_y += (ps_proc->i4_ht_mbs - i4_mb_y);
+ }
+
+ memset(pu1_slice_idx, slice_idx, cnt * sizeof(pu1_slice_idx[0]));
+
+ slice_idx++;
+ pu1_slice_idx += cnt;
+ }
+ }
+
+ if((e_pic_type != PIC_IDR) && (e_pic_type != PIC_I))
+ {
+ ps_proc->as_ref_pic_buf_props[L0] =
+ aps_ref_pic[L0]->ps_layer_yuv_buf_props[u1_spatial_layer_id];
+ ps_proc->as_ref_pic_buf_props[L1] =
+ aps_ref_pic[L1]->ps_layer_yuv_buf_props[u1_spatial_layer_id];
+ }
+
+ ps_entropy->i4_gen_header = ps_codec->i4_gen_header && (0 == u1_spatial_layer_id);
+ ps_entropy->i4_gen_subset_sps =
+ (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && ps_codec->i4_gen_header;
+
+ /* row '-1' */
+ memset(ps_entropy->pu1_entropy_map - ps_proc->i4_wd_mbs, 1,
+ ps_proc->i4_wd_mbs * sizeof(ps_entropy->pu1_entropy_map[0]));
+
+ /* row 0 to ht in mbs */
+ memset(ps_entropy->pu1_entropy_map, 0,
+ ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_entropy->pu1_entropy_map[0]));
+
+ isvce_init_cabac_table(ps_entropy);
+
+ ps_entropy->i4_wd_mbs = ps_proc->i4_wd_mbs;
+ ps_entropy->i4_ht_mbs = ps_proc->i4_ht_mbs;
+
+ ps_entropy->u1_entropy_coding_mode_flag =
+ ((ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && (0 == u1_spatial_layer_id))
+ ? CAVLC
+ : ps_codec->s_cfg.u4_entropy_coding_mode;
+
+ ps_proc->s_entropy.pi4_mb_skip_run[0] = 0;
+
+ ps_entropy->u4_header_bits[MB_TYPE_INTRA] = 0;
+ ps_entropy->u4_header_bits[MB_TYPE_INTER] = 0;
+ ps_entropy->u4_residue_bits[MB_TYPE_INTRA] = 0;
+ ps_entropy->u4_residue_bits[MB_TYPE_INTER] = 0;
+
+ ps_entropy->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+
+ ps_deblk->pu1_slice_idx = ps_proc->pu1_slice_idx;
+
+ ps_me_ctxt->u1_mb_qp = ps_codec->au4_frame_qp[u1_spatial_layer_id];
+
+ {
+ UWORD8 u1_min_qp;
+ UWORD8 u1_max_qp;
+
+ svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
+ svc_sub_pic_rc_layer_variables_t *ps_layer_variables =
+ &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_layer_variables;
+
+ switch(ps_proc->i4_slice_type)
+ {
+ case ISLICE:
+ {
+ u1_min_qp = ps_codec->s_cfg.au4_i_qp_min[u1_spatial_layer_id];
+ u1_max_qp = ps_codec->s_cfg.au4_i_qp_max[u1_spatial_layer_id];
+
+ break;
+ }
+ case PSLICE:
+ {
+ u1_min_qp = ps_codec->s_cfg.au4_p_qp_min[u1_spatial_layer_id];
+ u1_max_qp = ps_codec->s_cfg.au4_p_qp_max[u1_spatial_layer_id];
+
+ break;
+ }
+ default:
+ {
+ u1_min_qp = ps_codec->s_cfg.au4_b_qp_min[u1_spatial_layer_id];
+ u1_max_qp = ps_codec->s_cfg.au4_b_qp_max[u1_spatial_layer_id];
+
+ break;
+ }
+ }
+
+ ps_layer_variables->i4_max_num_reference_frames = ps_codec->i4_max_num_reference_frames;
+ ps_layer_variables->i4_slice_type = ps_proc->i4_slice_type;
+ ps_layer_variables->i4_frame_num = ps_proc->i4_frame_num;
+ ps_layer_variables->u1_frame_qp = ps_proc->u1_frame_qp;
+ ps_layer_variables->u1_spatial_layer_id = u1_spatial_layer_id;
+ ps_layer_variables->u1_min_qp = u1_min_qp;
+ ps_layer_variables->u1_max_qp = u1_max_qp;
+
+ isvce_sub_pic_rc_ctxt_layer_init(ps_proc->ps_sub_pic_rc_ctxt);
+ }
+ }
+
+ {
+ job_t s_job;
+
+ s_job.i4_cmd = CMD_PROCESS;
+ s_job.i2_mb_cnt =
+ ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width / MB_SIZE;
+ s_job.i2_mb_x = 0;
+
+ for(i = 0; i < (WORD32) (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height /
+ MB_SIZE);
+ i++)
+ {
+ s_job.i2_mb_y = i;
+
+ ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1);
+
+ if(ret != IH264_SUCCESS)
+ {
+ ps_codec->i4_error_code = ret;
+
+ return IH264E_FAIL;
+ }
+ }
+
+ /* Once all the jobs are queued, terminate the queue */
+ /* Since the threads are created and deleted in each call, terminating
+ here is not an issue */
+ ih264_list_terminate(ps_codec->pv_proc_jobq);
+ }
+
+ ps_codec->i4_gen_header = 0;
+
+ return error_status;
+}
+
+/**
+*******************************************************************************
+*
+* @brief initialize process context.
+*
+* @par Description:
+* Before dispatching the current job to process thread, the process context
+* associated with the job is initialized. Usually every job aims to encode one
+* row of mb's. Basing on the row indices provided by the job, the process
+* context's buffer ptrs, slice indices and other elements that are necessary
+* during core-coding are initialized.
+*
+* @param[in] ps_proc
+* Pointer to the current process context
+*
+* @returns error status
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_init_layer_proc_ctxt(isvce_process_ctxt_t *ps_proc)
+{
+ WORD32 i4_mb_x, i4_mb_y;
+
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
+ quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
+ isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
+ isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
+ svc_au_data_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
+
+ i4_mb_x = ps_proc->i4_mb_x;
+ i4_mb_y = ps_proc->i4_mb_y;
+
+ ASSERT((ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd) == 0);
+ ASSERT((ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht) == 0);
+
+ ps_proc->i4_nmb_ntrpy = ps_proc->i4_wd_mbs;
+ ps_proc->u4_nmb_me = 1;
+
+ ps_proc->s_src_buf_props = ps_proc->s_src_pic_buf_props;
+ ps_proc->s_rec_buf_props = ps_proc->s_rec_pic_buf_props;
+ ps_proc->as_ref_buf_props[0] = ps_proc->as_ref_pic_buf_props[0];
+ ps_proc->as_ref_buf_props[1] = ps_proc->as_ref_pic_buf_props[1];
+
+ ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + (i4_mb_x * MB_SIZE) +
+ ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
+ ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_src_pic_buf_props.as_component_bufs[1].pv_data) +
+ (i4_mb_x * MB_SIZE) +
+ ps_proc->s_src_buf_props.as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
+
+ ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + (i4_mb_x * MB_SIZE) +
+ ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
+ ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + (i4_mb_x * MB_SIZE) +
+ ps_proc->s_rec_buf_props.as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
+
+ ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) +
+ (i4_mb_x * MB_SIZE) +
+ ps_proc->as_ref_buf_props[0].as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
+ ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) +
+ (i4_mb_x * MB_SIZE) +
+ ps_proc->as_ref_buf_props[0].as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
+
+ ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) +
+ (i4_mb_x * MB_SIZE) +
+ ps_proc->as_ref_buf_props[1].as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
+ ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
+ ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) +
+ (i4_mb_x * MB_SIZE) +
+ ps_proc->as_ref_buf_props[1].as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
+
+ ps_proc->pv_mb_coeff_data =
+ ((UWORD8 *) ps_proc->pv_pic_mb_coeff_data) + i4_mb_y * ps_codec->u4_size_coeff_data;
+
+ ps_proc->pv_mb_header_data =
+ ((UWORD8 *) ps_proc->pv_pic_mb_header_data) + i4_mb_y * ps_codec->u4_size_header_data;
+
+ ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[i4_mb_y * ps_proc->i4_wd_mbs + i4_mb_x];
+
+ ps_proc->ps_mb_info =
+ ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
+ i4_mb_y * ps_proc->i4_wd_mbs;
+
+ ps_proc->ps_col_mb =
+ ps_proc->aps_mv_buf[1]->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
+ i4_mb_y * ps_proc->i4_wd_mbs;
+
+ {
+ ps_proc->s_nbr_info.ps_top_row_mb_info =
+ ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
+ .ps_top_row_mb_info +
+ (i4_mb_x + (i4_mb_y - 1) * ps_proc->i4_wd_mbs);
+
+ ps_proc->s_nbr_info.ps_top_mb_intra_modes =
+ ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
+ .ps_top_mb_intra_modes +
+ (i4_mb_x + (i4_mb_y - 1) * ps_proc->i4_wd_mbs);
+ }
+
+ ps_proc->pu4_mb_pu_cnt =
+ ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].pu4_num_pus_in_mb +
+ (i4_mb_y * ps_proc->i4_wd_mbs);
+
+ ps_proc->ps_mb_info->u2_mb_type = I16x16;
+
+ ps_proc->u4_lambda = gu1_qp0[ps_qp_params->u1_mb_qp];
+
+ ps_proc->i4_mb_distortion = SHRT_MAX;
+
+ if(i4_mb_x == 0)
+ {
+ ps_proc->s_nbr_info.ps_left_mb_info[0].i4_mb_distortion = 0;
+ }
+
+ ps_proc->i4_mb_cost = INT_MAX;
+
+ ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
+ /* deblk lags the current mb proc by 1 row */
+ /* NOTE: Intra prediction has to happen with non deblocked samples used as
+ * reference */
+ /* Hence to deblk MB 0 of row 0, you have wait till MB 0 of row 1 is encoded.
+ */
+ /* For simplicity, we chose to lag deblking by 1 Row wrt to proc */
+ ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
+
+ ps_deblk->s_rec_pic_buf_props = ps_proc->s_rec_pic_buf_props;
+
+ ps_bs->i4_mb_x = ps_proc->i4_mb_x;
+ ps_bs->i4_mb_y = ps_proc->i4_mb_y;
+
+ ps_n_mb_ctxt->i4_mb_x = 0;
+ ps_n_mb_ctxt->i4_mb_y = ps_deblk->i4_mb_y;
+ ps_n_mb_ctxt->i4_n_mbs = ps_proc->i4_nmb_ntrpy;
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Returns size of buffers for storing SVC ILP data
+*
+* @param[in] u1_num_spatial_layers
+* Num Spatial Layers
+*
+* @param[in] d_spatial_res_ratio
+* Resolution Ratio b/w spatial layers
+*
+* @param[in] u4_wd
+* Input Width
+*
+* @param[in] u4_ht
+* Input Height
+*
+* @returns Size of buffers
+*
+*******************************************************************************
+*/
+UWORD32 isvce_get_svc_ilp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht)
+{
+ WORD32 i;
+
+ UWORD32 u4_size = 0;
+
+ if(u1_num_spatial_layers > 1)
+ {
+ /* ps_intra_recon_bufs */
+ u4_size += u1_num_spatial_layers * sizeof(yuv_buf_props_t);
+
+ /* ps_residual_bufs */
+ u4_size += u1_num_spatial_layers * sizeof(yuv_buf_props_t);
+
+ /* aps_layer_resampler_props[Y] */
+ u4_size += u1_num_spatial_layers * sizeof(layer_resampler_props_t);
+
+ /* aps_layer_resampler_props[UV] */
+ u4_size += u1_num_spatial_layers * sizeof(layer_resampler_props_t);
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_uv_samples =
+ (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
+
+ /* ps_intra_recon_bufs */
+ u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(UWORD8);
+
+ /* ps_residual_bufs */
+ u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(WORD16);
+ }
+ }
+ else
+ {
+ WORD32 i4_layer_luma_wd = u4_wd;
+ WORD32 i4_layer_luma_ht = u4_ht;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_uv_samples = (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
+
+ /* ps_residual_bufs */
+ u4_size += sizeof(yuv_buf_props_t);
+
+ /* ps_residual_bufs */
+ u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(WORD16);
+ }
+
+ return u4_size;
+}
+
+static void isvce_layer_resampler_props_init(layer_resampler_props_t *ps_layer_props,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht, UWORD8 u1_level_idc,
+ UWORD8 u1_is_chroma)
+{
+ const UWORD8 u1_ref_layer_field_pic_flag = 0;
+ const UWORD8 u1_field_pic_flag = 0;
+ const UWORD8 u1_frame_mbs_only_flag = 1;
+ const UWORD8 u1_ref_layer_frame_mbs_only_flag = 1;
+ const UWORD8 u1_bot_field_flag = 0;
+ const WORD32 i4_scaled_ref_layer_left_offset = 0;
+ const WORD32 i4_scaled_ref_layer_top_offset = 0;
+ const WORD32 i4_ref_layer_chroma_phase_x_plus1 = 1;
+ const WORD32 i4_ref_layer_chroma_phase_y_plus1 = 1;
+ const WORD32 i4_chroma_phase_x_plus1 = 1;
+ const WORD32 i4_chroma_phase_y_plus1 = 1;
+ const WORD32 i4_sub_wd_chroma = 2;
+ const WORD32 i4_sub_ht_chroma = 2;
+ UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
+ UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
+ UWORD32 u4_scaled_wd = u4_wd;
+ UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
+
+ u4_ref_wd = u4_ref_wd >> u1_is_chroma;
+ u4_ref_ht = u4_ref_ht >> u1_is_chroma;
+ u4_scaled_wd = u4_scaled_wd >> u1_is_chroma;
+ u4_scaled_ht = u4_scaled_ht >> u1_is_chroma;
+
+ if(u1_is_chroma)
+ {
+ ps_layer_props->i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1 - 1;
+ ps_layer_props->i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
+ ps_layer_props->i4_phase_x = i4_chroma_phase_x_plus1 - 1;
+ ps_layer_props->i4_phase_y = i4_chroma_phase_y_plus1 - 1;
+ ps_layer_props->u4_sub_wd = i4_sub_wd_chroma;
+ ps_layer_props->u4_sub_ht = i4_sub_ht_chroma;
+ ps_layer_props->u4_mb_wd = MB_SIZE >> 1;
+ ps_layer_props->u4_mb_ht = MB_SIZE >> 1;
+ }
+ else
+ {
+ ps_layer_props->i4_refphase_x = 0;
+ ps_layer_props->i4_refphase_y = 0;
+ ps_layer_props->i4_phase_x = 0;
+ ps_layer_props->i4_phase_y = 0;
+ ps_layer_props->u4_sub_wd = 1;
+ ps_layer_props->u4_sub_ht = 1;
+ ps_layer_props->u4_mb_wd = MB_SIZE;
+ ps_layer_props->u4_mb_ht = MB_SIZE;
+ }
+
+ if(u1_level_idc <= 30)
+ {
+ ps_layer_props->u4_shift_x = 16;
+ ps_layer_props->u4_shift_y = 16;
+ }
+ else
+ {
+ ps_layer_props->u4_shift_x = 31 - isvcd_get_ceil_log2(u4_ref_wd);
+ ps_layer_props->u4_shift_y = 31 - isvcd_get_ceil_log2(u4_ref_ht);
+ }
+
+ if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ ps_layer_props->i4_phase_y = ps_layer_props->i4_phase_y + 4 * u1_bot_field_flag;
+
+ if(1 == u1_ref_layer_frame_mbs_only_flag)
+ {
+ ps_layer_props->i4_refphase_y = (2 * ps_layer_props->i4_refphase_y) + 2;
+ }
+ else
+ {
+ ps_layer_props->i4_refphase_y = ps_layer_props->i4_refphase_y + (4 * u1_bot_field_flag);
+ }
+ }
+
+ ps_layer_props->u4_scale_x =
+ ((u4_ref_wd << ps_layer_props->u4_shift_x) + (u4_scaled_wd >> 1)) / (u4_scaled_wd);
+ ps_layer_props->u4_scale_y =
+ ((u4_ref_ht << ps_layer_props->u4_shift_y) + (u4_scaled_ht >> 1)) / (u4_scaled_ht);
+
+ ps_layer_props->i4_offset_x = i4_scaled_ref_layer_left_offset / ps_layer_props->u4_sub_wd;
+ ps_layer_props->i4_add_x =
+ (((u4_ref_wd * (2 + ps_layer_props->i4_phase_x)) << (ps_layer_props->u4_shift_x - 2)) +
+ (u4_scaled_wd >> 1)) /
+ u4_scaled_wd +
+ (1 << (ps_layer_props->u4_shift_x - 5));
+ ps_layer_props->i4_delta_x = 4 * (2 + ps_layer_props->i4_refphase_x);
+
+ if((1 == u1_frame_mbs_only_flag) && (1 == u1_ref_layer_frame_mbs_only_flag))
+ {
+ ps_layer_props->i4_offset_y = i4_scaled_ref_layer_top_offset / ps_layer_props->u4_sub_ht;
+ ps_layer_props->i4_add_y =
+ (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y)) << (ps_layer_props->u4_shift_y - 2)) +
+ (u4_scaled_ht >> 1)) /
+ u4_scaled_ht +
+ (1 << (ps_layer_props->u4_shift_y - 5));
+ ps_layer_props->i4_delta_y = 4 * (2 + ps_layer_props->i4_refphase_y);
+ }
+ else
+ {
+ ps_layer_props->i4_offset_y =
+ i4_scaled_ref_layer_top_offset / (2 * ps_layer_props->u4_sub_ht);
+ ps_layer_props->i4_add_y =
+ (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y)) << (ps_layer_props->u4_shift_y - 3)) +
+ (u4_scaled_ht >> 1)) /
+ u4_scaled_ht +
+ (1 << (ps_layer_props->u4_shift_y - 5));
+ ps_layer_props->i4_delta_y = 2 * (2 + ps_layer_props->i4_refphase_y);
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to initialize svc ilp buffers
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_mem_rec
+* Pointer to memory allocated for input buffers
+*
+*******************************************************************************
+*/
+void isvce_svc_ilp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
+{
+ UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
+ UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
+ UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
+ UWORD8 *pu1_buf = ps_mem_rec->pv_base;
+ WORD64 i8_alloc_mem_size =
+ isvce_get_svc_ilp_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
+
+ if(u1_num_spatial_layers > 1)
+ {
+ WORD32 i, j;
+
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs = (yuv_buf_props_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[0]);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs = (yuv_buf_props_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
+ i8_alloc_mem_size -=
+ u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
+
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i] =
+ (layer_resampler_props_t *) pu1_buf;
+ pu1_buf += u1_num_spatial_layers *
+ sizeof(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i][0]);
+ i8_alloc_mem_size -= u1_num_spatial_layers *
+ sizeof(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i][0]);
+ }
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ for(i = u1_num_spatial_layers - 1; i >= 0; i--)
+ {
+ WORD32 i4_stride;
+
+ WORD32 i4_layer_luma_wd =
+ ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_ht =
+ ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_uv_samples =
+ (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
+
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u4_width = i4_layer_luma_wd;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u4_height = i4_layer_luma_ht;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].e_color_format = IV_YUV_420SP_UV;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u1_bit_depth = 8;
+
+ i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[Y].pv_data =
+ pu1_buf + PAD_LEFT + PAD_TOP * i4_stride;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[Y].i4_data_stride =
+ ALIGN16(i4_layer_luma_wd) + PAD_WD;
+ pu1_buf += i4_layer_luma_samples * sizeof(UWORD8);
+ i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(UWORD8);
+
+ i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[UV].pv_data =
+ pu1_buf + PAD_LEFT + PAD_TOP * i4_stride;
+ ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[UV].i4_data_stride =
+ ALIGN16(i4_layer_uv_wd) + PAD_WD;
+ pu1_buf += i4_layer_uv_samples * sizeof(UWORD8);
+ i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(UWORD8);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u4_width = i4_layer_luma_wd;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u4_height = i4_layer_luma_ht;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].e_color_format = IV_YUV_420SP_UV;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u1_bit_depth = 10;
+
+ i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[Y].pv_data =
+ pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[Y].i4_data_stride =
+ i4_stride;
+ pu1_buf += i4_layer_luma_samples * sizeof(WORD16);
+ i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(WORD16);
+
+ i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[UV].pv_data =
+ pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[UV].i4_data_stride =
+ i4_stride;
+ pu1_buf += i4_layer_uv_samples * sizeof(WORD16);
+ i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(WORD16);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[V].pv_data = NULL;
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ if(i >= 1)
+ {
+ for(j = 0; j < NUM_SP_COMPONENTS; j++)
+ {
+ isvce_layer_resampler_props_init(
+ &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[j][i],
+ d_spatial_res_ratio, i4_layer_luma_wd, i4_layer_luma_ht,
+ ps_codec->s_cfg.u4_max_level, ((COMPONENT_TYPE) j) == UV);
+ }
+ }
+ }
+ }
+ else
+ {
+ WORD32 i4_stride;
+
+ WORD32 i4_layer_luma_wd = u4_wd;
+ WORD32 i4_layer_luma_ht = u4_ht;
+ WORD32 i4_layer_luma_samples =
+ (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
+ WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
+ WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
+ WORD32 i4_layer_uv_samples = (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs = (yuv_buf_props_t *) pu1_buf;
+ pu1_buf += sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
+ i8_alloc_mem_size -= sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
+
+ ASSERT(i8_alloc_mem_size >= 0);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u4_width = i4_layer_luma_wd;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u4_height = i4_layer_luma_ht;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].e_color_format = IV_YUV_420SP_UV;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u1_bit_depth = 10;
+
+ i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[Y].pv_data =
+ pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[Y].i4_data_stride =
+ i4_stride;
+ pu1_buf += i4_layer_luma_samples * sizeof(WORD16);
+ i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(WORD16);
+
+ i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[UV].pv_data =
+ pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[UV].i4_data_stride =
+ i4_stride;
+ pu1_buf += i4_layer_uv_samples * sizeof(WORD16);
+ i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(WORD16);
+
+ ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[V].pv_data = NULL;
+
+ ASSERT(i8_alloc_mem_size >= 0);
+ }
+}
+
+static FORCEINLINE UWORD32 isvce_get_residual_csbf(mem_fxns_t *ps_mem_fxns,
+ buffer_container_t *ps_comp_buf)
+{
+ WORD32 i;
+
+ UWORD32 u4_csbf = 0;
+
+ for(i = 0; i < MAX_TU_IN_MB; i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[i];
+ UWORD8 u1_offset_x = (i % MAX_TU_IN_MB_ROW) * MIN_TU_SIZE;
+ UWORD8 u1_offset_y = (i / MAX_TU_IN_MB_ROW) * MIN_TU_SIZE;
+ WORD16 *pi2_res = ((WORD16 *) ps_comp_buf->pv_data) + u1_offset_x +
+ u1_offset_y * ps_comp_buf->i4_data_stride;
+ UWORD8 u1_cbf = ps_mem_fxns->pf_nonzero_checker(
+ (UWORD8 *) pi2_res, ps_comp_buf->i4_data_stride * (sizeof(WORD16) / sizeof(UWORD8)),
+ MIN_TU_SIZE * (sizeof(WORD16) / sizeof(UWORD8)), MIN_TU_SIZE);
+
+ u4_csbf |= (u1_cbf << u1_zscan_idx);
+ }
+
+ return u4_csbf;
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Function to update svc ilp buffers after every MB
+*
+* @param[in] ps_proc
+* Pointer to process context
+*
+*******************************************************************************
+*/
+void isvce_svc_ilp_buf_update(isvce_process_ctxt_t *ps_proc)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+ svc_params_t *ps_svc_params = &ps_codec->s_cfg.s_svc_params;
+
+ UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
+
+ if(ps_svc_params->u1_num_spatial_layers > 1)
+ {
+ buffer_container_t s_src;
+ buffer_container_t s_dst;
+
+ WORD32 i;
+
+ svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+ yuv_buf_props_t *ps_residual_buf =
+ &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
+
+ WORD32 i4_mb_x = ps_proc->i4_mb_x;
+ WORD32 i4_mb_y = ps_proc->i4_mb_y;
+
+ ASSERT(ps_proc->s_rec_buf_props.e_color_format == IV_YUV_420SP_UV);
+
+ if(u1_spatial_layer_id < (ps_svc_params->u1_num_spatial_layers - 1))
+ {
+ if(ps_proc->ps_mb_info->u1_is_intra)
+ {
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+
+ s_src = ps_proc->s_rec_buf_props.as_component_bufs[i];
+
+ s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .i4_data_stride;
+ s_dst.pv_data =
+ ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .pv_data) +
+ i4_mb_x * MB_SIZE +
+ i4_mb_y * (MB_SIZE >> u1_is_chroma) * s_dst.i4_data_stride;
+
+ ps_mem_fxns->pf_copy_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride,
+ (UWORD8 *) s_src.pv_data, s_src.i4_data_stride, MB_SIZE,
+ (MB_SIZE >> u1_is_chroma));
+ }
+ }
+ else
+ {
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+
+ s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .i4_data_stride;
+ s_dst.pv_data =
+ ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
+ .as_component_bufs[i]
+ .pv_data) +
+ i4_mb_x * MB_SIZE +
+ i4_mb_y * (MB_SIZE >> u1_is_chroma) * s_dst.i4_data_stride;
+
+ ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
+ MB_SIZE, (MB_SIZE >> u1_is_chroma));
+ }
+ }
+ }
+
+ if(ENABLE_RESIDUAL_PREDICTION && (ps_proc->i4_slice_type != ISLICE) &&
+ (u1_spatial_layer_id < (ps_svc_params->u1_num_spatial_layers - 1)))
+ {
+ if(ps_proc->ps_mb_info->u1_is_intra || (ps_proc->ps_mb_info->u2_mb_type == PSKIP) ||
+ (ps_proc->ps_mb_info->u2_mb_type == BSKIP))
+ {
+ for(i = 0; i < NUM_SP_COMPONENTS; i++)
+ {
+ buffer_container_t *ps_comp_buf;
+
+ WORD16 *pi2_res;
+
+ UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
+
+ ps_comp_buf = &ps_residual_buf->as_component_bufs[u1_is_chroma ? UV : Y];
+ pi2_res =
+ ((WORD16 *) ps_comp_buf->pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * (MB_SIZE >> u1_is_chroma) * ps_comp_buf->i4_data_stride;
+
+ ps_mem_fxns->pf_memset_2d(
+ (UWORD8 *) pi2_res,
+ ps_comp_buf->i4_data_stride * (sizeof(WORD16) / sizeof(UWORD8)), 0,
+ MB_SIZE * (sizeof(WORD16) / sizeof(UWORD8)), MB_SIZE >> u1_is_chroma);
+ }
+ }
+ }
+
+ if(ENABLE_RESIDUAL_PREDICTION && (u1_spatial_layer_id > 0) &&
+ !(ps_proc->ps_mb_info->u1_is_intra || (ps_proc->ps_mb_info->u2_mb_type == PSKIP) ||
+ (ps_proc->ps_mb_info->u2_mb_type == BSKIP)))
+ {
+ s_src = ps_residual_buf->as_component_bufs[Y];
+ s_src.pv_data = ((WORD16 *) s_src.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
+ ps_proc->i4_mb_y * MB_SIZE * s_src.i4_data_stride;
+
+ ps_proc->ps_mb_info->u4_res_csbp = isvce_get_residual_csbf(ps_mem_fxns, &s_src);
+ }
+ else
+ {
+ ps_proc->ps_mb_info->u4_res_csbp = 0;
+ }
+ }
+ else
+ {
+ ps_proc->ps_mb_info->u4_res_csbp = 0;
+ }
+}
+
+/*
+ * Padding has a one MB row dependency on deblock which
+ * in turn has a one MB row dependency on encode
+ */
+static IH264E_ERROR_T isvce_pad_frame(isvce_process_ctxt_t *ps_proc, yuv_buf_props_t *ps_pad_buf)
+{
+ /* codec context */
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ WORD32 i4_element_size = (ps_pad_buf->u1_bit_depth > 8) ? 2 : 1;
+
+ /* src buffers luma */
+ WORD32 i4_luma_stride = ps_pad_buf->as_component_bufs[0].i4_data_stride * i4_element_size;
+ UWORD8 *pu1_curr_pic_luma = (UWORD8 *) (ps_pad_buf->as_component_bufs[0].pv_data);
+
+ /* src buffers chroma */
+ WORD32 i4_chroma_stride = ps_pad_buf->as_component_bufs[1].i4_data_stride * i4_element_size;
+ UWORD8 *pu1_curr_pic_chroma = (UWORD8 *) (ps_pad_buf->as_component_bufs[1].pv_data);
+
+ WORD32 i4_bottom_offset_luma = ps_pad_buf->u4_height * i4_luma_stride;
+ WORD32 i4_bottom_offset_chroma = (ps_pad_buf->u4_height >> 1) * i4_chroma_stride;
+
+ /* Pad left */
+ ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_luma_stride, ps_pad_buf->u4_height,
+ PAD_LEFT * i4_element_size);
+ ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_chroma_stride, ps_pad_buf->u4_height >> 1,
+ PAD_LEFT * i4_element_size);
+
+ /* Pad right */
+ ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + ps_pad_buf->u4_width * i4_element_size,
+ i4_luma_stride, ps_pad_buf->u4_height, PAD_RIGHT * i4_element_size);
+ ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + ps_pad_buf->u4_width * i4_element_size,
+ i4_chroma_stride, ps_pad_buf->u4_height >> 1,
+ PAD_RIGHT * i4_element_size);
+
+ /* Pad top */
+ ps_codec->pf_pad_top(pu1_curr_pic_luma - (PAD_LEFT * i4_element_size), i4_luma_stride,
+ (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_TOP);
+ ps_codec->pf_pad_top(pu1_curr_pic_chroma - (PAD_LEFT * i4_element_size), i4_chroma_stride,
+ (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_TOP >> 1);
+
+ /* Pad bottom */
+ ps_codec->pf_pad_bottom(
+ pu1_curr_pic_luma + i4_bottom_offset_luma - (PAD_LEFT * i4_element_size), i4_luma_stride,
+ (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_BOT);
+ ps_codec->pf_pad_bottom(
+ pu1_curr_pic_chroma + i4_bottom_offset_chroma - (PAD_LEFT * i4_element_size),
+ i4_chroma_stride, (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_BOT >> 1);
+
+ return IH264E_SUCCESS;
+}
+
+void isvce_svc_pad_frame(isvce_process_ctxt_t *ps_proc)
+{
+ isvce_codec_t *ps_codec = ps_proc->ps_codec;
+
+ isvce_pad_frame(ps_proc, &(ps_proc->s_rec_pic_buf_props));
+
+ if(ps_proc->s_svc_params.u1_num_spatial_layers > 1)
+ {
+ isvce_pad_frame(
+ ps_proc, &(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id]));
+ isvce_pad_frame(ps_proc,
+ &(ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]));
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Initialize AIR mb frame Map
+*
+* @par Description:
+* Initialize AIR mb frame map
+* MB frame map indicates which frame an Mb should be coded as intra according
+*to AIR
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @returns error_status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_init_air_map(isvce_codec_t *ps_codec)
+{
+ /* intra refresh map */
+ UWORD16 *pu2_intr_rfrsh_map = ps_codec->pu2_intr_rfrsh_map;
+
+ /* air mode */
+ IVE_AIR_MODE_T air_mode = ps_codec->s_cfg.e_air_mode;
+
+ /* refresh period */
+ UWORD32 air_period = ps_codec->s_cfg.u4_air_refresh_period;
+
+ /* mb cnt */
+ UWORD32 u4_mb_cnt = ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs;
+
+ /* temp var */
+ UWORD32 curr_mb, seed_rand = 1;
+
+ switch(air_mode)
+ {
+ case IVE_AIR_MODE_CYCLIC:
+
+ for(curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
+ {
+ pu2_intr_rfrsh_map[curr_mb] = curr_mb % air_period;
+ }
+ break;
+
+ case IVE_AIR_MODE_RANDOM:
+
+ for(curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
+ {
+ seed_rand = (seed_rand * 32719 + 3) % 32749;
+ pu2_intr_rfrsh_map[curr_mb] = seed_rand % air_period;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ return IH264E_SUCCESS;
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* derivation process for macroblock availability
+*
+* @par Description
+* Calculates the availability of the left, top, topright and topleft macroblocks.
+*
+* @param[in] ps_proc_ctxt
+* pointer to proc context (handle)
+*
+* @remarks Based on section 6.4.5 in H264 spec
+*
+* @return none
+*
+******************************************************************************
+*/
+void isvce_derive_nghbr_avbl_of_mbs(isvce_process_ctxt_t *ps_proc)
+{
+ UWORD8 *pu1_slice_idx_curr = ps_proc->pu1_slice_idx;
+ UWORD8 *pu1_slice_idx_b;
+ UWORD8 *pu1_slice_idx_a;
+ UWORD8 *pu1_slice_idx_c;
+ UWORD8 *pu1_slice_idx_d;
+ block_neighbors_t *ps_ngbr_avbl;
+ WORD32 i4_mb_x, i4_mb_y;
+ WORD32 i4_wd_mbs;
+
+ i4_mb_x = ps_proc->i4_mb_x;
+ i4_mb_y = ps_proc->i4_mb_y;
+
+ i4_wd_mbs = ps_proc->i4_wd_mbs;
+
+ pu1_slice_idx_curr += (i4_mb_y * i4_wd_mbs) + i4_mb_x;
+ pu1_slice_idx_a = pu1_slice_idx_curr - 1;
+ pu1_slice_idx_b = pu1_slice_idx_curr - i4_wd_mbs;
+ pu1_slice_idx_c = pu1_slice_idx_b + 1;
+ pu1_slice_idx_d = pu1_slice_idx_b - 1;
+ ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
+
+ /**********************************************************************/
+ /* The macroblock is marked as available, unless one of the following */
+ /* conditions is true in which case the macroblock shall be marked as */
+ /* not available. */
+ /* 1. mbAddr < 0 */
+ /* 2 mbAddr > CurrMbAddr */
+ /* 3. the macroblock with address mbAddr belongs to a different slice */
+ /* than the macroblock with address CurrMbAddr */
+ /**********************************************************************/
+
+ /* left macroblock availability */
+ if(i4_mb_x == 0)
+ { /* macroblocks along first column */
+ ps_ngbr_avbl->u1_mb_a = 0;
+ }
+ else
+ { /* macroblocks belong to same slice? */
+ if(*pu1_slice_idx_a != *pu1_slice_idx_curr)
+ ps_ngbr_avbl->u1_mb_a = 0;
+ else
+ ps_ngbr_avbl->u1_mb_a = 1;
+ }
+
+ /* top macroblock availability */
+ if(i4_mb_y == 0)
+ { /* macroblocks along first row */
+ ps_ngbr_avbl->u1_mb_b = 0;
+ }
+ else
+ { /* macroblocks belong to same slice? */
+ if(*pu1_slice_idx_b != *pu1_slice_idx_curr)
+ ps_ngbr_avbl->u1_mb_b = 0;
+ else
+ ps_ngbr_avbl->u1_mb_b = 1;
+ }
+
+ /* top right macroblock availability */
+ if(i4_mb_x == i4_wd_mbs - 1 || i4_mb_y == 0)
+ { /* macroblocks along last column */
+ ps_ngbr_avbl->u1_mb_c = 0;
+ }
+ else
+ { /* macroblocks belong to same slice? */
+ if(*pu1_slice_idx_c != *pu1_slice_idx_curr)
+ ps_ngbr_avbl->u1_mb_c = 0;
+ else
+ ps_ngbr_avbl->u1_mb_c = 1;
+ }
+
+ /* top left macroblock availability */
+ if(i4_mb_x == 0 || i4_mb_y == 0)
+ { /* macroblocks along first column */
+ ps_ngbr_avbl->u1_mb_d = 0;
+ }
+ else
+ { /* macroblocks belong to same slice? */
+ if(*pu1_slice_idx_d != *pu1_slice_idx_curr)
+ ps_ngbr_avbl->u1_mb_d = 0;
+ else
+ ps_ngbr_avbl->u1_mb_d = 1;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief
+* Codec level initializations
+*
+* @par Description:
+* Initializes the codec with parameters that needs to be set before encoding
+* first frame
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_inp_buf
+* Pointer to input buffer context
+*
+* @returns error_status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_codec_init(isvce_codec_t *ps_codec)
+{
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ WORD8 i;
+
+ /********************************************************************
+ * INITIALIZE CODEC CONTEXT *
+ ********************************************************************/
+ /* encoder presets */
+ if(ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG)
+ {
+ if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
+ { /* high quality */
+ /* enable diamond search */
+ ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
+ ps_codec->s_cfg.u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
+ if(!FORCE_FAST_INTRA4X4)
+ {
+ ps_enc_loop_fxns->apf_luma_energy_compaction[1] =
+ isvce_code_luma_intra_macroblock_4x4_rdopt_on;
+ }
+
+ /* sub pel off */
+ ps_codec->s_cfg.u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_NORMAL)
+ { /* normal */
+ /* enable diamond search */
+ ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
+ ps_codec->s_cfg.u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
+
+ /* sub pel off */
+ ps_codec->s_cfg.u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST)
+ { /* normal */
+ /* enable diamond search */
+ ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
+ ps_codec->s_cfg.u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_codec->s_cfg.u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 1;
+ }
+ else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_HIGH_SPEED)
+ { /* fast */
+ /* enable diamond search */
+ ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
+ ps_codec->s_cfg.u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_codec->s_cfg.u4_enable_hpel = 0;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
+ { /* fastest */
+ /* enable diamond search */
+ ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
+
+ /* disable intra 4x4 */
+ ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_codec->s_cfg.u4_enable_hpel = 0;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 1;
+ }
+ }
+
+ /*****************************************************************
+ * Initialize AIR inside codec
+ *****************************************************************/
+ if(IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
+ {
+ isvce_init_air_map(ps_codec);
+
+ ps_codec->i4_air_pic_cnt = -1;
+ }
+
+ /****************************************************/
+ /* INITIALIZE RATE CONTROL */
+ /****************************************************/
+ {
+ for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
+ {
+ UWORD8 au1_init_qp[MAX_PIC_TYPE];
+ UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
+ UWORD8 au1_min_max_avc_qp[2 * MAX_PIC_TYPE];
+
+ /* update rc lib with modified qp */
+ au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp[i]];
+ au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp[i]];
+ au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp[i]];
+
+ au1_min_max_qp[2 * I_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_min[i]];
+ au1_min_max_qp[2 * I_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_max[i]];
+
+ au1_min_max_qp[2 * P_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_min[i]];
+ au1_min_max_qp[2 * P_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_max[i]];
+
+ au1_min_max_qp[2 * B_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_min[i]];
+ au1_min_max_qp[2 * B_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_max[i]];
+
+ /* get rc mode */
+ switch(ps_codec->s_cfg.e_rc_mode)
+ {
+ case IVE_RC_STORAGE:
+ ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
+ break;
+ case IVE_RC_CBR_NON_LOW_DELAY:
+ ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
+ break;
+ case IVE_RC_CBR_LOW_DELAY:
+ ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
+ break;
+ case IVE_RC_NONE:
+ ps_codec->s_rate_control.e_rc_type = CONST_QP;
+ break;
+ default:
+ break;
+ }
+
+ ps_codec->u1_enable_init_qp = DEFAULT_INIT_QP;
+
+ /* init rate control */
+ isvce_rc_init(
+ ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_codec->s_rate_control.pps_frame_time, ps_codec->s_rate_control.pps_time_stamp,
+ ps_codec->s_rate_control.pps_pd_frm_rate, ps_codec->s_cfg.u4_max_framerate,
+ ps_codec->s_cfg.u4_src_frame_rate, ps_codec->s_cfg.u4_tgt_frame_rate,
+ ps_codec->s_rate_control.e_rc_type, ps_codec->s_cfg.au4_target_bitrate[i],
+ ps_codec->s_cfg.au4_max_bitrate[i], ps_codec->s_cfg.au4_vbv_buffer_delay[i],
+ ps_codec->s_cfg.u4_i_frm_interval, ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
+ ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp,
+ MAX(ps_codec->s_cfg.u4_max_level,
+ (UWORD32) ih264e_get_min_level(ps_codec->s_cfg.u4_max_wd,
+ ps_codec->s_cfg.u4_max_ht)));
+
+ au1_min_max_avc_qp[2 * I_PIC] = ps_codec->s_cfg.au4_i_qp_min[i];
+ au1_min_max_avc_qp[2 * I_PIC + 1] = ps_codec->s_cfg.au4_i_qp_max[i];
+
+ au1_min_max_avc_qp[2 * P_PIC] = ps_codec->s_cfg.au4_p_qp_min[i];
+ au1_min_max_avc_qp[2 * P_PIC + 1] = ps_codec->s_cfg.au4_p_qp_max[i];
+
+ au1_min_max_avc_qp[2 * B_PIC] = ps_codec->s_cfg.au4_b_qp_min[i];
+ au1_min_max_avc_qp[2 * B_PIC + 1] = ps_codec->s_cfg.au4_b_qp_max[i];
+
+ irc_change_qp_constraints(ps_codec->s_rate_control.apps_rate_control_api[i],
+ au1_min_max_qp, au1_min_max_avc_qp);
+ }
+ }
+
+ /* recon stride */
+ ps_codec->i4_rec_strd = ALIGN16(ps_codec->s_cfg.u4_max_wd) + PAD_WD;
+
+ /* max ref and reorder cnt */
+ ps_codec->i4_ref_buf_cnt = ps_codec->s_cfg.u4_max_ref_cnt + ps_codec->s_cfg.u4_max_reorder_cnt;
+ ps_codec->i4_ref_buf_cnt += MAX_CTXT_SETS;
+ ps_codec->i4_ref_buf_cnt += ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers;
+
+ DEBUG_HISTOGRAM_INIT();
+
+ /* Init dependecy vars */
+ ps_codec->i4_last_inp_buff_received = 0;
+
+ /* At codec start no IDR is pending */
+ ps_codec->i4_pending_idr_flag = 0;
+
+ for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1; i++)
+ {
+ ps_codec->au4_constrained_intra_pred[i] = 1;
+ }
+
+ ps_codec->au4_constrained_intra_pred[ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1] =
+ 0;
+
+ return IH264E_SUCCESS;
+}
+
+/**
+*******************************************************************************
+*
+* @brief update encoder configuration parameters
+*
+* @par Description:
+* updates encoder configuration parameters from the given config set.
+* Initialize/reinitialize codec parameters according to new configurations.
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @param[in] ps_cfg
+* Pointer to config param set
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IH264E_ERROR_T isvce_codec_update_config(isvce_codec_t *ps_codec, isvce_cfg_params_t *ps_cfg)
+{
+ /* config params */
+ isvce_cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
+
+ /* error status */
+ IH264E_ERROR_T err = IH264E_SUCCESS;
+
+ /* temp var */
+ UWORD32 u4_init_rc = 0;
+
+ WORD8 i;
+
+ /***********************/
+ /* UPDATE CODEC CONFIG */
+ /***********************/
+ if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_DIMENSIONS)
+ {
+ UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd);
+ UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht);
+
+ if(ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln ||
+ ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd ||
+ ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht)
+ {
+ ps_curr_cfg->u4_wd = wd_aln;
+ ps_curr_cfg->u4_ht = ht_aln;
+
+ ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd;
+ ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht;
+
+ ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4;
+ ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4;
+
+ ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD;
+
+ /* If number of MBs in a frame changes the air map also changes.
+ * Hence recompute air map also reset air pic cnt */
+ if(ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE)
+ {
+ /* re-init the air map */
+ isvce_init_air_map(ps_codec);
+
+ /* reset air counter */
+ ps_codec->i4_air_pic_cnt = -1;
+ }
+
+ /* initialize mv bank buffer manager */
+ err = isvce_svc_au_data_mgr_add_bufs(ps_codec);
+ if(err != IH264E_SUCCESS) return err;
+
+ /* initialize ref bank buffer manager */
+ err = isvce_svc_au_buf_mgr_add_bufs(ps_codec);
+ if(err != IH264E_SUCCESS) return err;
+
+ /* since dimension changed, start new sequence by forcing IDR */
+ ps_codec->force_curr_frame_type = IV_IDR_FRAME;
+
+ /* in case dimension changes, we need to reinitialize RC as the
+ * old model shall not fit further */
+ u4_init_rc = 1;
+
+ /* when the dimension changes, the header needs to be regenerated */
+ ps_codec->i4_gen_header = 1;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_FRAMERATE)
+ {
+ /* temp var */
+ UWORD32 u4_src_ticks, u4_tgt_ticks;
+
+ u4_src_ticks = ih264e_frame_time_get_src_ticks(ps_codec->s_rate_control.pps_frame_time);
+
+ u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(ps_codec->s_rate_control.pps_frame_time);
+
+ /* Change frame rate */
+ if(ps_codec->s_cfg.u4_src_frame_rate != ps_cfg->u4_src_frame_rate * 1000)
+ {
+ ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate * 1000;
+
+ ih264e_frame_time_update_src_frame_rate(ps_codec->s_rate_control.pps_frame_time,
+ ps_codec->s_cfg.u4_src_frame_rate);
+
+ ih264_time_stamp_update_frame_rate(ps_codec->s_rate_control.pps_time_stamp,
+ ps_codec->s_cfg.u4_src_frame_rate);
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ irc_change_frame_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_codec->s_cfg.u4_src_frame_rate, u4_src_ticks,
+ u4_tgt_ticks);
+ }
+ }
+
+ if(ps_codec->s_cfg.u4_tgt_frame_rate != ps_cfg->u4_tgt_frame_rate * 1000)
+ {
+ ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate * 1000;
+
+ ih264e_frame_time_update_tgt_frame_rate(ps_codec->s_rate_control.pps_frame_time,
+ ps_codec->s_cfg.u4_tgt_frame_rate);
+
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ irc_change_frame_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_codec->s_cfg.u4_src_frame_rate, u4_src_ticks,
+ u4_tgt_ticks);
+
+ irc_change_frm_rate_for_bit_alloc(ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_codec->s_cfg.u4_tgt_frame_rate);
+ }
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_BITRATE)
+ {
+ for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
+ {
+ if(ps_curr_cfg->au4_target_bitrate[i] != ps_cfg->au4_target_bitrate[i])
+ {
+ if(IVE_RC_NONE != ps_curr_cfg->e_rc_mode)
+ irc_change_avg_bit_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_cfg->au4_target_bitrate[i]);
+
+ ps_curr_cfg->au4_target_bitrate[i] = ps_cfg->au4_target_bitrate[i];
+ }
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_FRAMETYPE)
+ {
+ switch(ps_cfg->e_frame_type)
+ {
+ case IV_I_FRAME:
+ ps_codec->force_curr_frame_type = IV_I_FRAME;
+ break;
+
+ case IV_IDR_FRAME:
+ ps_codec->force_curr_frame_type = IV_IDR_FRAME;
+ break;
+
+ case IV_P_FRAME:
+ default:
+ break;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_ME_PARAMS)
+ {
+ if(ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
+ {
+ ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel;
+ ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
+ ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset;
+ ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
+ {
+ ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
+ }
+ ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x;
+ ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y;
+
+ if(ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref)
+ {
+ ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref;
+ ps_codec->u4_is_curr_frm_ref = 1;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_IPE_PARAMS)
+ {
+ ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset;
+
+ if(ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST)
+ {
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+
+ /* enable diamond search */
+ ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
+ ps_curr_cfg->u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_curr_cfg->u4_enable_intra_4x4 = 1;
+ ps_enc_loop_fxns->apf_luma_energy_compaction[1] =
+ isvce_code_luma_intra_macroblock_4x4_rdopt_on;
+
+ /* sub pel off */
+ ps_curr_cfg->u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL)
+ { /* normal */
+ /* enable diamond search */
+ ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
+ ps_curr_cfg->u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_curr_cfg->u4_enable_intra_4x4 = 1;
+
+ /* sub pel off */
+ ps_curr_cfg->u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FAST)
+ { /* normal */
+ /* enable diamond search */
+ ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
+ ps_curr_cfg->u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_curr_cfg->u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_curr_cfg->u4_enable_hpel = 1;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 1;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED)
+ { /* fast */
+ /* enable diamond search */
+ ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
+ ps_curr_cfg->u4_enable_fast_sad = 0;
+
+ /* disable intra 4x4 */
+ ps_curr_cfg->u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_curr_cfg->u4_enable_hpel = 0;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 0;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
+ { /* fastest */
+ /* enable diamond search */
+ ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
+ // u4_num_layers = 4;
+
+ /* disable intra 4x4 */
+ ps_curr_cfg->u4_enable_intra_4x4 = 0;
+
+ /* sub pel off */
+ ps_curr_cfg->u4_enable_hpel = 0;
+
+ /* disabled intra inter gating in Inter slices */
+ ps_codec->u4_inter_gate = 1;
+ }
+ else if(ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
+ {
+ ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_GOP_PARAMS)
+ {
+ if(ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval)
+ {
+ ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval;
+
+ /* reset air counter */
+ ps_codec->i4_air_pic_cnt = -1;
+
+ /* re-init air map */
+ isvce_init_air_map(ps_codec);
+
+ /*Effect intra frame interval change*/
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ irc_change_intra_frm_int_call(ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_curr_cfg->u4_i_frm_interval);
+ }
+ }
+
+ ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS)
+ {
+ ps_curr_cfg->u4_disable_deblock_level = ps_cfg->u4_disable_deblock_level;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_QP)
+ {
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ UWORD8 au1_init_qp[MAX_PIC_TYPE];
+ UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
+ UWORD8 au1_min_max_avc_qp[2 * MAX_PIC_TYPE];
+
+ ps_codec->s_cfg.au4_i_qp_max[i] = ps_cfg->au4_i_qp_max[i];
+ ps_codec->s_cfg.au4_i_qp_min[i] = ps_cfg->au4_i_qp_min[i];
+ ps_codec->s_cfg.au4_i_qp[i] = ps_cfg->au4_i_qp[i];
+
+ ps_codec->s_cfg.au4_p_qp_max[i] = ps_cfg->au4_p_qp_max[i];
+ ps_codec->s_cfg.au4_p_qp_min[i] = ps_cfg->au4_p_qp_min[i];
+ ps_codec->s_cfg.au4_p_qp[i] = ps_cfg->au4_p_qp[i];
+
+ ps_codec->s_cfg.au4_b_qp_max[i] = ps_cfg->au4_b_qp_max[i];
+ ps_codec->s_cfg.au4_b_qp_min[i] = ps_cfg->au4_b_qp_min[i];
+ ps_codec->s_cfg.au4_b_qp[i] = ps_cfg->au4_b_qp[i];
+
+ /* update rc lib with modified qp */
+ au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp[i]];
+ au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp[i]];
+ au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp[i]];
+
+ irc_change_init_qp(ps_codec->s_rate_control.apps_rate_control_api[i], au1_init_qp);
+
+ au1_min_max_qp[2 * I_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_min[i]];
+ au1_min_max_qp[2 * I_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_max[i]];
+
+ au1_min_max_qp[2 * P_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_min[i]];
+ au1_min_max_qp[2 * P_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_max[i]];
+
+ au1_min_max_qp[2 * B_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_min[i]];
+ au1_min_max_qp[2 * B_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_max[i]];
+
+ au1_min_max_avc_qp[2 * I_PIC] = ps_codec->s_cfg.au4_i_qp_min[i];
+ au1_min_max_avc_qp[2 * I_PIC + 1] = ps_codec->s_cfg.au4_i_qp_max[i];
+
+ au1_min_max_avc_qp[2 * P_PIC] = ps_codec->s_cfg.au4_p_qp_min[i];
+ au1_min_max_avc_qp[2 * P_PIC + 1] = ps_codec->s_cfg.au4_p_qp_max[i];
+
+ au1_min_max_avc_qp[2 * B_PIC] = ps_codec->s_cfg.au4_b_qp_min[i];
+ au1_min_max_avc_qp[2 * B_PIC + 1] = ps_codec->s_cfg.au4_b_qp_max[i];
+
+ irc_change_qp_constraints(ps_codec->s_rate_control.apps_rate_control_api[i],
+ au1_min_max_qp, au1_min_max_avc_qp);
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_ENC_MODE)
+ {
+ ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode;
+
+ if(ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER)
+ {
+ ps_codec->i4_header_mode = 1;
+ ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE;
+ }
+ else
+ {
+ ps_codec->i4_header_mode = 0;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_VBV_PARAMS &&
+ IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode)
+ {
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ ps_codec->s_cfg.au4_vbv_buffer_delay[i] = ps_cfg->au4_vbv_buffer_delay[i];
+ }
+ // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api,
+ // ps_codec->s_cfg.u4_vbv_buffer_delay);
+
+ // TODO: remove this when the support for changing buffer dynamically
+ // is yet to be added.
+ u4_init_rc = 1;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_AIR_PARAMS)
+ {
+ if(ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode ||
+ ps_curr_cfg->u4_air_refresh_period != ps_cfg->u4_air_refresh_period)
+ {
+ ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode;
+ ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period;
+
+ isvce_init_air_map(ps_codec);
+
+ /* reset air counter */
+ ps_codec->i4_air_pic_cnt = -1;
+ }
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_PROFILE_PARAMS)
+ {
+ ps_codec->s_cfg.e_profile = ps_cfg->e_profile;
+ ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_NUM_CORES)
+ {
+ ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_VUI_PARAMS)
+ {
+ ps_codec->s_cfg.s_vui = ps_cfg->s_vui;
+ }
+
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS)
+ {
+ ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag =
+ ps_cfg->s_sei.u1_sei_mdcv_params_present_flag;
+ ps_codec->s_cfg.s_sei.s_sei_mdcv_params = ps_cfg->s_sei.s_sei_mdcv_params;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS)
+ {
+ ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag =
+ ps_cfg->s_sei.u1_sei_cll_params_present_flag;
+ ps_codec->s_cfg.s_sei.s_sei_cll_params = ps_cfg->s_sei.s_sei_cll_params;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS)
+ {
+ ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag =
+ ps_cfg->s_sei.u1_sei_ave_params_present_flag;
+ ps_codec->s_cfg.s_sei.s_sei_ave_params = ps_cfg->s_sei.s_sei_ave_params;
+ }
+ else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS)
+ {
+ ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag =
+ ps_cfg->s_sei.u1_sei_ccv_params_present_flag;
+ ps_codec->s_cfg.s_sei.s_sei_ccv_params = ps_cfg->s_sei.s_sei_ccv_params;
+ }
+
+ /* reset RC model */
+ if(u4_init_rc)
+ {
+ for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
+ {
+ /* init qp */
+ UWORD8 au1_init_qp[MAX_PIC_TYPE];
+
+ /* min max qp */
+ UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
+
+ /* init i,p,b qp */
+ au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp[i]];
+ au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp[i]];
+ au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp[i]];
+
+ /* init min max qp */
+ au1_min_max_qp[2 * I_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_min[i]];
+ au1_min_max_qp[2 * I_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_max[i]];
+
+ au1_min_max_qp[2 * P_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_min[i]];
+ au1_min_max_qp[2 * P_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_max[i]];
+
+ au1_min_max_qp[2 * B_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_min[i]];
+ au1_min_max_qp[2 * B_PIC + 1] =
+ gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_max[i]];
+
+ /* get rc mode */
+ switch(ps_codec->s_cfg.e_rc_mode)
+ {
+ case IVE_RC_STORAGE:
+ ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
+ break;
+
+ case IVE_RC_CBR_NON_LOW_DELAY:
+ ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
+ break;
+
+ case IVE_RC_CBR_LOW_DELAY:
+ ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
+ break;
+
+ case IVE_RC_NONE:
+ ps_codec->s_rate_control.e_rc_type = CONST_QP;
+ break;
+
+ default:
+ break;
+ }
+
+ /* init rate control */
+ for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
+ {
+ isvce_rc_init(
+ ps_codec->s_rate_control.apps_rate_control_api[i],
+ ps_codec->s_rate_control.pps_frame_time,
+ ps_codec->s_rate_control.pps_time_stamp,
+ ps_codec->s_rate_control.pps_pd_frm_rate, ps_codec->s_cfg.u4_max_framerate,
+ ps_codec->s_cfg.u4_src_frame_rate, ps_codec->s_cfg.u4_tgt_frame_rate,
+ ps_codec->s_rate_control.e_rc_type, ps_codec->s_cfg.au4_target_bitrate[i],
+ ps_codec->s_cfg.au4_max_bitrate[i], ps_codec->s_cfg.au4_vbv_buffer_delay[i],
+ ps_codec->s_cfg.u4_i_frm_interval, ps_codec->s_cfg.u4_num_bframes + 1,
+ au1_init_qp, ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp,
+ ps_codec->s_cfg.u4_max_level);
+ }
+ }
+ }
+
+ return err;
+}
+
+static FORCEINLINE void isvce_change_rc_init_qp(void *pv_rate_control_api, UWORD8 u1_qp)
+{
+ UWORD8 au1_pic_qps[MAX_PIC_TYPE];
+ WORD32 i;
+
+ for(i = 0; i < MAX_PIC_TYPE; i++)
+ {
+ au1_pic_qps[i] = gau1_h264_to_mpeg2_qmap[CLIP3(MIN_H264_QP, MAX_H264_QP, u1_qp + i)];
+ }
+
+ irc_change_init_qp(pv_rate_control_api, au1_pic_qps);
+}
+
+/**
+ *******************************************************************************
+ *
+ * @brief
+ * Queues the current buffer, gets back a another buffer for encoding with
+ *corrent picture type
+ *
+ * @par Description:
+ * This function performs 3 distinct but related functions.
+ * 1) Maintains an input queue [Note the the term queue donot imply a
+ * first-in first-out logic here] that queues input and dequeues them so
+ * that input frames can be encoded at any predetermined encoding order
+ * 2) Uses RC library to decide which frame must be encoded in current pass
+ * and which picture type it must be encoded to.
+ * 3) Uses RC library to decide the QP at which current frame has to be
+ * encoded
+ * 4) Determines if the current picture must be encoded or not based on
+ * PRE-ENC skip
+ *
+ * Input queue is used for storing input buffers till they are used for
+ * encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a
+ * valid input comes, it is added to the end of queue. This same input is
+ * added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any
+ * pic from RC can be located in the input queue easily.
+ *
+ * The dequeue operation does not start till we have
+ *ps_codec->s_cfg.u4_max_num_bframes frames in the queue. THis is done in order
+ *to ensure that once output starts we will have a constant stream of output
+ *with no gaps.
+ *
+ * THe output frame order is governed by RC library. When ever we dequeue a
+ * buffer from RC library, it ensures that we will get them in encoding
+ *order With the output of RC library, we can use the picture id to dequeue the
+ * corresponding buffer from input queue and encode it.
+ *
+ * Condition at the end of stream.
+ * -------------------------------
+ * At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last
+ * to be set. This will the given to lib when appropriate input buffer is
+ * given to encoding.
+ *
+ * Since we have to output is not in sync with input, we will have frames
+ *to encode even after we recive the last vaild input buffer. Hence we have to
+ * make sure that we donot queue any new buffers once we get the flag [It
+ *may mess up GOP ?]. This is acheived by setting
+ *ps_codec->i4_last_inp_buff_received to act as a permenent marker for last
+ *frame recived [This may not be needed, because in our current app, all buffers
+ *after the last are marked as last. But can we rely on that?] . Hence after
+ *this flgag is set no new buffers are queued.
+ *
+ * @param[in] ps_codec
+ * Pointer to codec descriptor
+ *
+ * @param[in] ps_ive_ip
+ * Current input buffer to the encoder
+ *
+ * @param[out] ps_inp
+ * Buffer to be encoded in the current pass
+ *
+ * @returns
+ * Flag indicating if we have a pre-enc skip or not
+ *
+ * @remarks
+ * TODO (bpic)
+ * The check for null ans is last is redudent.
+ * Need to see if we can remove it
+ *
+ *******************************************************************************
+ */
+WORD32 isvce_input_queue_update(isvce_codec_t *ps_codec, ive_video_encode_ip_t *ps_ive_ip,
+ isvce_inp_buf_t *ps_enc_buff, WORD8 i1_layer_id)
+{
+ isvce_inp_buf_t *ps_inp_buf;
+ picture_type_e e_pictype;
+ WORD32 i4_skip;
+ UWORD32 ctxt_sel, u4_pic_id, u4_pic_disp_id;
+ UWORD8 u1_frame_qp = MAX_H264_QP;
+ UWORD32 max_frame_bits = 0x7FFFFFFF;
+
+ WORD32 i;
+
+ /* Mark that the last input frame has been received */
+ if(ps_ive_ip->u4_is_last == 1)
+ {
+ ps_codec->i4_last_inp_buff_received = 1;
+ }
+
+ if(ps_ive_ip->s_inp_buf.apv_bufs[0] == NULL && !ps_codec->i4_last_inp_buff_received)
+ {
+ ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
+ ps_enc_buff->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
+ return 0;
+ }
+
+ /***************************************************************************
+ * Check for pre enc skip
+ * When src and target frame rates donot match, we skip some frames to
+ * maintain the relation ship between them
+ **************************************************************************/
+ {
+ WORD32 skip_src;
+
+ skip_src = isvce_update_rc_framerates(
+ ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
+ ps_codec->s_rate_control.pps_pd_frm_rate, ps_codec->s_rate_control.pps_time_stamp,
+ ps_codec->s_rate_control.pps_frame_time);
+
+ if(skip_src)
+ {
+ ps_enc_buff->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
+ return 1;
+ }
+ }
+
+ /***************************************************************************
+ *Queue the input to the queue
+ **************************************************************************/
+ ps_inp_buf = &(ps_codec->as_inp_list[ps_codec->i4_pic_cnt % SVC_MAX_NUM_INP_FRAMES]);
+
+ /* copy input info. to internal structure */
+ ps_inp_buf->s_inp_props.s_raw_buf = ps_ive_ip->s_inp_buf;
+ ps_inp_buf->s_inp_props.u4_timestamp_low = ps_ive_ip->u4_timestamp_low;
+ ps_inp_buf->s_inp_props.u4_timestamp_high = ps_ive_ip->u4_timestamp_high;
+ ps_inp_buf->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
+ ps_inp_buf->s_inp_props.pv_mb_info = ps_ive_ip->pv_mb_info;
+ ps_inp_buf->s_inp_props.u4_mb_info_type = ps_ive_ip->u4_mb_info_type;
+ ps_inp_buf->s_inp_props.pv_pic_info = ps_ive_ip->pv_pic_info;
+ ps_inp_buf->s_inp_props.u4_pic_info_type = ps_ive_ip->u4_pic_info_type;
+
+ ps_inp_buf->s_inp_props.u1_sei_ccv_params_present_flag =
+ ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag;
+ ps_inp_buf->s_inp_props.s_sei_ccv = ps_codec->s_cfg.s_sei.s_sei_ccv_params;
+
+ if(ps_inp_buf->s_inp_props.s_raw_buf.apv_bufs[0])
+ isvce_svc_inp_buf_populate(ps_codec, ps_inp_buf);
+
+ /***************************************************************************
+ * Now we should add the picture to RC stack here
+ **************************************************************************/
+ /*
+ * If an I frame has been requested, ask RC to force it
+ * For IDR requests, we have to ask RC to force I and set IDR by our selves
+ * since RC Donot know about IDR. For forcing an IDR at dequeue stage we
+ * should record that an IDR has been requested some where. Hence we will
+ * store it in the u4_idr_inp_list at a position same as that of input frame
+ */
+ {
+ WORD32 i4_force_idr, i4_force_i;
+
+ i4_force_idr = (ps_codec->force_curr_frame_type == IV_IDR_FRAME);
+ i4_force_idr |= !(ps_codec->i4_pic_cnt % ps_codec->s_cfg.u4_idr_frm_interval);
+
+ i4_force_i = (ps_codec->force_curr_frame_type == IV_I_FRAME);
+
+ ps_codec->i4_pending_idr_flag |= i4_force_idr;
+
+ if((ps_codec->i4_pic_cnt > 0) && (i4_force_idr || i4_force_i))
+ {
+ irc_force_I_frame(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id]);
+ }
+
+ if(i1_layer_id == (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
+ {
+ ps_codec->force_curr_frame_type = IV_NA_FRAME;
+ }
+ }
+
+ irc_add_picture_to_stack(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
+ ps_codec->i4_pic_cnt);
+
+ /* Delay */
+ if(ps_codec->i4_encode_api_call_cnt < (WORD32) (ps_codec->s_cfg.u4_num_bframes))
+ {
+ ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
+ ps_enc_buff->s_inp_props.u4_is_last = 0;
+ return 0;
+ }
+
+ /***************************************************************************
+ * Get a new pic to encode
+ **************************************************************************/
+ /* Query the picture_type */
+ e_pictype =
+ isvce_rc_get_picture_details(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
+ (WORD32 *) (&u4_pic_id), (WORD32 *) (&u4_pic_disp_id));
+
+ switch(e_pictype)
+ {
+ case I_PIC:
+ ps_codec->pic_type = PIC_I;
+ break;
+ case P_PIC:
+ ps_codec->pic_type = PIC_P;
+ break;
+ case B_PIC:
+ ps_codec->pic_type = PIC_B;
+ break;
+ default:
+ ps_codec->pic_type = PIC_NA;
+ ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
+ return 0;
+ }
+
+ /* Set IDR if it has been requested */
+ if(ps_codec->pic_type == PIC_I)
+ {
+ ps_codec->pic_type = ps_codec->i4_pending_idr_flag ? PIC_IDR : ps_codec->pic_type;
+ ps_codec->i4_pending_idr_flag = 0;
+ }
+
+ if(ps_codec->s_rate_control.e_rc_type != CONST_QP && ps_codec->u1_enable_init_qp &&
+ (u4_pic_id == 0 ||
+ irc_is_scenecut(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id])))
+ {
+ DOUBLE d_bpp;
+
+ svc_rc_utils_ctxt_t *ps_svc_rc_utils = &ps_codec->s_rate_control.s_rc_utils;
+
+ UWORD32 u4_src_fps = ps_codec->s_cfg.u4_src_frame_rate / 1000;
+ UWORD32 u4_wd = ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id].u4_width;
+ UWORD32 u4_ht = ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id].u4_height;
+ DOUBLE d_gpp =
+ isvce_compute_gpp(ps_svc_rc_utils, &ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id]);
+
+ d_bpp = ((DOUBLE) irc_get_vbv_buf_size(
+ ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id]) /
+ 10.) /
+ ((DOUBLE) (u4_src_fps * u4_wd * u4_ht));
+
+ u1_frame_qp = (UWORD8) irc_get_frame_level_init_qp(
+ ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
+ ps_codec->s_rate_control.e_rc_type, e_pictype, d_bpp, d_gpp);
+
+ isvce_change_rc_init_qp(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
+ u1_frame_qp);
+
+ ps_codec->au4_frame_qp[i1_layer_id] = u1_frame_qp;
+ }
+ else
+ {
+ /* Get current frame Qp */
+ u1_frame_qp = (UWORD8) irc_get_frame_level_qp(
+ ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id], e_pictype, max_frame_bits);
+ ps_codec->au4_frame_qp[i1_layer_id] = gau1_mpeg2_to_h264_qmap[u1_frame_qp];
+ }
+
+ /*
+ * copy the pic id to poc because the display order is assumed to be same
+ * as input order
+ */
+ ps_codec->i4_poc = u4_pic_id;
+
+ /***************************************************************************
+ * Now retrieve the correct picture from the queue
+ **************************************************************************/
+
+ /* Mark the skip flag */
+ i4_skip = 0;
+ ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
+ ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = i4_skip;
+
+ /* Get a buffer to encode */
+ ps_inp_buf = &(ps_codec->as_inp_list[u4_pic_id % SVC_MAX_NUM_INP_FRAMES]);
+
+ /* copy dequeued input to output */
+ ps_enc_buff[0] = ps_inp_buf[0];
+
+ /* Special case for encoding trailing B frames
+ *
+ * In encoding streams with B frames it may happen that we have a B frame
+ * at the end without a P/I frame after it. Hence when we are dequeing from
+ * the RC, it will return the P frame [next in display order but before in
+ * encoding order] first. Since the dequeue happens for an invalid frame we
+ * will get a frame with null buff and set u4_is_last. Hence lib with return
+ * last frame flag at this point and will stop encoding.
+ *
+ * Since for the last B frame, we does not have the forward ref frame
+ * it makes sense to force it into P.
+ *
+ * To solve this, in case the current frame is P and if the last frame flag
+ * is set, we need to see if there is and pending B frames. If there are any,
+ * we should just encode that picture as the current P frame and set
+ * that B frame as the last frame. Hence the encoder will terminate naturally
+ * once that B-frame is encoded after all the in between frames.
+ *
+ * Since we cannot touch RC stack directly, the option of actually swapping
+ * frames in RC is ruled out. We have to modify the as_inp_list to simulate
+ * such a behavior by RC. We can do that by
+ * 1) Search through as_inp_list to locate the largest u4_timestamp_low less
+ * than current u4_timestamp_low. This will give us the last B frame
+ * before the current P frame. Note that this will handle pre encode skip too
+ * since queue happens after pre enc skip. 2) Swap the position in
+ * as_inp_list. Hence now the last B frame is encoded as P frame. And the new
+ * last B frame will have u4_is_last set so that encoder will end naturally
+ * once we reached that B frame or any subsequent frame. Also the current GOP
+ * will have 1 less B frame Since we are swapping, the poc will also be
+ * in-order. 3) In case we have an IPP stream, the result of our search will
+ * be an I/P frame which is already encoded. Thus swap and encode will result
+ * in encoding of duplicate frames. Hence to avoid this we will only
+ * have this work around in case of u4_num_bframes > 0.
+ *
+ * In case we have forced an I/IDR frame In between this P frame and
+ * the last B frame -> This cannot happen as the current P frame is
+ * supposed to have u4_is_last set. Thus forcing an I/ IDR after this
+ * is illogical.
+ *
+ * In cae if we have forced an I such that the frame just before last
+ * frame in is I/P -> This case will never arise. Since we have a closed GOP
+ * now, once we force an I, the gop gets reset, hence there will be a B
+ * between I/P and I/P.
+ */
+ if(ps_enc_buff->s_inp_props.u4_is_last && (ps_codec->pic_type == PIC_P) &&
+ ps_codec->s_cfg.u4_num_bframes)
+ {
+ WORD32 cntr;
+ WORD32 lst_bframe = -1;
+ UWORD32 u4_timestamp_low = 0;
+ UWORD32 u4_timestamp_high = 0;
+ isvce_inp_buf_t *ps_swap_buff, *ps_inp_list;
+
+ ps_inp_list = &ps_codec->as_inp_list[0];
+
+ /* Now search the inp list for highest timestamp */
+ for(cntr = 0; cntr < SVC_MAX_NUM_INP_FRAMES; cntr++)
+ {
+ if(ps_inp_list[cntr].s_inp_props.s_raw_buf.apv_bufs[0] != NULL)
+ {
+ if((ps_inp_list[cntr].s_inp_props.u4_timestamp_high > u4_timestamp_high) ||
+ (ps_inp_list[cntr].s_inp_props.u4_timestamp_high == u4_timestamp_high &&
+ ps_inp_list[cntr].s_inp_props.u4_timestamp_low > u4_timestamp_low))
+ {
+ u4_timestamp_low = ps_inp_list[cntr].s_inp_props.u4_timestamp_low;
+ u4_timestamp_high = ps_inp_list[cntr].s_inp_props.u4_timestamp_high;
+ lst_bframe = cntr;
+ }
+ }
+ }
+
+ if(lst_bframe != -1)
+ {
+ ps_swap_buff = &(ps_codec->as_inp_list[lst_bframe]);
+
+ /* copy the last B buffer to output */
+ *ps_enc_buff = *ps_swap_buff;
+
+ /* Store the current buf into the queue in place of last B buf */
+ *ps_swap_buff = *ps_inp_buf;
+ }
+ }
+
+ if(ps_enc_buff->s_inp_props.u4_is_last)
+ {
+ ps_codec->pic_type = PIC_NA;
+ }
+
+ /* The buffer in the queue is set to NULL to specify that encoding is done for
+ * that frame */
+ for(i = 0; i < 3; i++)
+ {
+ ps_inp_buf->s_inp_props.s_raw_buf.apv_bufs[i] = NULL;
+ }
+
+ /* Return the buffer status */
+ return (0);
+}
+
+/**
+******************************************************************************
+*
+* @brief
+* This function joins all the spawned threads after successful completion of
+* their tasks
+*
+* @par Description
+*
+* @param[in] ps_codec
+* pointer to codec context
+*
+* @returns none
+*
+******************************************************************************
+*/
+void isvce_join_threads(isvce_codec_t *ps_codec)
+{
+ WORD32 i = 0;
+ WORD32 ret = 0;
+
+ /* join spawned threads */
+ while(i < ps_codec->i4_proc_thread_cnt)
+ {
+ if(ps_codec->ai4_process_thread_created[i])
+ {
+ ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL);
+
+ if(ret != 0)
+ {
+ ASSERT(0);
+ }
+
+ ps_codec->ai4_process_thread_created[i] = 0;
+ i++;
+ }
+ }
+
+ ps_codec->i4_proc_thread_cnt = 0;
+}
+
+UWORD32 isvce_get_min_outbuf_size(UWORD32 u4_wd, UWORD32 u4_ht, UWORD8 u1_num_spatial_layers)
+{
+ return MAX((u4_wd * u4_ht * 3), MIN_STREAM_SIZE) * u1_num_spatial_layers;
+} \ No newline at end of file
diff --git a/encoder/svc/isvce_utils.h b/encoder/svc/isvce_utils.h
new file mode 100644
index 0000000..a6dc9de
--- /dev/null
+++ b/encoder/svc/isvce_utils.h
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_utils.h
+*
+* @brief
+* Contains function declarations for function declared in ih264e_svc_utils.c
+*
+* @author
+* ittiam
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#ifndef _ISVCE_UTILS_H_
+#define _ISVCE_UTILS_H_
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "ih264_typedefs.h"
+#include "ih264e_bitstream.h"
+#include "isvc_macros.h"
+#include "isvc_structs.h"
+#include "isvce_defs.h"
+#include "isvce_globals.h"
+#include "isvce_interface_structs.h"
+#include "isvce_structs.h"
+
+static FORCEINLINE void isvce_svc_au_buf_init(svc_au_buf_t *ps_svc_pic_buf,
+ svc_params_t *ps_svc_params)
+{
+ ps_svc_pic_buf->i1_temporal_id = -1;
+ ps_svc_pic_buf->u1_num_spatial_layers = ps_svc_params->u1_num_spatial_layers;
+ ps_svc_pic_buf->d_spatial_res_ratio = ps_svc_params->d_spatial_res_ratio;
+}
+
+static FORCEINLINE WORD8 isvce_svc_temporal_id_compute(WORD32 i4_poc, UWORD8 u1_num_temporal_layers,
+ PIC_TYPE_T e_pic_type)
+{
+ if(e_pic_type == PIC_IDR)
+ {
+ return 0;
+ }
+ else
+ {
+ return i4_poc % u1_num_temporal_layers;
+ }
+}
+
+static FORCEINLINE WORD32 isvcd_get_ceil_log2(WORD32 i4_input)
+{
+ WORD32 i4_bits = 0;
+
+ /* check for negative number */
+ ASSERT(i4_input >= 0);
+
+ i4_input--;
+
+ while(i4_input > 0)
+ {
+ i4_bits++;
+ i4_input >>= 1;
+ }
+
+ return (i4_bits);
+}
+/**
+*******************************************************************************
+*
+* @brief calculate coded subblock pattern from nnz
+*
+* @par Description:
+* calculate coded subblock pattern from nnz
+*
+* @param[in] ps_proc
+* process context
+*
+* @returns csbp
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+static FORCEINLINE UWORD32 isvce_calculate_csbp(isvce_process_ctxt_t *ps_proc)
+{
+ WORD32 i;
+
+ UWORD8 *pu1_curr_nnz = ((UWORD8 *) ps_proc->au4_nnz) + 1;
+ UWORD32 u4_csbp = 0;
+
+ for(i = 0; i < 16; i++)
+ {
+ UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[i];
+
+ u4_csbp |= ((!!pu1_curr_nnz[i]) << u1_zscan_idx);
+ }
+
+ return u4_csbp;
+}
+
+static FORCEINLINE UWORD8 isvce_check_identical_mv(isvce_enc_pu_mv_t *ps_mv1,
+ isvce_enc_pu_mv_t *ps_mv2,
+ PRED_MODE_T e_pred_mode)
+{
+ if(e_pred_mode != L0)
+ {
+ if(!((ps_mv1[L1].i1_ref_idx == ps_mv2[L1].i1_ref_idx) &&
+ (ps_mv1[L1].s_mv.i2_mvx == ps_mv2[L1].s_mv.i2_mvx) &&
+ (ps_mv1[L1].s_mv.i2_mvy == ps_mv2[L1].s_mv.i2_mvy)))
+ {
+ return 0;
+ }
+ }
+
+ if(e_pred_mode != L1)
+ {
+ if(!((ps_mv1[L0].i1_ref_idx == ps_mv2[L0].i1_ref_idx) &&
+ (ps_mv1[L0].s_mv.i2_mvx == ps_mv2[L0].s_mv.i2_mvx) &&
+ (ps_mv1[L0].s_mv.i2_mvy == ps_mv2[L0].s_mv.i2_mvy)))
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static FORCEINLINE WORD32 isvce_get_num_bits(bitstrm_t *ps_bitstream)
+{
+ return GET_NUM_BITS(ps_bitstream);
+}
+
+extern WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht);
+
+extern WORD32 isvce_svc_au_props_validate(svc_inp_params_t *ps_svc_inp_params, UWORD32 u4_inp_wd,
+ UWORD32 u4_inp_ht, UWORD32 u4_svc_comp_wd,
+ UWORD32 u4_svc_comp_ht);
+
+extern WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t *ps_cfg);
+
+extern WORD32 isvce_get_total_svc_au_buf_size(svc_inp_params_t *ps_svc_inp_params,
+ WORD32 i4_pic_size, WORD32 i4_level,
+ WORD32 i4_horz_pad, WORD32 i4_vert_pad,
+ WORD32 i4_num_ref_frames,
+ WORD32 i4_num_reorder_frames);
+
+extern UWORD32 isvce_get_total_svc_au_data_size(WORD32 i4_num_luma_samples,
+ UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio);
+
+extern IH264E_ERROR_T isvce_svc_au_data_mgr_add_bufs(isvce_codec_t *ps_codec);
+
+extern IH264E_ERROR_T isvce_svc_au_buf_mgr_add_bufs(isvce_codec_t *ps_codec);
+
+extern UWORD32 isvce_get_svc_inp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht);
+
+extern void isvce_svc_inp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_init_svc_dimension(isvce_inp_buf_t *ps_inp);
+
+extern void isvce_svc_inp_buf_populate(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp);
+
+extern void isvce_get_svc_compliant_dimensions(UWORD8 u1_num_spatial_layers,
+ DOUBLE d_scaling_factor, UWORD32 u4_wd,
+ UWORD32 u4_ht, UWORD32 *pu4_svc_comp_wd,
+ UWORD32 *pu4_svc_comp_ht);
+
+extern UWORD32 isvce_get_svc_nbr_info_buf_size(UWORD8 u1_num_spatial_layers,
+ DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
+ UWORD32 u4_ht);
+
+extern void isvce_svc_nbr_info_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern IH264E_ERROR_T isvce_svc_au_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf);
+
+extern IH264E_ERROR_T isvce_svc_layer_pic_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf,
+ UWORD8 u1_spatial_layer_id);
+
+extern IH264E_ERROR_T isvce_init_layer_proc_ctxt(isvce_process_ctxt_t *ps_proc);
+
+extern UWORD32 isvce_get_svc_ilp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
+ UWORD32 u4_wd, UWORD32 u4_ht);
+
+extern void isvce_svc_ilp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec);
+
+extern void isvce_svc_ilp_buf_update(isvce_process_ctxt_t *ps_proc);
+
+extern void isvce_svc_pad_frame(isvce_process_ctxt_t *ps_proc);
+
+extern IH264E_ERROR_T isvce_init_air_map(isvce_codec_t *ps_codec);
+
+extern void isvce_derive_nghbr_avbl_of_mbs(isvce_process_ctxt_t *ps_proc);
+
+extern void isvce_init_quant_params(isvce_process_ctxt_t *ps_proc, WORD32 qp);
+
+extern IH264E_ERROR_T isvce_codec_init(isvce_codec_t *ps_codec);
+
+extern IH264E_ERROR_T isvce_codec_update_config(isvce_codec_t *ps_codec,
+ isvce_cfg_params_t *ps_cfg);
+
+extern WORD32 isvce_input_queue_update(isvce_codec_t *ps_codec, ive_video_encode_ip_t *ps_ive_ip,
+ isvce_inp_buf_t *ps_enc_buff, WORD8 i1_layer_id);
+
+extern void isvce_join_threads(isvce_codec_t *ps_codec);
+
+extern UWORD32 isvce_get_min_outbuf_size(UWORD32 u4_wd, UWORD32 u4_ht,
+ UWORD8 u1_num_spatial_layers);
+
+#endif
diff --git a/encoder/svc/libsvcenc.cmake b/encoder/svc/libsvcenc.cmake
new file mode 100644
index 0000000..91dda45
--- /dev/null
+++ b/encoder/svc/libsvcenc.cmake
@@ -0,0 +1,127 @@
+list(
+ APPEND
+ LIBSVCENC_SRCS
+ "${AVC_ROOT}/encoder/ih264e_bitstream.c"
+ "${AVC_ROOT}/encoder/ih264e_cabac_init.c"
+ "${AVC_ROOT}/encoder/ih264e_core_coding.c"
+ "${AVC_ROOT}/encoder/ih264e_encode_header.c"
+ "${AVC_ROOT}/encoder/ih264e_fmt_conv.c"
+ "${AVC_ROOT}/encoder/ih264e_globals.c"
+ "${AVC_ROOT}/encoder/ih264e_half_pel.c"
+ "${AVC_ROOT}/encoder/ih264e_intra_modes_eval.c"
+ "${AVC_ROOT}/encoder/ih264e_mc.c"
+ "${AVC_ROOT}/encoder/ih264e_me.c"
+ "${AVC_ROOT}/encoder/ih264e_modify_frm_rate.c"
+ "${AVC_ROOT}/encoder/ih264e_rate_control.c"
+ "${AVC_ROOT}/encoder/ih264e_rc_mem_interface.c"
+ "${AVC_ROOT}/encoder/ih264e_sei.c"
+ "${AVC_ROOT}/encoder/ih264e_time_stamp.c"
+ "${AVC_ROOT}/encoder/ih264e_utils.c"
+ "${AVC_ROOT}/encoder/ih264e_version.c"
+ "${AVC_ROOT}/encoder/ime.c"
+ "${AVC_ROOT}/encoder/ime_distortion_metrics.c"
+ "${AVC_ROOT}/encoder/irc_bit_allocation.c"
+ "${AVC_ROOT}/encoder/irc_cbr_buffer_control.c"
+ "${AVC_ROOT}/encoder/irc_est_sad.c"
+ "${AVC_ROOT}/encoder/irc_fixed_point_error_bits.c"
+ "${AVC_ROOT}/encoder/irc_frame_info_collector.c"
+ "${AVC_ROOT}/encoder/irc_mb_model_based.c"
+ "${AVC_ROOT}/encoder/irc_picture_type.c"
+ "${AVC_ROOT}/encoder/irc_rate_control_api.c"
+ "${AVC_ROOT}/encoder/irc_rd_model.c"
+ "${AVC_ROOT}/encoder/irc_vbr_storage_vbv.c"
+ "${AVC_ROOT}/encoder/irc_vbr_str_prms.c"
+ "${AVC_ROOT}/encoder/svc/irc_svc_rate_control_api.c"
+ "${AVC_ROOT}/encoder/svc/isvce_api.c"
+ "${AVC_ROOT}/encoder/svc/isvce_cabac.c"
+ "${AVC_ROOT}/encoder/svc/isvce_cabac_encode.c"
+ "${AVC_ROOT}/encoder/svc/isvce_cabac_init.c"
+ "${AVC_ROOT}/encoder/svc/isvce_cavlc.c"
+ "${AVC_ROOT}/encoder/svc/isvce_core_coding.c"
+ "${AVC_ROOT}/encoder/svc/isvce_deblk.c"
+ "${AVC_ROOT}/encoder/svc/isvce_downscaler.c"
+ "${AVC_ROOT}/encoder/svc/isvce_encode.c"
+ "${AVC_ROOT}/encoder/svc/isvce_encode_header.c"
+ "${AVC_ROOT}/encoder/svc/isvce_fmt_conv.c"
+ "${AVC_ROOT}/encoder/svc/isvce_function_selector_generic.c"
+ "${AVC_ROOT}/encoder/svc/isvce_globals.c"
+ "${AVC_ROOT}/encoder/svc/isvce_ibl_eval.c"
+ "${AVC_ROOT}/encoder/svc/isvce_ilp_mv.c"
+ "${AVC_ROOT}/encoder/svc/isvce_intra_modes_eval.c"
+ "${AVC_ROOT}/encoder/svc/isvce_mc.c"
+ "${AVC_ROOT}/encoder/svc/isvce_me.c"
+ "${AVC_ROOT}/encoder/svc/isvce_mode_stat_visualiser.c"
+ "${AVC_ROOT}/encoder/svc/isvce_nalu_stat_aggregator.c"
+ "${AVC_ROOT}/encoder/svc/isvce_process.c"
+ "${AVC_ROOT}/encoder/svc/isvce_rate_control.c"
+ "${AVC_ROOT}/encoder/svc/isvce_rc_mem_interface.c"
+ "${AVC_ROOT}/encoder/svc/isvce_rc_utils.c"
+ "${AVC_ROOT}/encoder/svc/isvce_residual_pred.c"
+ "${AVC_ROOT}/encoder/svc/isvce_sub_pic_rc.c"
+ "${AVC_ROOT}/encoder/svc/isvce_utils.c"
+ "${AVC_ROOT}/encoder/psnr.c")
+
+include_directories(${AVC_ROOT}/encoder)
+include_directories(${AVC_ROOT}/encoder/svc)
+
+if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR
+ "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch32")
+ list(
+ APPEND
+ LIBSVCENC_ASMS
+ "${AVC_ROOT}/encoder/arm/svc/isvce_function_selector.c"
+ "${AVC_ROOT}/encoder/arm/svc/isvce_function_selector_a9q.c"
+ "${AVC_ROOT}/encoder/arm/svc/isvce_function_selector_av8.c"
+ "${AVC_ROOT}/encoder/arm/svc/isvce_downscaler_neon.c"
+ "${AVC_ROOT}/encoder/arm/svc/isvce_rc_utils_neon.c"
+ "${AVC_ROOT}/encoder/arm/svc/isvce_residual_pred_neon.c")
+
+ include_directories(${AVC_ROOT}/encoder/arm)
+ include_directories(${AVC_ROOT}/encoder/arm/svc)
+endif()
+
+if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
+ list(
+ APPEND
+ LIBSVCENC_ASMS
+ "${AVC_ROOT}/encoder/armv8/ih264e_evaluate_intra16x16_modes_av8.s"
+ "${AVC_ROOT}/encoder/armv8/ih264e_evaluate_intra_chroma_modes_av8.s"
+ "${AVC_ROOT}/encoder/armv8/ih264e_half_pel_av8.s"
+ "${AVC_ROOT}/encoder/armv8/ime_distortion_metrics_av8.s")
+
+ include_directories(${AVC_ROOT}/encoder/armv8)
+elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch32")
+ list(
+ APPEND
+ LIBSVCENC_ASMS
+ "${AVC_ROOT}/encoder/arm/ih264e_evaluate_intra16x16_modes_a9q.s"
+ "${AVC_ROOT}/encoder/arm/ih264e_evaluate_intra4x4_modes_a9q.s"
+ "${AVC_ROOT}/encoder/arm/ih264e_evaluate_intra_chroma_modes_a9q.s"
+ "${AVC_ROOT}/encoder/arm/ih264e_fmt_conv.s"
+ "${AVC_ROOT}/encoder/arm/ih264e_half_pel.s"
+ "${AVC_ROOT}/encoder/arm/ime_distortion_metrics_a9q.s")
+else()
+ list(
+ APPEND
+ LIBSVCENC_SRCS
+ "${AVC_ROOT}/encoder/x86/ih264e_function_selector.c"
+ "${AVC_ROOT}/encoder/x86/ih264e_function_selector_sse42.c"
+ "${AVC_ROOT}/encoder/x86/ih264e_function_selector_ssse3.c"
+ "${AVC_ROOT}/encoder/x86/ih264e_half_pel_ssse3.c"
+ "${AVC_ROOT}/encoder/x86/ih264e_intra_modes_eval_ssse3.c"
+ "${AVC_ROOT}/encoder/x86/ime_distortion_metrics_sse42.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_downscaler_sse42.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_function_selector.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_function_selector_sse42.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_function_selector_ssse3.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_rc_utils_sse42.c"
+ "${AVC_ROOT}/encoder/x86/svc/isvce_residual_pred_sse42.c")
+
+ include_directories(${AVC_ROOT}/encoder/x86)
+ include_directories(${AVC_ROOT}/encoder/x86/svc)
+endif()
+
+add_library(libsvcenc STATIC ${LIBAVC_COMMON_SRCS} ${LIBAVC_COMMON_ASMS}
+ ${LIBSVCENC_SRCS} ${LIBSVCENC_ASMS})
+
+target_compile_definitions(libsvcenc PRIVATE N_MB_ENABLE)
diff --git a/encoder/x86/svc/isvce_downscaler_sse42.c b/encoder/x86/svc/isvce_downscaler_sse42.c
new file mode 100644
index 0000000..0055590
--- /dev/null
+++ b/encoder/x86/svc/isvce_downscaler_sse42.c
@@ -0,0 +1,652 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file isvce_downscaler_sse42.c
+*
+* @brief
+* This file contains the x86 SIMD version of the function which does
+* horizontal scaling and transpose
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_horizontal_downscale_and_transpose_sse42()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <immintrin.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "isvc_defs.h"
+#include "isvce_defs.h"
+#include "isvc_structs.h"
+#include "isvce_downscaler_private_defs.h"
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+/**
+*******************************************************************************
+*
+* @brief
+* horizontal scaler function
+*
+* @par Description:
+* Does horizontal scaling for the given block
+*
+* @param[in] ps_scaler
+* pointer to downscaler context
+*
+* @param[in] ps_src
+* pointer to source buffer container
+*
+* @param[in] ps_dst
+* pointer to destination buffer container
+*
+* @param[in] pai1_filters
+* pointer to array of downscaler filters
+*
+* @param[in] u4_blk_wd
+* width of the block after horizontal scaling (output block width)
+*
+* @param[in] u4_blk_ht
+* height of the current block (input block height)
+*
+* @param[in] u1_is_chroma
+* flag suggesting whether the buffer is luma or chroma
+*
+*
+* @returns
+*
+* @remarks
+* The same function is used for vertical scaling too as
+* the horizontally scaled input in stored in transpose fashion.
+*
+*******************************************************************************
+*/
+
+void isvce_horizontal_downscale_and_transpose_sse42(
+ downscaler_ctxt_t *ps_scaler, buffer_container_t *ps_src, buffer_container_t *ps_dst,
+ FILTER_COEFF_ARRAY pai1_filters, UWORD32 u4_blk_wd, UWORD32 u4_blk_ht, UWORD8 u1_is_chroma)
+{
+ WORD32 i, j;
+ UWORD8 u1_phase;
+ UWORD8 *pu1_src_j, *pu1_dst_j;
+ WORD32 i4_temp_pixel_holder;
+ UWORD32 u4_num_iterations_vertical_by_16;
+ UWORD32 u4_rem_vert_loop;
+ UWORD8 *pu1_in_pixel;
+ UWORD8 *pu1_out_pixel;
+ WORD8 *pi1_filter_for_grid;
+ UWORD16 u2_full_pixel_inc;
+
+ __m128i src_temp_0, src_temp_1, src_temp_2, src_temp_3, src_temp_4, src_temp_5, src_temp_6,
+ src_temp_7;
+
+ __m128i reg_all_1s, reg_64val_32bit, reg_all_0s, filt_coeff_grid, reg_shuffle;
+
+ __m128i reg_01_16x8b, reg_02_16x8b, reg_03_16x8b, reg_04_16x8b, reg_05_16x8b;
+
+ downscaler_state_t *ps_scaler_state = (downscaler_state_t *) ps_scaler->pv_scaler_state;
+
+ UWORD32 u4_center_pixel_pos = ps_scaler_state->i4_init_offset;
+ UWORD32 u4_src_vert_increments = ps_scaler_state->u4_vert_increment;
+ UWORD32 u4_src_horz_increments = ps_scaler_state->u4_horz_increment;
+
+ UWORD8 *pu1_src = ps_src->pv_data;
+ UWORD32 u4_in_stride = ps_src->i4_data_stride;
+ UWORD8 *pu1_dst = ps_dst->pv_data;
+ UWORD32 u4_out_stride = ps_dst->i4_data_stride;
+ UWORD32 u4_center_pixel_pos_src = u4_center_pixel_pos;
+
+ ASSERT((1 << DOWNSCALER_Q) == u4_src_vert_increments);
+
+ reg_all_1s = _mm_set1_epi16((short) 1);
+ reg_64val_32bit = _mm_set1_epi32((int) 64);
+ reg_all_0s = _mm_setzero_si128();
+ reg_shuffle = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0);
+
+ u4_num_iterations_vertical_by_16 = u4_blk_ht >> 4;
+ u4_rem_vert_loop = u4_blk_ht % 16;
+
+ /* Offset the input so that the input pixel to be processed
+ co-incides with the centre of filter (4th coefficient)*/
+ pu1_src += (1 + u1_is_chroma);
+
+ if(!u1_is_chroma)
+ {
+ for(j = 0; j < (WORD32) u4_num_iterations_vertical_by_16; j++)
+ {
+ pu1_src_j = pu1_src + ((j << 4) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 4);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_for_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ filt_coeff_grid = _mm_loadu_si128((__m128i *) pi1_filter_for_grid);
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ /*For row 0,1*/
+ src_temp_0 = _mm_loadl_epi64((__m128i *) pu1_in_pixel);
+ src_temp_1 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride));
+ /*next transfer the 8 pixels from temp_2 to temp_1 higher bits 64-127*/
+ src_temp_0 = _mm_unpacklo_epi64(src_temp_0, src_temp_1);
+
+ /*For row 2,3*/
+ src_temp_2 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 2));
+
+ src_temp_3 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 3));
+
+ src_temp_2 = _mm_unpacklo_epi64(src_temp_2, src_temp_3);
+
+ reg_01_16x8b = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+
+ /*multiply with filter coeffs to get 16 bit results*/
+ reg_02_16x8b = _mm_maddubs_epi16(src_temp_2, filt_coeff_grid);
+
+ reg_01_16x8b = _mm_hadd_epi16(reg_01_16x8b, reg_02_16x8b);
+ /*add adjacent 16 bit values to get 32 bit values*/
+ reg_01_16x8b = _mm_madd_epi16(reg_01_16x8b, reg_all_1s);
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_01_16x8b = _mm_add_epi32(reg_01_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_01_16x8b = _mm_srli_epi32(reg_01_16x8b, 7);
+
+ /*For row 4,5*/
+ src_temp_4 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 4));
+
+ src_temp_5 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 5));
+
+ src_temp_4 = _mm_unpacklo_epi64(src_temp_4, src_temp_5);
+
+ /*For row 6,7*/
+ src_temp_6 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 6));
+
+ src_temp_7 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 7));
+
+ src_temp_6 = _mm_unpacklo_epi64(src_temp_6, src_temp_7);
+
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_4, filt_coeff_grid);
+
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_6, filt_coeff_grid);
+
+ reg_03_16x8b = _mm_hadd_epi16(reg_03_16x8b, reg_04_16x8b);
+
+ reg_03_16x8b = _mm_madd_epi16(reg_03_16x8b, reg_all_1s);
+
+ /*next add 2 adjacent 32 bit values to get a single 32 bit
+ **value in each row
+ */
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_03_16x8b = _mm_add_epi32(reg_03_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_03_16x8b = _mm_srli_epi32(reg_03_16x8b, 7);
+
+ /*pack the lower 16 bit values corresponding to the 8 output
+ pixels from reg1 and reg 2*/
+ reg_01_16x8b = _mm_packus_epi32(reg_01_16x8b, reg_03_16x8b);
+
+ /*For row 8,9*/
+ src_temp_0 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + 8 * u4_in_stride));
+
+ src_temp_1 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + 9 * u4_in_stride));
+
+ /*next transfer the 8 pixels from temp_2 to temp_1 higher bits 64-127*/
+ src_temp_0 = _mm_unpacklo_epi64(src_temp_0, src_temp_1);
+
+ /*For row 10,11*/
+ src_temp_2 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 10));
+
+ src_temp_3 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 11));
+
+ src_temp_2 = _mm_unpacklo_epi64(src_temp_2, src_temp_3);
+
+ reg_02_16x8b = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+
+ /*multiply with filter coeffs to get 16 bit results*/
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_2, filt_coeff_grid);
+
+ reg_02_16x8b = _mm_hadd_epi16(reg_02_16x8b, reg_03_16x8b);
+ /*add adjacent 16 bit values to get 32 bit values*/
+ reg_02_16x8b = _mm_madd_epi16(reg_02_16x8b, reg_all_1s);
+
+ /*next add 2 adjacent 32 bit values to get a single
+ 32 bit value in each row*/
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_02_16x8b = _mm_add_epi32(reg_02_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_02_16x8b = _mm_srli_epi32(reg_02_16x8b, 7);
+
+ /*For row 12,13*/
+ src_temp_4 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 12));
+
+ src_temp_5 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 13));
+
+ src_temp_4 = _mm_unpacklo_epi64(src_temp_4, src_temp_5);
+
+ /*For row 14,15*/
+ src_temp_6 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 14));
+
+ src_temp_7 = _mm_loadl_epi64((__m128i *) (pu1_in_pixel + u4_in_stride * 15));
+
+ src_temp_6 = _mm_unpacklo_epi64(src_temp_6, src_temp_7);
+
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_4, filt_coeff_grid);
+
+ reg_05_16x8b = _mm_maddubs_epi16(src_temp_6, filt_coeff_grid);
+
+ reg_04_16x8b = _mm_hadd_epi16(reg_04_16x8b, reg_05_16x8b);
+ /*add adjacent 16 bit values to get 32 bit values*/
+ reg_04_16x8b = _mm_madd_epi16(reg_04_16x8b, reg_all_1s);
+
+ /*next add 2 adjacent 32 bit values to get a single
+ 32 bit value in each row*/
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_04_16x8b = _mm_add_epi32(reg_04_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_04_16x8b = _mm_srli_epi32(reg_04_16x8b, 7);
+
+ /*pack the lower 16 bit values corresponding to the 8 output
+ pixels from reg1 and reg 2*/
+ reg_02_16x8b = _mm_packus_epi32(reg_02_16x8b, reg_04_16x8b);
+
+ /*next get saturated 8 bit output pixel values for row 0-15*/
+ reg_01_16x8b = _mm_packus_epi16(reg_01_16x8b, reg_02_16x8b);
+
+ /*Store the 16 output values*/
+ _mm_storeu_si128((__m128i *) pu1_out_pixel, reg_01_16x8b);
+
+ pu1_out_pixel += 16;
+
+ pu1_in_pixel += ((u4_src_vert_increments * (u4_in_stride << 4)) >> DOWNSCALER_Q);
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /*if height is not a multiple of 8 process 2 rows at a
+ time for the remaining rows*/
+ if(u4_rem_vert_loop)
+ {
+ pu1_src_j = pu1_src + ((j << 4) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 4);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_for_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ filt_coeff_grid = _mm_loadu_si128((__m128i *) pi1_filter_for_grid);
+
+ for(j = u4_rem_vert_loop; j > 0; j--)
+ {
+ src_temp_0 = _mm_loadl_epi64((__m128i const *) pu1_in_pixel);
+
+ src_temp_0 = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+
+ src_temp_0 = _mm_madd_epi16(src_temp_0, reg_all_1s);
+
+ reg_01_16x8b = _mm_hadd_epi32(src_temp_0, reg_all_0s);
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_01_16x8b = _mm_add_epi32(reg_01_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_01_16x8b = _mm_srli_epi32(reg_01_16x8b, (int) 7);
+
+ reg_01_16x8b = _mm_packus_epi32(reg_01_16x8b, reg_all_0s);
+
+ /*next get saturated 8 bit output pixel values*/
+ reg_01_16x8b = _mm_packus_epi16(reg_01_16x8b, reg_all_0s);
+
+ /*Store the 1 output value*/
+ *pu1_out_pixel = (UWORD8) _mm_cvtsi128_si32(reg_01_16x8b);
+
+ pu1_in_pixel += (u4_src_vert_increments * u4_in_stride) >> DOWNSCALER_Q;
+
+ pu1_out_pixel++;
+ }
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+
+ else /* for chroma */
+ {
+ for(j = 0; j < (WORD32) u4_num_iterations_vertical_by_16; j++)
+ {
+ pu1_src_j = pu1_src + ((j << 4) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 4);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_for_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ filt_coeff_grid = _mm_loadu_si128((__m128i *) pi1_filter_for_grid);
+ /******************************************************/
+ /* This loop is going vertically in bottom direction */
+ /* but the output pixels are stored in horizontal */
+ /* direction in transpose manner */
+ /******************************************************/
+
+ /*Load 16 values shuffle to separate Cb and Cr and process*/
+
+ src_temp_0 = _mm_loadu_si128((__m128i *) pu1_in_pixel);
+ src_temp_1 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride));
+
+ src_temp_2 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 2));
+
+ src_temp_3 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 3));
+
+ src_temp_0 = _mm_shuffle_epi8(src_temp_0, reg_shuffle);
+ src_temp_1 = _mm_shuffle_epi8(src_temp_1, reg_shuffle);
+ src_temp_2 = _mm_shuffle_epi8(src_temp_2, reg_shuffle);
+ src_temp_3 = _mm_shuffle_epi8(src_temp_3, reg_shuffle);
+
+ reg_01_16x8b = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+ reg_02_16x8b = _mm_maddubs_epi16(src_temp_1, filt_coeff_grid);
+
+ reg_01_16x8b = _mm_hadd_epi16(reg_01_16x8b, reg_02_16x8b);
+
+ reg_01_16x8b = _mm_madd_epi16(reg_01_16x8b, reg_all_1s);
+
+ reg_01_16x8b = _mm_add_epi32(reg_01_16x8b, reg_64val_32bit);
+
+ reg_01_16x8b = _mm_srli_epi32(reg_01_16x8b, (int) 7);
+
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_2, filt_coeff_grid);
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_3, filt_coeff_grid);
+
+ src_temp_4 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 4));
+
+ src_temp_5 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 5));
+
+ src_temp_6 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 6));
+
+ src_temp_7 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 7));
+
+ src_temp_4 = _mm_shuffle_epi8(src_temp_4, reg_shuffle);
+ src_temp_5 = _mm_shuffle_epi8(src_temp_5, reg_shuffle);
+ src_temp_6 = _mm_shuffle_epi8(src_temp_6, reg_shuffle);
+ src_temp_7 = _mm_shuffle_epi8(src_temp_7, reg_shuffle);
+
+ reg_03_16x8b = _mm_hadd_epi16(reg_03_16x8b, reg_04_16x8b);
+
+ reg_03_16x8b = _mm_madd_epi16(reg_03_16x8b, reg_all_1s);
+
+ reg_03_16x8b = _mm_add_epi32(reg_03_16x8b, reg_64val_32bit);
+
+ reg_03_16x8b = _mm_srli_epi32(reg_03_16x8b, (int) 7);
+
+ reg_01_16x8b = _mm_packus_epi32(reg_01_16x8b, reg_03_16x8b);
+
+ reg_02_16x8b = _mm_maddubs_epi16(src_temp_4, filt_coeff_grid);
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_5, filt_coeff_grid);
+
+ reg_02_16x8b = _mm_hadd_epi16(reg_02_16x8b, reg_04_16x8b);
+
+ reg_02_16x8b = _mm_madd_epi16(reg_02_16x8b, reg_all_1s);
+
+ reg_02_16x8b = _mm_add_epi32(reg_02_16x8b, reg_64val_32bit);
+
+ reg_02_16x8b = _mm_srli_epi32(reg_02_16x8b, (int) 7);
+
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_6, filt_coeff_grid);
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_7, filt_coeff_grid);
+
+ reg_03_16x8b = _mm_hadd_epi16(reg_03_16x8b, reg_04_16x8b);
+
+ reg_03_16x8b = _mm_madd_epi16(reg_03_16x8b, reg_all_1s);
+
+ reg_03_16x8b = _mm_add_epi32(reg_03_16x8b, reg_64val_32bit);
+
+ reg_03_16x8b = _mm_srli_epi32(reg_03_16x8b, (int) 7);
+
+ reg_02_16x8b = _mm_packus_epi32(reg_02_16x8b, reg_03_16x8b);
+
+ reg_01_16x8b = _mm_packus_epi16(reg_01_16x8b, reg_02_16x8b);
+
+ reg_01_16x8b = _mm_shuffle_epi8(reg_01_16x8b, reg_shuffle);
+
+ src_temp_0 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + 8 * u4_in_stride));
+
+ src_temp_1 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + 9 * u4_in_stride));
+
+ src_temp_2 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 10));
+
+ src_temp_3 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 11));
+
+ src_temp_0 = _mm_shuffle_epi8(src_temp_0, reg_shuffle);
+ src_temp_1 = _mm_shuffle_epi8(src_temp_1, reg_shuffle);
+ src_temp_2 = _mm_shuffle_epi8(src_temp_2, reg_shuffle);
+ src_temp_3 = _mm_shuffle_epi8(src_temp_3, reg_shuffle);
+
+ reg_02_16x8b = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_1, filt_coeff_grid);
+
+ reg_02_16x8b = _mm_hadd_epi16(reg_02_16x8b, reg_03_16x8b);
+
+ reg_02_16x8b = _mm_madd_epi16(reg_02_16x8b, reg_all_1s);
+
+ reg_02_16x8b = _mm_add_epi32(reg_02_16x8b, reg_64val_32bit);
+
+ reg_02_16x8b = _mm_srli_epi32(reg_02_16x8b, (int) 7);
+
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_2, filt_coeff_grid);
+ reg_05_16x8b = _mm_maddubs_epi16(src_temp_3, filt_coeff_grid);
+
+ src_temp_4 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 12));
+
+ src_temp_5 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 13));
+
+ src_temp_6 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 14));
+
+ src_temp_7 = _mm_loadu_si128((__m128i *) (pu1_in_pixel + u4_in_stride * 15));
+
+ src_temp_4 = _mm_shuffle_epi8(src_temp_4, reg_shuffle);
+ src_temp_5 = _mm_shuffle_epi8(src_temp_5, reg_shuffle);
+ src_temp_6 = _mm_shuffle_epi8(src_temp_6, reg_shuffle);
+ src_temp_7 = _mm_shuffle_epi8(src_temp_7, reg_shuffle);
+
+ reg_04_16x8b = _mm_hadd_epi16(reg_04_16x8b, reg_05_16x8b);
+
+ reg_04_16x8b = _mm_madd_epi16(reg_04_16x8b, reg_all_1s);
+
+ reg_04_16x8b = _mm_add_epi32(reg_04_16x8b, reg_64val_32bit);
+
+ reg_04_16x8b = _mm_srli_epi32(reg_04_16x8b, (int) 7);
+
+ reg_02_16x8b = _mm_packus_epi32(reg_02_16x8b, reg_04_16x8b);
+
+ reg_03_16x8b = _mm_maddubs_epi16(src_temp_4, filt_coeff_grid);
+ reg_05_16x8b = _mm_maddubs_epi16(src_temp_5, filt_coeff_grid);
+
+ reg_03_16x8b = _mm_hadd_epi16(reg_03_16x8b, reg_05_16x8b);
+
+ reg_03_16x8b = _mm_madd_epi16(reg_03_16x8b, reg_all_1s);
+
+ reg_03_16x8b = _mm_add_epi32(reg_03_16x8b, reg_64val_32bit);
+
+ reg_03_16x8b = _mm_srli_epi32(reg_03_16x8b, (int) 7);
+
+ reg_04_16x8b = _mm_maddubs_epi16(src_temp_6, filt_coeff_grid);
+ reg_05_16x8b = _mm_maddubs_epi16(src_temp_7, filt_coeff_grid);
+
+ reg_04_16x8b = _mm_hadd_epi16(reg_04_16x8b, reg_05_16x8b);
+
+ reg_04_16x8b = _mm_madd_epi16(reg_04_16x8b, reg_all_1s);
+
+ reg_04_16x8b = _mm_add_epi32(reg_04_16x8b, reg_64val_32bit);
+
+ reg_04_16x8b = _mm_srli_epi32(reg_04_16x8b, (int) 7);
+
+ reg_03_16x8b = _mm_packus_epi32(reg_03_16x8b, reg_04_16x8b);
+
+ reg_02_16x8b = _mm_packus_epi16(reg_02_16x8b, reg_03_16x8b);
+
+ reg_02_16x8b = _mm_shuffle_epi8(reg_02_16x8b, reg_shuffle);
+
+ reg_03_16x8b = _mm_unpacklo_epi64(reg_01_16x8b, reg_02_16x8b);
+
+ reg_04_16x8b = _mm_unpackhi_epi64(reg_01_16x8b, reg_02_16x8b);
+
+ /*Storing after shuffling again*/
+
+ _mm_storeu_si128((__m128i *) pu1_out_pixel, reg_03_16x8b);
+ _mm_storeu_si128((__m128i *) (pu1_out_pixel + u4_out_stride), reg_04_16x8b);
+
+ pu1_out_pixel += 16;
+
+ pu1_in_pixel += (u4_src_vert_increments * (u4_in_stride << 4)) >> DOWNSCALER_Q;
+
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+
+ /*if height is not a multiple of 8 process 2 rows at a
+ time for the remaining rows*/
+ if(u4_rem_vert_loop)
+ {
+ pu1_src_j = pu1_src + ((j << 4) * u4_in_stride);
+ pu1_dst_j = pu1_dst + (j << 4);
+
+ u4_center_pixel_pos = u4_center_pixel_pos_src;
+ for(i = 0; i < (WORD32) u4_blk_wd; i++)
+ {
+ UWORD8 u1_phase = get_filter_phase(u4_center_pixel_pos);
+ pi1_filter_for_grid = pai1_filters[u1_phase];
+
+ u2_full_pixel_inc = u4_center_pixel_pos >> DOWNSCALER_Q;
+
+ pu1_in_pixel = pu1_src_j + (u2_full_pixel_inc << u1_is_chroma);
+
+ pu1_out_pixel = pu1_dst_j + ((i << u1_is_chroma) * u4_out_stride);
+
+ filt_coeff_grid = _mm_loadu_si128((__m128i *) pi1_filter_for_grid);
+
+ for(j = u4_rem_vert_loop; j > 0; j = j - 2)
+ {
+ src_temp_0 = _mm_loadu_si128((__m128i const *) pu1_in_pixel);
+ src_temp_0 = _mm_shuffle_epi8(src_temp_0, reg_shuffle);
+
+ src_temp_1 = _mm_loadu_si128((__m128i const *) (pu1_in_pixel + u4_in_stride));
+
+ src_temp_1 = _mm_shuffle_epi8(src_temp_1, reg_shuffle);
+
+ src_temp_0 = _mm_maddubs_epi16(src_temp_0, filt_coeff_grid);
+ src_temp_1 = _mm_maddubs_epi16(src_temp_1, filt_coeff_grid);
+
+ reg_01_16x8b = _mm_hadd_epi16(src_temp_0, src_temp_1);
+
+ reg_01_16x8b = _mm_madd_epi16(reg_01_16x8b, reg_all_1s);
+
+ /*Add offset of 64 for rounding each out pixel value*/
+ reg_01_16x8b = _mm_add_epi32(reg_01_16x8b, reg_64val_32bit);
+ /*Divide by 128 each out pixel value*/
+ reg_01_16x8b = _mm_srli_epi32(reg_01_16x8b, (int) 7);
+
+ reg_01_16x8b = _mm_packus_epi32(reg_01_16x8b, reg_all_0s);
+
+ /*next get saturated 8 bit output pixel values*/
+ reg_01_16x8b = _mm_packus_epi16(reg_01_16x8b, reg_all_0s);
+
+ reg_01_16x8b = _mm_shuffle_epi8(reg_01_16x8b, reg_shuffle);
+
+ reg_02_16x8b = _mm_srli_si128(reg_01_16x8b, (int) 8);
+
+ /*Store the 2 output values*/
+ i4_temp_pixel_holder = _mm_cvtsi128_si32(reg_01_16x8b);
+
+ *pu1_out_pixel = (UWORD8) i4_temp_pixel_holder;
+ i4_temp_pixel_holder >>= 8;
+
+ *(pu1_out_pixel + 1) = (UWORD8) i4_temp_pixel_holder;
+
+ i4_temp_pixel_holder = _mm_cvtsi128_si32(reg_02_16x8b);
+
+ *(pu1_out_pixel + u4_out_stride) = (UWORD8) i4_temp_pixel_holder;
+ i4_temp_pixel_holder >>= 8;
+
+ *(pu1_out_pixel + u4_out_stride + 1) = (UWORD8) i4_temp_pixel_holder;
+
+ pu1_in_pixel += (u4_src_vert_increments * (u4_in_stride << 1)) >> DOWNSCALER_Q;
+ pu1_out_pixel += 2;
+ }
+ /* Update the context for next Loop Count */
+ u4_center_pixel_pos += u4_src_horz_increments;
+ }
+ }
+ }
+}
diff --git a/encoder/x86/svc/isvce_function_selector.c b/encoder/x86/svc/isvce_function_selector.c
new file mode 100644
index 0000000..7ff22a2
--- /dev/null
+++ b/encoder/x86/svc/isvce_function_selector.c
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector.c
+*
+* @brief
+* Contains functions to initialize function pointers used in h264
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include Files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include Files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "isvc_macros.h"
+#include "ih264_platform_macros.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "isvce_platform_macros.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(isvce_codec_t *ps_codec)
+{
+ isvce_init_function_ptr_generic(ps_codec);
+
+ switch(ps_codec->s_cfg.e_arch)
+ {
+ case ARCH_X86_GENERIC:
+ isvce_init_function_ptr_generic(ps_codec);
+ break;
+ case ARCH_X86_SSSE3:
+ isvce_init_function_ptr_ssse3(ps_codec);
+ break;
+ case ARCH_X86_SSE42:
+ default:
+ isvce_init_function_ptr_ssse3(ps_codec);
+ isvce_init_function_ptr_sse42(ps_codec);
+ break;
+ }
+}
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void) { return ARCH_X86_SSE42; }
diff --git a/encoder/x86/svc/isvce_function_selector_sse42.c b/encoder/x86/svc/isvce_function_selector_sse42.c
new file mode 100644
index 0000000..709155f
--- /dev/null
+++ b/encoder/x86/svc/isvce_function_selector_sse42.c
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector_sse42.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_init_function_ptr_sse42
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "isvc_inter_pred_filters.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "isvce_cabac.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_core_coding.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_intra_modes_eval.h"
+#include "ih264e_fmt_conv.h"
+#include "ih264e_half_pel.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_sse42(isvce_codec_t *ps_codec)
+{
+ WORD32 i;
+ isvce_process_ctxt_t *ps_proc = NULL;
+ isvce_me_ctxt_t *ps_me_ctxt = NULL;
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ ps_enc_loop_fxns->pf_hadamard_quant_4x4 = isvc_hadamard_quant_4x4_sse42;
+ ps_enc_loop_fxns->pf_hadamard_quant_2x2_uv = isvc_hadamard_quant_2x2_uv_sse42;
+
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[0] = isvc_resi_trans_quant_4x4_sse42;
+ ps_enc_loop_fxns->apf_resi_trans_quant_4x4[1] = isvc_resi_trans_quant_4x4_with_res_pred_sse42;
+
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[0] = isvc_resi_trans_quant_chroma_4x4_sse42;
+ ps_enc_loop_fxns->apf_resi_trans_quant_chroma_4x4[1] =
+ isvc_resi_trans_quant_chroma_4x4_with_res_pred_sse42;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[0] = isvc_iquant_itrans_recon_res_4x4_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[1] =
+ isvc_iquant_itrans_recon_res_4x4_with_res_acc_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4[2] = isvc_iquant_itrans_recon_4x4_sse42;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[0] =
+ isvc_iquant_itrans_recon_res_chroma_4x4_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[1] =
+ isvc_iquant_itrans_recon_res_chroma_4x4_with_res_acc_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_sse42;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[0] = isvc_iquant_itrans_recon_res_dc_4x4_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[1] =
+ isvc_iquant_itrans_recon_res_dc_with_res_acc_4x4_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_4x4_dc[2] = isvc_iquant_itrans_recon_dc_4x4_sse42;
+
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[0] =
+ isvc_iquant_itrans_recon_res_chroma_4x4_dc_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[1] =
+ isvc_iquant_itrans_recon_res_chroma_4x4_dc_with_res_acc_sse42;
+ ps_enc_loop_fxns->apf_iquant_itrans_recon_chroma_4x4_dc[2] =
+ isvc_iquant_itrans_recon_chroma_4x4_dc_sse42;
+
+ ps_enc_loop_fxns->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_sse42;
+
+ /* sad me level functions */
+ ps_codec->apf_compute_sad_16x16[0] = ime_compute_sad_16x16_sse42;
+ ps_codec->apf_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_sse42;
+ ps_codec->pf_compute_sad_16x8 = ime_compute_sad_16x8_sse42;
+
+ ps_mem_fxns->pf_copy_2d = isvc_copy_2d_ssse3;
+ ps_mem_fxns->pf_memset_2d = isvc_memset_2d_sse42;
+
+ /* sad me level functions */
+ for(i = 0; i < (MAX_PROCESS_CTXT); i++)
+ {
+ ps_proc = &ps_codec->as_process[i];
+
+ ps_me_ctxt = &ps_proc->s_me_ctxt;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[0] = ime_compute_sad_16x16_sse42;
+ ps_me_ctxt->pf_ime_compute_sad_16x16[1] = ime_compute_sad_16x16_fast_sse42;
+ ps_me_ctxt->pf_ime_compute_sad_16x8 = ime_compute_sad_16x8_sse42;
+ ps_me_ctxt->pf_ime_compute_sad4_diamond = ime_calculate_sad4_prog_sse42;
+ ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16 = ime_sub_pel_compute_sad_16x16_sse42;
+ ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16 = ime_compute_satqd_16x16_lumainter_sse42;
+ }
+}
diff --git a/encoder/x86/svc/isvce_function_selector_ssse3.c b/encoder/x86/svc/isvce_function_selector_ssse3.c
new file mode 100644
index 0000000..298b490
--- /dev/null
+++ b/encoder/x86/svc/isvce_function_selector_ssse3.c
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+*******************************************************************************
+* @file
+* isvce_function_selector_ssse3.c
+*
+* @brief
+* Contains functions to initialize function pointers of codec context
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_init_function_ptr_ssse3
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System Include files */
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* User Include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvc_defs.h"
+#include "ih264_size_defs.h"
+#include "isvce_defs.h"
+#include "ih264e_error.h"
+#include "ih264e_bitstream.h"
+#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
+#include "ime_structs.h"
+#include "ih264_error.h"
+#include "isvc_structs.h"
+#include "isvc_trans_quant_itrans_iquant.h"
+#include "ih264_inter_pred_filters.h"
+#include "ih264_mem_fns.h"
+#include "isvc_mem_fns.h"
+#include "ih264_padding.h"
+#include "ih264_intra_pred_filters.h"
+#include "ih264_deblk_edge_filters.h"
+#include "isvc_cabac_tables.h"
+#include "irc_cntrl_param.h"
+#include "irc_frame_info_collector.h"
+#include "isvce_rate_control.h"
+#include "isvce_cabac_structs.h"
+#include "isvce_structs.h"
+#include "ih264e_platform_macros.h"
+#include "isvce_cabac.h"
+#include "isvce_core_coding.h"
+#include "ih264_cavlc_tables.h"
+#include "isvce_cavlc.h"
+#include "ih264e_intra_modes_eval.h"
+#include "ih264e_fmt_conv.h"
+#include "ih264e_half_pel.h"
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_ssse3(isvce_codec_t *ps_codec)
+{
+ isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
+ inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
+ mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 16x16 */
+ ps_codec->apf_intra_pred_16_l[0] = ih264_intra_pred_luma_16x16_mode_vert_ssse3;
+ ps_codec->apf_intra_pred_16_l[1] = ih264_intra_pred_luma_16x16_mode_horz_ssse3;
+ ps_codec->apf_intra_pred_16_l[2] = ih264_intra_pred_luma_16x16_mode_dc_ssse3;
+ ps_codec->apf_intra_pred_16_l[3] = ih264_intra_pred_luma_16x16_mode_plane_ssse3;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 4x4 */
+ ps_codec->apf_intra_pred_4_l[0] = ih264_intra_pred_luma_4x4_mode_vert_ssse3;
+ ps_codec->apf_intra_pred_4_l[1] = ih264_intra_pred_luma_4x4_mode_horz_ssse3;
+ ps_codec->apf_intra_pred_4_l[2] = ih264_intra_pred_luma_4x4_mode_dc_ssse3;
+ ps_codec->apf_intra_pred_4_l[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_ssse3;
+ ps_codec->apf_intra_pred_4_l[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_ssse3;
+ ps_codec->apf_intra_pred_4_l[5] = ih264_intra_pred_luma_4x4_mode_vert_r_ssse3;
+ ps_codec->apf_intra_pred_4_l[6] = ih264_intra_pred_luma_4x4_mode_horz_d_ssse3;
+ ps_codec->apf_intra_pred_4_l[7] = ih264_intra_pred_luma_4x4_mode_vert_l_ssse3;
+ ps_codec->apf_intra_pred_4_l[8] = ih264_intra_pred_luma_4x4_mode_horz_u_ssse3;
+
+ /* Init function pointers for intra pred leaf level functions luma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_8_l[0] = ih264_intra_pred_luma_8x8_mode_vert_ssse3;
+ ps_codec->apf_intra_pred_8_l[2] = ih264_intra_pred_luma_8x8_mode_dc_ssse3;
+ ps_codec->apf_intra_pred_8_l[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_ssse3;
+ ps_codec->apf_intra_pred_8_l[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_ssse3;
+ ps_codec->apf_intra_pred_8_l[5] = ih264_intra_pred_luma_8x8_mode_vert_r_ssse3;
+ ps_codec->apf_intra_pred_8_l[6] = ih264_intra_pred_luma_8x8_mode_horz_d_ssse3;
+ ps_codec->apf_intra_pred_8_l[7] = ih264_intra_pred_luma_8x8_mode_vert_l_ssse3;
+ ps_codec->apf_intra_pred_8_l[8] = ih264_intra_pred_luma_8x8_mode_horz_u_ssse3;
+
+ /* Init function pointers for intra pred leaf level functions chroma
+ * Intra 8x8 */
+ ps_codec->apf_intra_pred_c[1] = ih264_intra_pred_chroma_8x8_mode_horz_ssse3;
+ ps_codec->apf_intra_pred_c[2] = ih264_intra_pred_chroma_8x8_mode_vert_ssse3;
+ ps_codec->apf_intra_pred_c[3] = ih264_intra_pred_chroma_8x8_mode_plane_ssse3;
+
+ /* Init fn ptr luma deblocking */
+ ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_ssse3;
+ ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_ssse3;
+ ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_ssse3;
+ ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_ssse3;
+ /* Init fn ptr chroma deblocking */
+ ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_ssse3;
+ ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_ssse3;
+ ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_ssse3;
+ ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_ssse3;
+
+ /* Padding Functions */
+ ps_codec->pf_pad_left_luma = ih264_pad_left_luma_ssse3;
+ ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_ssse3;
+ ps_codec->pf_pad_right_luma = ih264_pad_right_luma_ssse3;
+ ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_ssse3;
+
+ /* Inter pred leaf level functions */
+ ps_inter_pred_fxns->pf_inter_pred_luma_copy = ih264_inter_pred_luma_copy_ssse3;
+ ps_inter_pred_fxns->pf_inter_pred_luma_horz = ih264_inter_pred_luma_horz_ssse3;
+ ps_inter_pred_fxns->pf_inter_pred_luma_vert = ih264_inter_pred_luma_vert_ssse3;
+ ps_inter_pred_fxns->pf_inter_pred_chroma = ih264_inter_pred_chroma_ssse3;
+
+ /* memory handling operations */
+ ps_mem_fxns->pf_mem_cpy_mul8 = ih264_memcpy_mul_8_ssse3;
+ ps_mem_fxns->pf_mem_set_mul8 = ih264_memset_mul_8_ssse3;
+ ps_mem_fxns->pf_copy_2d = isvc_copy_2d_ssse3;
+
+ /*intra mode eval -encoder level function*/
+ ps_codec->pf_ih264e_evaluate_intra16x16_modes = ih264e_evaluate_intra16x16_modes_ssse3;
+ ps_codec->pf_ih264e_evaluate_intra_4x4_modes = ih264e_evaluate_intra_4x4_modes_ssse3;
+ ps_codec->pf_ih264e_evaluate_intra_chroma_modes = ih264e_evaluate_intra_chroma_modes_ssse3;
+
+ /* Halp pel generation function - encoder level*/
+ ps_codec->pf_ih264e_sixtapfilter_horz = ih264e_sixtapfilter_horz_ssse3;
+ ps_codec->pf_ih264e_sixtap_filter_2dvh_vert = ih264e_sixtap_filter_2dvh_vert_ssse3;
+}
diff --git a/encoder/x86/svc/isvce_platform_macros.h b/encoder/x86/svc/isvce_platform_macros.h
new file mode 100644
index 0000000..f6e1ceb
--- /dev/null
+++ b/encoder/x86/svc/isvce_platform_macros.h
@@ -0,0 +1,119 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * isvce_platform_macros.h
+ *
+ * @brief
+ * Contains platform specific routines used for codec context intialization
+ *
+ * @author
+ * ittiam
+ *
+ * @remarks
+ * none
+ *
+ *******************************************************************************
+ */
+
+#ifndef _ISVCE_PLATFORM_MACROS_H_
+#define _ISVCE_PLATFORM_MACROS_H_
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_generic(isvce_codec_t *ps_codec);
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr_ssse3(isvce_codec_t *ps_codec);
+void isvce_init_function_ptr_sse42(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Initialize the intra/inter/transform/deblk function pointers of
+* codec context
+*
+* @par Description: the current routine initializes the function pointers of
+* codec context basing on the architecture in use
+*
+* @param[in] ps_codec
+* Codec context pointer
+*
+* @returns none
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+void isvce_init_function_ptr(isvce_codec_t *ps_codec);
+
+/**
+*******************************************************************************
+*
+* @brief Determine the architecture of the encoder executing environment
+*
+* @par Description: This routine returns the architecture of the enviro-
+* ment in which the current encoder is being tested
+*
+* @param[in] void
+*
+* @returns IV_ARCH_T
+* architecture
+*
+* @remarks none
+*
+*******************************************************************************
+*/
+IV_ARCH_T isvce_default_arch(void);
+
+#endif
diff --git a/encoder/x86/svc/isvce_rc_utils_sse42.c b/encoder/x86/svc/isvce_rc_utils_sse42.c
new file mode 100644
index 0000000..6444d72
--- /dev/null
+++ b/encoder/x86/svc/isvce_rc_utils_sse42.c
@@ -0,0 +1,450 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+******************************************************************************
+* @file isvce_rc_utils_sse42.c
+*
+* @brief
+* This file contains the x86 SIMD version of the function which computes
+* gradient per pixel value being used in Init Qp
+*
+* @author
+* Ittiam
+*
+* @par List of Functions:
+* - isvce_get_gpp_sse42()
+*
+* @remarks
+* None
+*
+*******************************************************************************
+*/
+
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_debug.h"
+#include "isvc_structs.h"
+#include "isvce_rc_utils_private_defs.h"
+
+/**
+*******************************************************************************
+*
+* @brief
+* get gpp function
+*
+* @par Description:
+* computes gradient per pixel value for a given frame
+*
+* @param[in] ps_input_buf
+* pointer to yuv buffer properties
+*
+* @returns
+* calculated gpp value
+*
+* @remarks
+* none
+*
+*******************************************************************************
+*/
+
+DOUBLE isvce_get_gpp_sse42(yuv_buf_props_t *ps_input_buf)
+{
+ UWORD8 *pu1_input_buf;
+ UWORD16 mask_ffff, mask_00ff;
+ UWORD32 i, j, k;
+ UWORD32 u4_width, u4_height, i4_input_stride;
+ DOUBLE d_gpp_y, d_gpp_u, d_gpp_v, d_gpp;
+
+ __m128i u1_src_r0, u1_src_r1, u1_src_r2, u1_src_r3, u1_src_r4;
+ __m128i u1_src_right_r0, u1_src_right_r1, u1_src_right_r2, u1_src_right_r3;
+ __m128i u2_sad_cur_bot_r01, u2_sad_cur_bot_r12, u2_sad_cur_bot_r23, u2_sad_cur_bot_r34;
+ __m128i u2_sad_cur_right_r0, u2_sad_cur_right_r1, u2_sad_cur_right_r2, u2_sad_cur_right_r3;
+ __m128i u2_sad_hadd, u1_shuffle_chroma, u2_mask_and_pixY, u2_mask_and_pixUV;
+
+ d_gpp_y = 0;
+ d_gpp_u = 0;
+ d_gpp_v = 0;
+ d_gpp = 0;
+ mask_ffff = 0xffff;
+ mask_00ff = 0x00ff;
+ pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[0].pv_data;
+ i4_input_stride = ps_input_buf->as_component_bufs[0].i4_data_stride;
+ u4_width = ps_input_buf->u4_width;
+ u4_height = ps_input_buf->u4_height;
+
+ u1_shuffle_chroma = _mm_setr_epi8(0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x01, 0x03,
+ 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f);
+ u2_mask_and_pixY = _mm_setr_epi16(mask_ffff, mask_ffff, mask_ffff, mask_ffff, mask_ffff,
+ mask_ffff, mask_ffff, mask_00ff);
+ u2_mask_and_pixUV = _mm_setr_epi16(mask_ffff, mask_ffff, mask_ffff, mask_00ff, mask_ffff,
+ mask_ffff, mask_ffff, mask_00ff);
+
+ ASSERT((u4_width % 16) == 0);
+
+ /***********************************************************/
+ /* For Luma - */
+ /* This code block calculates gpp value for luma by adding */
+ /* the absolute difference between the current pixel and */
+ /* it's immediate right pixel with the absolute difference */
+ /* between the current pixel and it's immediate bottom */
+ /* pixel and accumulating for every pixel in the frame. */
+ /***********************************************************/
+ for(i = 0; i < u4_height - 4; i += 4)
+ {
+ for(j = 0; j < u4_width - 16; j += 16)
+ {
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_r2 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j));
+ u1_src_r3 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j));
+ u1_src_r4 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 4) + j));
+ u1_src_right_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j + 1));
+ u1_src_right_r1 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j + 1));
+ u1_src_right_r2 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j + 1));
+ u1_src_right_r3 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j + 1));
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_bot_r12 = _mm_sad_epu8(u1_src_r1, u1_src_r2);
+ u2_sad_cur_bot_r23 = _mm_sad_epu8(u1_src_r2, u1_src_r3);
+ u2_sad_cur_bot_r34 = _mm_sad_epu8(u1_src_r3, u1_src_r4);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+ u2_sad_cur_right_r1 = _mm_sad_epu8(u1_src_r1, u1_src_right_r1);
+ u2_sad_cur_right_r2 = _mm_sad_epu8(u1_src_r2, u1_src_right_r2);
+ u2_sad_cur_right_r3 = _mm_sad_epu8(u1_src_r3, u1_src_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r12);
+ u2_sad_cur_bot_r23 = _mm_adds_epu16(u2_sad_cur_bot_r23, u2_sad_cur_bot_r34);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r1);
+ u2_sad_cur_right_r2 = _mm_adds_epu16(u2_sad_cur_right_r2, u2_sad_cur_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r23);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r2);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_y += _mm_extract_epi16(u2_sad_hadd, 0);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 15 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with u2_mask_and_pixY mask */
+ /************************************************************/
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_r2 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j));
+ u1_src_r3 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j));
+ u1_src_r4 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 4) + j));
+ u1_src_right_r0 = _mm_srli_si128(u1_src_r0, 1);
+ u1_src_right_r1 = _mm_srli_si128(u1_src_r1, 1);
+ u1_src_right_r2 = _mm_srli_si128(u1_src_r2, 1);
+ u1_src_right_r3 = _mm_srli_si128(u1_src_r3, 1);
+
+ u1_src_r0 = _mm_and_si128(u1_src_r0, u2_mask_and_pixY);
+ u1_src_r1 = _mm_and_si128(u1_src_r1, u2_mask_and_pixY);
+ u1_src_r2 = _mm_and_si128(u1_src_r2, u2_mask_and_pixY);
+ u1_src_r3 = _mm_and_si128(u1_src_r3, u2_mask_and_pixY);
+ u1_src_r4 = _mm_and_si128(u1_src_r4, u2_mask_and_pixY);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_bot_r12 = _mm_sad_epu8(u1_src_r1, u1_src_r2);
+ u2_sad_cur_bot_r23 = _mm_sad_epu8(u1_src_r2, u1_src_r3);
+ u2_sad_cur_bot_r34 = _mm_sad_epu8(u1_src_r3, u1_src_r4);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+ u2_sad_cur_right_r1 = _mm_sad_epu8(u1_src_r1, u1_src_right_r1);
+ u2_sad_cur_right_r2 = _mm_sad_epu8(u1_src_r2, u1_src_right_r2);
+ u2_sad_cur_right_r3 = _mm_sad_epu8(u1_src_r3, u1_src_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r12);
+ u2_sad_cur_bot_r23 = _mm_adds_epu16(u2_sad_cur_bot_r23, u2_sad_cur_bot_r34);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r1);
+ u2_sad_cur_right_r2 = _mm_adds_epu16(u2_sad_cur_right_r2, u2_sad_cur_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r23);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r2);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_y += _mm_extract_epi16(u2_sad_hadd, 0);
+
+ pu1_input_buf += (i4_input_stride << 2);
+ }
+
+ /* Loop for the remaining height */
+ for(k = i; k < u4_height - 1; k++)
+ {
+ for(j = 0; j < u4_width - 16; j += 16)
+ {
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_right_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j + 1));
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_y += _mm_extract_epi16(u2_sad_hadd, 0);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 15 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with u2_mask_and_pixY mask */
+ /************************************************************/
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_right_r0 = _mm_srli_si128(u1_src_r0, 1);
+
+ u1_src_r0 = _mm_and_si128(u1_src_r0, u2_mask_and_pixY);
+ u1_src_r1 = _mm_and_si128(u1_src_r1, u2_mask_and_pixY);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_y += _mm_extract_epi16(u2_sad_hadd, 0);
+
+ pu1_input_buf += (i4_input_stride);
+ }
+
+ pu1_input_buf = (UWORD8 *) ps_input_buf->as_component_bufs[1].pv_data;
+ i4_input_stride = ps_input_buf->as_component_bufs[1].i4_data_stride;
+
+ /**************************************************************/
+ /* For Chroma - */
+ /* This code block first deinterleaves the Cb and Cr values */
+ /* from the loaded registers, calculates gpp value for both */
+ /* Cb and Cr separately by adding the absolute difference */
+ /* between the current pixel and it's immediate right pixel */
+ /* with the absolute difference between the current pixel and */
+ /* it's immediate bottom pixel and accumulating for every */
+ /* pixel in the frame. */
+ /**************************************************************/
+ for(i = 0; i < (u4_height / 2) - 4; i += 4)
+ {
+ for(j = 0; j < u4_width - 16; j += 16)
+ {
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_r2 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j));
+ u1_src_r3 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j));
+ u1_src_r4 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 4) + j));
+ u1_src_right_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j + 2));
+ u1_src_right_r1 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j + 2));
+ u1_src_right_r2 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j + 2));
+ u1_src_right_r3 =
+ _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j + 2));
+
+ /* separating u and v */
+ u1_src_r0 = _mm_shuffle_epi8(u1_src_r0, u1_shuffle_chroma);
+ u1_src_r1 = _mm_shuffle_epi8(u1_src_r1, u1_shuffle_chroma);
+ u1_src_r2 = _mm_shuffle_epi8(u1_src_r2, u1_shuffle_chroma);
+ u1_src_r3 = _mm_shuffle_epi8(u1_src_r3, u1_shuffle_chroma);
+ u1_src_r4 = _mm_shuffle_epi8(u1_src_r4, u1_shuffle_chroma);
+ u1_src_right_r0 = _mm_shuffle_epi8(u1_src_right_r0, u1_shuffle_chroma);
+ u1_src_right_r1 = _mm_shuffle_epi8(u1_src_right_r1, u1_shuffle_chroma);
+ u1_src_right_r2 = _mm_shuffle_epi8(u1_src_right_r2, u1_shuffle_chroma);
+ u1_src_right_r3 = _mm_shuffle_epi8(u1_src_right_r3, u1_shuffle_chroma);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_bot_r12 = _mm_sad_epu8(u1_src_r1, u1_src_r2);
+ u2_sad_cur_bot_r23 = _mm_sad_epu8(u1_src_r2, u1_src_r3);
+ u2_sad_cur_bot_r34 = _mm_sad_epu8(u1_src_r3, u1_src_r4);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+ u2_sad_cur_right_r1 = _mm_sad_epu8(u1_src_r1, u1_src_right_r1);
+ u2_sad_cur_right_r2 = _mm_sad_epu8(u1_src_r2, u1_src_right_r2);
+ u2_sad_cur_right_r3 = _mm_sad_epu8(u1_src_r3, u1_src_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r12);
+ u2_sad_cur_bot_r23 = _mm_adds_epu16(u2_sad_cur_bot_r23, u2_sad_cur_bot_r34);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r1);
+ u2_sad_cur_right_r2 = _mm_adds_epu16(u2_sad_cur_right_r2, u2_sad_cur_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r23);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r2);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_u += _mm_extract_epi16(u2_sad_hadd, 0);
+ d_gpp_v += _mm_extract_epi16(u2_sad_hadd, 1);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 15 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with u2_mask_and_pixUV mask */
+ /************************************************************/
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_r2 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 2) + j));
+ u1_src_r3 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 3) + j));
+ u1_src_r4 = _mm_loadu_si128((__m128i *) (pu1_input_buf + (i4_input_stride * 4) + j));
+ u1_src_right_r0 = _mm_srli_si128(u1_src_r0, 2);
+ u1_src_right_r1 = _mm_srli_si128(u1_src_r1, 2);
+ u1_src_right_r2 = _mm_srli_si128(u1_src_r2, 2);
+ u1_src_right_r3 = _mm_srli_si128(u1_src_r3, 2);
+
+ /* separating u and v */
+ u1_src_r0 = _mm_shuffle_epi8(u1_src_r0, u1_shuffle_chroma);
+ u1_src_r1 = _mm_shuffle_epi8(u1_src_r1, u1_shuffle_chroma);
+ u1_src_r2 = _mm_shuffle_epi8(u1_src_r2, u1_shuffle_chroma);
+ u1_src_r3 = _mm_shuffle_epi8(u1_src_r3, u1_shuffle_chroma);
+ u1_src_r4 = _mm_shuffle_epi8(u1_src_r4, u1_shuffle_chroma);
+ u1_src_right_r0 = _mm_shuffle_epi8(u1_src_right_r0, u1_shuffle_chroma);
+ u1_src_right_r1 = _mm_shuffle_epi8(u1_src_right_r1, u1_shuffle_chroma);
+ u1_src_right_r2 = _mm_shuffle_epi8(u1_src_right_r2, u1_shuffle_chroma);
+ u1_src_right_r3 = _mm_shuffle_epi8(u1_src_right_r3, u1_shuffle_chroma);
+
+ u1_src_r0 = _mm_and_si128(u1_src_r0, u2_mask_and_pixUV);
+ u1_src_r1 = _mm_and_si128(u1_src_r1, u2_mask_and_pixUV);
+ u1_src_r2 = _mm_and_si128(u1_src_r2, u2_mask_and_pixUV);
+ u1_src_r3 = _mm_and_si128(u1_src_r3, u2_mask_and_pixUV);
+ u1_src_r4 = _mm_and_si128(u1_src_r4, u2_mask_and_pixUV);
+ u1_src_right_r0 = _mm_and_si128(u1_src_right_r0, u2_mask_and_pixUV);
+ u1_src_right_r1 = _mm_and_si128(u1_src_right_r1, u2_mask_and_pixUV);
+ u1_src_right_r2 = _mm_and_si128(u1_src_right_r2, u2_mask_and_pixUV);
+ u1_src_right_r3 = _mm_and_si128(u1_src_right_r3, u2_mask_and_pixUV);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_bot_r12 = _mm_sad_epu8(u1_src_r1, u1_src_r2);
+ u2_sad_cur_bot_r23 = _mm_sad_epu8(u1_src_r2, u1_src_r3);
+ u2_sad_cur_bot_r34 = _mm_sad_epu8(u1_src_r3, u1_src_r4);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+ u2_sad_cur_right_r1 = _mm_sad_epu8(u1_src_r1, u1_src_right_r1);
+ u2_sad_cur_right_r2 = _mm_sad_epu8(u1_src_r2, u1_src_right_r2);
+ u2_sad_cur_right_r3 = _mm_sad_epu8(u1_src_r3, u1_src_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r12);
+ u2_sad_cur_bot_r23 = _mm_adds_epu16(u2_sad_cur_bot_r23, u2_sad_cur_bot_r34);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r1);
+ u2_sad_cur_right_r2 = _mm_adds_epu16(u2_sad_cur_right_r2, u2_sad_cur_right_r3);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r23);
+ u2_sad_cur_right_r0 = _mm_adds_epu16(u2_sad_cur_right_r0, u2_sad_cur_right_r2);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_u += _mm_extract_epi16(u2_sad_hadd, 0);
+ d_gpp_v += _mm_extract_epi16(u2_sad_hadd, 1);
+
+ pu1_input_buf += (i4_input_stride * 4);
+ }
+
+ /* Loop for the remaining height */
+ for(k = i; k < (u4_height / 2) - 1; k++)
+ {
+ for(j = 0; j < u4_width - 16; j += 16)
+ {
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_right_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j + 2));
+
+ /* separating u and v */
+ u1_src_r0 = _mm_shuffle_epi8(u1_src_r0, u1_shuffle_chroma);
+ u1_src_r1 = _mm_shuffle_epi8(u1_src_r1, u1_shuffle_chroma);
+ u1_src_right_r0 = _mm_shuffle_epi8(u1_src_right_r0, u1_shuffle_chroma);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_u += _mm_extract_epi16(u2_sad_hadd, 0);
+ d_gpp_v += _mm_extract_epi16(u2_sad_hadd, 1);
+ }
+
+ /************************************************************/
+ /* Remaining width - */
+ /* Since Last pixel is not getting processed, remaining 15 */
+ /* pixels are getting processed separately by performing */
+ /* and operations with u2_mask_and_pixUV mask */
+ /************************************************************/
+ u1_src_r0 = _mm_loadu_si128((__m128i *) (pu1_input_buf + j));
+ u1_src_r1 = _mm_loadu_si128((__m128i *) (pu1_input_buf + i4_input_stride + j));
+ u1_src_right_r0 = _mm_srli_si128(u1_src_r0, 2);
+
+ /* separating u and v */
+ u1_src_r0 = _mm_shuffle_epi8(u1_src_r0, u1_shuffle_chroma);
+ u1_src_r1 = _mm_shuffle_epi8(u1_src_r1, u1_shuffle_chroma);
+ u1_src_right_r0 = _mm_shuffle_epi8(u1_src_right_r0, u1_shuffle_chroma);
+
+ u1_src_r0 = _mm_and_si128(u1_src_r0, u2_mask_and_pixUV);
+ u1_src_r1 = _mm_and_si128(u1_src_r1, u2_mask_and_pixUV);
+ u1_src_right_r0 = _mm_and_si128(u1_src_right_r0, u2_mask_and_pixUV);
+
+ u2_sad_cur_bot_r01 = _mm_sad_epu8(u1_src_r0, u1_src_r1);
+ u2_sad_cur_right_r0 = _mm_sad_epu8(u1_src_r0, u1_src_right_r0);
+
+ u2_sad_cur_bot_r01 = _mm_adds_epu16(u2_sad_cur_bot_r01, u2_sad_cur_right_r0);
+
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_cur_bot_r01, u2_sad_cur_bot_r01);
+ u2_sad_hadd = _mm_hadd_epi16(u2_sad_hadd, u2_sad_hadd);
+
+ d_gpp_u += _mm_extract_epi16(u2_sad_hadd, 0);
+ d_gpp_v += _mm_extract_epi16(u2_sad_hadd, 1);
+
+ pu1_input_buf += i4_input_stride;
+ }
+
+ d_gpp_y /= (u4_width * u4_height);
+ d_gpp_u /= ((u4_width / 2) * (u4_height / 2));
+ d_gpp_v /= ((u4_width / 2) * (u4_height / 2));
+
+ d_gpp = (DOUBLE) ((WT_LUMA_GPP * d_gpp_y) + d_gpp_u + d_gpp_v) / WT_TOTAL_GPP;
+
+ return d_gpp;
+}
diff --git a/encoder/x86/svc/isvce_residual_pred_sse42.c b/encoder/x86/svc/isvce_residual_pred_sse42.c
new file mode 100644
index 0000000..6b7fce7
--- /dev/null
+++ b/encoder/x86/svc/isvce_residual_pred_sse42.c
@@ -0,0 +1,735 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/**
+*******************************************************************************
+*
+* @file
+* isvce_residual_pred_sse42.c
+*
+* @brief
+* Contains functions
+* used for SVC residual
+* prediction
+*
+*******************************************************************************
+*/
+#include <immintrin.h>
+
+#include "ih264_typedefs.h"
+#include "ih264_macros.h"
+#include "isvc_structs.h"
+
+void isvce_luma_residual_sampler_2x_sse42(coordinates_t *ps_ref_array_positions,
+ coordinates_t *ps_ref_array_phases,
+ buffer_container_t *ps_inp, buffer_container_t *ps_out,
+ buffer_container_t *ps_scratch, UWORD32 u4_ref_nnz,
+ UWORD8 u1_ref_tx_size)
+{
+ WORD16 *pi2_inp_data = (WORD16 *) ps_inp->pv_data;
+ WORD16 *pi2_out_res = (WORD16 *) ps_out->pv_data;
+ WORD32 i4_inp_data_stride = ps_inp->i4_data_stride;
+ WORD32 i4_out_res_stride = ps_out->i4_data_stride;
+ WORD16 *pi2_refarray_buffer = (WORD16 *) ps_scratch->pv_data;
+ WORD32 i4_blk_ctr;
+
+ UNUSED(ps_ref_array_positions);
+ UNUSED(ps_ref_array_phases);
+
+ /* For 2x scaling, offsets always point to TL pixel outside MB */
+ /* Hence, refTransBlkIdc will be different and since phase */
+ /* for first refArray pos for horiz filtering samples > 8, */
+ /* first row and first column from the refArray is never used */
+ pi2_inp_data += 1 + i4_inp_data_stride;
+
+ if((u1_ref_tx_size) && (0 != u4_ref_nnz))
+ {
+ WORD16 *pi2_ref_data_byte;
+ WORD32 i4_i, i4_j;
+ WORD16 *pi2_refarray_buffer_tmp = pi2_refarray_buffer;
+
+ __m128i i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1;
+ __m128i res_8x16b_r1_0, res_8x16b_r1_1;
+ __m128i final_res_8x16b_r1_0, final_res_8x16b_r1_1;
+ __m128i coeff_add_8x16b_r1;
+ __m128i coeff_add_8x16b_r2;
+ __m128i i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1;
+ __m128i res_8x16b_r2_0, res_8x16b_r2_1;
+ __m128i final_res_8x16b_r2_0, final_res_8x16b_r2_1;
+
+ pi2_ref_data_byte = pi2_inp_data;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ for(i4_i = 0; i4_i < BLK8x8SIZE; i4_i += 2)
+ {
+ /* a0 a1 a2 a3 a4 a5 a6 a7 */
+ i2_coeff_8x16b_r1_0 = _mm_loadu_si128((__m128i *) pi2_ref_data_byte);
+ /* b0 b1 b2 b3 b4 b5 b6 b7 */
+ i2_coeff_8x16b_r2_0 =
+ _mm_loadu_si128((__m128i *) (pi2_ref_data_byte + i4_inp_data_stride));
+
+ /* a1 a2 a3 a4 a5 a6 a7 0 */
+ i2_coeff_8x16b_r1_1 = _mm_srli_si128(i2_coeff_8x16b_r1_0, 2);
+ /* b1 b2 b3 b4 b5 b6 b7 0 */
+ i2_coeff_8x16b_r2_1 = _mm_srli_si128(i2_coeff_8x16b_r2_0, 2);
+
+ coeff_add_8x16b_r1 = _mm_add_epi16(i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1);
+ coeff_add_8x16b_r2 = _mm_add_epi16(i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1);
+
+ i2_coeff_8x16b_r1_0 = _mm_slli_epi16(i2_coeff_8x16b_r1_0, 1);
+ i2_coeff_8x16b_r2_0 = _mm_slli_epi16(i2_coeff_8x16b_r2_0, 1);
+
+ i2_coeff_8x16b_r1_1 = _mm_slli_epi16(i2_coeff_8x16b_r1_1, 1);
+ i2_coeff_8x16b_r2_1 = _mm_slli_epi16(i2_coeff_8x16b_r2_1, 1);
+
+ res_8x16b_r1_0 = _mm_add_epi16(i2_coeff_8x16b_r1_0, coeff_add_8x16b_r1);
+ res_8x16b_r2_0 = _mm_add_epi16(i2_coeff_8x16b_r2_0, coeff_add_8x16b_r2);
+
+ res_8x16b_r1_1 = _mm_add_epi16(i2_coeff_8x16b_r1_1, coeff_add_8x16b_r1);
+ res_8x16b_r2_1 = _mm_add_epi16(i2_coeff_8x16b_r2_1, coeff_add_8x16b_r2);
+
+ final_res_8x16b_r1_0 = _mm_unpacklo_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_0 = _mm_unpacklo_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+
+ final_res_8x16b_r1_1 = _mm_unpackhi_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_1 = _mm_unpackhi_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 1), final_res_8x16b_r1_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 9), final_res_8x16b_r1_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 17), final_res_8x16b_r2_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 25), final_res_8x16b_r2_1);
+
+ pi2_refarray_buffer[0] = (pi2_ref_data_byte[0] << 2);
+ pi2_refarray_buffer[15] = (pi2_ref_data_byte[7] << 2);
+ pi2_ref_data_byte += i4_inp_data_stride;
+ pi2_refarray_buffer[16] = (pi2_ref_data_byte[0] << 2);
+ pi2_refarray_buffer[31] = (pi2_ref_data_byte[7] << 2);
+
+ /* vertical loop updates */
+ pi2_ref_data_byte = pi2_inp_data + ((i4_i + 2) * i4_inp_data_stride);
+ pi2_refarray_buffer += 32;
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ pi2_refarray_buffer = pi2_refarray_buffer_tmp;
+
+ {
+ __m128i i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r1_3,
+ i4_horz_samp_4x32b_r1_4;
+ __m128i i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r2_2, i4_horz_samp_4x32b_r2_3,
+ i4_horz_samp_4x32b_r2_4;
+ __m128i i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2, i4_res_samp_4x32b_r1_3,
+ i4_res_samp_4x32b_r1_4;
+ __m128i i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2, i4_res_samp_4x32b_r2_3,
+ i4_res_samp_4x32b_r2_4;
+ __m128i horz_add_4x32b_r2_1, horz_add_4x32b_r2_2, horz_add_4x32b_r2_3,
+ horz_add_4x32b_r2_4;
+
+ __m128i i4_horz_samp_8x16b_r1_1, i4_horz_samp_8x16b_r2_1;
+ __m128i i4_horz_samp_8x16b_r1_2, i4_horz_samp_8x16b_r2_2;
+ __m128i i4_horz_samp_8x16b_r1_3, i4_horz_samp_8x16b_r2_3;
+ __m128i i4_horz_samp_8x16b_r1_4, i4_horz_samp_8x16b_r2_4;
+
+ __m128i twos = _mm_set1_epi32(2);
+ __m128i eights = _mm_set1_epi32(8);
+
+ WORD16 *pi2_out;
+ pi2_out = pi2_out_res;
+
+ i4_horz_samp_8x16b_r1_1 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r1_2 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r1_3 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 8));
+ i4_horz_samp_8x16b_r1_4 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 12));
+
+ i4_horz_samp_4x32b_r1_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_1);
+ i4_horz_samp_4x32b_r1_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_2);
+ i4_horz_samp_4x32b_r1_3 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_3);
+ i4_horz_samp_4x32b_r1_4 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_4);
+
+ /* populate the first inter sample */
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_1, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_2, twos), 2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_3, twos), 2);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_4, twos), 2);
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ pi2_out += i4_out_res_stride;
+
+ for(i4_j = 0; i4_j < 14; i4_j += 2)
+ {
+ pi2_refarray_buffer += MB_SIZE;
+
+ i4_horz_samp_8x16b_r2_1 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r2_2 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r2_3 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 8));
+ i4_horz_samp_8x16b_r2_4 = _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 12));
+
+ i4_horz_samp_4x32b_r2_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_1);
+ i4_horz_samp_4x32b_r2_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_2);
+ i4_horz_samp_4x32b_r2_3 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_3);
+ i4_horz_samp_4x32b_r2_4 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_4);
+
+ horz_add_4x32b_r2_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r2_1);
+ horz_add_4x32b_r2_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r2_2);
+ horz_add_4x32b_r2_3 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_3, i4_horz_samp_4x32b_r2_3);
+ horz_add_4x32b_r2_4 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_4, i4_horz_samp_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_3, 1), horz_add_4x32b_r2_3);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r1_4, 1), horz_add_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r2_1 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r2_3 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_3, 1), horz_add_4x32b_r2_3);
+ i4_res_samp_4x32b_r2_4 =
+ _mm_add_epi32(_mm_slli_epi32(i4_horz_samp_4x32b_r2_4, 1), horz_add_4x32b_r2_4);
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_1, eights), 4);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_2, eights), 4);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_3, eights), 4);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_4, eights), 4);
+
+ i4_res_samp_4x32b_r2_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_1, eights), 4);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_2, eights), 4);
+ i4_res_samp_4x32b_r2_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_3, eights), 4);
+ i4_res_samp_4x32b_r2_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_4, eights), 4);
+
+ /* populate 2 samples based on current coeffs */
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ pi2_out += i4_out_res_stride;
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_3, i4_res_samp_4x32b_r2_4));
+ pi2_out += i4_out_res_stride;
+
+ /* store the coeff 2 to coeff 1 */
+ /* (used in next iteration) */
+ i4_horz_samp_4x32b_r1_1 = i4_horz_samp_4x32b_r2_1;
+ i4_horz_samp_4x32b_r1_2 = i4_horz_samp_4x32b_r2_2;
+ i4_horz_samp_4x32b_r1_3 = i4_horz_samp_4x32b_r2_3;
+ i4_horz_samp_4x32b_r1_4 = i4_horz_samp_4x32b_r2_4;
+ }
+
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_1, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_2, twos), 2);
+ i4_res_samp_4x32b_r1_3 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_3, twos), 2);
+ i4_res_samp_4x32b_r1_4 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r1_4, twos), 2);
+
+ _mm_storeu_si128((__m128i *) pi2_out,
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128((__m128i *) (pi2_out + 8),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_3, i4_res_samp_4x32b_r1_4));
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------------------------- */
+ /* LOOP over number of blocks */
+ /* ----------------------------------------------------------------- */
+ for(i4_blk_ctr = 0; i4_blk_ctr < 4; i4_blk_ctr++)
+ {
+ /* if reference layer is not coded then no processing */
+ if(0 != (u4_ref_nnz & 0x1))
+ {
+ {
+ __m128i i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1;
+ __m128i i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1;
+ __m128i i2_coeff_8x16b_r3_0, i2_coeff_8x16b_r3_1;
+ __m128i i2_coeff_8x16b_r4_0, i2_coeff_8x16b_r4_1;
+
+ __m128i res_8x16b_r1_0, res_8x16b_r1_1;
+ __m128i res_8x16b_r2_0, res_8x16b_r2_1;
+ __m128i res_8x16b_r3_0, res_8x16b_r3_1;
+ __m128i res_8x16b_r4_0, res_8x16b_r4_1;
+ __m128i final_res_8x16b_r1_0;
+ __m128i final_res_8x16b_r2_0;
+ __m128i final_res_8x16b_r3_0;
+ __m128i final_res_8x16b_r4_0;
+
+ __m128i coeff_add_8x16b_r1;
+ __m128i coeff_add_8x16b_r2;
+ __m128i coeff_add_8x16b_r3;
+ __m128i coeff_add_8x16b_r4;
+
+ /* ----------- Horizontal Interpolation ---------------- */
+ {
+ /* a0 a1 a2 a3 a4 a5 a6 a7 */
+ i2_coeff_8x16b_r1_0 = _mm_loadu_si128((__m128i *) pi2_inp_data);
+ /* b0 b1 b2 b3 b4 b5 b6 b7 */
+ i2_coeff_8x16b_r2_0 =
+ _mm_loadu_si128((__m128i *) (pi2_inp_data + i4_inp_data_stride));
+ i2_coeff_8x16b_r3_0 =
+ _mm_loadu_si128((__m128i *) (pi2_inp_data + (i4_inp_data_stride << 1)));
+ i2_coeff_8x16b_r4_0 =
+ _mm_loadu_si128((__m128i *) (pi2_inp_data + (i4_inp_data_stride * 3)));
+
+ /* a1 a2 a3 a4 a5 a6 a7 0 */
+ i2_coeff_8x16b_r1_1 = _mm_srli_si128(i2_coeff_8x16b_r1_0, 2);
+ /* b1 b2 b3 b4 b5 b6 b7 0 */
+ i2_coeff_8x16b_r2_1 = _mm_srli_si128(i2_coeff_8x16b_r2_0, 2);
+ i2_coeff_8x16b_r3_1 = _mm_srli_si128(i2_coeff_8x16b_r3_0, 2);
+ i2_coeff_8x16b_r4_1 = _mm_srli_si128(i2_coeff_8x16b_r4_0, 2);
+
+ coeff_add_8x16b_r1 =
+ _mm_add_epi16(i2_coeff_8x16b_r1_0, i2_coeff_8x16b_r1_1);
+ coeff_add_8x16b_r2 =
+ _mm_add_epi16(i2_coeff_8x16b_r2_0, i2_coeff_8x16b_r2_1);
+ coeff_add_8x16b_r3 =
+ _mm_add_epi16(i2_coeff_8x16b_r3_0, i2_coeff_8x16b_r3_1);
+ coeff_add_8x16b_r4 =
+ _mm_add_epi16(i2_coeff_8x16b_r4_0, i2_coeff_8x16b_r4_1);
+
+ i2_coeff_8x16b_r1_0 = _mm_slli_epi16(i2_coeff_8x16b_r1_0, 1);
+ i2_coeff_8x16b_r2_0 = _mm_slli_epi16(i2_coeff_8x16b_r2_0, 1);
+ i2_coeff_8x16b_r3_0 = _mm_slli_epi16(i2_coeff_8x16b_r3_0, 1);
+ i2_coeff_8x16b_r4_0 = _mm_slli_epi16(i2_coeff_8x16b_r4_0, 1);
+
+ i2_coeff_8x16b_r1_1 = _mm_slli_epi16(i2_coeff_8x16b_r1_1, 1);
+ i2_coeff_8x16b_r2_1 = _mm_slli_epi16(i2_coeff_8x16b_r2_1, 1);
+ i2_coeff_8x16b_r3_1 = _mm_slli_epi16(i2_coeff_8x16b_r3_1, 1);
+ i2_coeff_8x16b_r4_1 = _mm_slli_epi16(i2_coeff_8x16b_r4_1, 1);
+
+ res_8x16b_r1_0 = _mm_add_epi16(i2_coeff_8x16b_r1_0, coeff_add_8x16b_r1);
+ res_8x16b_r2_0 = _mm_add_epi16(i2_coeff_8x16b_r2_0, coeff_add_8x16b_r2);
+ res_8x16b_r3_0 = _mm_add_epi16(i2_coeff_8x16b_r3_0, coeff_add_8x16b_r3);
+ res_8x16b_r4_0 = _mm_add_epi16(i2_coeff_8x16b_r4_0, coeff_add_8x16b_r4);
+
+ res_8x16b_r1_1 = _mm_add_epi16(i2_coeff_8x16b_r1_1, coeff_add_8x16b_r1);
+ res_8x16b_r2_1 = _mm_add_epi16(i2_coeff_8x16b_r2_1, coeff_add_8x16b_r2);
+ res_8x16b_r3_1 = _mm_add_epi16(i2_coeff_8x16b_r3_1, coeff_add_8x16b_r3);
+ res_8x16b_r4_1 = _mm_add_epi16(i2_coeff_8x16b_r4_1, coeff_add_8x16b_r4);
+
+ final_res_8x16b_r1_0 = _mm_unpacklo_epi16(res_8x16b_r1_0, res_8x16b_r1_1);
+ final_res_8x16b_r2_0 = _mm_unpacklo_epi16(res_8x16b_r2_0, res_8x16b_r2_1);
+ final_res_8x16b_r3_0 = _mm_unpacklo_epi16(res_8x16b_r3_0, res_8x16b_r3_1);
+ final_res_8x16b_r4_0 = _mm_unpacklo_epi16(res_8x16b_r4_0, res_8x16b_r4_1);
+
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 1),
+ final_res_8x16b_r1_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 9),
+ final_res_8x16b_r2_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 17),
+ final_res_8x16b_r3_0);
+ _mm_storeu_si128((__m128i *) (pi2_refarray_buffer + 25),
+ final_res_8x16b_r4_0);
+
+ pi2_refarray_buffer[0] = (pi2_inp_data[0] << 2);
+ pi2_refarray_buffer[7] = (pi2_inp_data[3] << 2);
+ pi2_refarray_buffer[8] = (pi2_inp_data[i4_inp_data_stride] << 2);
+ pi2_refarray_buffer[15] = (pi2_inp_data[i4_inp_data_stride + 3] << 2);
+ pi2_refarray_buffer[16] = (pi2_inp_data[(i4_inp_data_stride << 1)] << 2);
+ pi2_refarray_buffer[23] =
+ (pi2_inp_data[(i4_inp_data_stride << 1) + 3] << 2);
+ pi2_refarray_buffer[24] = (pi2_inp_data[(i4_inp_data_stride * 3)] << 2);
+ pi2_refarray_buffer[31] = (pi2_inp_data[(i4_inp_data_stride * 3) + 3] << 2);
+ }
+
+ /* ----------- Vertical Interpolation ---------------- */
+ {
+ __m128i i4_horz_samp_8x16b_r0_1, i4_horz_samp_8x16b_r0_2;
+ __m128i i4_horz_samp_8x16b_r1_1, i4_horz_samp_8x16b_r1_2;
+ __m128i i4_horz_samp_8x16b_r2_1, i4_horz_samp_8x16b_r2_2;
+ __m128i i4_horz_samp_8x16b_r3_1, i4_horz_samp_8x16b_r3_2;
+
+ __m128i i4_horz_samp_4x32b_r0_1, i4_horz_samp_4x32b_r0_2;
+ __m128i i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r1_2;
+ __m128i i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r2_2;
+ __m128i i4_horz_samp_4x32b_r3_1, i4_horz_samp_4x32b_r3_2;
+
+ __m128i i4_res_samp_4x32b_r0_1, i4_res_samp_4x32b_r0_2;
+ __m128i i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2;
+ __m128i i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2;
+ __m128i i4_res_samp_4x32b_r3_1, i4_res_samp_4x32b_r3_2;
+ __m128i i4_res_samp_4x32b_r4_1, i4_res_samp_4x32b_r4_2;
+ __m128i i4_res_samp_4x32b_r5_1, i4_res_samp_4x32b_r5_2;
+ __m128i i4_res_samp_4x32b_r6_1, i4_res_samp_4x32b_r6_2;
+ __m128i i4_res_samp_4x32b_r7_1, i4_res_samp_4x32b_r7_2;
+
+ __m128i horz_add_4x32b_r1_1, horz_add_4x32b_r1_2;
+ __m128i horz_add_4x32b_r2_1, horz_add_4x32b_r2_2;
+ __m128i horz_add_4x32b_r3_1, horz_add_4x32b_r3_2;
+
+ __m128i twos = _mm_set1_epi32(2);
+ __m128i eights = _mm_set1_epi32(8);
+
+ i4_horz_samp_8x16b_r0_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer));
+ i4_horz_samp_8x16b_r0_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + 4));
+ i4_horz_samp_8x16b_r1_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + BLK8x8SIZE));
+ i4_horz_samp_8x16b_r1_2 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + BLK8x8SIZE + 4));
+ i4_horz_samp_8x16b_r2_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLK8x8SIZE << 1)));
+ i4_horz_samp_8x16b_r2_2 = _mm_loadu_si128(
+ (__m128i *) (pi2_refarray_buffer + (BLK8x8SIZE << 1) + 4));
+ i4_horz_samp_8x16b_r3_1 =
+ _mm_loadu_si128((__m128i *) (pi2_refarray_buffer + (BLK8x8SIZE * 3)));
+ i4_horz_samp_8x16b_r3_2 = _mm_loadu_si128(
+ (__m128i *) (pi2_refarray_buffer + (BLK8x8SIZE * 3) + 4));
+
+ i4_horz_samp_4x32b_r0_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r0_1);
+ i4_horz_samp_4x32b_r0_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r0_2);
+ i4_horz_samp_4x32b_r1_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_1);
+ i4_horz_samp_4x32b_r1_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r1_2);
+ i4_horz_samp_4x32b_r2_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_1);
+ i4_horz_samp_4x32b_r2_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r2_2);
+ i4_horz_samp_4x32b_r3_1 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r3_1);
+ i4_horz_samp_4x32b_r3_2 = _mm_cvtepi16_epi32(i4_horz_samp_8x16b_r3_2);
+
+ horz_add_4x32b_r1_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r0_1, i4_horz_samp_4x32b_r1_1);
+ horz_add_4x32b_r2_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_1, i4_horz_samp_4x32b_r2_1);
+ horz_add_4x32b_r3_1 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r2_1, i4_horz_samp_4x32b_r3_1);
+
+ horz_add_4x32b_r1_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r0_2, i4_horz_samp_4x32b_r1_2);
+ horz_add_4x32b_r2_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r1_2, i4_horz_samp_4x32b_r2_2);
+ horz_add_4x32b_r3_2 =
+ _mm_add_epi32(i4_horz_samp_4x32b_r2_2, i4_horz_samp_4x32b_r3_2);
+
+ i4_res_samp_4x32b_r1_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r0_1, 1), horz_add_4x32b_r1_1);
+ i4_res_samp_4x32b_r2_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r1_1);
+ i4_res_samp_4x32b_r3_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r4_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r2_1);
+ i4_res_samp_4x32b_r5_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_1, 1), horz_add_4x32b_r3_1);
+ i4_res_samp_4x32b_r6_1 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r3_1, 1), horz_add_4x32b_r3_1);
+
+ i4_res_samp_4x32b_r1_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r0_2, 1), horz_add_4x32b_r1_2);
+ i4_res_samp_4x32b_r2_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r1_2);
+ i4_res_samp_4x32b_r3_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r1_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r4_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r2_2);
+ i4_res_samp_4x32b_r5_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r2_2, 1), horz_add_4x32b_r3_2);
+ i4_res_samp_4x32b_r6_2 = _mm_add_epi32(
+ _mm_slli_epi32(i4_horz_samp_4x32b_r3_2, 1), horz_add_4x32b_r3_2);
+
+ i4_res_samp_4x32b_r0_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r0_1, twos), 2);
+ i4_res_samp_4x32b_r1_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_1, eights), 4);
+ i4_res_samp_4x32b_r2_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_1, eights), 4);
+ i4_res_samp_4x32b_r3_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r3_1, eights), 4);
+ i4_res_samp_4x32b_r4_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r4_1, eights), 4);
+ i4_res_samp_4x32b_r5_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r5_1, eights), 4);
+ i4_res_samp_4x32b_r6_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r6_1, eights), 4);
+ i4_res_samp_4x32b_r7_1 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r3_1, twos), 2);
+
+ i4_res_samp_4x32b_r0_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r0_2, twos), 2);
+ i4_res_samp_4x32b_r1_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r1_2, eights), 4);
+ i4_res_samp_4x32b_r2_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r2_2, eights), 4);
+ i4_res_samp_4x32b_r3_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r3_2, eights), 4);
+ i4_res_samp_4x32b_r4_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r4_2, eights), 4);
+ i4_res_samp_4x32b_r5_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r5_2, eights), 4);
+ i4_res_samp_4x32b_r6_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_res_samp_4x32b_r6_2, eights), 4);
+ i4_res_samp_4x32b_r7_2 =
+ _mm_srai_epi32(_mm_add_epi32(i4_horz_samp_4x32b_r3_2, twos), 2);
+
+ /* populate 2 samples based on current coeffs */
+ _mm_storeu_si128(
+ (__m128i *) pi2_out_res,
+ _mm_packs_epi32(i4_res_samp_4x32b_r0_1, i4_res_samp_4x32b_r0_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + i4_out_res_stride),
+ _mm_packs_epi32(i4_res_samp_4x32b_r1_1, i4_res_samp_4x32b_r1_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride << 1)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r2_1, i4_res_samp_4x32b_r2_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 3)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r3_1, i4_res_samp_4x32b_r3_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride << 2)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r4_1, i4_res_samp_4x32b_r4_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 5)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r5_1, i4_res_samp_4x32b_r5_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 6)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r6_1, i4_res_samp_4x32b_r6_2));
+ _mm_storeu_si128(
+ (__m128i *) (pi2_out_res + (i4_out_res_stride * 7)),
+ _mm_packs_epi32(i4_res_samp_4x32b_r7_1, i4_res_samp_4x32b_r7_2));
+
+ pi2_out_res += BLK8x8SIZE;
+ }
+ }
+ }
+ else
+ {
+ pi2_out_res += BLK8x8SIZE;
+ }
+
+ /* Block level loop updates */
+ if(1 == i4_blk_ctr)
+ {
+ pi2_inp_data -= 4;
+ pi2_inp_data += (i4_inp_data_stride * 4);
+ pi2_out_res -= MB_SIZE;
+ pi2_out_res += (i4_out_res_stride * BLK8x8SIZE);
+ u4_ref_nnz >>= 2;
+ }
+ else
+ {
+ pi2_inp_data += 4;
+ }
+
+ u4_ref_nnz >>= 1;
+
+ } /* end of loop over all the blocks */
+ }
+}
+
+UWORD32 isvce_get_sad_with_residual_pred_sse42(buffer_container_t *ps_src,
+ buffer_container_t *ps_pred,
+ buffer_container_t *ps_res, UWORD32 u4_mb_wd,
+ UWORD32 u4_mb_ht)
+{
+ UWORD32 i, j, u4_sad = 0;
+ UWORD8 *pu1_src = (UWORD8 *) ps_src->pv_data;
+ UWORD8 *pu1_pred = (UWORD8 *) ps_pred->pv_data;
+ WORD16 *pi2_res = (WORD16 *) ps_res->pv_data;
+ WORD32 i4_src_stride = ps_src->i4_data_stride;
+ WORD32 i4_pred_stride = ps_pred->i4_data_stride;
+ WORD32 i4_res_stride = ps_res->i4_data_stride;
+ UWORD32 u4_num_rows_per_loop = 8;
+ UWORD32 u4_ht_by_8 = u4_mb_ht / u4_num_rows_per_loop;
+
+ __m128i src_r0, src_r1, src_r2, src_r3;
+ __m128i src_r4, src_r5, src_r6, src_r7;
+ __m128i pred_r0, pred_r1, pred_r2, pred_r3;
+ __m128i pred_r4, pred_r5, pred_r6, pred_r7;
+ __m128i res_r0, res_r1, res_r2, res_r3;
+ __m128i res_r4, res_r5, res_r6, res_r7;
+ __m128i zero_4x32 = _mm_set1_epi32((WORD32) 0);
+
+ if((u4_mb_wd == 16) && (u4_mb_ht % 8 == 0))
+ {
+ for(i = 0; i < u4_ht_by_8; i++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ src_r0 = _mm_loadl_epi64((__m128i *) (pu1_src));
+ src_r1 = _mm_loadl_epi64((__m128i *) (pu1_src + 8));
+
+ pu1_src += i4_src_stride;
+
+ src_r2 = _mm_loadl_epi64((__m128i *) (pu1_src));
+ src_r3 = _mm_loadl_epi64((__m128i *) (pu1_src + 8));
+
+ pu1_src += i4_src_stride;
+
+ src_r4 = _mm_loadl_epi64((__m128i *) (pu1_src));
+ src_r5 = _mm_loadl_epi64((__m128i *) (pu1_src + 8));
+
+ pu1_src += i4_src_stride;
+
+ src_r6 = _mm_loadl_epi64((__m128i *) (pu1_src));
+ src_r7 = _mm_loadl_epi64((__m128i *) (pu1_src + 8));
+
+ pu1_src += i4_src_stride;
+
+ pred_r0 = _mm_loadl_epi64((__m128i *) (pu1_pred));
+ pred_r1 = _mm_loadl_epi64((__m128i *) (pu1_pred + 8));
+
+ pu1_pred += i4_pred_stride;
+
+ pred_r2 = _mm_loadl_epi64((__m128i *) (pu1_pred));
+ pred_r3 = _mm_loadl_epi64((__m128i *) (pu1_pred + 8));
+
+ pu1_pred += i4_pred_stride;
+
+ pred_r4 = _mm_loadl_epi64((__m128i *) (pu1_pred));
+ pred_r5 = _mm_loadl_epi64((__m128i *) (pu1_pred + 8));
+
+ pu1_pred += i4_pred_stride;
+
+ pred_r6 = _mm_loadl_epi64((__m128i *) (pu1_pred));
+ pred_r7 = _mm_loadl_epi64((__m128i *) (pu1_pred + 8));
+
+ pu1_pred += i4_pred_stride;
+
+ src_r0 = _mm_cvtepu8_epi16(src_r0);
+ src_r1 = _mm_cvtepu8_epi16(src_r1);
+ src_r2 = _mm_cvtepu8_epi16(src_r2);
+ src_r3 = _mm_cvtepu8_epi16(src_r3);
+ src_r4 = _mm_cvtepu8_epi16(src_r4);
+ src_r5 = _mm_cvtepu8_epi16(src_r5);
+ src_r6 = _mm_cvtepu8_epi16(src_r6);
+ src_r7 = _mm_cvtepu8_epi16(src_r7);
+
+ pred_r0 = _mm_cvtepu8_epi16(pred_r0);
+ pred_r1 = _mm_cvtepu8_epi16(pred_r1);
+ pred_r2 = _mm_cvtepu8_epi16(pred_r2);
+ pred_r3 = _mm_cvtepu8_epi16(pred_r3);
+ pred_r4 = _mm_cvtepu8_epi16(pred_r4);
+ pred_r5 = _mm_cvtepu8_epi16(pred_r5);
+ pred_r6 = _mm_cvtepu8_epi16(pred_r6);
+ pred_r7 = _mm_cvtepu8_epi16(pred_r7);
+
+ res_r0 = _mm_loadu_si128((__m128i *) (pi2_res));
+ res_r1 = _mm_loadu_si128((__m128i *) (pi2_res + 8));
+
+ pi2_res += i4_res_stride;
+
+ res_r2 = _mm_loadu_si128((__m128i *) (pi2_res));
+ res_r3 = _mm_loadu_si128((__m128i *) (pi2_res + 8));
+
+ pi2_res += i4_res_stride;
+
+ res_r4 = _mm_loadu_si128((__m128i *) (pi2_res));
+ res_r5 = _mm_loadu_si128((__m128i *) (pi2_res + 8));
+
+ pi2_res += i4_res_stride;
+
+ res_r6 = _mm_loadu_si128((__m128i *) (pi2_res));
+ res_r7 = _mm_loadu_si128((__m128i *) (pi2_res + 8));
+
+ pi2_res += i4_res_stride;
+
+ src_r0 = _mm_sub_epi16(src_r0, pred_r0);
+ src_r1 = _mm_sub_epi16(src_r1, pred_r1);
+ src_r2 = _mm_sub_epi16(src_r2, pred_r2);
+ src_r3 = _mm_sub_epi16(src_r3, pred_r3);
+ src_r4 = _mm_sub_epi16(src_r4, pred_r4);
+ src_r5 = _mm_sub_epi16(src_r5, pred_r5);
+ src_r6 = _mm_sub_epi16(src_r6, pred_r6);
+ src_r7 = _mm_sub_epi16(src_r7, pred_r7);
+
+ src_r0 = _mm_sub_epi16(src_r0, res_r0);
+ src_r1 = _mm_sub_epi16(src_r1, res_r1);
+ src_r2 = _mm_sub_epi16(src_r2, res_r2);
+ src_r3 = _mm_sub_epi16(src_r3, res_r3);
+ src_r4 = _mm_sub_epi16(src_r4, res_r4);
+ src_r5 = _mm_sub_epi16(src_r5, res_r5);
+ src_r6 = _mm_sub_epi16(src_r6, res_r6);
+ src_r7 = _mm_sub_epi16(src_r7, res_r7);
+
+ src_r0 = _mm_abs_epi16(src_r0);
+ src_r1 = _mm_abs_epi16(src_r1);
+ src_r2 = _mm_abs_epi16(src_r2);
+ src_r3 = _mm_abs_epi16(src_r3);
+ src_r4 = _mm_abs_epi16(src_r4);
+ src_r5 = _mm_abs_epi16(src_r5);
+ src_r6 = _mm_abs_epi16(src_r6);
+ src_r7 = _mm_abs_epi16(src_r7);
+
+ src_r0 = _mm_adds_epu16(src_r0, src_r1);
+ src_r1 = _mm_adds_epu16(src_r2, src_r3);
+ src_r2 = _mm_adds_epu16(src_r4, src_r5);
+ src_r3 = _mm_adds_epu16(src_r6, src_r7);
+
+ src_r0 = _mm_adds_epu16(src_r0, src_r1);
+ src_r1 = _mm_adds_epu16(src_r2, src_r3);
+
+ src_r0 = _mm_adds_epu16(src_r0, src_r1);
+
+ src_r1 = _mm_cvtepu16_epi32(src_r0);
+ src_r2 = _mm_srli_si128(src_r0, 8);
+ src_r2 = _mm_cvtepu16_epi32(src_r2);
+
+ src_r0 = _mm_hadd_epi32(src_r1, src_r2);
+ src_r0 = _mm_hadd_epi32(src_r0, zero_4x32);
+ src_r0 = _mm_hadd_epi32(src_r0, zero_4x32);
+
+ u4_sad += _mm_extract_epi32(src_r0, 0);
+ }
+ }
+ }
+ else
+ {
+ for(i = 0; i < u4_mb_ht; i++)
+ {
+ for(j = 0; j < u4_mb_wd; j++)
+ {
+ WORD16 i2_src = pu1_src[j + i * i4_src_stride];
+ WORD16 i2_pred = pu1_pred[j + i * i4_pred_stride];
+ WORD16 i2_res = pi2_res[j + i * i4_res_stride];
+ u4_sad += ABS(i2_src - i2_pred - i2_res);
+ }
+ }
+ }
+
+ return u4_sad;
+}
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
index 4c83461..5d3e63b 100644
--- a/fuzzer/Android.bp
+++ b/fuzzer/Android.bp
@@ -7,16 +7,10 @@ package {
default_applicable_licenses: ["external_libavc_license"],
}
-cc_fuzz {
- name: "avc_dec_fuzzer",
+cc_defaults {
+ name: "libavc_fuzzer_defaults",
host_supported: true,
- srcs: [
- "avc_dec_fuzzer.cpp",
- ],
- static_libs: [
- "libavcdec",
- "liblog",
- ],
+ static_libs: ["liblog"],
target: {
darwin: {
enabled: false,
@@ -27,27 +21,88 @@ cc_fuzz {
"android-media-fuzzing-reports@google.com",
],
componentid: 155276,
+ hotlists: [
+ "4593311",
+ "2281331",
+ ],
+ description: "The fuzzers target the APIs of libavc",
+ service_privilege: "constrained",
+ users: "multi_user",
+ },
+
+}
+
+cc_fuzz {
+ name: "avc_dec_fuzzer",
+ defaults: ["libavc_fuzzer_defaults"],
+ srcs: [
+ "avc_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libavcdec",
+ ],
+ fuzz_config: {
+ fuzzed_code_usage: "shipped",
+ vector: "remote",
+ },
+}
+
+cc_fuzz {
+ name: "mvc_dec_fuzzer",
+ defaults: ["libavc_fuzzer_defaults"],
+ srcs: [
+ "mvc_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libmvcdec",
+ ],
+ fuzz_config: {
+ fuzzed_code_usage: "experimental",
+ vector: "remote",
},
}
cc_fuzz {
name: "avc_enc_fuzzer",
- host_supported: true,
+ defaults: ["libavc_fuzzer_defaults"],
srcs: [
"avc_enc_fuzzer.cpp",
],
static_libs: [
"libavcenc",
- "liblog",
],
- cflags: [
- "-Wall",
- "-Werror",
+ fuzz_config: {
+ fuzzed_code_usage: "shipped",
+ vector: "local_no_privileges_required",
+ },
+}
+
+cc_fuzz {
+ name: "svc_enc_fuzzer",
+ defaults: ["libavc_fuzzer_defaults"],
+ srcs: [
+ "svc_enc_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libsvcenc",
+ ],
+ fuzz_config: {
+ fuzzed_code_usage: "experimental",
+ vector: "local_no_privileges_required",
+ },
+}
+
+cc_fuzz {
+ name: "svc_dec_fuzzer",
+ defaults: ["libavc_fuzzer_defaults"],
+ srcs: [
+ "svc_dec_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libsvcdec",
],
fuzz_config: {
- cc: [
- "android-media-fuzzing-reports@google.com",
- ],
- componentid: 155276,
+ fuzzed_code_usage: "experimental",
+ vector: "remote",
},
}
diff --git a/fuzzer/README.md b/fuzzer/README.md
index f848629..e59524e 100644
--- a/fuzzer/README.md
+++ b/fuzzer/README.md
@@ -25,7 +25,8 @@ Build fuzzer with required sanitizers (-DSANITIZE=fuzzer-no-link is mandatory
to enable fuzzers)
```
$ cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
- -DCMAKE_BUILD_TYPE=Debug -DSANITIZE=fuzzer-no-link,address
+ -DCMAKE_BUILD_TYPE=Debug -DSANITIZE=fuzzer-no-link,address,\
+ signed-integer-overflow,unsigned-integer-overflow
$ make
```
@@ -36,6 +37,7 @@ Create a directory CORPUS_DIR and copy some elementary h264 files
To run the fuzzers
```
$ ./avc_dec_fuzzer CORPUS_DIR
+$ ./mvc_dec_fuzzer CORPUS_DIR
$ ./avc_enc_fuzzer CORPUS_DIR
```
@@ -45,6 +47,7 @@ $ ./avc_enc_fuzzer CORPUS_DIR
Build the fuzzers
```
$ mm -j$(nproc) avc_dec_fuzzer
+ $ mm -j$(nproc) mvc_dec_fuzzer
$ mm -j$(nproc) avc_enc_fuzzer
```
@@ -58,6 +61,11 @@ To run avc_dec_fuzzer on device
$ adb sync data
$ adb shell /data/fuzz/arm64/avc_dec_fuzzer/avc_dec_fuzzer CORPUS_DIR
```
+To run mvc_dec_fuzzer on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mvc_dec_fuzzer/mvc_dec_fuzzer CORPUS_DIR
+```
To run avc_enc_fuzzer on device
```
$ adb sync data
@@ -69,6 +77,11 @@ To run avc_dec_fuzzer on host
$ $ANDROID_HOST_OUT/fuzz/x86_64/avc_dec_fuzzer/avc_dec_fuzzer CORPUS_DIR
```
+To run mvc_dec_fuzzer on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/mvc_dec_fuzzer/mvc_dec_fuzzer CORPUS_DIR
+```
+
To run avc_enc_fuzzer on host
```
$ $ANDROID_HOST_OUT/fuzz/x86_64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR
diff --git a/fuzzer/avc_dec_fuzzer.cpp b/fuzzer/avc_dec_fuzzer.cpp
index c292298..4e0876e 100644
--- a/fuzzer/avc_dec_fuzzer.cpp
+++ b/fuzzer/avc_dec_fuzzer.cpp
@@ -109,8 +109,8 @@ Codec::Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores) {
Codec::~Codec() {}
void Codec::createCodec() {
IV_API_CALL_STATUS_T ret;
- ih264d_create_ip_t create_ip;
- ih264d_create_op_t create_op;
+ ih264d_create_ip_t create_ip{};
+ ih264d_create_op_t create_op{};
void *fxns = (void *)&ivd_api_function;
create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
@@ -132,8 +132,8 @@ void Codec::createCodec() {
}
void Codec::deleteCodec() {
- ivd_delete_ip_t delete_ip;
- ivd_delete_op_t delete_op;
+ ivd_delete_ip_t delete_ip{};
+ ivd_delete_op_t delete_op{};
delete_ip.e_cmd = IVD_CMD_DELETE;
delete_ip.u4_size = sizeof(ivd_delete_ip_t);
@@ -142,8 +142,8 @@ void Codec::deleteCodec() {
ivd_api_function(mCodec, (void *)&delete_ip, (void *)&delete_op);
}
void Codec::resetCodec() {
- ivd_ctl_reset_ip_t s_ctl_ip;
- ivd_ctl_reset_op_t s_ctl_op;
+ ivd_ctl_reset_ip_t s_ctl_ip{};
+ ivd_ctl_reset_op_t s_ctl_op{};
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
@@ -154,8 +154,8 @@ void Codec::resetCodec() {
}
void Codec::setCores() {
- ih264d_ctl_set_num_cores_ip_t s_ctl_ip;
- ih264d_ctl_set_num_cores_op_t s_ctl_op;
+ ih264d_ctl_set_num_cores_ip_t s_ctl_ip{};
+ ih264d_ctl_set_num_cores_op_t s_ctl_op{};
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
s_ctl_ip.e_sub_cmd =
@@ -168,8 +168,8 @@ void Codec::setCores() {
}
void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode) {
- ivd_ctl_set_config_ip_t s_ctl_ip;
- ivd_ctl_set_config_op_t s_ctl_op;
+ ivd_ctl_set_config_ip_t s_ctl_ip{};
+ ivd_ctl_set_config_op_t s_ctl_op{};
s_ctl_ip.u4_disp_wd = 0;
s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
@@ -184,8 +184,8 @@ void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode) {
}
void Codec::setArchitecture(IVD_ARCH_T arch) {
- ih264d_ctl_set_processor_ip_t s_ctl_ip;
- ih264d_ctl_set_processor_op_t s_ctl_op;
+ ih264d_ctl_set_processor_ip_t s_ctl_ip{};
+ ih264d_ctl_set_processor_op_t s_ctl_op{};
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
s_ctl_ip.e_sub_cmd =
@@ -253,13 +253,10 @@ void Codec::decodeHeader(const uint8_t *data, size_t size) {
while (size > 0) {
IV_API_CALL_STATUS_T ret;
- ivd_video_decode_ip_t dec_ip;
- ivd_video_decode_op_t dec_op;
+ ivd_video_decode_ip_t dec_ip{};
+ ivd_video_decode_op_t dec_op{};
size_t bytes_consumed;
- memset(&dec_ip, 0, sizeof(dec_ip));
- memset(&dec_op, 0, sizeof(dec_op));
-
dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
dec_ip.u4_ts = 0;
dec_ip.pv_stream_buffer = (void *)data;
@@ -295,11 +292,8 @@ void Codec::decodeHeader(const uint8_t *data, size_t size) {
IV_API_CALL_STATUS_T Codec::decodeFrame(const uint8_t *data, size_t size,
size_t *bytesConsumed) {
IV_API_CALL_STATUS_T ret;
- ivd_video_decode_ip_t dec_ip;
- ivd_video_decode_op_t dec_op;
-
- memset(&dec_ip, 0, sizeof(dec_ip));
- memset(&dec_op, 0, sizeof(dec_op));
+ ivd_video_decode_ip_t dec_ip{};
+ ivd_video_decode_op_t dec_op{};
dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
dec_ip.u4_ts = 0;
diff --git a/fuzzer/avc_enc_fuzzer.cpp b/fuzzer/avc_enc_fuzzer.cpp
index ce36756..d0587e9 100644
--- a/fuzzer/avc_enc_fuzzer.cpp
+++ b/fuzzer/avc_enc_fuzzer.cpp
@@ -20,6 +20,7 @@
#include <malloc.h>
#include <algorithm>
#include <string.h>
+#include <tuple>
#include <vector>
#include "ih264_defs.h"
@@ -87,6 +88,7 @@ enum {
IDX_SEI_CLL_FLAG,
IDX_SEI_AVE_FLAG,
IDX_SEI_CCV_FLAG,
+ IDX_SEI_SII_FLAG,
IDX_PROFILE,
IDX_ASPECT_RATIO_FLAG,
IDX_NAL_HRD_FLAG,
@@ -132,6 +134,7 @@ class Codec {
void setSeiCllParams();
void setSeiAveParams();
void setSeiCcvParams();
+ void setSeiSiiParams();
void logVersion();
bool mHalfPelEnable = 1;
bool mQPelEnable = 1;
@@ -143,6 +146,7 @@ class Codec {
bool mSeiAveFlag = 1;
bool mSeiCcvFlag = 1;
bool mSeiMdcvFlag = 1;
+ bool mSeiSiiFlag = 1;
bool mAspectRatioFlag = 0;
bool mNalHrdFlag = 0;
bool mVclHrdFlag = 0;
@@ -217,6 +221,7 @@ bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) {
mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
+ mSeiSiiFlag = data[IDX_SEI_SII_FLAG] & 0x01;
mProfile = kProfle[data[IDX_PROFILE] % kProfleNum];
mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
@@ -345,6 +350,7 @@ bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) {
setSeiCllParams();
setSeiAveParams();
setSeiCcvParams();
+ setSeiSiiParams();
setProfileParams();
setEncMode(IVE_ENC_MODE_HEADER);
@@ -824,6 +830,37 @@ void Codec::setSeiCcvParams() {
return;
}
+void Codec::setSeiSiiParams() {
+ ih264e_ctl_set_sei_sii_params_ip_t sSeiSiiParamsIp{};
+ ih264e_ctl_set_sei_sii_params_op_t sSeiSiiParamsOp{};
+
+ sSeiSiiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sSeiSiiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_SII_PARAMS;
+ sSeiSiiParamsIp.u1_shutter_interval_info_present_flag = mSeiSiiFlag;
+ if(mSeiSiiFlag) {
+ sSeiSiiParamsIp.u4_sii_sub_layer_idx = 0;
+ sSeiSiiParamsIp.u1_shutter_interval_info_present_flag = 1;
+ sSeiSiiParamsIp.u4_sii_time_scale = 24000000;
+ sSeiSiiParamsIp.u1_fixed_shutter_interval_within_cvs_flag = 0;
+ sSeiSiiParamsIp.u4_sii_num_units_in_shutter_interval = 480000;
+ sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1 = 7;
+ for(int count = 0; count <= sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1; ++count) {
+ sSeiSiiParamsIp.au4_sub_layer_num_units_in_shutter_interval[count] = 480000;
+ }
+ sSeiSiiParamsIp.au4_sub_layer_num_units_in_shutter_interval
+ [sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1] = 240000;
+ }
+
+ sSeiSiiParamsIp.u4_timestamp_high = -1;
+ sSeiSiiParamsIp.u4_timestamp_low = -1;
+
+ sSeiSiiParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_ip_t);
+ sSeiSiiParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_op_t);
+
+ ih264e_api_function(mCodecCtx, &sSeiSiiParamsIp, &sSeiSiiParamsOp);
+ return;
+}
+
void Codec::logVersion() {
ive_ctl_getversioninfo_ip_t sCtlIp{};
ive_ctl_getversioninfo_op_t sCtlOp{};
diff --git a/fuzzer/mvc_dec_fuzzer.cmake b/fuzzer/mvc_dec_fuzzer.cmake
new file mode 100644
index 0000000..469d62e
--- /dev/null
+++ b/fuzzer/mvc_dec_fuzzer.cmake
@@ -0,0 +1,2 @@
+libavc_add_fuzzer(mvc_dec_fuzzer libmvcdec SOURCES
+ "${AVC_ROOT}/fuzzer/mvc_dec_fuzzer.cpp")
diff --git a/fuzzer/mvc_dec_fuzzer.cpp b/fuzzer/mvc_dec_fuzzer.cpp
new file mode 100644
index 0000000..8bb1330
--- /dev/null
+++ b/fuzzer/mvc_dec_fuzzer.cpp
@@ -0,0 +1,416 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <algorithm>
+
+#ifdef __cplusplus
+extern "C"
+{
+#include "ih264_typedefs.h"
+#include "imvcd.h"
+}
+#endif
+
+#define MAX_NUM_VIEWS 6
+
+#define NUM_COMPONENTS 3
+
+#define NELEMENTS(x) (sizeof(x) / sizeof(x[0]))
+
+typedef enum ARG_OFFSETS_T
+{
+ OFFSET_COLOR_FORMAT = 6,
+ OFFSET_NUM_CORES,
+ OFFSET_ARCH,
+ /* Should be the last entry */
+ OFFSET_MAX,
+} ARG_OFFSETS_T;
+
+static const IV_COLOR_FORMAT_T supportedColorFormats[] = {IV_YUV_420P};
+static const IVD_ARCH_T supportedArchitectures[] = {ARCH_ARM_NEONINTR, ARCH_X86_GENERIC,
+ ARCH_X86_SSSE3, ARCH_X86_SSE42};
+static const int kMaxNumDecodeCalls = 1000;
+static const int kSupportedColorFormats = NELEMENTS(supportedColorFormats);
+static const int kSupportedArchitectures = NELEMENTS(supportedArchitectures);
+static const int kMaxCores = 3;
+
+static inline void *mvcd_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ void *buf = nullptr;
+ (void) pv_ctxt;
+
+ if(0 != posix_memalign(&buf, alignment, i4_size))
+ {
+ return nullptr;
+ }
+
+ return buf;
+}
+
+static inline void mvcd_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+}
+
+class Codec
+{
+ public:
+ Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores);
+ ~Codec();
+
+ void resetCodec();
+ WORD32 allocFrame();
+ void freeFrame();
+ IV_API_CALL_STATUS_T decodeHeader(const uint8_t *data, size_t size);
+ IV_API_CALL_STATUS_T decodeFrame(const uint8_t *data, size_t size, size_t *bytesConsumed);
+ void setArchitecture(IVD_ARCH_T arch);
+ void setBufInfo();
+ void setCores();
+
+ ivd_out_bufdesc_t *getOutBuf() { return &mOutBufHandle; }
+
+ iv_yuv_buf_t *getViewDispBuf(UWORD16 u2_view_id = 0) { return &as_view_disp_bufs[u2_view_id]; }
+
+ UWORD32 getNumViews() { return mBufInfo.s_mvc_buf_info.u2_num_views; }
+
+ iv_obj_t *getCodecHandle() { return mCodec; }
+
+ private:
+ iv_obj_t *mCodec;
+ ivd_out_bufdesc_t mOutBufHandle;
+ iv_yuv_buf_t as_view_disp_bufs[MAX_NUM_VIEWS];
+ imvcd_get_buf_info_op_t mBufInfo;
+ IV_COLOR_FORMAT_T mColorFormat;
+ size_t mNumCores;
+ uint32_t mWidth;
+ uint32_t mHeight;
+};
+
+Codec::Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores)
+ : mCodec(nullptr), mColorFormat(colorFormat), mNumCores(numCores), mWidth(0), mHeight(0)
+{
+ imvcd_create_ip_t s_create_ip;
+ imvcd_create_op_t s_create_op;
+
+ s_create_ip.s_ivd_ip.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_ip.e_output_format = colorFormat;
+ s_create_ip.s_ivd_ip.pf_aligned_alloc = mvcd_aligned_malloc;
+ s_create_ip.s_ivd_ip.pf_aligned_free = mvcd_aligned_free;
+ s_create_ip.s_ivd_ip.u4_share_disp_buf = 0;
+ s_create_ip.s_ivd_ip.pv_mem_ctxt = nullptr;
+
+ s_create_ip.s_ivd_ip.u4_size = sizeof(s_create_ip.s_ivd_ip);
+ s_create_op.s_ivd_op.u4_size = sizeof(s_create_op.s_ivd_op);
+
+ imvcd_api_function(NULL, &s_create_ip, &s_create_op);
+
+ mCodec = static_cast<iv_obj_t *>(s_create_op.s_ivd_op.pv_handle);
+
+ setCores();
+
+ memset(getOutBuf(), 0, sizeof(getOutBuf()[0]));
+}
+
+Codec::~Codec()
+{
+ imvcd_delete_ip_t s_delete_ip;
+ imvcd_delete_op_t s_delete_op;
+
+ s_delete_ip.s_ivd_ip.e_cmd = IVD_CMD_DELETE;
+
+ s_delete_ip.s_ivd_ip.u4_size = sizeof(s_delete_ip.s_ivd_ip);
+ s_delete_op.s_ivd_op.u4_size = sizeof(s_delete_op.s_ivd_op);
+
+ imvcd_api_function(mCodec, &s_delete_ip, &s_delete_op);
+}
+
+void Codec::setCores()
+{
+ imvcd_set_num_cores_ip_t s_ctl_ip;
+ imvcd_set_num_cores_op_t s_ctl_op;
+
+ s_ctl_ip.u4_size = sizeof(s_ctl_ip);
+ s_ctl_op.u4_size = sizeof(s_ctl_op);
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = static_cast<IVD_CONTROL_API_COMMAND_TYPE_T>(IMVCD_CTL_SET_NUM_CORES);
+ s_ctl_ip.u4_num_cores = mNumCores;
+
+ imvcd_api_function(mCodec, &s_ctl_ip, &s_ctl_op);
+}
+
+void Codec::setArchitecture(IVD_ARCH_T e_arch)
+{
+ imvcd_set_arch_ip_t s_ctl_ip;
+ imvcd_set_arch_op_t s_ctl_op;
+
+ s_ctl_ip.u4_size = sizeof(s_ctl_ip);
+ s_ctl_op.u4_size = sizeof(s_ctl_op);
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = static_cast<IVD_CONTROL_API_COMMAND_TYPE_T>(IMVCD_CTL_SET_PROCESSOR);
+ s_ctl_ip.e_arch = e_arch;
+ s_ctl_ip.e_soc = SOC_GENERIC;
+
+ imvcd_api_function(mCodec, &s_ctl_ip, &s_ctl_op);
+}
+
+void Codec::setBufInfo()
+{
+ imvcd_get_buf_info_ip_t s_ctl_ip;
+ imvcd_get_buf_info_op_t s_ctl_op;
+
+ s_ctl_ip.s_ivd_ip.u4_size = sizeof(s_ctl_ip.s_ivd_ip);
+ s_ctl_op.s_ivd_op.u4_size = sizeof(s_ctl_op.s_ivd_op);
+ s_ctl_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.s_ivd_ip.e_sub_cmd =
+ static_cast<IVD_CONTROL_API_COMMAND_TYPE_T>(IVD_CMD_CTL_GETBUFINFO);
+
+ imvcd_api_function(mCodec, &s_ctl_ip, &s_ctl_op);
+
+ mBufInfo = s_ctl_op;
+}
+
+WORD32 Codec::allocFrame()
+{
+ if(getNumViews() > MAX_NUM_VIEWS)
+ {
+ return IV_FAIL;
+ }
+
+ if(mBufInfo.s_ivd_op.u4_min_num_out_bufs < (NUM_COMPONENTS * getNumViews()))
+ {
+ return IV_FAIL;
+ }
+
+ getOutBuf()->u4_num_bufs = mBufInfo.s_ivd_op.u4_min_num_out_bufs;
+
+ for(UWORD32 i = 0; i < getOutBuf()->u4_num_bufs; i++)
+ {
+ getOutBuf()->u4_min_out_buf_size[i] = mBufInfo.s_ivd_op.u4_min_out_buf_size[i];
+ getOutBuf()->pu1_bufs[i] =
+ (UWORD8 *) mvcd_aligned_malloc(nullptr, 16, mBufInfo.s_ivd_op.u4_min_out_buf_size[i]);
+
+ if(getOutBuf()->pu1_bufs[i] == nullptr)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+void Codec::freeFrame()
+{
+ for(UWORD32 i = 0; i < getOutBuf()->u4_num_bufs; i++)
+ {
+ if(getOutBuf()->pu1_bufs[i])
+ {
+ mvcd_aligned_free(nullptr, getOutBuf()->pu1_bufs[i]);
+ getOutBuf()->pu1_bufs[i] = nullptr;
+ }
+ }
+}
+
+static void sendDecodeSignal(iv_obj_t *psCodec, IVD_VIDEO_DECODE_MODE_T eDecMode)
+{
+ imvcd_set_config_ip_t s_ctl_ip;
+ imvcd_set_config_op_t s_ctl_op;
+
+ s_ctl_ip.s_ivd_ip.u4_size = sizeof(s_ctl_ip.s_ivd_ip);
+ s_ctl_op.s_ivd_op.u4_size = sizeof(s_ctl_op.s_ivd_op);
+ s_ctl_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.s_ivd_ip.e_sub_cmd =
+ static_cast<IVD_CONTROL_API_COMMAND_TYPE_T>(IVD_CMD_CTL_SETPARAMS);
+
+ s_ctl_ip.s_ivd_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ s_ctl_ip.s_ivd_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+ s_ctl_ip.s_ivd_ip.e_vid_dec_mode = eDecMode;
+
+ imvcd_api_function(psCodec, &s_ctl_ip, &s_ctl_op);
+}
+
+IV_API_CALL_STATUS_T Codec::decodeHeader(const uint8_t *data, size_t size)
+{
+ IV_API_CALL_STATUS_T ret;
+
+ WORD32 numBytesRemaining = size;
+
+ sendDecodeSignal(mCodec, IVD_DECODE_HEADER);
+
+ while(size > 0)
+ {
+ imvcd_video_decode_ip_t s_video_decode_ip;
+ imvcd_video_decode_op_t s_video_decode_op;
+
+ UWORD32 u4_num_bytes_dec = 0;
+
+ memset(&s_video_decode_ip, 0, sizeof(s_video_decode_ip));
+ memset(&s_video_decode_op, 0, sizeof(s_video_decode_op));
+
+ s_video_decode_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_ip.u4_ts = 0;
+ s_video_decode_ip.s_ivd_ip.pv_stream_buffer =
+ static_cast<void *>(const_cast<uint8_t *>(data));
+ s_video_decode_ip.s_ivd_ip.u4_num_Bytes = numBytesRemaining;
+ s_video_decode_ip.s_ivd_ip.s_out_buffer = getOutBuf()[0];
+ s_video_decode_op.ps_view_disp_bufs = getViewDispBuf();
+
+ s_video_decode_ip.s_ivd_ip.u4_size = sizeof(s_video_decode_ip.s_ivd_ip);
+ s_video_decode_op.s_ivd_op.u4_size = sizeof(s_video_decode_op.s_ivd_op);
+
+ ret = imvcd_api_function(mCodec, &s_video_decode_ip, &s_video_decode_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ return IV_FAIL;
+ }
+
+ u4_num_bytes_dec = s_video_decode_op.s_ivd_op.u4_num_bytes_consumed;
+
+ data += u4_num_bytes_dec;
+ numBytesRemaining -= u4_num_bytes_dec;
+ mWidth = s_video_decode_op.s_ivd_op.u4_pic_wd;
+ mHeight = s_video_decode_op.s_ivd_op.u4_pic_ht;
+
+ /* Break after successful header decode */
+ if(mWidth && mHeight)
+ {
+ break;
+ }
+ }
+
+ /* if width / height are invalid, set them to defaults */
+ if(!mWidth)
+ {
+ mWidth = 1920;
+ }
+
+ if(!mHeight)
+ {
+ mHeight = 1080;
+ }
+
+ setBufInfo();
+
+ return IV_SUCCESS;
+}
+
+IV_API_CALL_STATUS_T Codec::decodeFrame(const uint8_t *data, size_t size, size_t *bytesConsumed)
+{
+ imvcd_video_decode_ip_t s_video_decode_ip;
+ imvcd_video_decode_op_t s_video_decode_op;
+
+ IV_API_CALL_STATUS_T ret;
+
+ memset(&s_video_decode_ip, 0, sizeof(s_video_decode_ip));
+ memset(&s_video_decode_op, 0, sizeof(s_video_decode_op));
+
+ sendDecodeSignal(mCodec, IVD_DECODE_FRAME);
+
+ s_video_decode_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_ip.u4_ts = 0;
+ s_video_decode_ip.s_ivd_ip.pv_stream_buffer = static_cast<void *>(const_cast<uint8_t *>(data));
+ s_video_decode_ip.s_ivd_ip.u4_num_Bytes = size;
+ s_video_decode_ip.s_ivd_ip.s_out_buffer = getOutBuf()[0];
+ s_video_decode_op.ps_view_disp_bufs = getViewDispBuf();
+
+ s_video_decode_ip.s_ivd_ip.u4_size = sizeof(s_video_decode_ip.s_ivd_ip);
+ s_video_decode_op.s_ivd_op.u4_size = sizeof(s_video_decode_op.s_ivd_op);
+
+ ret = imvcd_api_function(mCodec, &s_video_decode_ip, &s_video_decode_op);
+
+ bytesConsumed[0] = s_video_decode_op.s_ivd_op.u4_num_bytes_consumed;
+
+ if(s_video_decode_op.s_ivd_op.u4_pic_wd && s_video_decode_op.s_ivd_op.u4_pic_ht &&
+ ((mWidth != s_video_decode_op.s_ivd_op.u4_pic_wd) ||
+ (mHeight != s_video_decode_op.s_ivd_op.u4_pic_ht)))
+ {
+ mWidth = s_video_decode_op.s_ivd_op.u4_pic_wd;
+ mHeight = s_video_decode_op.s_ivd_op.u4_pic_ht;
+ freeFrame();
+ allocFrame();
+ }
+
+ return ret;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ if(size < 1)
+ {
+ return 0;
+ }
+
+ WORD32 ret;
+
+ size_t colorFormatOfst = std::min((size_t) OFFSET_COLOR_FORMAT, size - 1);
+ size_t numCoresOfst = std::min((size_t) OFFSET_NUM_CORES, size - 1);
+ size_t architectureOfst = std::min((size_t) OFFSET_ARCH, size - 1);
+ size_t architectureIdx = data[architectureOfst] % kSupportedArchitectures;
+ size_t colorFormatIdx = data[colorFormatOfst] % kSupportedColorFormats;
+ uint32_t numCores = (data[numCoresOfst] % kMaxCores) + 1;
+ uint32_t numDecodeCalls = 0;
+
+ IVD_ARCH_T arch = (IVD_ARCH_T) supportedArchitectures[architectureIdx];
+ IV_COLOR_FORMAT_T colorFormat = (IV_COLOR_FORMAT_T) (supportedColorFormats[colorFormatIdx]);
+
+ Codec cCodec = Codec(colorFormat, numCores);
+
+ cCodec.setArchitecture(arch);
+
+ ret = cCodec.decodeHeader(data, size);
+
+ if(IV_SUCCESS != ret)
+ {
+ return 0;
+ }
+
+ ret = cCodec.allocFrame();
+
+ if(IV_SUCCESS != ret)
+ {
+ cCodec.freeFrame();
+
+ return 0;
+ }
+
+ while((size > 0) && (numDecodeCalls < kMaxNumDecodeCalls))
+ {
+ size_t bytesConsumed;
+
+ IV_API_CALL_STATUS_T ret = cCodec.decodeFrame(data, size, &bytesConsumed);
+
+ if(ret != IV_SUCCESS)
+ {
+ break;
+ }
+
+ bytesConsumed = std::min(size, bytesConsumed);
+ data += bytesConsumed;
+ size -= bytesConsumed;
+ numDecodeCalls++;
+ }
+
+ cCodec.freeFrame();
+
+ return 0;
+}
diff --git a/fuzzer/ossfuzz.sh b/fuzzer/ossfuzz.sh
index b1328ab..e203fbd 100755
--- a/fuzzer/ossfuzz.sh
+++ b/fuzzer/ossfuzz.sh
@@ -24,9 +24,11 @@ rm -rf ${build_dir}
mkdir -p ${build_dir}
pushd ${build_dir}
-cmake ${SRC}/libavc
-make -j$(nproc) avc_dec_fuzzer
-cp ${build_dir}/avc_dec_fuzzer $OUT/avc_dec_fuzzer
+cmake ${SRC}/libavc -DENABLE_SVC=1 -DENABLE_MVC=1
+make -j$(nproc) avc_dec_fuzzer svc_dec_fuzzer svc_enc_fuzzer
+cp ${build_dir}/avc_dec_fuzzer $OUT/
+cp ${build_dir}/svc_dec_fuzzer $OUT/
+cp ${build_dir}/svc_enc_fuzzer $OUT/
popd
cp $SRC/avc_dec_fuzzer_seed_corpus.zip $OUT/avc_dec_fuzzer_seed_corpus.zip
diff --git a/fuzzer/svc_dec_fuzzer.cmake b/fuzzer/svc_dec_fuzzer.cmake
new file mode 100644
index 0000000..8f0d14c
--- /dev/null
+++ b/fuzzer/svc_dec_fuzzer.cmake
@@ -0,0 +1,2 @@
+libavc_add_fuzzer(svc_dec_fuzzer libsvcdec SOURCES
+ "${AVC_ROOT}/fuzzer/svc_dec_fuzzer.cpp")
diff --git a/fuzzer/svc_dec_fuzzer.cpp b/fuzzer/svc_dec_fuzzer.cpp
new file mode 100644
index 0000000..6ae8747
--- /dev/null
+++ b/fuzzer/svc_dec_fuzzer.cpp
@@ -0,0 +1,449 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * svc_dec_fuzzer.cpp
+ *
+ * @brief
+ * Contains functions required for fuzzer tests
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "ih264_typedefs.h"
+#include "ithread.h"
+#include "iv.h"
+#include "ivd.h"
+
+#include "ih264d.h"
+#include "isvcd.h"
+
+#define NELEMENTS(x) (sizeof(x) / sizeof(x[0]))
+#define ivd_api_function isvcd_api_function
+const IV_COLOR_FORMAT_T supportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV, IV_YUV_420SP_VU,
+ IV_YUV_422ILE, IV_RGB_565, IV_RGBA_8888};
+
+/* Decoder ignores invalid arch, i.e. for arm build, if SSSE3 is requested,
+ * decoder defaults to a supported configuration. So same set of supported
+ * architectures can be used in arm/arm64/x86 builds */
+const IVD_ARCH_T supportedArchitectures[] = {
+ ARCH_ARM_NONEON, ARCH_ARM_A9Q, ARCH_ARM_NEONINTR, ARCH_ARMV8_GENERIC,
+ ARCH_X86_GENERIC, ARCH_X86_SSSE3, ARCH_X86_SSE42};
+
+enum
+{
+ OFFSET_COLOR_FORMAT = 6,
+ OFFSET_NUM_CORES,
+ OFFSET_ARCH,
+ OFFSET_TGT_LAYER,
+ /* Should be the last entry */
+ OFFSET_MAX,
+};
+
+const static int kMaxNumDecodeCalls = 100;
+const static int kSupportedColorFormats = NELEMENTS(supportedColorFormats);
+const static int kSupportedArchitectures = NELEMENTS(supportedArchitectures);
+const static int kMaxCores = 4;
+const static int kMaxTgtLayer = 2;
+void *iv_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size)
+{
+ void *buf = NULL;
+ (void) ctxt;
+ if(0 != posix_memalign(&buf, alignment, size))
+ {
+ return NULL;
+ }
+ return buf;
+}
+
+void iv_aligned_free(void *ctxt, void *buf)
+{
+ (void) ctxt;
+ free(buf);
+}
+
+class Codec
+{
+ public:
+ Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores);
+ ~Codec();
+
+ void createCodec();
+ void deleteCodec();
+ void resetCodec();
+ void setCores();
+ void allocFrame();
+ void freeFrame();
+ void decodeHeader(const uint8_t *data, size_t size);
+ IV_API_CALL_STATUS_T decodeFrame(const uint8_t *data, size_t size, size_t *bytesConsumed);
+ void setParams(IVD_VIDEO_DECODE_MODE_T mode);
+ void setArchitecture(IVD_ARCH_T arch);
+ void setTgtLayer(size_t tgtLayer);
+
+ private:
+ IV_COLOR_FORMAT_T mColorFormat;
+ size_t mNumCores;
+ iv_obj_t *mCodec;
+ ivd_out_bufdesc_t mOutBufHandle;
+ uint32_t mWidth;
+ uint32_t mHeight;
+};
+
+Codec::Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores)
+{
+ mColorFormat = colorFormat;
+ mNumCores = numCores;
+ mCodec = nullptr;
+ mWidth = 0;
+ mHeight = 0;
+
+ memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
+}
+
+Codec::~Codec() {}
+void Codec::createCodec()
+{
+ IV_API_CALL_STATUS_T ret;
+ ih264d_create_ip_t create_ip{};
+ ih264d_create_op_t create_op{};
+ void *fxns = (void *) &ivd_api_function;
+
+ create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+ create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+ create_ip.s_ivd_create_ip_t.e_output_format = mColorFormat;
+ create_ip.s_ivd_create_ip_t.pf_aligned_alloc = iv_aligned_malloc;
+ create_ip.s_ivd_create_ip_t.pf_aligned_free = iv_aligned_free;
+ create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
+ create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t);
+ create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t);
+
+ ret = ivd_api_function(NULL, (void *) &create_ip, (void *) &create_op);
+ if(ret != IV_SUCCESS)
+ {
+ return;
+ }
+ mCodec = (iv_obj_t *) create_op.s_ivd_create_op_t.pv_handle;
+ mCodec->pv_fxns = fxns;
+ mCodec->u4_size = sizeof(iv_obj_t);
+}
+
+void Codec::deleteCodec()
+{
+ ivd_delete_ip_t delete_ip{};
+ ivd_delete_op_t delete_op{};
+
+ delete_ip.e_cmd = IVD_CMD_DELETE;
+ delete_ip.u4_size = sizeof(ivd_delete_ip_t);
+ delete_op.u4_size = sizeof(ivd_delete_op_t);
+
+ ivd_api_function(mCodec, (void *) &delete_ip, (void *) &delete_op);
+}
+
+void Codec::resetCodec()
+{
+ ivd_ctl_reset_ip_t s_ctl_ip{};
+ ivd_ctl_reset_op_t s_ctl_op{};
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+
+ ivd_api_function(mCodec, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+}
+
+void Codec::setCores()
+{
+ ih264d_ctl_set_num_cores_ip_t s_ctl_ip{};
+ ih264d_ctl_set_num_cores_op_t s_ctl_op{};
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_ip.u4_num_cores = mNumCores;
+ s_ctl_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t);
+ s_ctl_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t);
+
+ ivd_api_function(mCodec, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+}
+
+void Codec::setTgtLayer(size_t TgtLayer)
+{
+ isvcd_set_target_layer_ip_t s_ctl_set_target_layer_ip{};
+ isvcd_set_target_layer_op_t s_ctl_set_target_layer_op{};
+
+ s_ctl_set_target_layer_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_target_layer_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) ISVCD_CMD_CTL_SET_TGT_LAYER;
+ s_ctl_set_target_layer_ip.u1_tgt_priority_id = 63;
+ s_ctl_set_target_layer_ip.u1_tgt_temp_id = 7;
+ s_ctl_set_target_layer_ip.u1_tgt_quality_id = 0;
+ s_ctl_set_target_layer_ip.u1_tgt_dep_id = TgtLayer;
+ s_ctl_set_target_layer_ip.u4_size = sizeof(isvcd_set_target_layer_ip_t);
+ s_ctl_set_target_layer_op.u4_size = sizeof(isvcd_set_target_layer_op_t);
+
+ ivd_api_function(mCodec, (void *) &s_ctl_set_target_layer_ip,
+ (void *) &s_ctl_set_target_layer_op);
+}
+
+void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode)
+{
+ ivd_ctl_set_config_ip_t s_ctl_ip{};
+ ivd_ctl_set_config_op_t s_ctl_op{};
+
+ s_ctl_ip.u4_disp_wd = 0;
+ s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+ s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ s_ctl_ip.e_vid_dec_mode = mode;
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+ ivd_api_function(mCodec, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+}
+
+void Codec::setArchitecture(IVD_ARCH_T arch)
+{
+ ih264d_ctl_set_processor_ip_t s_ctl_ip{};
+ ih264d_ctl_set_processor_op_t s_ctl_op{};
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR;
+ s_ctl_ip.u4_arch = arch;
+ s_ctl_ip.u4_soc = SOC_GENERIC;
+ s_ctl_ip.u4_size = sizeof(ih264d_ctl_set_processor_ip_t);
+ s_ctl_op.u4_size = sizeof(ih264d_ctl_set_processor_op_t);
+
+ ivd_api_function(mCodec, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+}
+
+void Codec::freeFrame()
+{
+ for(unsigned int i = 0; i < mOutBufHandle.u4_num_bufs; i++)
+ {
+ if(mOutBufHandle.pu1_bufs[i])
+ {
+ iv_aligned_free(NULL, mOutBufHandle.pu1_bufs[i]);
+ mOutBufHandle.pu1_bufs[i] = nullptr;
+ }
+ }
+}
+
+void Codec::allocFrame()
+{
+ size_t sizes[4] = {0};
+ UWORD32 num_bufs = 0;
+
+ freeFrame();
+
+ memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
+
+ switch(mColorFormat)
+ {
+ case IV_YUV_420SP_UV:
+ [[fallthrough]];
+ case IV_YUV_420SP_VU:
+ sizes[0] = mWidth * mHeight;
+ sizes[1] = mWidth * mHeight >> 1;
+ num_bufs = 2;
+ break;
+ case IV_YUV_422ILE:
+ sizes[0] = mWidth * mHeight * 2;
+ num_bufs = 1;
+ break;
+ case IV_RGB_565:
+ sizes[0] = mWidth * mHeight * 2;
+ num_bufs = 1;
+ break;
+ case IV_RGBA_8888:
+ sizes[0] = mWidth * mHeight * 4;
+ num_bufs = 1;
+ break;
+ case IV_YUV_420P:
+ [[fallthrough]];
+ default:
+ sizes[0] = mWidth * mHeight;
+ sizes[1] = mWidth * mHeight >> 2;
+ sizes[2] = mWidth * mHeight >> 2;
+ num_bufs = 3;
+ break;
+ }
+ mOutBufHandle.u4_num_bufs = num_bufs;
+ for(UWORD32 i = 0; i < num_bufs; i++)
+ {
+ mOutBufHandle.u4_min_out_buf_size[i] = sizes[i];
+ mOutBufHandle.pu1_bufs[i] = (UWORD8 *) iv_aligned_malloc(NULL, 16, sizes[i]);
+ }
+}
+
+void Codec::decodeHeader(const uint8_t *data, size_t size)
+{
+ setParams(IVD_DECODE_HEADER);
+ while(size > 0)
+ {
+ IV_API_CALL_STATUS_T ret;
+ isvcd_video_decode_ip_t s_video_decode_ip;
+ isvcd_video_decode_op_t s_video_decode_op;
+ size_t bytes_consumed;
+ memset(&s_video_decode_ip, 0, sizeof(s_video_decode_ip));
+ memset(&s_video_decode_op, 0, sizeof(s_video_decode_op));
+
+ s_video_decode_ip.s_ivd_video_decode_ip_t.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_ts = 0;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.pv_stream_buffer = (void *) data;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_num_Bytes = size;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(s_video_decode_ip);
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_size = sizeof(s_video_decode_op);
+
+ ret = ivd_api_function(mCodec, (void *) &s_video_decode_ip, (void *) &s_video_decode_op);
+ (void(ret));
+ bytes_consumed = s_video_decode_op.s_ivd_video_decode_op_t.u4_num_bytes_consumed;
+ /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
+ * to feed next data */
+ if(!bytes_consumed) bytes_consumed = 4;
+
+ bytes_consumed = std::min(size, bytes_consumed);
+
+ data += bytes_consumed;
+ size -= bytes_consumed;
+
+ mWidth = std::min(s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_wd, (UWORD32) 10240);
+ mHeight = std::min(s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_ht, (UWORD32) 10240);
+
+ /* Break after successful header decode */
+ if(mWidth && mHeight)
+ {
+ break;
+ }
+ }
+ /* if width / height are invalid, set them to defaults */
+ if(!mWidth) mWidth = 1920;
+ if(!mHeight) mHeight = 1088;
+}
+
+IV_API_CALL_STATUS_T Codec::decodeFrame(const uint8_t *data, size_t size, size_t *bytesConsumed)
+{
+ IV_API_CALL_STATUS_T ret;
+ isvcd_video_decode_ip_t s_video_decode_ip{};
+ isvcd_video_decode_op_t s_video_decode_op{};
+
+ s_video_decode_ip.s_ivd_video_decode_ip_t.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_ts = 0;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.pv_stream_buffer = (void *) data;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_num_Bytes = size;
+ s_video_decode_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(s_video_decode_ip);
+ s_video_decode_ip.s_ivd_video_decode_ip_t.s_out_buffer = mOutBufHandle;
+
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_size = sizeof(s_video_decode_op);
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_wd = 0;
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_ht = 0;
+
+ ret = ivd_api_function(mCodec, (void *) &s_video_decode_ip, (void *) &s_video_decode_op);
+
+ /* In case of change in resolution, reset codec and feed the same data again
+ */
+ if(IVD_RES_CHANGED == (s_video_decode_op.s_ivd_video_decode_op_t.u4_error_code & 0xFF))
+ {
+ resetCodec();
+ ret = ivd_api_function(mCodec, (void *) &s_video_decode_ip, (void *) &s_video_decode_op);
+ }
+ *bytesConsumed = s_video_decode_op.s_ivd_video_decode_op_t.u4_num_bytes_consumed;
+
+ /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
+ * to feed next data */
+ if(!*bytesConsumed)
+ {
+ *bytesConsumed = 4;
+ }
+ if(s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_wd &&
+ s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_ht &&
+ (mWidth != s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_wd ||
+ mHeight != s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_ht))
+ {
+ mWidth = std::min(s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_wd, (UWORD32) 10240);
+ mHeight = std::min(s_video_decode_op.s_ivd_video_decode_op_t.u4_pic_ht, (UWORD32) 10240);
+ allocFrame();
+ }
+
+ return ret;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ if(size < 1)
+ {
+ return 0;
+ }
+ size_t colorFormatOfst = std::min((size_t) OFFSET_COLOR_FORMAT, size - 1);
+ size_t numCoresOfst = std::min((size_t) OFFSET_NUM_CORES, size - 1);
+ size_t architectureOfst = std::min((size_t) OFFSET_ARCH, size - 1);
+ size_t architectureIdx = data[architectureOfst] % kSupportedArchitectures;
+ IVD_ARCH_T arch = (IVD_ARCH_T) supportedArchitectures[architectureIdx];
+ size_t colorFormatIdx = data[colorFormatOfst] % kSupportedColorFormats;
+ IV_COLOR_FORMAT_T colorFormat = (IV_COLOR_FORMAT_T) (supportedColorFormats[colorFormatIdx]);
+ uint32_t numCores = (data[numCoresOfst] % kMaxCores) + 1;
+
+ size_t numTgtLayerOfst = std::min((size_t) OFFSET_TGT_LAYER, size - 1);
+ uint32_t tgtLayer = (data[numTgtLayerOfst] % kMaxTgtLayer);
+
+ size_t numDecodeCalls = 0;
+ Codec *codec = new Codec(colorFormat, numCores);
+ codec->createCodec();
+ codec->setArchitecture(arch);
+ codec->setCores();
+ codec->setTgtLayer(tgtLayer);
+ codec->decodeHeader(data, size);
+ codec->setParams(IVD_DECODE_FRAME);
+ codec->allocFrame();
+
+ while(size > 0 && numDecodeCalls < kMaxNumDecodeCalls)
+ {
+ IV_API_CALL_STATUS_T ret;
+ size_t bytesConsumed;
+ ret = codec->decodeFrame(data, size, &bytesConsumed);
+ (void(ret));
+ bytesConsumed = std::min(size, bytesConsumed);
+ data += bytesConsumed;
+ size -= bytesConsumed;
+ numDecodeCalls++;
+ }
+
+ codec->freeFrame();
+ codec->deleteCodec();
+ delete codec;
+ return 0;
+}
diff --git a/fuzzer/svc_enc_fuzzer.cmake b/fuzzer/svc_enc_fuzzer.cmake
new file mode 100644
index 0000000..527effa
--- /dev/null
+++ b/fuzzer/svc_enc_fuzzer.cmake
@@ -0,0 +1,2 @@
+libavc_add_fuzzer(svc_enc_fuzzer libsvcenc SOURCES
+ ${AVC_ROOT}/fuzzer/svc_enc_fuzzer.cpp)
diff --git a/fuzzer/svc_enc_fuzzer.cpp b/fuzzer/svc_enc_fuzzer.cpp
new file mode 100644
index 0000000..b4c644f
--- /dev/null
+++ b/fuzzer/svc_enc_fuzzer.cpp
@@ -0,0 +1,1343 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <numeric>
+#include <utility>
+#include <vector>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+
+constexpr WORD32 kMeSpeedPreset[] = {100};
+constexpr WORD32 kDeblkLevel[] = {0, 2, 3, 4};
+constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE};
+constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL,
+ IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST};
+constexpr IV_PROFILE_T kProfile[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN};
+constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY,
+ IVE_RC_CBR_LOW_DELAY};
+constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV};
+constexpr WORD32 kSupportedLevels[] = {10, 9, 11, 12, 13, 20, 21, 22,
+ 30, 31, 32, 40, 41, 42, 50, 51};
+constexpr IVE_SLICE_MODE_T kSliceMode[] = {IVE_SLICE_MODE_NONE};
+constexpr IV_ARCH_T kArchs[] = {
+ ARCH_ARM_NONEON, ARCH_ARM_A9Q, ARCH_ARM_A9A, ARCH_ARM_A9, ARCH_ARM_A7,
+ ARCH_ARM_A5, ARCH_ARM_A15, ARCH_ARM_NEONINTR, ARCH_X86_GENERIC, ARCH_X86_SSSE3,
+ ARCH_X86_SSE42, ARCH_ARM_A53, ARCH_ARM_A57, ARCH_ARM_V8_NEON};
+constexpr DOUBLE kSpatialResRatio[] = {1.5, 2};
+constexpr UWORD8 kSpatialLayers[] = {1, 2, 3};
+constexpr UWORD8 kTemporalLayers[] = {1, 2, 3};
+constexpr size_t kAirModeNum = std::size(kAirMode);
+constexpr size_t kEncSpeedNum = std::size(kEncSpeed);
+constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset);
+constexpr size_t kDeblkLevelNum = std::size(kDeblkLevel);
+constexpr size_t kProfileNum = std::size(kProfile);
+constexpr size_t kRCModeNum = std::size(kRCMode);
+constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats);
+constexpr size_t kSupportedLevelsNum = std::size(kSupportedLevels);
+constexpr size_t kSliceModeNum = std::size(kSliceMode);
+constexpr size_t kSpatialResRatioNum = std::size(kSpatialResRatio);
+constexpr size_t kSpatialLayersNum = std::size(kSpatialLayers);
+constexpr size_t kTemporalLayersNum = std::size(kTemporalLayers);
+constexpr size_t kMinQP = 0;
+constexpr size_t kMaxQP = 51;
+constexpr size_t kMaxWidth = 2560;
+constexpr size_t kMaxHeight = 2560;
+constexpr size_t kMaxBitrate = 500000000;
+constexpr UWORD8 kNumSeiMdcvPrimaries = 3;
+constexpr UWORD8 kNumSeiCcvPrimaries = 3;
+constexpr double kSvcCompliantDimProb = 0.75;
+constexpr size_t kMaxEncodeCalls = 100;
+
+typedef enum ARG_INDICES_T
+{
+ IDX_WD_BYTE_1,
+ IDX_WD_BYTE_2,
+ IDX_HT_BYTE_1,
+ IDX_HT_BYTE_2,
+ IDX_COLOR_FORMAT,
+ IDX_ARCH_TYPE,
+ IDX_RC_MODE,
+ IDX_NUM_CORES,
+ IDX_NUM_ARCH,
+ IDX_NUM_B_FRAMES,
+ IDX_ENC_SPEED,
+ IDX_CONSTRAINED_INTRA_FLAG,
+ IDX_INTRA_4x4,
+ IDX_I_FRAME_QP,
+ IDX_P_FRAME_QP,
+ IDX_B_FRAME_QP,
+ IDX_BITRATE_BYTE_1,
+ IDX_BITRATE_BYTE_2,
+ IDX_FRAME_RATE,
+ IDX_INTRA_REFRESH,
+ IDX_ENABLE_HALF_PEL,
+ IDX_ENABLE_Q_PEL,
+ IDX_ME_SPEED_PRESET,
+ IDX_AIR_MODE,
+ IDX_DISABLE_DEBLOCK_LEVEL,
+ IDX_SEARCH_RANGE_X,
+ IDX_SEARCH_RANGE_Y,
+ IDX_I_INTERVAL,
+ IDX_IDR_INTERVAL,
+ IDX_SEI_MDCV_FLAG,
+ IDX_SEI_CLL_FLAG,
+ IDX_SEI_AVE_FLAG,
+ IDX_SEI_CCV_FLAG,
+ IDX_PROFILE,
+ IDX_ASPECT_RATIO_FLAG,
+ IDX_NAL_HRD_FLAG,
+ IDX_VCL_HRD_FLAG,
+ IDX_ENABLE_FORCE_IDR,
+ IDX_ENABLE_DYNAMIC_BITRATE,
+ IDX_ENABLE_DYNAMIC_FRAME_RATE,
+ IDX_FORCE_IDR_INTERVAL,
+ IDX_DYNAMIC_BITRATE_INTERVAL,
+ IDX_DYNAMIC_FRAME_RATE_INTERVAL,
+ IDX_ENC_LEVEL,
+ IDX_RECON_FMT,
+ IDX_SLICE_MODE,
+ IDX_ENABLE_FAST_SAD,
+ IDX_NUM_SPATIAL_LAYERS,
+ IDX_NUM_TEMPORAL_LAYERS,
+ IDX_SPATIAL_RES_RATIO,
+ IDX_SVC_COMPLIANT_DIMS,
+ IDX_ENABLE_RECON,
+ IDX_ENABLE_NALU_INFO_EXPORT,
+ IDX_LAST
+} ARG_INDICES_T;
+
+class Codec
+{
+ public:
+ struct FrameDims
+ {
+ size_t mWidth;
+ size_t mHeight;
+
+ FrameDims(size_t w, size_t h) : mWidth(w), mHeight(h) {}
+ FrameDims(const std::pair<size_t, size_t> &dimPair)
+ : FrameDims(dimPair.first, dimPair.second)
+ {
+ }
+ FrameDims(const FrameDims &other) : FrameDims(other.mWidth, other.mHeight) {}
+
+ void operator=(const FrameDims &other)
+ {
+ mWidth = other.mWidth;
+ mHeight = other.mHeight;
+ }
+
+ size_t getFrameSize() const { return (mWidth * mHeight * 3) / 2; };
+ };
+
+ struct EncBufs
+ {
+ std::vector<UWORD8> mInputBuf;
+ std::vector<UWORD8> mOutputBuf;
+ std::vector<UWORD8> mReconBuf;
+ std::vector<isvce_nalu_info_buf_t> mNaluInfoStructBuf;
+ std::vector<std::vector<UWORD8>> mNaluInfoDataBuf;
+ };
+
+ Codec()
+ : mCodecCtx(nullptr),
+ mMemRecords(),
+ mMemRecBufs(),
+ mEncBufs(),
+ mAirMode(IVE_AIR_MODE_NONE),
+ mEncSpeed(IVE_NORMAL),
+ mRCMode(IVE_RC_NONE),
+ mArch(ARCH_NA),
+ mSliceMode(IVE_SLICE_MODE_NONE),
+ mIvVideoColorFormat(IV_YUV_420P),
+ mProfile(IV_PROFILE_BASE),
+ mSvcCompDims{kMaxWidth, kMaxHeight},
+ mInputDims{kMaxWidth, kMaxHeight},
+ mHalfPelEnable(1),
+ mQPelEnable(1),
+ mIntra4x4(0),
+ mEnableFastSad(0),
+ mEnableAltRef(0),
+ mConstrainedIntraFlag(0),
+ mSeiCllFlag(1),
+ mSeiAveFlag(1),
+ mSeiCcvFlag(1),
+ mSeiMdcvFlag(1),
+ mAspectRatioFlag(0),
+ mNalHrdFlag(0),
+ mVclHrdFlag(0),
+ mIsForceIdrEnabled(false),
+ mIsDynamicBitRateChangeEnabled(false),
+ mIsDynamicFrameRateChangeEnabled(false),
+ mEnableRecon(false),
+ mEnableNaluInfoExport(false),
+ mAvcEncLevel(41),
+ mNumMemRecords(0),
+ mNumCores(1),
+ mBframes(0),
+ mSliceParam(256),
+ mMeSpeedPreset(100),
+ mIInterval(60),
+ mIDRInterval(60),
+ mDisableDeblockLevel(0),
+ m_I_QP(22),
+ m_P_QP(28),
+ m_B_QP(22),
+ mIntraRefresh(30),
+ mSearchRangeX(64),
+ mSearchRangeY(48),
+ mForceIdrInterval(0),
+ mDynamicBitRateInterval(0),
+ mDynamicFrameRateInterval(0),
+ mBitrate(6000000),
+ mFrameRate(30),
+ mNumSpatialLayers(1),
+ mNumTemporalLayers(1),
+ mSpatialResRatio(2)
+ {
+ }
+
+ ~Codec() { delMemRecs(); };
+
+ bool initEncoder(const UWORD8 *data);
+ bool encodeFrames(const UWORD8 *data, size_t size);
+
+ private:
+ void setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
+ IV_COLOR_FORMAT_T colorFormat = IV_YUV_420P);
+ void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType);
+ void setQp();
+ void setEncMode(IVE_ENC_MODE_T eEncMode);
+ void setDimensions();
+ void setNumCores();
+ void setFrameRate();
+ void setIpeParams();
+ void setBitRate();
+ void setAirParams();
+ void setMeParams();
+ void setGopParams();
+ void setProfileParams();
+ void setDeblockParams();
+ void setVbvParams();
+ void setDefault();
+ void setVuiParams();
+ void getBufInfo();
+ void setSeiMdcvParams();
+ void setSeiCllParams();
+ void setSeiAveParams();
+ void setSeiCcvParams();
+ void logVersion();
+ void initEncBufs();
+ bool initMemRecs();
+ void delMemRecs();
+
+ iv_obj_t *mCodecCtx;
+ std::vector<iv_mem_rec_t> mMemRecords;
+ std::vector<UWORD8 *> mMemRecBufs;
+ EncBufs mEncBufs;
+
+ IVE_AIR_MODE_T mAirMode;
+ IVE_SPEED_CONFIG mEncSpeed;
+ IVE_RC_MODE_T mRCMode;
+ IV_ARCH_T mArch;
+ IVE_SLICE_MODE_T mSliceMode;
+ IV_COLOR_FORMAT_T mIvVideoColorFormat;
+ IV_PROFILE_T mProfile;
+ FrameDims mSvcCompDims;
+ FrameDims mInputDims;
+
+ bool mHalfPelEnable;
+ bool mQPelEnable;
+ bool mIntra4x4;
+ bool mEnableFastSad;
+ bool mEnableAltRef;
+ bool mConstrainedIntraFlag;
+ bool mSeiCllFlag;
+ bool mSeiAveFlag;
+ bool mSeiCcvFlag;
+ bool mSeiMdcvFlag;
+ bool mAspectRatioFlag;
+ bool mNalHrdFlag;
+ bool mVclHrdFlag;
+ bool mIsForceIdrEnabled;
+ bool mIsDynamicBitRateChangeEnabled;
+ bool mIsDynamicFrameRateChangeEnabled;
+ bool mEnableRecon;
+ bool mEnableNaluInfoExport;
+ UWORD32 mAvcEncLevel;
+ UWORD32 mNumMemRecords;
+ UWORD32 mNumCores;
+ UWORD32 mBframes;
+ UWORD32 mSliceParam;
+ UWORD32 mMeSpeedPreset;
+ UWORD32 mIInterval;
+ UWORD32 mIDRInterval;
+ UWORD32 mDisableDeblockLevel;
+ UWORD32 m_I_QP;
+ UWORD32 m_P_QP;
+ UWORD32 m_B_QP;
+ UWORD32 mIntraRefresh;
+ UWORD32 mSearchRangeX;
+ UWORD32 mSearchRangeY;
+ /* Units - number of frames */
+ UWORD32 mForceIdrInterval;
+ /* Units - number of frames */
+ UWORD32 mDynamicBitRateInterval;
+ /* Units - number of frames */
+ UWORD32 mDynamicFrameRateInterval;
+ UWORD64 mBitrate;
+ DOUBLE mFrameRate;
+ UWORD8 mNumSpatialLayers;
+ UWORD8 mNumTemporalLayers;
+ DOUBLE mSpatialResRatio;
+};
+
+void Codec::initEncBufs()
+{
+ size_t frameSize = mInputDims.getFrameSize();
+ constexpr size_t minOutBufSize = 0x800;
+ size_t outBufSize = std::max(minOutBufSize, frameSize * mNumSpatialLayers);
+ size_t naluInfoBufSize = 460 * mNumSpatialLayers;
+
+ mEncBufs.mInputBuf.resize(frameSize);
+ mEncBufs.mOutputBuf.resize(outBufSize);
+
+ if(mEnableRecon)
+ {
+ mEncBufs.mReconBuf.resize(frameSize);
+ }
+
+ if(mEnableNaluInfoExport)
+ {
+ mEncBufs.mNaluInfoStructBuf.resize(mNumSpatialLayers * 2);
+ mEncBufs.mNaluInfoDataBuf.resize(mNumSpatialLayers);
+
+ for(auto i = 0; i < mNumSpatialLayers; i++)
+ {
+ mEncBufs.mNaluInfoDataBuf[i].resize(naluInfoBufSize);
+ }
+ }
+}
+
+bool Codec::initMemRecs()
+{
+ std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
+
+ for(auto i = 0u; i < mNumMemRecords; i++)
+ {
+ mMemRecBufs[i] = reinterpret_cast<UWORD8 *>(
+ aligned_alloc(mMemRecords[i].u4_mem_alignment, mMemRecords[i].u4_mem_size));
+ mMemRecords[i].pv_base = mMemRecBufs[i];
+
+ if(nullptr == mMemRecBufs[i])
+ {
+ for(auto j = 0u; j < i; j++)
+ {
+ free(mMemRecBufs[j]);
+ }
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Codec::delMemRecs()
+{
+ for(auto i = 0u; i < mNumMemRecords; i++)
+ {
+ if(mMemRecBufs[i])
+ {
+ free(mMemRecBufs[i]);
+ }
+ }
+
+ std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
+}
+
+bool Codec::initEncoder(const UWORD8 *data)
+{
+ mInputDims = FrameDims{((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth,
+ ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight};
+
+ mNumSpatialLayers = kSpatialLayers[data[IDX_NUM_SPATIAL_LAYERS] % kSpatialLayersNum];
+ mNumTemporalLayers = kTemporalLayers[data[IDX_NUM_TEMPORAL_LAYERS] % kTemporalLayersNum];
+ mSpatialResRatio = kSpatialResRatio[data[IDX_SPATIAL_RES_RATIO] % kSpatialResRatioNum];
+ bool useSvcCompliantDims =
+ data[IDX_SVC_COMPLIANT_DIMS] <
+ static_cast<UWORD8>(std::numeric_limits<UWORD8>::max() * kSvcCompliantDimProb);
+
+ if(useSvcCompliantDims)
+ {
+ auto getSvcCompliantDims = [&]() -> FrameDims
+ {
+ auto maxResRatio = pow(mSpatialResRatio, mNumSpatialLayers - 1);
+ UWORD32 dimPadding = 0;
+ UWORD32 numDecimalDigits = mNumSpatialLayers;
+ constexpr auto minDimGcd = 16;
+ UWORD32 decPtDelMultiplier = static_cast<UWORD32>(std::pow(10, numDecimalDigits));
+ FrameDims dims{mInputDims};
+
+ if(std::fmod(minDimGcd, maxResRatio))
+ {
+ dimPadding = std::lcm(minDimGcd * decPtDelMultiplier,
+ static_cast<UWORD32>(maxResRatio * decPtDelMultiplier)) /
+ decPtDelMultiplier;
+ }
+ else
+ {
+ dimPadding = static_cast<UWORD32>(minDimGcd * maxResRatio);
+ }
+
+ if(mInputDims.mWidth % dimPadding)
+ {
+ dims.mWidth = mInputDims.mWidth - ((mInputDims.mWidth) % dimPadding) + dimPadding;
+ }
+
+ if(mInputDims.mHeight % dimPadding)
+ {
+ dims.mHeight =
+ mInputDims.mHeight - ((mInputDims.mHeight) % dimPadding) + dimPadding;
+ }
+
+ return dims;
+ };
+
+ mSvcCompDims = getSvcCompliantDims();
+ mInputDims = mSvcCompDims;
+ }
+
+ mIvVideoColorFormat =
+ kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum];
+ mArch = kArchs[data[IDX_ARCH_TYPE] % std::size(kArchs)];
+ mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum];
+ mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1;
+ mBframes = 0;
+
+ mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum];
+ mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01;
+ mIntra4x4 = data[IDX_INTRA_4x4] & 0x01;
+ m_I_QP = data[IDX_I_FRAME_QP];
+ m_P_QP = data[IDX_P_FRAME_QP];
+ m_B_QP = data[IDX_B_FRAME_QP];
+ mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
+ mFrameRate = data[IDX_FRAME_RATE] % 120;
+ mIntraRefresh = data[IDX_INTRA_REFRESH] + 1;
+ mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01;
+ mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01;
+ mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum];
+ mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum];
+ mDisableDeblockLevel = kDeblkLevel[data[IDX_DISABLE_DEBLOCK_LEVEL] % kDeblkLevelNum];
+ mSearchRangeX = data[IDX_SEARCH_RANGE_X];
+ mSearchRangeY = data[IDX_SEARCH_RANGE_Y];
+ mIInterval = data[IDX_I_INTERVAL] + 1;
+ mIDRInterval = data[IDX_IDR_INTERVAL] + 1;
+ mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01;
+ mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
+ mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
+ mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
+ mProfile = kProfile[data[IDX_PROFILE] % kProfileNum];
+ mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
+ mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
+ mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01;
+ mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01;
+ mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01;
+ mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01;
+ mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07;
+ mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07;
+ mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07;
+
+ mSliceParam = std::min(256u, static_cast<UWORD32>(mInputDims.mHeight >> 4));
+ mAvcEncLevel = kSupportedLevels[data[IDX_ENC_LEVEL] % kSupportedLevelsNum];
+ mSliceMode = kSliceMode[data[IDX_SLICE_MODE] % kSliceModeNum];
+ mEnableFastSad = data[IDX_ENABLE_FAST_SAD] & 0x01;
+
+ mEnableRecon = !!(data[IDX_ENABLE_RECON] & 1);
+ mEnableNaluInfoExport = !!(data[IDX_ENABLE_NALU_INFO_EXPORT] & 1);
+
+ isvce_num_mem_rec_ip_t s_num_mem_rec_ip{};
+ isvce_num_mem_rec_op_t s_num_mem_rec_op{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_GET_NUM_MEM_REC, ISVCE_CMD_CT_NA};
+
+ /* Getting Number of MemRecords */
+ s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(isvce_num_mem_rec_ip_t);
+ s_num_mem_rec_op.s_ive_op.u4_size = sizeof(isvce_num_mem_rec_op_t);
+
+ if(IV_SUCCESS != isvce_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op, &s_api_cmds))
+ {
+ return false;
+ }
+
+ mNumMemRecords = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec;
+ mMemRecords.resize(mNumMemRecords);
+ mMemRecBufs.resize(mNumMemRecords);
+
+ for(auto i = 0u; i < mNumMemRecords; i++)
+ {
+ mMemRecords[i].u4_size = sizeof(iv_mem_rec_t);
+ mMemRecords[i].pv_base = nullptr;
+ mMemRecords[i].u4_mem_size = 0;
+ mMemRecords[i].u4_mem_alignment = 0;
+ mMemRecords[i].e_mem_type = IV_NA_MEM_TYPE;
+ }
+
+ isvce_fill_mem_rec_ip_t sFillMemRecIp{};
+ isvce_fill_mem_rec_op_t sFillMemRecOp{};
+
+ s_api_cmds = {ISVCE_CMD_FILL_NUM_MEM_REC, ISVCE_CMD_CT_NA};
+
+ sFillMemRecIp.s_ive_ip.u4_size = sizeof(isvce_fill_mem_rec_ip_t);
+ sFillMemRecOp.s_ive_op.u4_size = sizeof(isvce_fill_mem_rec_op_t);
+
+ sFillMemRecIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
+ sFillMemRecIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
+ sFillMemRecIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
+ sFillMemRecIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
+ sFillMemRecIp.u4_wd = mInputDims.mWidth;
+ sFillMemRecIp.u4_ht = mInputDims.mHeight;
+ sFillMemRecIp.s_ive_ip.u4_max_level = mAvcEncLevel;
+ sFillMemRecIp.s_ive_ip.e_color_format = mIvVideoColorFormat;
+ sFillMemRecIp.s_ive_ip.u4_max_ref_cnt = 2;
+ sFillMemRecIp.s_ive_ip.u4_max_reorder_cnt = 0;
+ sFillMemRecIp.s_ive_ip.u4_max_srch_rng_x = 256;
+ sFillMemRecIp.s_ive_ip.u4_max_srch_rng_y = 256;
+
+ sFillMemRecIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
+ sFillMemRecIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
+ sFillMemRecIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
+
+ if(IV_SUCCESS != isvce_api_function(0, &sFillMemRecIp, &sFillMemRecOp, &s_api_cmds))
+ {
+ return false;
+ }
+
+ if(!initMemRecs())
+ {
+ return false;
+ }
+
+ /* Codec Instance Creation */
+ isvce_init_ip_t sInitIp{};
+ isvce_init_op_t sInitOp{};
+
+ std::vector<UWORD32> sMaxBitrates(mNumSpatialLayers, 240000000);
+
+ mCodecCtx = reinterpret_cast<iv_obj_t *>(mMemRecords[0].pv_base);
+ mCodecCtx->u4_size = sizeof(iv_obj_t);
+ mCodecCtx->pv_fxns = reinterpret_cast<void *>(isvce_api_function);
+
+ sInitIp.s_ive_ip.u4_size = sizeof(isvce_init_ip_t);
+ sInitOp.s_ive_op.u4_size = sizeof(isvce_init_op_t);
+
+ s_api_cmds = {ISVCE_CMD_INIT, ISVCE_CMD_CT_NA};
+
+ sInitIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
+ sInitIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
+ sInitIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
+ sInitIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
+ sInitIp.u4_wd = mInputDims.mWidth;
+ sInitIp.u4_ht = mInputDims.mHeight;
+
+ sInitIp.s_ive_ip.u4_max_ref_cnt = 2;
+ sInitIp.s_ive_ip.u4_max_reorder_cnt = 0;
+ sInitIp.s_ive_ip.u4_max_level = mAvcEncLevel;
+ sInitIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
+
+ sInitIp.s_ive_ip.u4_enable_recon = mEnableRecon;
+ sInitIp.s_ive_ip.e_recon_color_fmt = IV_YUV_420P;
+ sInitIp.b_nalu_info_export_enable = mEnableNaluInfoExport;
+ sInitIp.s_ive_ip.e_rc_mode = mRCMode;
+ sInitIp.s_ive_ip.u4_max_framerate = 120000;
+ sInitIp.pu4_max_bitrate = sMaxBitrates.data();
+ sInitIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
+ sInitIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
+ sInitIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
+
+ sInitIp.s_ive_ip.u4_num_bframes = mBframes;
+ sInitIp.s_ive_ip.e_content_type = IV_PROGRESSIVE;
+ sInitIp.s_ive_ip.u4_max_srch_rng_x = 256;
+ sInitIp.s_ive_ip.u4_max_srch_rng_y = 256;
+ sInitIp.s_ive_ip.e_slice_mode = mSliceMode;
+ sInitIp.s_ive_ip.u4_slice_param = mSliceParam;
+ sInitIp.s_ive_ip.e_arch = mArch;
+ sInitIp.s_ive_ip.e_soc = SOC_GENERIC;
+ sInitIp.b_use_default_vui = true;
+
+ if(IV_SUCCESS != isvce_api_function(mCodecCtx, &sInitIp, &sInitOp, &s_api_cmds))
+ {
+ delMemRecs();
+
+ return false;
+ }
+
+ setDefault();
+ setNumCores();
+ logVersion();
+ getBufInfo();
+ setDimensions();
+ setFrameRate();
+ setIpeParams();
+ setBitRate();
+ setQp();
+ setAirParams();
+ setVbvParams();
+ setMeParams();
+ setGopParams();
+ setDeblockParams();
+ setProfileParams();
+ setEncMode(IVE_ENC_MODE_HEADER);
+ setVuiParams();
+ setSeiMdcvParams();
+ setSeiCllParams();
+ setSeiAveParams();
+ setSeiCcvParams();
+
+ initEncBufs();
+
+ return true;
+}
+
+void Codec::setDimensions()
+{
+ isvce_ctl_set_dimensions_ip_t s_frame_dimensions_ip{};
+ isvce_ctl_set_dimensions_op_t s_frame_dimensions_op{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DIMENSIONS};
+
+ s_frame_dimensions_ip.s_ive_ip.u4_ht = mInputDims.mHeight;
+ s_frame_dimensions_ip.s_ive_ip.u4_wd = mInputDims.mWidth;
+
+ s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = 0;
+ s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = 0;
+
+ s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_dimensions_ip_t);
+ s_frame_dimensions_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_dimensions_op_t);
+
+ isvce_api_function(mCodecCtx, &s_frame_dimensions_ip, &s_frame_dimensions_op, &s_api_cmds);
+}
+
+void Codec::setNumCores()
+{
+ isvce_ctl_set_num_cores_ip_t sNumCoresIp{};
+ isvce_ctl_set_num_cores_op_t sNumCoresOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_NUM_CORES};
+
+ sNumCoresIp.s_ive_ip.u4_num_cores = mNumCores;
+
+ sNumCoresIp.s_ive_ip.u4_timestamp_high = 0;
+ sNumCoresIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sNumCoresIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_num_cores_ip_t);
+ sNumCoresOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_num_cores_op_t);
+
+ isvce_api_function(mCodecCtx, (void *) &sNumCoresIp, (void *) &sNumCoresOp, &s_api_cmds);
+}
+
+void Codec::setDefault()
+{
+ isvce_ctl_setdefault_ip_t sDefaultIp{};
+ isvce_ctl_setdefault_op_t sDefaultOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SETDEFAULT};
+
+ sDefaultIp.s_ive_ip.u4_timestamp_high = 0;
+ sDefaultIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sDefaultIp.s_ive_ip.u4_size = sizeof(isvce_ctl_setdefault_ip_t);
+ sDefaultOp.s_ive_op.u4_size = sizeof(isvce_ctl_setdefault_op_t);
+
+ isvce_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp, &s_api_cmds);
+}
+
+void Codec::getBufInfo()
+{
+ isvce_ctl_getbufinfo_ip_t s_get_buf_info_ip{};
+ isvce_ctl_getbufinfo_op_t s_get_buf_info_op{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETBUFINFO};
+
+ s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getbufinfo_ip_t);
+ s_get_buf_info_op.s_ive_op.u4_size = sizeof(isvce_ctl_getbufinfo_op_t);
+
+ s_get_buf_info_ip.s_ive_ip.u4_max_ht = mInputDims.mHeight;
+ s_get_buf_info_ip.s_ive_ip.u4_max_wd = mInputDims.mWidth;
+ s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
+
+ isvce_api_function(mCodecCtx, &s_get_buf_info_ip, &s_get_buf_info_op, &s_api_cmds);
+}
+
+void Codec::setFrameRate()
+{
+ isvce_ctl_set_frame_rate_ip_t sFrameRateIp{};
+ isvce_ctl_set_frame_rate_op_t sFrameRateOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMERATE};
+
+ sFrameRateIp.s_ive_ip.u4_src_frame_rate = (UWORD32) mFrameRate;
+ sFrameRateIp.s_ive_ip.u4_tgt_frame_rate = (UWORD32) mFrameRate;
+
+ sFrameRateIp.s_ive_ip.u4_timestamp_high = 0;
+ sFrameRateIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sFrameRateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_rate_ip_t);
+ sFrameRateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_rate_op_t);
+
+ isvce_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp, &s_api_cmds);
+}
+
+void Codec::setIpeParams()
+{
+ isvce_ctl_set_ipe_params_ip_t sIpeParamsIp{};
+ isvce_ctl_set_ipe_params_op_t sIpeParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_IPE_PARAMS};
+
+ sIpeParamsIp.s_ive_ip.u4_enable_intra_4x4 = mIntra4x4;
+ sIpeParamsIp.s_ive_ip.u4_enc_speed_preset = mEncSpeed;
+
+ sIpeParamsIp.s_ive_ip.u4_timestamp_high = 0;
+ sIpeParamsIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sIpeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_ipe_params_ip_t);
+ sIpeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_ipe_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp, &s_api_cmds);
+}
+
+void Codec::setBitRate()
+{
+ isvce_ctl_set_bitrate_ip_t sBitrateIp{};
+ isvce_ctl_set_bitrate_op_t sBitrateOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_BITRATE};
+ std::vector<UWORD32> sTargetBitrates(mNumSpatialLayers, mBitrate);
+
+ sBitrateIp.pu4_target_bitrate = sTargetBitrates.data();
+
+ sBitrateIp.s_ive_ip.u4_timestamp_high = 0;
+ sBitrateIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sBitrateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_bitrate_ip_t);
+ sBitrateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_bitrate_op_t);
+
+ isvce_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp, &s_api_cmds);
+}
+
+void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType)
+{
+ isvce_ctl_set_frame_type_ip_t sFrameTypeIp{};
+ isvce_ctl_set_frame_type_op_t sFrameTypeOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMETYPE};
+
+ sFrameTypeIp.s_ive_ip.e_frame_type = eFrameType;
+
+ sFrameTypeIp.s_ive_ip.u4_timestamp_high = 0;
+ sFrameTypeIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sFrameTypeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_type_ip_t);
+ sFrameTypeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_type_op_t);
+
+ isvce_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp, &s_api_cmds);
+}
+
+void Codec::setQp()
+{
+ constexpr UWORD8 u1NumSliceTypes = 3;
+ isvce_ctl_set_qp_ip_t s_QpIp{};
+ isvce_ctl_set_qp_op_t s_QpOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_QP};
+ std::vector<UWORD32> sQps(u1NumSliceTypes * mNumSpatialLayers);
+ std::vector<UWORD32> sMinQps(u1NumSliceTypes * mNumSpatialLayers);
+ std::vector<UWORD32> sMaxQps(u1NumSliceTypes * mNumSpatialLayers);
+
+ s_QpIp.pu4_i_qp = sQps.data();
+ s_QpIp.pu4_i_qp_min = sMinQps.data();
+ s_QpIp.pu4_i_qp_max = sMaxQps.data();
+
+ s_QpIp.pu4_p_qp = sQps.data() + mNumSpatialLayers;
+ s_QpIp.pu4_p_qp_min = sMinQps.data() + mNumSpatialLayers;
+ s_QpIp.pu4_p_qp_max = sMaxQps.data() + mNumSpatialLayers;
+
+ s_QpIp.pu4_b_qp = sQps.data() + mNumSpatialLayers * 2;
+ s_QpIp.pu4_b_qp_min = sMinQps.data() + mNumSpatialLayers * 2;
+ s_QpIp.pu4_b_qp_max = sMaxQps.data() + mNumSpatialLayers * 2;
+
+ for(auto i = 0; i < mNumSpatialLayers; i++)
+ {
+ s_QpIp.pu4_i_qp[i] = m_I_QP;
+ s_QpIp.pu4_i_qp_max[i] = kMaxQP;
+ s_QpIp.pu4_i_qp_min[i] = kMinQP;
+
+ s_QpIp.pu4_p_qp[i] = m_P_QP;
+ s_QpIp.pu4_p_qp_max[i] = kMaxQP;
+ s_QpIp.pu4_p_qp_min[i] = kMinQP;
+
+ s_QpIp.pu4_b_qp[i] = m_B_QP;
+ s_QpIp.pu4_b_qp_max[i] = kMaxQP;
+ s_QpIp.pu4_b_qp_min[i] = kMinQP;
+ }
+
+ s_QpIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_qp_ip_t);
+ s_QpOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_qp_op_t);
+
+ isvce_api_function(mCodecCtx, &s_QpIp, &s_QpOp, &s_api_cmds);
+}
+
+void Codec::setEncMode(IVE_ENC_MODE_T eEncMode)
+{
+ isvce_ctl_set_enc_mode_ip_t sEncModeIp{};
+ isvce_ctl_set_enc_mode_op_t sEncModeOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ENC_MODE};
+
+ sEncModeIp.s_ive_ip.e_enc_mode = eEncMode;
+
+ sEncModeIp.s_ive_ip.u4_timestamp_high = 0;
+ sEncModeIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sEncModeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_enc_mode_ip_t);
+ sEncModeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_enc_mode_op_t);
+
+ isvce_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp, &s_api_cmds);
+}
+
+void Codec::setVbvParams()
+{
+ isvce_ctl_set_vbv_params_ip_t sVbvIp{};
+ isvce_ctl_set_vbv_params_op_t sVbvOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VBV_PARAMS};
+ std::vector<UWORD32> sBufferDelays(mNumSpatialLayers, 1000);
+
+ sVbvIp.pu4_vbv_buffer_delay = sBufferDelays.data();
+
+ sVbvIp.s_ive_ip.u4_timestamp_high = 0;
+ sVbvIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sVbvIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_vbv_params_ip_t);
+ sVbvOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_vbv_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sVbvIp, &sVbvOp, &s_api_cmds);
+}
+
+void Codec::setAirParams()
+{
+ isvce_ctl_set_air_params_ip_t sAirIp{};
+ isvce_ctl_set_air_params_op_t sAirOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_AIR_PARAMS};
+
+ sAirIp.s_ive_ip.e_air_mode = mAirMode;
+ sAirIp.s_ive_ip.u4_air_refresh_period = mIntraRefresh;
+
+ sAirIp.s_ive_ip.u4_timestamp_high = 0;
+ sAirIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sAirIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_air_params_ip_t);
+ sAirOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_air_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sAirIp, &sAirOp, &s_api_cmds);
+}
+
+void Codec::setMeParams()
+{
+ isvce_ctl_set_me_params_ip_t sMeParamsIp{};
+ isvce_ctl_set_me_params_op_t sMeParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ME_PARAMS};
+
+ sMeParamsIp.s_ive_ip.u4_enable_fast_sad = mEnableFastSad;
+ sMeParamsIp.s_ive_ip.u4_enable_alt_ref = mEnableAltRef;
+
+ sMeParamsIp.s_ive_ip.u4_enable_hpel = mHalfPelEnable;
+ sMeParamsIp.s_ive_ip.u4_enable_qpel = mQPelEnable;
+ sMeParamsIp.s_ive_ip.u4_me_speed_preset = mMeSpeedPreset;
+ sMeParamsIp.s_ive_ip.u4_srch_rng_x = mSearchRangeX;
+ sMeParamsIp.s_ive_ip.u4_srch_rng_y = mSearchRangeY;
+
+ sMeParamsIp.s_ive_ip.u4_timestamp_high = 0;
+ sMeParamsIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sMeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_me_params_ip_t);
+ sMeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_me_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp, &s_api_cmds);
+}
+
+void Codec::setGopParams()
+{
+ isvce_ctl_set_gop_params_ip_t sGopParamsIp{};
+ isvce_ctl_set_gop_params_op_t sGopParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_GOP_PARAMS};
+
+ sGopParamsIp.s_ive_ip.u4_i_frm_interval = mIInterval;
+ sGopParamsIp.s_ive_ip.u4_idr_frm_interval = mIDRInterval;
+
+ sGopParamsIp.s_ive_ip.u4_timestamp_high = 0;
+ sGopParamsIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sGopParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_gop_params_ip_t);
+ sGopParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_gop_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp, &s_api_cmds);
+}
+
+void Codec::setProfileParams()
+{
+ isvce_ctl_set_profile_params_ip_t sProfileParamsIp{};
+ isvce_ctl_set_profile_params_op_t sProfileParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_PROFILE_PARAMS};
+
+ sProfileParamsIp.s_ive_ip.e_profile = mProfile;
+ if(sProfileParamsIp.s_ive_ip.e_profile == IV_PROFILE_BASE)
+ {
+ sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 0;
+ }
+ else
+ {
+ sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 1;
+ }
+
+ sProfileParamsIp.s_ive_ip.u4_timestamp_high = 0;
+ sProfileParamsIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sProfileParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_profile_params_ip_t);
+ sProfileParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_profile_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp, &s_api_cmds);
+}
+
+void Codec::setDeblockParams()
+{
+ isvce_ctl_set_deblock_params_ip_t sDeblockParamsIp{};
+ isvce_ctl_set_deblock_params_op_t sDeblockParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS};
+
+ sDeblockParamsIp.s_ive_ip.u4_disable_deblock_level = mDisableDeblockLevel;
+
+ sDeblockParamsIp.s_ive_ip.u4_timestamp_high = 0;
+ sDeblockParamsIp.s_ive_ip.u4_timestamp_low = 0;
+
+ sDeblockParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_deblock_params_ip_t);
+ sDeblockParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_deblock_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp, &s_api_cmds);
+}
+
+void Codec::setVuiParams()
+{
+ isvce_vui_ip_t sVuiParamsIp{};
+ isvce_vui_op_t sVuiParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VUI_PARAMS};
+
+ sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag;
+ sVuiParamsIp.u1_aspect_ratio_idc = 0;
+ sVuiParamsIp.u2_sar_width = 0;
+ sVuiParamsIp.u2_sar_height = 0;
+ sVuiParamsIp.u1_overscan_info_present_flag = 0;
+ sVuiParamsIp.u1_overscan_appropriate_flag = 0;
+ sVuiParamsIp.u1_video_signal_type_present_flag = 1;
+ sVuiParamsIp.u1_video_format = 0;
+ sVuiParamsIp.u1_video_full_range_flag = 0;
+ sVuiParamsIp.u1_colour_description_present_flag = 0;
+ sVuiParamsIp.u1_colour_primaries = 0;
+ sVuiParamsIp.u1_transfer_characteristics = 0;
+ sVuiParamsIp.u1_matrix_coefficients = 0;
+ sVuiParamsIp.u1_chroma_loc_info_present_flag = 0;
+ sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0;
+ sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0;
+ sVuiParamsIp.u1_vui_timing_info_present_flag = 0;
+ sVuiParamsIp.u4_vui_num_units_in_tick = 0;
+ sVuiParamsIp.u4_vui_time_scale = 0;
+ sVuiParamsIp.u1_fixed_frame_rate_flag = 0;
+ sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag;
+ sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag;
+ sVuiParamsIp.u1_low_delay_hrd_flag = 0;
+ sVuiParamsIp.u1_pic_struct_present_flag = 0;
+ sVuiParamsIp.u1_bitstream_restriction_flag = 0;
+ sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0;
+ sVuiParamsIp.u1_max_bytes_per_pic_denom = 0;
+ sVuiParamsIp.u1_max_bits_per_mb_denom = 0;
+ sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0;
+ sVuiParamsIp.u1_log2_max_mv_length_vertical = 0;
+ sVuiParamsIp.u1_num_reorder_frames = 0;
+ sVuiParamsIp.u1_max_dec_frame_buffering = 0;
+
+ sVuiParamsIp.u4_size = sizeof(isvce_vui_ip_t);
+ sVuiParamsOp.u4_size = sizeof(isvce_vui_op_t);
+
+ isvce_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp, &s_api_cmds);
+}
+
+void Codec::setSeiMdcvParams()
+{
+ isvce_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{};
+ isvce_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS};
+
+ sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag;
+ if(mSeiMdcvFlag)
+ {
+ for(int i4_count = 0; i4_count < kNumSeiMdcvPrimaries; ++i4_count)
+ {
+ sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000;
+ sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000;
+ }
+ sSeiMdcvParamsIp.u2_white_point_x = 30000;
+ sSeiMdcvParamsIp.u2_white_point_y = 35000;
+ sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000;
+ sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000;
+ }
+
+ sSeiMdcvParamsIp.u4_timestamp_high = 0;
+ sSeiMdcvParamsIp.u4_timestamp_low = 0;
+
+ sSeiMdcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_ip_t);
+ sSeiMdcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp, &s_api_cmds);
+}
+
+void Codec::setSeiCllParams()
+{
+ isvce_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{};
+ isvce_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS};
+
+ sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag;
+
+ if(mSeiCllFlag)
+ {
+ sSeiCllParamsIp.u2_max_content_light_level = 0;
+ sSeiCllParamsIp.u2_max_pic_average_light_level = 0;
+ }
+
+ sSeiCllParamsIp.u4_timestamp_high = 0;
+ sSeiCllParamsIp.u4_timestamp_low = 0;
+
+ sSeiCllParamsIp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_ip_t);
+ sSeiCllParamsOp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp, &s_api_cmds);
+}
+
+void Codec::setSeiAveParams()
+{
+ isvce_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{};
+ isvce_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS};
+
+ sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag;
+
+ if(mSeiAveFlag)
+ {
+ sSeiAveParamsIp.u4_ambient_illuminance = 1;
+ sSeiAveParamsIp.u2_ambient_light_x = 0;
+ sSeiAveParamsIp.u2_ambient_light_y = 0;
+ }
+
+ sSeiAveParamsIp.u4_timestamp_high = 0;
+ sSeiAveParamsIp.u4_timestamp_low = 0;
+
+ sSeiAveParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_ip_t);
+ sSeiAveParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp, &s_api_cmds);
+}
+
+void Codec::setSeiCcvParams()
+{
+ isvce_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{};
+ isvce_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS};
+
+ sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag;
+
+ if(mSeiCcvFlag)
+ {
+ sSeiCcvParamsIp.u1_ccv_cancel_flag = 0;
+ sSeiCcvParamsIp.u1_ccv_persistence_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0;
+ for(int i4_count = 0; i4_count < kNumSeiCcvPrimaries; ++i4_count)
+ {
+ sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1;
+ sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1;
+ }
+ sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1;
+ sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1;
+ sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1;
+ }
+
+ sSeiCcvParamsIp.u4_timestamp_high = 0;
+ sSeiCcvParamsIp.u4_timestamp_low = 0;
+
+ sSeiCcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_ip_t);
+ sSeiCcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_op_t);
+
+ isvce_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp, &s_api_cmds);
+}
+
+void Codec::logVersion()
+{
+ isvce_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip{};
+ isvce_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op{};
+
+ CHAR ac_version_string[512];
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETVERSION};
+
+ s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *) ac_version_string;
+ s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string);
+ s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getversioninfo_ip_t);
+ s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(isvce_ctl_getversioninfo_op_t);
+
+ isvce_api_function(mCodecCtx, (void *) &s_ctl_set_getversioninfo_ip,
+ (void *) &s_ctl_set_getversioninfo_op, &s_api_cmds);
+}
+
+bool Codec::encodeFrames(const UWORD8 *data, size_t size)
+{
+ isvce_video_encode_ip_t sEncodeIp{};
+ isvce_video_encode_op_t sEncodeOp{};
+
+ isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_ENCODE, ISVCE_CMD_CT_NA};
+ iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_ive_ip.s_inp_buf;
+ iv_raw_buf_t *psRecRawBuf = &sEncodeIp.s_ive_ip.s_recon_buf;
+
+ size_t frameSize = mInputDims.getFrameSize();
+ auto bytesLeft = std::min(size, frameSize);
+ auto bytesConsumed = 0;
+ UWORD32 numFrames = 0;
+
+ sEncodeIp.s_ive_ip.s_out_buf.pv_buf = mEncBufs.mOutputBuf.data();
+ sEncodeIp.s_ive_ip.s_out_buf.u4_bytes = 0;
+ sEncodeIp.s_ive_ip.s_out_buf.u4_bufsize = static_cast<UWORD32>(mEncBufs.mOutputBuf.size());
+ sEncodeOp.s_ive_op.s_out_buf.pv_buf = nullptr;
+ sEncodeIp.s_ive_ip.pv_bufs = nullptr;
+ sEncodeIp.s_ive_ip.pv_mb_info = nullptr;
+ sEncodeIp.s_ive_ip.pv_pic_info = nullptr;
+ sEncodeIp.s_ive_ip.u4_mb_info_type = 0;
+ sEncodeIp.s_ive_ip.u4_pic_info_type = 0;
+ sEncodeIp.s_ive_ip.u4_is_last = 0;
+
+ sEncodeIp.s_ive_ip.u4_timestamp_high = 0;
+ sEncodeIp.s_ive_ip.u4_timestamp_low = 0;
+
+ memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t));
+ psInpRawBuf->u4_size = sizeof(iv_raw_buf_t);
+ psInpRawBuf->e_color_fmt = mIvVideoColorFormat;
+
+ sEncodeIp.s_ive_ip.u4_size = sizeof(isvce_video_encode_ip_t);
+ sEncodeOp.s_ive_op.u4_size = sizeof(isvce_video_encode_op_t);
+
+ isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
+
+ if(mEnableNaluInfoExport)
+ {
+ sEncodeIp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data();
+ sEncodeOp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data() + mNumSpatialLayers;
+ }
+
+ while(!sEncodeOp.s_ive_op.u4_is_last && (kMaxEncodeCalls > (mNumSpatialLayers * numFrames)))
+ {
+ if(mEnableRecon)
+ {
+ setEncParams(psRecRawBuf, mEncBufs.mReconBuf, mInputDims);
+ }
+
+ if(mEnableNaluInfoExport)
+ {
+ for(auto i = 0; i < mNumSpatialLayers; i++)
+ {
+ sEncodeIp.ps_nalu_info_buf[i].pu1_buf = mEncBufs.mNaluInfoDataBuf[i].data();
+ sEncodeIp.ps_nalu_info_buf[i].u4_num_bytes = 0;
+ sEncodeIp.ps_nalu_info_buf[i].u4_buf_size =
+ static_cast<UWORD32>(mEncBufs.mNaluInfoDataBuf[i].size());
+ }
+ }
+
+ if(size > 0)
+ {
+ bytesLeft = std::min(size, frameSize);
+ std::copy(data, data + bytesLeft, mEncBufs.mInputBuf.begin());
+ std::fill(std::next(mEncBufs.mInputBuf.begin(), bytesLeft), mEncBufs.mInputBuf.end(),
+ data[0]);
+ setEncParams(psInpRawBuf, mEncBufs.mInputBuf, mInputDims, mIvVideoColorFormat);
+
+ bytesConsumed = bytesLeft;
+ }
+ else
+ {
+ sEncodeIp.s_ive_ip.u4_is_last = 1;
+
+ for(auto i = 0; i < 3; i++)
+ {
+ psInpRawBuf->apv_bufs[i] = nullptr;
+ }
+
+ bytesConsumed = 0;
+ }
+
+ if(mIsForceIdrEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
+ {
+ if(numFrames == mForceIdrInterval)
+ {
+ setFrameType(IV_IDR_FRAME);
+ }
+ }
+
+ if(mIsDynamicBitRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
+ {
+ if(numFrames == mDynamicBitRateInterval)
+ {
+ if(data[0] & 0x01)
+ {
+ mBitrate *= 2;
+ }
+ else
+ {
+ mBitrate /= 2;
+ }
+
+ setBitRate();
+ }
+ }
+
+ if(mIsDynamicFrameRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
+ {
+ if(numFrames == mDynamicFrameRateInterval)
+ {
+ if(size > 1 && data[1] & 0x01)
+ {
+ mFrameRate *= 2;
+ }
+ else
+ {
+ mFrameRate /= 2;
+ }
+
+ setFrameRate();
+ }
+ }
+
+ isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
+
+ if(!sEncodeOp.s_ive_op.u4_is_last)
+ {
+ numFrames++;
+ data += bytesConsumed;
+ size -= bytesConsumed;
+ }
+ }
+
+ return true;
+}
+
+void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
+ IV_COLOR_FORMAT_T colorFormat)
+{
+ switch(colorFormat)
+ {
+ case IV_YUV_420SP_UV:
+ case IV_YUV_420SP_VU:
+ {
+ WORD32 yStride = dims.mWidth;
+ WORD32 uStride = dims.mWidth / 2;
+
+ psInpRawBuf->apv_bufs[0] = buf.data();
+ psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
+
+ psInpRawBuf->au4_wd[0] = dims.mWidth;
+ psInpRawBuf->au4_wd[1] = dims.mWidth;
+
+ psInpRawBuf->au4_ht[0] = dims.mHeight;
+ psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
+
+ psInpRawBuf->au4_strd[0] = yStride;
+ psInpRawBuf->au4_strd[1] = uStride;
+
+ break;
+ }
+ default:
+ {
+ WORD32 yStride = dims.mWidth;
+ WORD32 uStride = dims.mWidth / 2;
+ WORD32 vStride = dims.mWidth / 2;
+
+ psInpRawBuf->apv_bufs[0] = buf.data();
+ psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
+ psInpRawBuf->apv_bufs[2] = buf.data() + (dims.mWidth * dims.mHeight * 5) / 4;
+
+ psInpRawBuf->au4_wd[0] = dims.mWidth;
+ psInpRawBuf->au4_wd[1] = dims.mWidth / 2;
+ psInpRawBuf->au4_wd[2] = dims.mWidth / 2;
+
+ psInpRawBuf->au4_ht[0] = dims.mHeight;
+ psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
+ psInpRawBuf->au4_ht[2] = dims.mHeight / 2;
+
+ psInpRawBuf->au4_strd[0] = yStride;
+ psInpRawBuf->au4_strd[1] = uStride;
+ psInpRawBuf->au4_strd[2] = vStride;
+
+ break;
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const UWORD8 *data, size_t size)
+{
+ if(size < IDX_LAST)
+ {
+ return 0;
+ }
+
+ std::unique_ptr<Codec> codec = std::make_unique<Codec>();
+
+ if(codec->initEncoder(data))
+ {
+ codec->encodeFrames(data, size);
+ }
+
+ return 0;
+}
diff --git a/libavc_blocklist.txt b/libavc_blocklist.txt
index 30a2cef..1da77c6 100644
--- a/libavc_blocklist.txt
+++ b/libavc_blocklist.txt
@@ -27,6 +27,7 @@ fun:irc_initialise_rate_control
# Numerous overflows in multiple functions, CAVLC is a compression technique.
src:*/decoder/ih264d_parse_cavlc.c
src:*/encoder/ih264e_cavlc.c
+src:*/encoder/svc/isvce_cavlc.c
# Performance related
fun:ih264e_pack_c_mb
diff --git a/test/Android.bp b/test/Android.bp
index b859f49..7a9ac03 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -7,10 +7,10 @@ package {
default_applicable_licenses: ["external_libavc_license"],
}
-cc_test {
- name: "avcdec",
+cc_defaults {
+ name: "avcdec_defaults",
gtest: false,
- host_supported:true,
+ host_supported: true,
cflags: [
"-DPROFILE_ENABLE",
"-DARM",
@@ -19,11 +19,6 @@ cc_test {
"-Wall",
"-Werror",
],
- local_include_dirs: [
- "decoder/",
- ],
- srcs: ["decoder/main.c"],
- static_libs: ["libavcdec"],
shared_libs: ["liblog"],
target: {
darwin: {
@@ -32,11 +27,10 @@ cc_test {
},
}
-cc_test {
- name: "avcenc",
+cc_defaults {
+ name: "avcenc_defaults",
gtest: false,
host_supported: true,
-
cflags: [
"-DPROFILE_ENABLE",
"-DARM",
@@ -47,8 +41,37 @@ cc_test {
"-Wno-unused-variable",
],
local_include_dirs: [
- "encoder/",
+ "encoder",
],
+ static_libs: ["libavcenc"],
+}
+
+cc_test {
+ name: "avcdec",
+ defaults: ["avcdec_defaults"],
+ local_include_dirs: [
+ "decoder",
+ ],
+ srcs: ["decoder/main.c"],
+ static_libs: ["libavcdec"],
+}
+
+cc_test {
+ name: "mvcdec",
+ defaults: ["avcdec_defaults"],
+ local_include_dirs: [
+ "mvcdec",
+ ],
+ srcs: ["mvcdec/main.c"],
+ static_libs: [
+ "libmvcdec",
+ ],
+}
+
+cc_test {
+ name: "avcenc",
+ defaults: ["avcenc_defaults"],
+
srcs: [
"encoder/main.c",
"encoder/psnr.c",
@@ -56,5 +79,42 @@ cc_test {
"encoder/output.c",
"encoder/recon.c",
],
- static_libs: ["libavcenc"],
+}
+
+cc_test {
+ name: "svcenc",
+ defaults: ["avcenc_defaults"],
+
+ local_include_dirs: [
+ "svcenc",
+ ],
+
+ srcs: [
+ "svcenc/main.c",
+ "svcenc/input.c",
+ "svcenc/output.c",
+ "svcenc/psnr.c",
+ "svcenc/recon.c",
+ ],
+
+ static_libs: [
+ "libsvcenc",
+ ],
+}
+
+cc_test {
+ name: "svcdec",
+ defaults: ["avcdec_defaults"],
+
+ local_include_dirs: [
+ "svcdec",
+ ],
+
+ srcs: [
+ "svcdec/main.c",
+ ],
+
+ static_libs: [
+ "libsvcdec",
+ ],
}
diff --git a/test/decoder/avcdec.cmake b/test/decoder/avcdec.cmake
index e626611..c244131 100644
--- a/test/decoder/avcdec.cmake
+++ b/test/decoder/avcdec.cmake
@@ -1 +1,2 @@
libavc_add_executable(avcdec libavcdec SOURCES ${AVC_ROOT}/test/decoder/main.c)
+target_compile_definitions(avcdec PRIVATE PROFILE_ENABLE MD5_DISABLE)
diff --git a/test/decoder/main.c b/test/decoder/main.c
index bddf0b8..6cbf466 100644
--- a/test/decoder/main.c
+++ b/test/decoder/main.c
@@ -1887,6 +1887,63 @@ void flush_output(iv_obj_t *codec_obj,
s_ctl_get_sei_ccv_params_op.u4_error_code);
}
}
+ /*************************************************************************/
+ /* Get SEI SII parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_sii_params_present_flag)
+ {
+ ih264d_ctl_get_sei_sii_params_ip_t s_ctl_get_sei_sii_params_ip = {0};
+ ih264d_ctl_get_sei_sii_params_op_t s_ctl_get_sei_sii_params_op = {0};
+
+ s_ctl_get_sei_sii_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_sii_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_SII_PARAMS;
+ s_ctl_get_sei_sii_params_ip.u4_size =
+ sizeof(ih264d_ctl_get_sei_sii_params_ip_t);
+ s_ctl_get_sei_sii_params_op.u4_size =
+ sizeof(ih264d_ctl_get_sei_sii_params_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_sii_params_ip,
+ (void *) &s_ctl_get_sei_sii_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("SII SEI params not present : Error %x\n",
+ s_ctl_get_sei_sii_params_op.u4_error_code);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get SEI film grain parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_fgc_params_present_flag)
+ {
+ ih264d_ctl_get_sei_fgc_params_ip_t s_ctl_get_sei_fgc_params_ip;
+ ih264d_ctl_get_sei_fgc_params_op_t s_ctl_get_sei_fgc_params_op;
+
+ memset(&s_ctl_get_sei_fgc_params_ip, 0,
+ sizeof(ih264d_ctl_get_sei_fgc_params_ip_t));
+ memset(&s_ctl_get_sei_fgc_params_op, 0,
+ sizeof(ih264d_ctl_get_sei_fgc_params_op_t));
+
+ s_ctl_get_sei_fgc_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_fgc_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_FGC_PARAMS;
+ s_ctl_get_sei_fgc_params_ip.u4_size =
+ sizeof(ih264d_ctl_get_sei_fgc_params_ip_t);
+ s_ctl_get_sei_fgc_params_op.u4_size =
+ sizeof(ih264d_ctl_get_sei_fgc_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_fgc_params_ip,
+ (void *) &s_ctl_get_sei_fgc_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("FGC SEI params not present : Error %x\n",
+ s_ctl_get_sei_fgc_params_op.u4_error_code);
+ }
+ }
if(ps_app_ctx->u4_file_save_flag)
{
@@ -3382,6 +3439,58 @@ int main(WORD32 argc, CHAR *argv[])
s_ctl_get_sei_ccv_params_op.u4_error_code);
}
}
+ /*************************************************************************/
+ /* Get SEI SII parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_sii_params_present_flag)
+ {
+ ih264d_ctl_get_sei_sii_params_ip_t s_ctl_get_sei_sii_params_ip = {0};
+ ih264d_ctl_get_sei_sii_params_op_t s_ctl_get_sei_sii_params_op = {0};
+
+ s_ctl_get_sei_sii_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_sii_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_SII_PARAMS;
+ s_ctl_get_sei_sii_params_ip.u4_size = sizeof(ih264d_ctl_get_sei_sii_params_ip_t);
+ s_ctl_get_sei_sii_params_op.u4_size = sizeof(ih264d_ctl_get_sei_sii_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_sii_params_ip,
+ (void *) &s_ctl_get_sei_sii_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("SII SEI params not present : Error %x\n",
+ s_ctl_get_sei_sii_params_op.u4_error_code);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get SEI FGC parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_fgc_params_present_flag)
+ {
+ ih264d_ctl_get_sei_fgc_params_ip_t s_ctl_get_sei_fgc_params_ip;
+ ih264d_ctl_get_sei_fgc_params_op_t s_ctl_get_sei_fgc_params_op;
+
+ memset(&s_ctl_get_sei_fgc_params_ip, 0, sizeof(ih264d_ctl_get_sei_fgc_params_ip_t));
+ memset(&s_ctl_get_sei_fgc_params_op, 0, sizeof(ih264d_ctl_get_sei_fgc_params_op_t));
+
+ s_ctl_get_sei_fgc_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_fgc_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_FGC_PARAMS;
+ s_ctl_get_sei_fgc_params_ip.u4_size = sizeof(ih264d_ctl_get_sei_fgc_params_ip_t);
+ s_ctl_get_sei_fgc_params_op.u4_size = sizeof(ih264d_ctl_get_sei_fgc_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_fgc_params_ip,
+ (void *) &s_ctl_get_sei_fgc_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("FGC SEI params not present : Error %x\n",
+ s_ctl_get_sei_fgc_params_op.u4_error_code);
+ }
+ }
if((1 == s_app_ctx.display) &&
(1 == ps_video_decode_op->u4_output_present))
diff --git a/test/encoder/app.h b/test/encoder/app.h
index 232a59b..4abbe54 100644
--- a/test/encoder/app.h
+++ b/test/encoder/app.h
@@ -354,9 +354,18 @@ typedef struct
UWORD32 u4_ccv_max_luminance_value;
UWORD32 u4_ccv_avg_luminance_value;
+ UWORD32 u4_shutter_interval_info_present_flag;
+ UWORD32 u4_sii_sub_layer_idx;
+ UWORD32 u4_sii_time_scale;
+ UWORD32 u4_fixed_shutter_interval_within_cvs_flag;
+ UWORD32 u4_sii_num_units_in_shutter_interval;
+ UWORD32 u4_sii_max_sub_layers_minus1;
+ UWORD32 au4_sub_layer_num_units_in_shutter_interval[SII_MAX_SUB_LAYERS];
+
ih264e_ctl_set_sei_mdcv_params_ip_t s_sei_mdcv_params;
ih264e_ctl_set_sei_cll_params_ip_t s_sei_cll_params;
ih264e_ctl_set_sei_ave_params_ip_t s_sei_ave_params;
+ ih264e_ctl_set_sei_sii_params_ip_t s_sei_sii_params;
} app_ctxt_t;
diff --git a/test/encoder/avcenc.cmake b/test/encoder/avcenc.cmake
index 99f93db..9fbd565 100644
--- a/test/encoder/avcenc.cmake
+++ b/test/encoder/avcenc.cmake
@@ -8,3 +8,4 @@ list(
"${AVC_ROOT}/test/encoder/recon.c")
libavc_add_executable(avcenc libavcenc SOURCES ${AVCENC_SRCS})
+target_compile_definitions(avcenc PRIVATE PROFILE_ENABLE MD5_DISABLE)
diff --git a/test/encoder/main.c b/test/encoder/main.c
index 471d630..25a063c 100644
--- a/test/encoder/main.c
+++ b/test/encoder/main.c
@@ -28,6 +28,7 @@
#include <stddef.h>
#include <assert.h>
#include <string.h>
+#include <stdbool.h>
#ifdef WINDOWS_TIMER
#include "windows.h"
@@ -1724,12 +1725,95 @@ void set_sei_ccv_params(app_ctxt_t *ps_app_ctxt,
return;
}
+void set_sei_sii_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+ int i;
+ bool au4_sub_layer_num_units_in_shutter_interval_flag = 0;
+
+ ih264e_ctl_set_sei_sii_params_ip_t s_sei_sii_params_ip = {0};
+ ih264e_ctl_set_sei_sii_params_op_t s_sei_sii_params_op = {0};
+
+ s_sei_sii_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+ s_sei_sii_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_SII_PARAMS;
+
+ s_sei_sii_params_ip.u4_sii_sub_layer_idx = ps_app_ctxt->u4_sii_sub_layer_idx;
+
+ if(0 == s_sei_sii_params_ip.u4_sii_sub_layer_idx)
+ {
+ s_sei_sii_params_ip.u1_shutter_interval_info_present_flag =
+ (UWORD8) ps_app_ctxt->u4_shutter_interval_info_present_flag;
+
+ if(1 == s_sei_sii_params_ip.u1_shutter_interval_info_present_flag)
+ {
+ s_sei_sii_params_ip.u4_sii_time_scale = ps_app_ctxt->u4_sii_time_scale;
+ s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag =
+ (UWORD8) ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag;
+
+ if(1 == s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag)
+ {
+ s_sei_sii_params_ip.u4_sii_num_units_in_shutter_interval =
+ ps_app_ctxt->u4_sii_num_units_in_shutter_interval;
+ }
+ else
+ {
+ s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1 =
+ (UWORD8) ps_app_ctxt->u4_sii_max_sub_layers_minus1;
+
+ for(i = 0; i <= s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1; i++)
+ {
+ s_sei_sii_params_ip.au4_sub_layer_num_units_in_shutter_interval[i] =
+ ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval[i];
+ }
+ }
+ }
+ }
+
+ s_sei_sii_params_ip.u4_timestamp_high = u4_timestamp_high;
+ s_sei_sii_params_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_sei_sii_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_ip_t);
+ s_sei_sii_params_op.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_op_t);
+
+ for(i = 0; i <= s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1; i++)
+ {
+ au4_sub_layer_num_units_in_shutter_interval_flag =
+ (au4_sub_layer_num_units_in_shutter_interval_flag ||
+ (ps_app_ctxt->s_sei_sii_params.au4_sub_layer_num_units_in_shutter_interval[i] !=
+ s_sei_sii_params_ip.au4_sub_layer_num_units_in_shutter_interval[i]));
+ }
+
+ if((ps_app_ctxt->s_sei_sii_params.u4_sii_sub_layer_idx !=
+ s_sei_sii_params_ip.u4_sii_sub_layer_idx) ||
+ (ps_app_ctxt->s_sei_sii_params.u1_shutter_interval_info_present_flag !=
+ s_sei_sii_params_ip.u1_shutter_interval_info_present_flag) ||
+ (ps_app_ctxt->s_sei_sii_params.u4_sii_time_scale != s_sei_sii_params_ip.u4_sii_time_scale) ||
+ (ps_app_ctxt->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag !=
+ s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag) ||
+ (ps_app_ctxt->s_sei_sii_params.u4_sii_num_units_in_shutter_interval !=
+ s_sei_sii_params_ip.u4_sii_num_units_in_shutter_interval) ||
+ (ps_app_ctxt->s_sei_sii_params.u1_sii_max_sub_layers_minus1 !=
+ s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1) ||
+ au4_sub_layer_num_units_in_shutter_interval_flag)
+ {
+ status =
+ ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_sii_params_ip, &s_sei_sii_params_op);
+ if(status != IV_SUCCESS)
+ {
+ printf("Unable to set sei sii params = 0x%x\n", s_sei_sii_params_op.u4_error_code);
+ }
+ ps_app_ctxt->s_sei_sii_params = s_sei_sii_params_ip;
+ }
+ return;
+}
+
#define PEAK_WINDOW_SIZE 8
void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
{
- ih264e_video_encode_ip_t ih264e_video_encode_ip;
- ih264e_video_encode_op_t ih264e_video_encode_op;
+ ih264e_video_encode_ip_t ih264e_video_encode_ip = {0};
+ ih264e_video_encode_op_t ih264e_video_encode_op = {0};
ive_video_encode_ip_t *ps_video_encode_ip = &ih264e_video_encode_ip.s_ive_ip;
ive_video_encode_op_t *ps_video_encode_op = &ih264e_video_encode_op.s_ive_op;
@@ -1836,6 +1920,59 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
}
}
+ /*****************************************************************************/
+ /* Video control Set in Encode header mode */
+ /*****************************************************************************/
+ set_enc_mode(ps_app_ctxt, -1, -1, IVE_ENC_MODE_HEADER);
+
+ // Encode header
+ memset(&ih264e_video_encode_ip, 0, sizeof(ih264e_video_encode_ip));
+ memset(&ih264e_video_encode_op, 0, sizeof(ih264e_video_encode_op));
+
+ ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t);
+ ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t);
+
+ ps_inp_raw_buf->apv_bufs[0] = NULL;
+ ps_inp_raw_buf->apv_bufs[1] = NULL;
+ ps_inp_raw_buf->apv_bufs[2] = NULL;
+
+ ps_video_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
+ ps_video_encode_ip->pv_bufs = NULL;
+ ps_video_encode_ip->pv_mb_info = NULL;
+ ps_video_encode_ip->pv_pic_info = NULL;
+ ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;
+ ps_video_encode_ip->u4_is_last = 0;
+ ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type;
+ ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;
+ ps_video_encode_ip->s_out_buf.pv_buf = ps_app_ctxt->as_output_buf[0].pu1_buf;
+ ps_video_encode_ip->s_out_buf.u4_bytes = 0;
+ ps_video_encode_ip->s_out_buf.u4_bufsize = ps_app_ctxt->as_output_buf[0].u4_buf_size;
+ ps_video_encode_ip->u4_timestamp_high = 0;
+ ps_video_encode_ip->u4_timestamp_low = 0;
+
+ status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, &ih264e_video_encode_op);
+ if(IV_SUCCESS != status)
+ {
+ printf("Encode Header failed = 0x%x\n", ih264e_video_encode_op.s_ive_op.u4_error_code);
+ return;
+ }
+
+ if(1 == ps_video_encode_op->output_present)
+ {
+ status = write_output(ps_app_ctxt->fp_op, (UWORD8 *) ps_video_encode_op->s_out_buf.pv_buf,
+ ps_video_encode_op->s_out_buf.u4_bytes);
+ if(IV_SUCCESS != status)
+ {
+ printf("Error: Unable to write to output file\n");
+ return;
+ }
+ }
+
+ /*****************************************************************************/
+ /* Video control Set in Encode picture mode */
+ /*****************************************************************************/
+ set_enc_mode(ps_app_ctxt, -1, -1, IVE_ENC_MODE_PICTURE);
+
GETTIME(&ps_app_ctxt->enc_start_time);
ps_app_ctxt->enc_last_time = ps_app_ctxt->enc_start_time;
@@ -1898,6 +2035,41 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
set_sei_ccv_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
}
+ ps_app_ctxt->u4_sii_sub_layer_idx = SII_SUB_LAYER_IDX;
+
+ if(0 == ps_app_ctxt->u4_sii_sub_layer_idx)
+ {
+ ps_app_ctxt->u4_shutter_interval_info_present_flag = SHUTTER_INTERVAL_INFO_PRESENT_FLAG;
+
+ if(1 == ps_app_ctxt->u4_shutter_interval_info_present_flag)
+ {
+ ps_app_ctxt->u4_sii_time_scale = SII_TIME_SCALE;
+ ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag =
+ FIXED_SHUTTER_INTERVAL_WITHIN_CVS_FLAG;
+
+ if(1 == ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag)
+ {
+ ps_app_ctxt->u4_sii_num_units_in_shutter_interval =
+ SII_NUM_UNITS_IN_SHUTTER_INTERVAL;
+ }
+ else
+ {
+ int i;
+ ps_app_ctxt->u4_sii_max_sub_layers_minus1 = SII_MAX_SUB_LAYERS_MINUS1;
+
+ for(i = 0; i <= (int) ps_app_ctxt->u4_sii_max_sub_layers_minus1; i++)
+ {
+ ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval[i] =
+ SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_HFR;
+ }
+ ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval
+ [ps_app_ctxt->u4_sii_max_sub_layers_minus1] =
+ SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_SFR;
+ }
+ }
+ }
+ set_sei_sii_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
+
/******************************************************************************/
/****************** Input Initialization **************************************/
/******************************************************************************/
@@ -1920,6 +2092,9 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
exit(0);
}
+ memset(&ih264e_video_encode_ip, 0, sizeof(ih264e_video_encode_ip));
+ memset(&ih264e_video_encode_op, 0, sizeof(ih264e_video_encode_op));
+
ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t);
ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t);
@@ -2078,7 +2253,6 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
ps_video_encode_ip->u4_is_last = is_last;
ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type;
ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;;
- ps_video_encode_op->s_out_buf.pv_buf= NULL;
ps_video_encode_ip->u4_timestamp_high = u4_timestamp_high;
ps_video_encode_ip->u4_timestamp_low = u4_timestamp_low;
@@ -2808,11 +2982,6 @@ int main(int argc, char *argv[])
set_profile_params(&s_app_ctxt, 0, 0);
/*****************************************************************************/
- /* Video control Set in Encode header mode */
- /*****************************************************************************/
- set_enc_mode(&s_app_ctxt, 0, 0, IVE_ENC_MODE_PICTURE);
-
- /*****************************************************************************/
/* Video usability information */
/*****************************************************************************/
set_vui_params(&s_app_ctxt);
diff --git a/test/mvcdec/dec.cfg b/test/mvcdec/dec.cfg
new file mode 100644
index 0000000..f452ea1
--- /dev/null
+++ b/test/mvcdec/dec.cfg
@@ -0,0 +1,12 @@
+--input input.h264
+--save_output 0
+--num_frames -1
+--output out.yuv
+--chroma_format YUV_420P
+--share_display_buf 0
+--num_cores 3
+--loopback 0
+--display 0
+--fps 59.94
+--arch ARM_A9Q
+--soc GENERIC
diff --git a/test/mvcdec/main.c b/test/mvcdec/main.c
new file mode 100644
index 0000000..e5b700f
--- /dev/null
+++ b/test/mvcdec/main.c
@@ -0,0 +1,1544 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+#include "ih264_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "imvcd.h"
+#include "ih264_debug.h"
+#include "ih264d.h"
+#include "ithread.h"
+
+/* Constants */
+#define DEFAULT_NON_DEGRADE_INTERVAL 4
+
+#define MAX_DISP_BUFFERS 64
+
+#define STRLENGTH 1000
+
+#define PEAK_WINDOW_SIZE 8
+
+#define DEFAULT_COLOR_FORMAT IV_YUV_420P
+
+#define DEFAULT_NUM_CORES 1
+
+#define MAX_ARG_SHORTNAME_LENGTH 4
+
+#define MAX_ARG_NAME_LENGTH 128
+
+#define MAX_ARG_DESC_LENGTH 512
+
+#define MAX_NUM_VIEWS 6
+
+#undef PROFILE_ENABLE
+
+/* Macro functions */
+#ifdef PROFILE_ENABLE
+#define GETTIME(timer) gettimeofday(timer, NULL);
+
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ s_elapsed_time = ((s_end_timer.tv_sec - s_start_timer.tv_sec) * 1000000) + \
+ (s_end_timer.tv_usec - s_start_timer.tv_usec);
+#else
+#define GETTIME(timer)
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency)
+#endif
+
+/* Typedefs */
+typedef enum ARGUMENT_T
+{
+ INVALID,
+ HELP,
+ INPUT_FILE,
+ OUTPUT,
+ CHKSUM,
+ SAVE_OUTPUT,
+ SAVE_CHKSUM,
+ NUM_FRAMES,
+ NUM_CORES,
+ DISABLE_DEBLOCK_LEVEL,
+ LOOPBACK,
+ CONFIG,
+ DEGRADE_TYPE,
+ DEGRADE_PICS,
+ ARCH
+} ARGUMENT_T;
+
+typedef enum COMPONENT_TYPES_T
+{
+ Y = 0,
+ UV = 1,
+ U = 1,
+ V = 2,
+ NUM_SP_COMPONENTS = 2,
+ NUM_COMPONENTS = 3
+} COMPONENT_TYPES_T;
+
+#ifdef PROFILE_ENABLE
+typedef struct timeval TIMER;
+#else
+typedef WORD32 TIMER;
+#endif
+
+typedef struct mvc_app_files_t
+{
+ UWORD8 au1_ip_fname[STRLENGTH];
+
+ UWORD8 au1_op_fname[STRLENGTH];
+
+ UWORD8 au1_op_chksum_fname[STRLENGTH];
+
+ UWORD32 au4_disp_frm_id_queue[MAX_DISP_BUFFERS];
+} mvc_app_files_t;
+
+typedef struct mvc_dec_ctx_t
+{
+ mvc_app_files_t s_mvc_app_files;
+
+ imvcd_get_buf_info_op_t s_disp_buf_props;
+
+ iv_yuv_buf_t as_view_disp_bufs[MAX_NUM_VIEWS];
+
+ iv_obj_t *ps_codec_obj;
+
+ IV_COLOR_FORMAT_T e_output_chroma_format;
+
+ IVD_ARCH_T e_arch;
+
+ IVD_SOC_T e_soc;
+
+ UWORD32 u4_max_frm_ts;
+
+ UWORD32 u4_disable_dblk_level;
+
+ WORD32 i4_degrade_type;
+
+ WORD32 i4_degrade_pics;
+
+ UWORD32 u4_num_cores;
+
+ UWORD32 u4_disp_delay;
+
+ UWORD32 u4_fps;
+
+ UWORD32 u4_pic_wd;
+
+ UWORD32 u4_pic_ht;
+
+ UWORD32 u4_loopback;
+
+ UWORD32 u4_file_save_flag;
+
+ UWORD32 u4_chksum_save_flag;
+
+ UWORD8 u1_quit;
+
+} mvc_dec_ctx_t;
+
+typedef struct argument_t
+{
+ UWORD8 au1_argument_shortname[MAX_ARG_SHORTNAME_LENGTH];
+
+ UWORD8 au1_argument_name[MAX_ARG_NAME_LENGTH];
+
+ ARGUMENT_T e_argument;
+
+ UWORD8 au1_description[MAX_ARG_DESC_LENGTH];
+
+} argument_t;
+
+/* Function declarations */
+#ifndef MD5_DISABLE
+void calc_md5_cksum(UWORD8 *pu1_inbuf, UWORD32 u4_stride, UWORD32 u4_width, UWORD32 u4_height,
+ UWORD8 *pu1_cksum_p);
+#else
+#define calc_md5_cksum(a, b, c, d, e)
+#endif
+
+static inline void *mvcd_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ void *buf = NULL;
+ (void) pv_ctxt;
+ if(0 != posix_memalign(&buf, alignment, i4_size))
+ {
+ return NULL;
+ }
+ return buf;
+}
+
+static inline void mvcd_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+ return;
+}
+
+static const argument_t argument_mapping[] = {
+ {"-h", "--help", HELP, "Print this help\n"},
+ {"-c", "--config", CONFIG, "config file (Default: test.cfg)\n"},
+ {"-i", "--input", INPUT_FILE, "Input file\n"},
+ {"-o", "--output", OUTPUT, "Output file\n"},
+ {"--", "--chksum", CHKSUM, "Output MD5 Checksum file\n"},
+ {"-s", "--save_output", SAVE_OUTPUT, "Save Output file\n"},
+ {"--", "--save_chksum", SAVE_CHKSUM, "Save Check sum file\n"},
+ {"-n", "--num_frames", NUM_FRAMES, "Number of frames to be decoded\n"},
+ {"--", "--num_cores", NUM_CORES, "Number of cores to be used\n"},
+ {"--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL,
+ "Disable deblocking level : 0 to 4 - 0 Enable deblocking 4 Disable "
+ "deblocking completely\n"},
+ {"--", "--u4_loopback", LOOPBACK, "Enable playback in a loop\n"},
+ {"--", "--degrade_type", DEGRADE_TYPE,
+ "Degrade type : 0: No degrade 0th bit set : Disable SAO 1st bit set : "
+ "Disable deblocking 2nd bit set : Faster inter prediction filters 3rd bit "
+ "set : Fastest inter prediction filters\n"},
+ {"--", "--degrade_pics", DEGRADE_PICS,
+ "Degrade pics : 0 : No degrade 1 : Only on non-reference frames 2 : Do "
+ "not degrade every 4th or key frames 3 : All non-key frames 4 : All "
+ "frames\n"},
+ {"--", "--arch", ARCH,
+ "Set Architecture. Supported values - ARM_A9Q, ARMV8_GENERIC, "
+ "X86_GENERIC, X86_SSE4 \n"},
+};
+
+#if ANDROID_NDK
+/*****************************************************************************/
+/* */
+/* Function Name : raise */
+/* */
+/* Description : Needed as a workaround when the application is built in */
+/* Android NDK. This is an exception to be called for divide*/
+/* by zero error */
+/* */
+/* Inputs : a */
+/* Globals : */
+/* Processing : None */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+static int raise(int a)
+{
+ printf("Divide by zero\n");
+ return 0;
+}
+#endif
+
+static void mvcd_print_usage(void)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+
+ printf("\nUsage:\n");
+
+ while(i < num_entries)
+ {
+ printf("%-32s\t %s", argument_mapping[i].au1_argument_name,
+ argument_mapping[i].au1_description);
+ i++;
+ }
+}
+
+static ARGUMENT_T mvcd_get_argument(char *name)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+
+ while(i < num_entries)
+ {
+ if((0 == strcmp((char *) argument_mapping[i].au1_argument_name, name)) ||
+ ((0 == strcmp((char *) argument_mapping[i].au1_argument_shortname, name)) &&
+ (0 != strcmp((char *) argument_mapping[i].au1_argument_shortname, "--"))))
+ {
+ return argument_mapping[i].e_argument;
+ }
+ i++;
+ }
+
+ return INVALID;
+}
+
+static void mvcd_exit(UWORD8 *pu1_err_message)
+{
+ printf("%s\n", pu1_err_message);
+ exit(-1);
+}
+
+static void mvcd_parse_argument(mvc_dec_ctx_t *ps_app_ctx, char *argument, char *value)
+{
+ ARGUMENT_T arg;
+
+ arg = mvcd_get_argument((char *) argument);
+
+ switch(arg)
+ {
+ case HELP:
+ {
+ mvcd_print_usage();
+
+ exit(-1);
+ }
+ case INPUT_FILE:
+ {
+ sscanf(value, "%s", ps_app_ctx->s_mvc_app_files.au1_ip_fname);
+
+ break;
+ }
+ case OUTPUT:
+ {
+ sscanf(value, "%s", ps_app_ctx->s_mvc_app_files.au1_op_fname);
+
+ break;
+ }
+ case CHKSUM:
+ {
+ sscanf(value, "%s", ps_app_ctx->s_mvc_app_files.au1_op_chksum_fname);
+
+ break;
+ }
+ case SAVE_OUTPUT:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_file_save_flag);
+
+ break;
+ }
+ case SAVE_CHKSUM:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_chksum_save_flag);
+
+ break;
+ }
+ case NUM_FRAMES:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_max_frm_ts);
+
+ break;
+ }
+ case NUM_CORES:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_num_cores);
+
+ break;
+ }
+ case DEGRADE_PICS:
+ {
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_pics);
+
+ break;
+ }
+ case DEGRADE_TYPE:
+ {
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_type);
+
+ break;
+ }
+ case LOOPBACK:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_loopback);
+
+ break;
+ }
+ case ARCH:
+ {
+ if((strcmp(value, "ARM_A9Q")) == 0)
+ {
+ ps_app_ctx->e_arch = ARCH_ARM_A9Q;
+ }
+ else if((strcmp(value, "X86_GENERIC")) == 0)
+ {
+ ps_app_ctx->e_arch = ARCH_X86_GENERIC;
+ }
+ else if((strcmp(value, "X86_SSSE3")) == 0)
+ {
+ ps_app_ctx->e_arch = ARCH_X86_SSSE3;
+ }
+ else if((strcmp(value, "X86_SSE42")) == 0)
+ {
+ ps_app_ctx->e_arch = ARCH_X86_SSE42;
+ }
+ else if((strcmp(value, "ARMV8_GENERIC")) == 0)
+ {
+ ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC;
+ }
+ else
+ {
+ printf("\nInvalid Arch. Setting it to ARCH_ARMV8_GENERIC\n");
+ ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC;
+ }
+
+ break;
+ }
+ case DISABLE_DEBLOCK_LEVEL:
+ {
+ sscanf(value, "%u", &ps_app_ctx->u4_disable_dblk_level);
+
+ break;
+ }
+ default:
+ {
+ printf("Ignoring argument : %s\n", argument);
+
+ break;
+ }
+ }
+}
+
+static void mvcd_read_cfg_file(mvc_dec_ctx_t *ps_app_ctx, FILE *ps_cfg_file)
+{
+ char line[STRLENGTH];
+ char description[STRLENGTH];
+ char value[STRLENGTH];
+ char argument[STRLENGTH];
+ void *ret;
+
+ while(0 == feof(ps_cfg_file))
+ {
+ line[0] = '\0';
+ ret = fgets(line, STRLENGTH, ps_cfg_file);
+ if(NULL == ret) break;
+ argument[0] = '\0';
+ /* Reading Input File Name */
+ sscanf(line, "%s %s %s", argument, value, description);
+ if(argument[0] == '\0') continue;
+
+ mvcd_parse_argument(ps_app_ctx, argument, value);
+ }
+}
+
+static void mvcd_get_view_file_name(const UWORD8 *pu1_default_name, UWORD8 *pu1_view_file_name,
+ UWORD16 u2_view_id)
+{
+ CHAR *apc_sub_str[2];
+ CHAR ac_string[STRLENGTH];
+
+ const CHAR ac_delimiters[] = ".";
+
+ strcpy(ac_string, (char *) pu1_default_name);
+
+ apc_sub_str[0] = strtok(ac_string, ac_delimiters);
+ apc_sub_str[1] = strtok(NULL, ac_delimiters);
+
+ ASSERT(NULL == strtok(NULL, ac_delimiters));
+ ASSERT((strlen(apc_sub_str[0]) + strlen(apc_sub_str[1]) + 3) < STRLENGTH);
+
+ sprintf((char *) pu1_view_file_name, "%s_%d.%s", apc_sub_str[0], u2_view_id, apc_sub_str[1]);
+}
+
+static IV_API_CALL_STATUS_T mvcd_in_buf_alloc(mvc_dec_ctx_t *ps_app_ctxt, UWORD8 **ppu1_bs_buf)
+{
+ ppu1_bs_buf[0] =
+ (UWORD8 *) malloc(ps_app_ctxt->s_disp_buf_props.s_ivd_op.u4_min_in_buf_size[0]);
+
+ if(ppu1_bs_buf[0] == NULL)
+ {
+ return IV_FAIL;
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_in_buf_free(UWORD8 *pu1_bs_buf)
+{
+ free(pu1_bs_buf);
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_out_buf_alloc(mvc_dec_ctx_t *ps_app_ctxt, ivd_out_bufdesc_t *ps_out_buf)
+{
+ UWORD32 i;
+
+ UWORD16 u2_num_views = ps_app_ctxt->s_disp_buf_props.s_mvc_buf_info.u2_num_views;
+
+ if(ps_app_ctxt->s_disp_buf_props.s_ivd_op.u4_min_num_out_bufs < (NUM_COMPONENTS * u2_num_views))
+ {
+ return IV_FAIL;
+ }
+
+ ps_out_buf->u4_num_bufs = ps_app_ctxt->s_disp_buf_props.s_ivd_op.u4_min_num_out_bufs;
+
+ for(i = 0; i < ps_out_buf->u4_num_bufs; i++)
+ {
+ ps_out_buf->u4_min_out_buf_size[i] =
+ ps_app_ctxt->s_disp_buf_props.s_ivd_op.u4_min_out_buf_size[i];
+ ps_out_buf->pu1_bufs[i] =
+ (UWORD8 *) malloc(ps_app_ctxt->s_disp_buf_props.s_ivd_op.u4_min_out_buf_size[i]);
+
+ if(ps_out_buf->pu1_bufs[i] == NULL)
+ {
+ return IV_FAIL;
+ }
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_out_buf_free(ivd_out_bufdesc_t *ps_out_buf)
+{
+ UWORD32 i;
+
+ for(i = 0; i < ps_out_buf->u4_num_bufs; i++)
+ {
+ free(ps_out_buf->pu1_bufs[i]);
+ }
+
+ return IV_SUCCESS;
+}
+
+static void mvcd_output_write_stall(UWORD8 *au1_fname, UWORD32 u4_cur_frm_idx)
+{
+ FILE *fp_fast_file = NULL;
+
+ const UWORD8 threshold = 64;
+ char past_fname[1000];
+
+ if(u4_cur_frm_idx >= threshold)
+ {
+ sprintf(past_fname, (char *) au1_fname, u4_cur_frm_idx - threshold);
+ do
+ {
+ fp_fast_file = fopen(past_fname, "rb");
+
+ if(fp_fast_file != NULL)
+ {
+ fclose(fp_fast_file);
+ /* Wait until the resource is released by a third party app*/
+ ithread_sleep(5000);
+ }
+ else
+ {
+ break;
+ }
+ } while(1);
+ }
+}
+
+static IV_API_CALL_STATUS_T mvcd_create_decoder(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_create_ip_t s_create_ip;
+ imvcd_create_op_t s_create_op;
+
+ IV_API_CALL_STATUS_T ret;
+
+ s_create_ip.s_ivd_ip.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_ip.e_output_format = ps_app_ctxt->e_output_chroma_format;
+ s_create_ip.s_ivd_ip.pf_aligned_alloc = mvcd_aligned_malloc;
+ s_create_ip.s_ivd_ip.pf_aligned_free = mvcd_aligned_free;
+ s_create_ip.s_ivd_ip.u4_share_disp_buf = 0;
+ s_create_ip.s_ivd_ip.pv_mem_ctxt = NULL;
+
+ s_create_ip.s_ivd_ip.u4_size = sizeof(s_create_ip.s_ivd_ip);
+ s_create_op.s_ivd_op.u4_size = sizeof(s_create_op.s_ivd_op);
+
+ ret = imvcd_api_function(NULL, &s_create_ip, &s_create_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ return ret;
+ }
+
+ ps_app_ctxt->ps_codec_obj = (iv_obj_t *) s_create_op.s_ivd_op.pv_handle;
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_set_decode_mode(mvc_dec_ctx_t *ps_app_ctxt,
+ IVD_VIDEO_DECODE_MODE_T e_decode_mode)
+{
+ imvcd_set_config_ip_t s_ctl_ip;
+ imvcd_set_config_op_t s_ctl_op;
+
+ s_ctl_ip.s_ivd_ip.u4_size = sizeof(s_ctl_ip.s_ivd_ip);
+ s_ctl_op.s_ivd_op.u4_size = sizeof(s_ctl_op.s_ivd_op);
+ s_ctl_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.s_ivd_ip.e_sub_cmd = (WORD32) IVD_CMD_CTL_SETPARAMS;
+ s_ctl_ip.s_ivd_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ s_ctl_ip.s_ivd_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+ s_ctl_ip.s_ivd_ip.e_vid_dec_mode = e_decode_mode;
+
+ return imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+}
+
+static IV_API_CALL_STATUS_T mvcd_set_num_cores(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_set_num_cores_ip_t s_ctl_ip;
+ imvcd_set_num_cores_op_t s_ctl_op;
+
+ s_ctl_ip.u4_size = sizeof(s_ctl_ip);
+ s_ctl_op.u4_size = sizeof(s_ctl_op);
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (WORD32) IMVCD_CTL_SET_NUM_CORES;
+ s_ctl_ip.u4_num_cores = ps_app_ctxt->u4_num_cores;
+
+ return imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+}
+
+static IV_API_CALL_STATUS_T mvcd_set_arch(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_set_arch_ip_t s_ctl_ip;
+ imvcd_set_arch_op_t s_ctl_op;
+
+ s_ctl_ip.u4_size = sizeof(s_ctl_ip);
+ s_ctl_op.u4_size = sizeof(s_ctl_op);
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (WORD32) IMVCD_CTL_SET_PROCESSOR;
+ s_ctl_ip.e_arch = ps_app_ctxt->e_arch;
+ s_ctl_ip.e_soc = ps_app_ctxt->e_soc;
+
+ return imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+}
+
+static IV_API_CALL_STATUS_T mvcd_dump_output(mvc_dec_ctx_t *ps_app_ctxt,
+ iv_yuv_buf_t *ps_view_disp_bufs, FILE **pps_op_file,
+ FILE **pps_op_chksum_file, UWORD16 u2_num_views)
+{
+ UWORD32 i, j;
+
+ UWORD32 u4_file_save = ps_app_ctxt->u4_file_save_flag;
+ UWORD32 u4_chksum_save = ps_app_ctxt->u4_chksum_save_flag;
+
+ if(!u4_file_save && !u4_chksum_save)
+ {
+ return IV_SUCCESS;
+ }
+
+ if(NULL == ps_view_disp_bufs->pv_y_buf)
+ {
+ return IV_FAIL;
+ }
+
+ for(i = 0; i < u2_num_views; i++)
+ {
+ iv_yuv_buf_t *ps_view_buf = &ps_view_disp_bufs[i];
+
+ if(ps_app_ctxt->e_output_chroma_format == IV_YUV_420P)
+ {
+ if(u4_file_save)
+ {
+ UWORD8 *pu1_buf = (UWORD8 *) ps_view_buf->pv_y_buf;
+ UWORD16 u2_width = ps_view_buf->u4_y_wd;
+ UWORD16 u2_height = ps_view_buf->u4_y_ht;
+
+ for(j = 0; j < u2_height; j++)
+ {
+ fwrite(pu1_buf, 1, u2_width, pps_op_file[i]);
+
+ pu1_buf += ps_view_buf->u4_y_strd;
+ }
+
+ pu1_buf = (UWORD8 *) ps_view_buf->pv_u_buf;
+ u2_width = ps_view_buf->u4_u_wd;
+ u2_height = ps_view_buf->u4_u_ht;
+
+ for(j = 0; j < u2_height; j++)
+ {
+ fwrite(pu1_buf, 1, u2_width, pps_op_file[i]);
+
+ pu1_buf += ps_view_buf->u4_u_strd;
+ }
+
+ pu1_buf = (UWORD8 *) ps_view_buf->pv_v_buf;
+ u2_width = ps_view_buf->u4_v_wd;
+ u2_height = ps_view_buf->u4_v_ht;
+
+ for(j = 0; j < u2_height; j++)
+ {
+ fwrite(pu1_buf, 1, u2_width, pps_op_file[i]);
+
+ pu1_buf += ps_view_buf->u4_v_strd;
+ }
+ }
+
+#ifndef MD5_DISABLE
+ if(u4_chksum_save)
+ {
+ UWORD8 au1_cksum[16];
+
+ UWORD8 *pu1_buf = (UWORD8 *) ps_view_buf->pv_y_buf;
+ UWORD16 u2_width = ps_view_buf->u4_y_wd;
+ UWORD16 u2_height = ps_view_buf->u4_y_ht;
+
+ calc_md5_cksum(pu1_buf, ps_view_buf->u4_y_strd, u2_width, u2_height, au1_cksum);
+
+ fwrite(au1_cksum, sizeof(UWORD8), 16, pps_op_chksum_file[i]);
+
+ pu1_buf = (UWORD8 *) ps_view_buf->pv_u_buf;
+ u2_width = ps_view_buf->u4_u_wd;
+ u2_height = ps_view_buf->u4_u_ht;
+
+ calc_md5_cksum(pu1_buf, ps_view_buf->u4_u_strd, u2_width, u2_height, au1_cksum);
+
+ fwrite(au1_cksum, sizeof(UWORD8), 16, pps_op_chksum_file[i]);
+
+ pu1_buf = (UWORD8 *) ps_view_buf->pv_v_buf;
+ u2_width = ps_view_buf->u4_v_wd;
+ u2_height = ps_view_buf->u4_v_ht;
+
+ calc_md5_cksum(pu1_buf, ps_view_buf->u4_v_strd, u2_width, u2_height, au1_cksum);
+
+ fwrite(au1_cksum, sizeof(UWORD8), 16, pps_op_chksum_file[i]);
+ }
+#endif
+ }
+ else
+ {
+ return IV_FAIL;
+ }
+
+ fflush(pps_op_file[i]);
+ fflush(pps_op_chksum_file[i]);
+ }
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_flush(mvc_dec_ctx_t *ps_app_ctxt, ivd_out_bufdesc_t *ps_out_buf,
+ FILE **pps_op_file, FILE **pps_op_chksum_file, UWORD8 *pu1_bs_buf,
+ UWORD32 *pu4_op_frm_ts, UWORD32 u4_ip_frm_ts,
+ UWORD32 u4_bytes_remaining, UWORD16 u2_num_views)
+{
+ IV_API_CALL_STATUS_T ret = IV_SUCCESS;
+
+ do
+ {
+ imvcd_flush_dec_ip_t s_ctl_ip;
+ imvcd_flush_dec_op_t s_ctl_op;
+
+ if(*(pu4_op_frm_ts) >= u4_ip_frm_ts)
+ {
+ break;
+ }
+
+ s_ctl_ip.s_ivd_ip.u4_size = sizeof(s_ctl_ip.s_ivd_ip);
+ s_ctl_op.s_ivd_op.u4_size = sizeof(s_ctl_op.s_ivd_op);
+ s_ctl_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.s_ivd_ip.e_sub_cmd = (WORD32) IVD_CMD_CTL_FLUSH;
+
+ ret = imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+
+ if(IV_SUCCESS == ret)
+ {
+ imvcd_video_decode_ip_t s_video_decode_ip;
+ imvcd_video_decode_op_t s_video_decode_op;
+
+ s_video_decode_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_ip.u4_ts = u4_ip_frm_ts;
+ s_video_decode_ip.s_ivd_ip.pv_stream_buffer = pu1_bs_buf;
+ s_video_decode_ip.s_ivd_ip.u4_num_Bytes = u4_bytes_remaining;
+ s_video_decode_ip.s_ivd_ip.s_out_buffer = ps_out_buf[0];
+ s_video_decode_op.ps_view_disp_bufs = ps_app_ctxt->as_view_disp_bufs;
+
+ s_video_decode_ip.s_ivd_ip.u4_size = sizeof(s_video_decode_ip.s_ivd_ip);
+ s_video_decode_op.s_ivd_op.u4_size = sizeof(s_video_decode_op.s_ivd_op);
+
+ ret = imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_video_decode_ip,
+ &s_video_decode_op);
+
+ if(1 == s_video_decode_op.s_ivd_op.u4_output_present)
+ {
+ ret = mvcd_dump_output(ps_app_ctxt, s_video_decode_op.ps_view_disp_bufs,
+ pps_op_file, pps_op_chksum_file, u2_num_views);
+
+ (*pu4_op_frm_ts)++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ } while(IV_SUCCESS == ret);
+
+ return ret;
+}
+
+static IV_API_CALL_STATUS_T mvcd_decode_header(mvc_dec_ctx_t *ps_app_ctxt, ivd_out_bufdesc_t *ps_out_buf,
+ FILE *ps_ip_file, IVD_ERROR_CODES_T *pe_error_code,
+ UWORD32 *pu4_num_bytes_dec, UWORD32 u4_ip_frm_ts)
+{
+ IV_API_CALL_STATUS_T ret;
+
+ UWORD32 u4_ip_buf_len;
+ UWORD8 *pu1_bs_buf;
+
+ imvcd_video_decode_ip_t s_video_decode_ip = {0};
+ imvcd_video_decode_op_t s_video_decode_op = {0};
+
+ UWORD32 u4_file_pos = 0;
+ UWORD32 u4_num_bytes_dec = 0;
+
+ ret = mvcd_set_decode_mode(ps_app_ctxt, IVD_DECODE_HEADER);
+
+ if(ret != IV_SUCCESS)
+ {
+ pe_error_code[0] = IVD_INIT_DEC_FAILED;
+
+ return ret;
+ }
+
+ /* Allocate input buffer for header */
+ u4_ip_buf_len = 256 * 1024;
+ pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+ if(pu1_bs_buf == NULL)
+ {
+ pe_error_code[0] = IVD_MEM_ALLOC_FAILED;
+
+ return IV_FAIL;
+ }
+
+ do
+ {
+ WORD32 u4_numbytes;
+ UWORD32 u4_bytes_remaining;
+
+ fseek(ps_ip_file, u4_file_pos, SEEK_SET);
+ u4_numbytes = u4_ip_buf_len;
+
+ u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), u4_numbytes, ps_ip_file);
+
+ if(0 == u4_bytes_remaining)
+ {
+ pe_error_code[0] = IVD_UNEXPECTED_END_OF_STREAM;
+
+ return IV_FAIL;
+ }
+
+ s_video_decode_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_ip.u4_ts = u4_ip_frm_ts;
+ s_video_decode_ip.s_ivd_ip.pv_stream_buffer = pu1_bs_buf;
+ s_video_decode_ip.s_ivd_ip.u4_num_Bytes = u4_bytes_remaining;
+ s_video_decode_ip.s_ivd_ip.s_out_buffer = ps_out_buf[0];
+ s_video_decode_op.ps_view_disp_bufs = ps_app_ctxt->as_view_disp_bufs;
+
+ s_video_decode_ip.s_ivd_ip.u4_size = sizeof(s_video_decode_ip.s_ivd_ip);
+ s_video_decode_op.s_ivd_op.u4_size = sizeof(s_video_decode_op.s_ivd_op);
+
+ ret = imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_video_decode_ip, &s_video_decode_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ pe_error_code[0] = s_video_decode_op.s_ivd_op.u4_error_code;
+
+ return ret;
+ }
+
+ u4_num_bytes_dec += s_video_decode_op.s_ivd_op.u4_num_bytes_consumed;
+
+#ifndef PROFILE_ENABLE
+ printf("%d\n", s_video_decode_op.s_ivd_op.u4_num_bytes_consumed);
+#endif
+ } while(ret != IV_SUCCESS);
+
+ ps_app_ctxt->u4_pic_wd = s_video_decode_op.s_ivd_op.u4_pic_wd;
+ ps_app_ctxt->u4_pic_ht = s_video_decode_op.s_ivd_op.u4_pic_ht;
+
+ pu4_num_bytes_dec[0] = u4_num_bytes_dec;
+ pe_error_code[0] = IVD_ERROR_NONE;
+
+ free(pu1_bs_buf);
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_get_buf_info(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_get_buf_info_ip_t s_ctl_ip;
+ imvcd_get_buf_info_op_t s_ctl_op;
+
+ IV_API_CALL_STATUS_T e_retval;
+
+ s_ctl_ip.s_ivd_ip.u4_size = sizeof(s_ctl_ip.s_ivd_ip);
+ s_ctl_op.s_ivd_op.u4_size = sizeof(s_ctl_op.s_ivd_op);
+ s_ctl_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.s_ivd_ip.e_sub_cmd = (WORD32) IVD_CMD_CTL_GETBUFINFO;
+
+ e_retval = imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+
+ ps_app_ctxt->s_disp_buf_props = s_ctl_op;
+
+ return e_retval;
+}
+
+static IV_API_CALL_STATUS_T mvcd_set_degrade_type(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_set_degrade_mode_ip_t s_ctl_ip;
+ imvcd_set_degrade_mode_op_t s_ctl_op;
+
+ s_ctl_ip.u4_size = sizeof(s_ctl_ip);
+ s_ctl_op.u4_size = sizeof(s_ctl_op);
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (WORD32) IMVCD_CTL_DEGRADE;
+ s_ctl_ip.i4_degrade_type = ps_app_ctxt->i4_degrade_type;
+ s_ctl_ip.i4_degrade_pics = ps_app_ctxt->i4_degrade_pics;
+ s_ctl_ip.i4_nondegrade_interval = DEFAULT_NON_DEGRADE_INTERVAL;
+
+ return imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_ctl_ip, &s_ctl_op);
+}
+
+static IV_API_CALL_STATUS_T mvcd_decode_frame(mvc_dec_ctx_t *ps_app_ctxt, ivd_out_bufdesc_t *ps_out_buf,
+ FILE *ps_ip_file, FILE **pps_op_file,
+ FILE **pps_op_chksum_file, UWORD8 *pu1_bs_buf,
+ IVD_ERROR_CODES_T *pe_error_code,
+ UWORD32 *pu4_num_bytes_consumed, UWORD32 *pu4_file_pos,
+ UWORD32 *pu4_ip_frm_ts, UWORD32 *pu4_op_frm_ts,
+ UWORD32 u4_ip_buf_len)
+{
+ imvcd_video_decode_ip_t s_video_decode_ip;
+ imvcd_video_decode_op_t s_video_decode_op;
+#ifdef PROFILE_ENABLE
+ TIMER s_start_timer;
+ TIMER s_end_timer;
+#ifdef WINDOWS_TIMER
+ TIMER frequency;
+#endif
+
+ UWORD32 au4_peak_window[PEAK_WINDOW_SIZE];
+ UWORD32 s_elapsed_time;
+#endif
+ UWORD32 u4_max_op_frm_ts;
+ UWORD32 u4_bytes_remaining;
+ UWORD32 u4_numbytes;
+
+ IV_API_CALL_STATUS_T ret;
+
+ UWORD32 u4_num_bytes_dec = 0;
+ UWORD16 u2_num_views = ps_app_ctxt->s_disp_buf_props.s_mvc_buf_info.u2_num_views;
+#ifdef PROFILE_ENABLE
+ UWORD32 u4_frm_cnt = 0;
+ UWORD32 u4_tot_cycles = 0;
+ UWORD32 u4_tot_fmt_cycles = 0;
+ UWORD32 u4_peak_window_idx = 0;
+ UWORD32 u4_peak_avg_max = 0;
+#endif
+
+#ifdef PROFILE_ENABLE
+ memset(au4_peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE);
+
+#ifdef WINDOWS_TIMER
+ QueryPerformanceFrequency(&frequency);
+#endif
+#endif
+
+ /*************************************************************************/
+ /* Set the decoder in frame decode mode. It was set in header decode */
+ /* mode earlier */
+ /*************************************************************************/
+ ret = mvcd_set_decode_mode(ps_app_ctxt, IVD_DECODE_FRAME);
+
+ if(IV_SUCCESS != ret)
+ {
+ pe_error_code[0] = IVD_INIT_DEC_FAILED;
+
+ return ret;
+ }
+
+ /*************************************************************************/
+ /* If required disable deblocking and sao at given level */
+ /*************************************************************************/
+ ret = mvcd_set_degrade_type(ps_app_ctxt);
+
+ if(IV_SUCCESS != ret)
+ {
+ pe_error_code[0] = IVD_INIT_DEC_FAILED;
+
+ return ret;
+ }
+
+ u4_max_op_frm_ts = ps_app_ctxt->u4_max_frm_ts + ps_app_ctxt->u4_disp_delay;
+
+ if(u4_max_op_frm_ts < ps_app_ctxt->u4_disp_delay)
+ {
+ /* clip as overflow has occured*/
+ u4_max_op_frm_ts = UINT32_MAX;
+ }
+
+ if(IV_SUCCESS != ret)
+ {
+ pe_error_code[0] = IVD_INIT_DEC_FAILED;
+
+ return ret;
+ }
+
+ while(pu4_op_frm_ts[0] < u4_max_op_frm_ts)
+ {
+ fseek(ps_ip_file, pu4_file_pos[0], SEEK_SET);
+ u4_numbytes = u4_ip_buf_len;
+
+ u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), u4_numbytes, ps_ip_file);
+
+ if(0 == u4_bytes_remaining)
+ {
+ if(ps_app_ctxt->u4_loopback)
+ {
+ pu4_file_pos[0] = 0;
+
+ fseek(ps_ip_file, pu4_file_pos[0], SEEK_SET);
+ u4_numbytes = u4_ip_buf_len;
+
+ u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), u4_numbytes, ps_ip_file);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ s_video_decode_ip.s_ivd_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+ s_video_decode_ip.s_ivd_ip.u4_ts = pu4_ip_frm_ts[0];
+ s_video_decode_ip.s_ivd_ip.pv_stream_buffer = pu1_bs_buf;
+ s_video_decode_ip.s_ivd_ip.u4_num_Bytes = u4_bytes_remaining;
+ s_video_decode_ip.s_ivd_ip.s_out_buffer = ps_out_buf[0];
+ s_video_decode_op.ps_view_disp_bufs = ps_app_ctxt->as_view_disp_bufs;
+
+ s_video_decode_ip.s_ivd_ip.u4_size = sizeof(s_video_decode_ip.s_ivd_ip);
+ s_video_decode_op.s_ivd_op.u4_size = sizeof(s_video_decode_op.s_ivd_op);
+
+ /****************/
+ /* Video Decode */
+ /****************/
+ GETTIME(&s_start_timer);
+
+ ret = imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_video_decode_ip, &s_video_decode_op);
+
+ GETTIME(&s_end_timer);
+ ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency);
+
+#ifdef PROFILE_ENABLE
+ {
+ UWORD32 peak_avg, id;
+
+ u4_tot_cycles += s_elapsed_time;
+ au4_peak_window[u4_peak_window_idx++] = s_elapsed_time;
+
+ if(u4_peak_window_idx == PEAK_WINDOW_SIZE)
+ {
+ u4_peak_window_idx = 0;
+ }
+
+ peak_avg = 0;
+ for(id = 0; id < PEAK_WINDOW_SIZE; id++)
+ {
+ peak_avg += au4_peak_window[id];
+ }
+
+ peak_avg /= PEAK_WINDOW_SIZE;
+ if(peak_avg > u4_peak_avg_max) u4_peak_avg_max = peak_avg;
+ u4_frm_cnt++;
+
+ printf(
+ "FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d "
+ "PeakAvgTimeMax: "
+ "%6d Output: %2d NumBytes: %6d \n",
+ u4_frm_cnt, s_elapsed_time, u4_tot_cycles / u4_frm_cnt, u4_peak_avg_max,
+ s_video_decode_op.s_ivd_op.u4_output_present,
+ s_video_decode_op.s_ivd_op.u4_num_bytes_consumed);
+ }
+#else
+ printf("%d\n", s_video_decode_op.s_ivd_op.u4_num_bytes_consumed);
+#endif
+
+ if(ret != IV_SUCCESS)
+ {
+ pe_error_code[0] = s_video_decode_op.s_ivd_op.u4_error_code;
+
+ return ret;
+ }
+
+ u4_num_bytes_dec = s_video_decode_op.s_ivd_op.u4_num_bytes_consumed;
+
+ pu4_file_pos[0] += u4_num_bytes_dec;
+ pu4_num_bytes_consumed[0] += u4_num_bytes_dec;
+ pu4_ip_frm_ts[0]++;
+
+ if(s_video_decode_op.s_ivd_op.u4_output_present)
+ {
+ char cur_fname[1000];
+
+ char *extn = NULL;
+
+ /* The objective is to dump the decoded frames into separate files
+ * instead of dumping all the frames in one common file. Also, the
+ * number of dumped frames at any given instance of time cannot exceed
+ * 'frame_memory'
+ */
+ if(ps_app_ctxt->u4_file_save_flag)
+ {
+ /* Locate the position of extension yuv */
+ extn = strstr((char *) ps_app_ctxt->s_mvc_app_files.au1_op_fname, "%d");
+
+ if(extn != NULL)
+ {
+ mvcd_output_write_stall(ps_app_ctxt->s_mvc_app_files.au1_op_fname,
+ pu4_op_frm_ts[0]);
+
+ sprintf(cur_fname, (char *) ps_app_ctxt->s_mvc_app_files.au1_op_fname,
+ pu4_op_frm_ts[0]);
+
+ pps_op_file[0] = fopen(cur_fname, "wb");
+
+ if(NULL == pps_op_file[0])
+ {
+ pe_error_code[0] = IVD_MEM_ALLOC_FAILED;
+
+ return IV_FAIL;
+ }
+ }
+ }
+
+ if(u2_num_views > 1)
+ {
+ if(s_video_decode_op.ps_view_disp_bufs[0].u4_y_wd !=
+ s_video_decode_op.ps_view_disp_bufs[1].u4_y_wd)
+ {
+ pe_error_code[0] = IVD_MEM_ALLOC_FAILED;
+
+ return IV_FAIL;
+ }
+
+ if(s_video_decode_op.ps_view_disp_bufs[0].u4_y_ht !=
+ s_video_decode_op.ps_view_disp_bufs[1].u4_y_ht)
+ {
+ pe_error_code[0] = IVD_MEM_ALLOC_FAILED;
+
+ return IV_FAIL;
+ }
+ }
+
+ mvcd_dump_output(ps_app_ctxt, s_video_decode_op.ps_view_disp_bufs, pps_op_file,
+ pps_op_chksum_file, u2_num_views);
+
+ pu4_op_frm_ts[0]++;
+ }
+ else if((s_video_decode_op.s_ivd_op.u4_error_code >> IVD_FATALERROR) & 1)
+ {
+ pe_error_code[0] = s_video_decode_op.s_ivd_op.u4_error_code;
+
+ return IV_FAIL;
+ }
+ }
+
+#ifdef PROFILE_ENABLE
+ printf("Summary\n");
+ printf("Input filename : %s\n", ps_app_ctxt->s_mvc_app_files.au1_ip_fname);
+ printf("Output Width : %-4d\n", ps_app_ctxt->u4_pic_wd);
+ printf("Output Height : %-4d\n", ps_app_ctxt->u4_pic_ht);
+
+ if(u4_frm_cnt)
+ {
+ double avg = u4_tot_cycles / u4_frm_cnt;
+ double bytes_avg = pu4_num_bytes_consumed[0] / u4_frm_cnt;
+ double bitrate = (bytes_avg * 8 * ps_app_ctxt->u4_fps) / 1000000;
+
+ printf("Bitrate @ %2d u4_fps(mbps) : %-6.2f\n", ps_app_ctxt->u4_fps, bitrate);
+ printf("Average decode time(micro sec) : %-6d\n", (WORD32) avg);
+ printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE,
+ (WORD32) u4_peak_avg_max);
+
+ avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / u4_frm_cnt;
+ printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg);
+ }
+#endif
+
+ return IV_SUCCESS;
+}
+
+static IV_API_CALL_STATUS_T mvcd_delete_decoder(mvc_dec_ctx_t *ps_app_ctxt)
+{
+ imvcd_delete_ip_t s_delete_ip;
+ imvcd_delete_op_t s_delete_op;
+
+ s_delete_ip.s_ivd_ip.e_cmd = IVD_CMD_DELETE;
+
+ s_delete_ip.s_ivd_ip.u4_size = sizeof(s_delete_ip.s_ivd_ip);
+ s_delete_op.s_ivd_op.u4_size = sizeof(s_delete_op.s_ivd_op);
+
+ return imvcd_api_function(ps_app_ctxt->ps_codec_obj, &s_delete_ip, &s_delete_op);
+}
+
+int main(WORD32 argc, char *argv[])
+{
+ mvc_dec_ctx_t s_app_ctxt;
+ ivd_out_bufdesc_t s_out_buf;
+
+ IV_API_CALL_STATUS_T ret;
+ IVD_ERROR_CODES_T e_error_code;
+
+ UWORD8 au1_cfg_fname[STRLENGTH];
+ UWORD8 au1_error_str[STRLENGTH];
+ UWORD32 i;
+ UWORD32 u4_ip_buf_len;
+ UWORD32 u4_total_bytes_consumed;
+ UWORD8 au1_view_file_names[STRLENGTH];
+ UWORD16 u2_num_views;
+ UWORD32 u4_num_header_bytes;
+
+ FILE *ps_cfg_file = NULL;
+ FILE *ps_ip_file = NULL;
+ FILE *aps_op_file[MAX_NUM_VIEWS] = {NULL};
+ FILE *aps_op_chksum_file[MAX_NUM_VIEWS] = {NULL};
+
+ UWORD8 *pu1_bs_buf = NULL;
+ UWORD32 u4_file_pos = 0;
+ UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
+ UWORD32 u4_bytes_remaining = 0;
+
+ /* Usage */
+ if(argc < 2)
+ {
+ mvcd_print_usage();
+
+ exit(-1);
+ }
+ else if(argc == 2)
+ {
+ strcpy((char *) au1_cfg_fname, argv[1]);
+ }
+
+ /***********************************************************************/
+ /* Initialize Application parameters */
+ /***********************************************************************/
+ strcpy((char *) s_app_ctxt.s_mvc_app_files.au1_ip_fname, "\0");
+ s_app_ctxt.u4_disp_delay = 0;
+ s_app_ctxt.u4_max_frm_ts = 100;
+ s_app_ctxt.u4_loopback = 0;
+ u4_file_pos = 0;
+ u4_total_bytes_consumed = 0;
+ u4_ip_frm_ts = 0;
+ u4_op_frm_ts = 0;
+
+ s_app_ctxt.u4_num_cores = DEFAULT_NUM_CORES;
+ s_app_ctxt.i4_degrade_type = 0;
+ s_app_ctxt.i4_degrade_pics = 0;
+ s_app_ctxt.e_arch = ARCH_X86_SSE42;
+ s_app_ctxt.e_soc = SOC_GENERIC;
+ s_app_ctxt.u1_quit = 0;
+ s_app_ctxt.u4_disable_dblk_level = 0;
+ s_app_ctxt.u4_file_save_flag = 0;
+ s_app_ctxt.u4_chksum_save_flag = 0;
+ s_app_ctxt.e_output_chroma_format = DEFAULT_COLOR_FORMAT;
+
+ /*************************************************************************/
+ /* Parse arguments */
+ /*************************************************************************/
+
+ /* Read command line arguments */
+ if(argc > 2)
+ {
+ for(i = 1; i < (UWORD32) argc; i += 2)
+ {
+ if(CONFIG == mvcd_get_argument(argv[i]))
+ {
+ strcpy((char *) au1_cfg_fname, argv[i + 1]);
+
+ if((ps_cfg_file = fopen((char *) au1_cfg_fname, "r")) == NULL)
+ {
+ sprintf((char *) au1_error_str, "Could not open Configuration file %s",
+ au1_cfg_fname);
+
+ mvcd_exit(au1_error_str);
+ }
+ mvcd_read_cfg_file(&s_app_ctxt, ps_cfg_file);
+ fclose(ps_cfg_file);
+ }
+ else
+ {
+ mvcd_parse_argument(&s_app_ctxt, argv[i], argv[i + 1]);
+ }
+ }
+ }
+ else
+ {
+ if((ps_cfg_file = fopen((char *) au1_cfg_fname, "r")) == NULL)
+ {
+ sprintf((char *) au1_error_str, "Could not open Configuration file %s", au1_cfg_fname);
+ mvcd_exit(au1_error_str);
+ }
+
+ mvcd_read_cfg_file(&s_app_ctxt, ps_cfg_file);
+
+ fclose(ps_cfg_file);
+ }
+
+ if(strcmp((char *) s_app_ctxt.s_mvc_app_files.au1_ip_fname, "\0") == 0)
+ {
+ printf("\nNo input file given for decoding\n");
+
+ exit(-1);
+ }
+
+ /***********************************************************************/
+ /* create the file object for input file */
+ /***********************************************************************/
+ ps_ip_file = fopen((char *) s_app_ctxt.s_mvc_app_files.au1_ip_fname, "rb");
+
+ if(NULL == ps_ip_file)
+ {
+ sprintf((char *) au1_error_str, "Could not open input file %s",
+ s_app_ctxt.s_mvc_app_files.au1_ip_fname);
+
+ mvcd_exit(au1_error_str);
+ }
+
+ /***********************************************************************/
+ /* create the file object for output file */
+ /***********************************************************************/
+ /* If the filename does not contain %d, then output will be dumped to
+ a single file and it is opened here */
+ if((1 == s_app_ctxt.u4_file_save_flag) &&
+ (strstr((char *) s_app_ctxt.s_mvc_app_files.au1_op_fname, "%d") == NULL))
+ {
+ mvcd_get_view_file_name(s_app_ctxt.s_mvc_app_files.au1_op_fname, au1_view_file_names, 0);
+
+ aps_op_file[0] = fopen((char *) au1_view_file_names, "wb");
+
+ if(NULL == aps_op_file[0])
+ {
+ const CHAR au1_explanatory_string[] = "Could not open output file ";
+ UWORD8 au1_error_str[STRLENGTH + sizeof(au1_explanatory_string) + 1];
+
+ sprintf((char *) au1_error_str, "%s%s", au1_explanatory_string, au1_view_file_names);
+ mvcd_exit(au1_error_str);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for check sum file */
+ /***********************************************************************/
+ if((1 == s_app_ctxt.u4_chksum_save_flag) &&
+ (strstr((char *) s_app_ctxt.s_mvc_app_files.au1_op_chksum_fname, "%d") == NULL))
+ {
+ mvcd_get_view_file_name(s_app_ctxt.s_mvc_app_files.au1_op_chksum_fname, au1_view_file_names,
+ 0);
+ aps_op_chksum_file[0] = fopen((char *) au1_view_file_names, "wb");
+
+ if(NULL == aps_op_chksum_file[0])
+ {
+ const CHAR au1_explanatory_string[] = "Could not open check sum file ";
+ UWORD8 au1_error_str[STRLENGTH + sizeof(au1_explanatory_string) + 1];
+
+ sprintf((char *) au1_error_str, "%s%s", au1_explanatory_string, au1_view_file_names);
+ mvcd_exit(au1_error_str);
+ }
+ }
+
+ /***************************/
+ /* Create decoder instance */
+ /***************************/
+ ret = mvcd_create_decoder(&s_app_ctxt);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "Error in Create %8x\n", ret);
+
+ mvcd_exit(au1_error_str);
+ }
+
+ /**************/
+ /* set params */
+ /**************/
+ ret = mvcd_set_decode_mode(&s_app_ctxt, IVD_DECODE_HEADER);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "\nError in Dec mode");
+ mvcd_exit(au1_error_str);
+ }
+
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+ ret = mvcd_set_num_cores(&s_app_ctxt);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "\nError in setting number of cores");
+ mvcd_exit(au1_error_str);
+ }
+
+ /*************************************************************************/
+ /* set processsor */
+ /*************************************************************************/
+ ret = mvcd_set_arch(&s_app_ctxt);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "\nError in setting Processor type");
+ mvcd_exit(au1_error_str);
+ }
+
+ /*****************/
+ /* Header Decode */
+ /*****************/
+ ret = mvcd_decode_header(&s_app_ctxt, &s_out_buf, ps_ip_file, &e_error_code,
+ &u4_num_header_bytes, u4_ip_frm_ts);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "Error in header decode 0x%x\n", e_error_code);
+ mvcd_exit(au1_error_str);
+ }
+
+ u4_file_pos += u4_num_header_bytes;
+ u4_total_bytes_consumed += u4_num_header_bytes;
+
+ /****************/
+ /* Get buf info */
+ /****************/
+ ret = mvcd_get_buf_info(&s_app_ctxt);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "Error in Get Buf Info %x",
+ s_app_ctxt.s_disp_buf_props.s_ivd_op.u4_error_code);
+ mvcd_exit(au1_error_str);
+ }
+
+ u2_num_views = s_app_ctxt.s_disp_buf_props.s_mvc_buf_info.u2_num_views;
+ ASSERT(u2_num_views <= MAX_NUM_VIEWS);
+
+ ret = mvcd_out_buf_alloc(&s_app_ctxt, &s_out_buf);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf((char *) au1_error_str, "Error in Out buf alloc\n");
+ mvcd_exit(au1_error_str);
+ }
+
+ /***************************************************************************/
+ /* create the file object for output file for other views(if present) */
+ /***************************************************************************/
+ for(i = 1; i < u2_num_views; i++)
+ {
+ if((1 == s_app_ctxt.u4_file_save_flag) &&
+ (strstr((char *) s_app_ctxt.s_mvc_app_files.au1_op_fname, "%d") == NULL))
+ {
+ mvcd_get_view_file_name(s_app_ctxt.s_mvc_app_files.au1_op_fname, au1_view_file_names,
+ i);
+
+ aps_op_file[i] = fopen((char *) au1_view_file_names, "wb");
+
+ if(NULL == aps_op_file[i])
+ {
+ const UWORD8 au1_explanatory_string[] = "Could not open output file ";
+ UWORD8 au1_error_str[STRLENGTH + sizeof(au1_explanatory_string) + 1];
+
+ sprintf((char *) au1_error_str, "%s%s", au1_explanatory_string,
+ au1_view_file_names);
+ mvcd_exit(au1_error_str);
+ }
+ }
+
+ if((1 == s_app_ctxt.u4_chksum_save_flag) &&
+ (strstr((char *) s_app_ctxt.s_mvc_app_files.au1_op_chksum_fname, "%d") == NULL))
+ {
+ mvcd_get_view_file_name(s_app_ctxt.s_mvc_app_files.au1_op_chksum_fname,
+ au1_view_file_names, i);
+ aps_op_chksum_file[i] = fopen((char *) au1_view_file_names, "wb");
+
+ if(NULL == aps_op_chksum_file[i])
+ {
+ const UWORD8 au1_explanatory_string[] = "Could not open check sum file ";
+ UWORD8 au1_error_str[STRLENGTH + sizeof(au1_explanatory_string) + 1];
+
+ sprintf((char *) au1_error_str, "%s%s", au1_explanatory_string,
+ au1_view_file_names);
+ mvcd_exit(au1_error_str);
+ }
+ }
+ }
+
+ u4_ip_buf_len = s_app_ctxt.s_disp_buf_props.s_ivd_op.u4_min_in_buf_size[0];
+ ret = mvcd_in_buf_alloc(&s_app_ctxt, &pu1_bs_buf);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf((char *) au1_error_str, "Error in In buf alloc\n");
+ mvcd_exit(au1_error_str);
+ }
+
+ ret = mvcd_decode_frame(&s_app_ctxt, &s_out_buf, ps_ip_file, aps_op_file, aps_op_chksum_file,
+ pu1_bs_buf, &e_error_code, &u4_total_bytes_consumed, &u4_file_pos,
+ &u4_ip_frm_ts, &u4_op_frm_ts, u4_ip_buf_len);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "Error in Frame decode 0x%x\n", e_error_code);
+ mvcd_exit(au1_error_str);
+ }
+
+ /***********************************************************************/
+ /* To get the last decoded frames, call process with NULL input */
+ /***********************************************************************/
+ ret = mvcd_flush(&s_app_ctxt, &s_out_buf, aps_op_file, aps_op_chksum_file, pu1_bs_buf,
+ &u4_op_frm_ts, u4_ip_frm_ts, u4_bytes_remaining, u2_num_views);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf((char *) au1_error_str, "\nError in Setting the decoder in flush mode");
+ mvcd_exit(au1_error_str);
+ }
+
+ s_app_ctxt.u1_quit = 1;
+
+ ret = mvcd_delete_decoder(&s_app_ctxt);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf((char *) au1_error_str, "Error in Codec delete");
+ mvcd_exit(au1_error_str);
+ }
+
+ /***********************************************************************/
+ /* Close all the files and free all the memory */
+ /***********************************************************************/
+ fclose(ps_ip_file);
+
+ for(i = 0; i < u2_num_views; i++)
+ {
+ if(aps_op_file[i])
+ {
+ fclose(aps_op_file[i]);
+ }
+
+ if(aps_op_chksum_file[i])
+ {
+ fclose(aps_op_chksum_file[i]);
+ }
+ }
+
+ mvcd_in_buf_free(pu1_bs_buf);
+
+ mvcd_out_buf_free(&s_out_buf);
+
+ return (0);
+}
diff --git a/test/mvcdec/mvcdec.cmake b/test/mvcdec/mvcdec.cmake
new file mode 100644
index 0000000..8f3e6c2
--- /dev/null
+++ b/test/mvcdec/mvcdec.cmake
@@ -0,0 +1,4 @@
+list(APPEND MVC_DEC_APP_SRCS "${AVC_ROOT}/test/mvcdec/main.c")
+
+libavc_add_executable(mvcdec libmvcdec SOURCES ${MVC_DEC_APP_SRCS})
+target_compile_definitions(mvcdec PRIVATE PROFILE_ENABLE MD5_DISABLE)
diff --git a/test/svcdec/dec.cfg b/test/svcdec/dec.cfg
new file mode 100644
index 0000000..5d31a8f
--- /dev/null
+++ b/test/svcdec/dec.cfg
@@ -0,0 +1,13 @@
+--input input.h264
+--save_output 1
+--num_frames -1
+--output out.yuv
+--chroma_format YUV_420P
+--share_display_buf 0
+--num_cores 1
+--loopback 0
+--display 0
+--fps 30
+--arch X86_GENERIC
+--soc GENERIC
+--target_layer_id 2 \ No newline at end of file
diff --git a/test/svcdec/main.c b/test/svcdec/main.c
new file mode 100644
index 0000000..412062c
--- /dev/null
+++ b/test/svcdec/main.c
@@ -0,0 +1,3441 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * main.c
+ *
+ * @brief
+ * Contains an application that demonstrates use of H264 decoder API
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef X86_MINGW
+#include <signal.h>
+#endif
+
+#ifdef IOS_DISPLAY
+#include "cast_types.h"
+#else
+#include "ih264_typedefs.h"
+#endif
+
+#include "iv.h"
+#include "ivd.h"
+#include "ithread.h"
+
+#include "ih264d.h"
+#include "isvcd.h"
+#ifdef WINDOWS_TIMER
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+// #define ADAPTIVE_TEST
+#define ADAPTIVE_MAX_WD 4096
+#define ADAPTIVE_MAX_HT 2160
+
+#define ALIGN8(x) ((((x) + 7) >> 3) << 3)
+#define NUM_DISPLAY_BUFFERS 4
+#define DEFAULT_FPS 30
+
+#define ENABLE_DEGRADE 0
+#define MAX_DISP_BUFFERS 64
+#define EXTRA_DISP_BUFFERS 8
+#define STRLENGTH 1000
+#define STR2(x) #x
+#define STR(X) STR2(X)
+
+// #define TEST_FLUSH
+#define FLUSH_FRM_CNT 100
+// #define APP_EXTRA_BUFS 1
+
+#undef PROFILE_ENABLE
+
+#ifdef IOS
+#define PATHLENMAX 500
+char filename_with_path[PATHLENMAX];
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+typedef LARGE_INTEGER TIMER;
+#else
+// #ifdef GCC_TIMER
+typedef struct timeval TIMER;
+// #endif
+#endif
+#else
+typedef WORD32 TIMER;
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+#define GETTIME(timer) QueryPerformanceCounter(timer);
+#else
+// #ifdef GCC_TIMER
+#define GETTIME(timer) gettimeofday(timer, NULL);
+// #endif
+#endif
+
+#ifdef WINDOWS_TIMER
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ { \
+ TIMER s_temp_time; \
+ s_temp_time.LowPart = s_end_timer.LowPart - s_start_timer.LowPart; \
+ s_elapsed_time = \
+ (UWORD32) (((DOUBLE) s_temp_time.LowPart / (DOUBLE) frequency.LowPart) * 1000000); \
+ }
+#else
+// #ifdef GCC_TIMER
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ s_elapsed_time = ((s_end_timer.tv_sec - s_start_timer.tv_sec) * 1000000) + \
+ (s_end_timer.tv_usec - s_start_timer.tv_usec);
+// #endif
+#endif
+
+#else
+#define GETTIME(timer)
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency)
+#endif
+
+/* Function declarations */
+#ifndef MD5_DISABLE
+void calc_md5_cksum(UWORD8 *pu1_inbuf, UWORD32 u4_stride, UWORD32 u4_width, UWORD32 u4_height,
+ UWORD8 *pu1_cksum_p);
+#else
+#define calc_md5_cksum(a, b, c, d, e)
+#endif
+#ifdef SDL_DISPLAY
+void *sdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void sdl_alloc_disp_buffers(void *);
+void sdl_display(void *, WORD32);
+void sdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void sdl_disp_deinit(void *);
+void sdl_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T sdl_get_color_fmt(void);
+UWORD32 sdl_get_stride(void);
+#endif
+
+#ifdef INTEL_CE5300
+void *gdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void gdl_alloc_disp_buffers(void *);
+void gdl_display(void *, WORD32);
+void gdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void gdl_disp_deinit(void *);
+void gdl_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T gdl_get_color_fmt(void);
+UWORD32 gdl_get_stride(void);
+#endif
+
+#ifdef FBDEV_DISPLAY
+void *fbd_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void fbd_alloc_disp_buffers(void *);
+void fbd_display(void *, WORD32);
+void fbd_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void fbd_disp_deinit(void *);
+void fbd_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T fbd_get_color_fmt(void);
+UWORD32 fbd_get_stride(void);
+#endif
+
+#ifdef IOS_DISPLAY
+void *ios_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void ios_alloc_disp_buffers(void *);
+void ios_display(void *, WORD32);
+void ios_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void ios_disp_deinit(void *);
+void ios_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T ios_get_color_fmt(void);
+UWORD32 ios_get_stride(void);
+#endif
+
+typedef struct
+{
+ UWORD32 u4_piclen_flag;
+ UWORD32 u4_file_save_flag;
+ UWORD32 u4_frame_info_enable;
+ UWORD32 u4_chksum_save_flag;
+ UWORD32 u4_max_frm_ts;
+ IV_COLOR_FORMAT_T e_output_chroma_format;
+ IVD_ARCH_T e_arch;
+ IVD_SOC_T e_soc;
+ UWORD32 dump_q_rd_idx;
+ UWORD32 dump_q_wr_idx;
+ WORD32 disp_q_wr_idx;
+ WORD32 disp_q_rd_idx;
+
+ void *cocodec_obj;
+ UWORD32 u4_share_disp_buf;
+ UWORD32 num_disp_buf;
+ UWORD32 b_pic_present;
+ UWORD32 u4_disable_dblk_level;
+ WORD32 i4_target_layer_id;
+ WORD32 i4_degrade_type;
+ WORD32 i4_degrade_pics;
+ UWORD32 u4_num_cores;
+ UWORD32 disp_delay;
+ WORD32 trace_enable;
+ CHAR ac_trace_fname[STRLENGTH];
+ CHAR ac_piclen_fname[STRLENGTH];
+ CHAR ac_ip_fname[STRLENGTH];
+ CHAR ac_op_fname[STRLENGTH];
+ CHAR ac_qp_map_fname[STRLENGTH];
+ CHAR ac_blk_type_map_fname[STRLENGTH];
+ CHAR ac_op_chksum_fname[STRLENGTH];
+ ivd_out_bufdesc_t s_disp_buffers[MAX_DISP_BUFFERS];
+ iv_yuv_buf_t s_disp_frm_queue[MAX_DISP_BUFFERS];
+ UWORD32 s_disp_frm_id_queue[MAX_DISP_BUFFERS];
+ UWORD32 loopback;
+ UWORD32 display;
+ UWORD32 full_screen;
+ UWORD32 fps;
+
+ UWORD32 u4_strd;
+
+ /* For signalling to display thread */
+ UWORD32 u4_pic_wd;
+ UWORD32 u4_pic_ht;
+
+ /* For IOS diplay */
+ WORD32 i4_screen_wd;
+ WORD32 i4_screen_ht;
+
+ WORD32 quit;
+ WORD32 paused;
+
+ void *pv_disp_ctx;
+ void *display_thread_handle;
+ WORD32 display_thread_created;
+ volatile WORD32 display_init_done;
+ volatile WORD32 display_deinit_flag;
+
+ void *(*disp_init)(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *,
+ WORD32 *);
+ void (*alloc_disp_buffers)(void *);
+ void (*display_buffer)(void *, WORD32);
+ void (*set_disp_buffers)(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+ void (*disp_deinit)(void *);
+ void (*disp_usleep)(UWORD32);
+ IV_COLOR_FORMAT_T (*get_color_fmt)(void);
+ UWORD32 (*get_stride)(void);
+} vid_dec_ctx_t;
+
+/**
+ * function pointer to malloc
+ */
+void *(*pf_mem_alloc)(UWORD32 u4_size);
+
+/**
+ * function pointer to free
+ */
+void (*pf_mem_free)(void *pv_mem);
+
+typedef enum
+{
+ INVALID,
+ HELP,
+ VERSION,
+ INPUT_FILE,
+ OUTPUT,
+ QP_MAP_FILE,
+ BLK_TYPE_MAP_FILE,
+ CHKSUM,
+ SAVE_OUTPUT,
+ SAVE_FRAME_INFO,
+ SAVE_CHKSUM,
+ CHROMA_FORMAT,
+ NUM_FRAMES,
+ NUM_CORES,
+ DISABLE_DEBLOCK_LEVEL,
+ SHARE_DISPLAY_BUF,
+ LOOPBACK,
+ DISPLAY,
+ FULLSCREEN,
+ FPS,
+ TRACE,
+ CONFIG,
+
+ DEGRADE_TYPE,
+ DEGRADE_PICS,
+ ARCH,
+ SOC,
+ PICLEN,
+ PICLEN_FILE,
+ TARGET_LAYER_ID,
+} ARGUMENT_T;
+
+typedef struct
+{
+ CHAR argument_shortname[4];
+ CHAR argument_name[128];
+ ARGUMENT_T argument;
+ CHAR description[512];
+} argument_t;
+
+static const argument_t argument_mapping[] = {
+ {"-h", "--help", HELP, "Print this help\n"},
+ {"-c", "--config", CONFIG, "config file (Default: test.cfg)\n"},
+
+ {"-v", "--version", VERSION, "Version information\n"},
+ {"-i", "--input", INPUT_FILE, "Input file\n"},
+ {"-o", "--output", OUTPUT, "Output file\n"},
+ {"--", "--qp_map_file", QP_MAP_FILE, "QP map file\n"},
+ {"--", "--blk_type_map_file", BLK_TYPE_MAP_FILE, "Block type map file\n"},
+ {"--", "--piclen", PICLEN,
+ "Flag to signal if the decoder has to use a file containing number of "
+ "bytes in each picture to be fed in each call\n"},
+ {"--", "--piclen_file", PICLEN_FILE,
+ "File containing number of bytes in each picture - each line containing "
+ "one i4_size\n"},
+ {"--", "--chksum", CHKSUM, "Output MD5 Checksum file\n"},
+ {"-s", "--save_output", SAVE_OUTPUT, "Save Output file\n"},
+ {"--", "--save_frame_info", SAVE_FRAME_INFO, "Save frame_info file\n"},
+ {"--", "--save_chksum", SAVE_CHKSUM, "Save Check sum file\n"},
+ {"--", "--chroma_format", CHROMA_FORMAT,
+ "Output Chroma format Supported values YUV_420P, YUV_422ILE, RGB_565, "
+ "YUV_420SP_UV, YUV_420SP_VU\n"},
+ {"-n", "--num_frames", NUM_FRAMES, "Number of frames to be decoded\n"},
+ {"--", "--num_cores", NUM_CORES, "Number of cores to be used\n"},
+ {"--", "--share_display_buf", SHARE_DISPLAY_BUF, "Enable shared display buffer mode\n"},
+ {"--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL,
+ "Disable deblocking level : 0 to 4 - 0 Enable deblocking 4 Disable "
+ "deblocking completely\n"},
+ {"--", "--loopback", LOOPBACK, "Enable playback in a loop\n"},
+ {"--", "--display", DISPLAY, "Enable display (uses SDL)\n"},
+ {"--", "--fullscreen", FULLSCREEN, "Enable full screen (Only for GDL and SDL)\n"},
+ {"--", "--fps", FPS, "FPS to be used for display \n"},
+ {"-i", "--trace", TRACE, "Trace file\n"},
+
+ {"--", "--degrade_type", DEGRADE_TYPE,
+ "Degrade type : 0: No degrade 0th bit set : Disable SAO 1st bit set : "
+ "Disable deblocking 2nd bit set : Faster inter prediction filters 3rd bit "
+ "set : Fastest inter prediction filters\n"},
+ {"--", "--degrade_pics", DEGRADE_PICS,
+ "Degrade pics : 0 : No degrade 1 : Only on non-reference frames 2 : Do "
+ "not degrade every 4th or key frames 3 : All non-key frames 4 : All "
+ "frames"},
+
+ {"--", "--arch", ARCH,
+ "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, "
+ "ARM_NEONINTR,ARMV8_GENERIC, X86_GENERIC, X86_SSSE3, X86_SSE4 \n"},
+ {"--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n"},
+ {"-t", "--target_layer_id", TARGET_LAYER_ID, "Version information\n"},
+
+};
+
+#define PEAK_WINDOW_SIZE 8
+#define DEFAULT_SHARE_DISPLAY_BUF 0
+#define STRIDE 0
+#define DEFAULT_NUM_CORES 1
+
+#define DUMP_SINGLE_BUF 0
+#define IV_ISFATALERROR(x) (((x) >> IVD_FATALERROR) & 0x1)
+
+#define ivd_api_function isvcd_api_function
+
+#ifdef IOS
+char filename_trace[PATHLENMAX];
+#endif
+
+#if ANDROID_NDK
+/*****************************************************************************/
+/* */
+/* Function Name : raise */
+/* */
+/* Description : Needed as a workaround when the application is built in */
+/* Android NDK. This is an exception to be called for divide*/
+/* by zero error */
+/* */
+/* Inputs : a */
+/* Globals : */
+/* Processing : None */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+int raise(int a)
+{
+ printf("Divide by zero\n");
+ return 0;
+}
+#endif
+
+#ifdef _WIN32
+/*****************************************************************************/
+/* Function to print library calls */
+/*****************************************************************************/
+/*****************************************************************************/
+/* */
+/* Function Name : memalign */
+/* */
+/* Description : Returns malloc data. Ideally should return aligned memory*/
+/* support alignment will be added later */
+/* */
+/* Inputs : alignment i4_size */
+/* Globals : */
+/* Processing : */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ (void) pv_ctxt;
+ return (void *) _aligned_malloc(i4_size, alignment);
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ _aligned_free(pv_buf);
+ return;
+}
+#endif
+
+#if IOS
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ (void) pv_ctxt;
+ return malloc(i4_size);
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+}
+#endif
+
+#if(!defined(IOS)) && (!defined(_WIN32))
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ void *buf = NULL;
+ (void) pv_ctxt;
+ if(0 != posix_memalign(&buf, alignment, i4_size))
+ {
+ return NULL;
+ }
+ return buf;
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+}
+#endif
+
+void *ih264a_memory_alloc(UWORD32 u4_size) { return (malloc(u4_size)); }
+
+void ih264a_memory_free(void *pv_mem) { free(pv_mem); }
+/*****************************************************************************/
+/* */
+/* Function Name : set_degrade */
+/* */
+/* Description : Control call to set degrade level */
+/* */
+/* */
+/* Inputs : codec_obj - Codec Handle */
+/* type - degrade level value between 0 to 4 */
+/* 0 : No degrade */
+/* 1st bit : Disable SAO */
+/* 2nd bit : Disable Deblock */
+/* 3rd bit : Faster MC for non-ref */
+/* 4th bit : Fastest MC for non-ref */
+/* pics - Pictures that are are degraded */
+/* 0 : No degrade */
+/* 1 : Non-ref pictures */
+/* 2 : Pictures at given interval are not degraded */
+/* 3 : All non-key pictures */
+/* 4 : All pictures */
+/* Globals : */
+/* Processing : Calls degrade control to the codec */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics)
+{
+ isvcd_ctl_degrade_ip_t s_ctl_ip;
+ isvcd_ctl_degrade_op_t s_ctl_op;
+ void *pv_api_ip, *pv_api_op;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ s_ctl_ip.u4_size = sizeof(isvcd_ctl_degrade_ip_t);
+ s_ctl_ip.i4_degrade_type = type;
+ s_ctl_ip.i4_nondegrade_interval = 4;
+ s_ctl_ip.i4_degrade_pics = pics;
+
+ s_ctl_op.u4_size = sizeof(isvcd_ctl_degrade_op_t);
+
+ pv_api_ip = (void *) &s_ctl_ip;
+ pv_api_op = (void *) &s_ctl_op;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_DEGRADE;
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, pv_api_ip, pv_api_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in setting degrade level \n");
+ }
+ return (e_dec_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : enable_skipb_frames */
+/* */
+/* Description : Control call to enable skipping of b frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_B;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Enable SkipB frames \n");
+ }
+
+ return e_dec_status;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : disable_skipb_frames */
+/* */
+/* Description : Control call to disable skipping of b frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls disable B frame skip control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Disable SkipB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : enable_skippb_frames */
+/* */
+/* Description : Control call to enable skipping of P & B frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip P and B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_PB;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Enable SkipPB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : disable_skippb_frames */
+/* */
+/* Description : Control call to disable skipping of P and B frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls disable P and B frame skip control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Disable SkipPB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : release_disp_frame */
+/* */
+/* Description : Calls release display control - Used to signal to the */
+/* decoder that this particular buffer has been displayed */
+/* and that the codec is now free to write to this buffer */
+/* */
+/* */
+/* Inputs : codec_obj : Codec Handle */
+/* buf_id : Buffer Id of the buffer to be released */
+/* This id would have been returned earlier by */
+/* the codec */
+/* Globals : */
+/* Processing : Calls Release Display call */
+/* */
+/* Outputs : */
+/* Returns : Status of release display call */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T release_disp_frame(void *codec_obj, UWORD32 buf_id)
+{
+ ivd_rel_display_frame_ip_t s_video_rel_disp_ip;
+ ivd_rel_display_frame_op_t s_video_rel_disp_op;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ s_video_rel_disp_ip.e_cmd = IVD_CMD_REL_DISPLAY_FRAME;
+ s_video_rel_disp_ip.u4_size = sizeof(ivd_rel_display_frame_ip_t);
+ s_video_rel_disp_op.u4_size = sizeof(ivd_rel_display_frame_op_t);
+ s_video_rel_disp_ip.u4_disp_buf_id = buf_id;
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_video_rel_disp_ip,
+ (void *) &s_video_rel_disp_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Release Disp frame\n");
+ }
+
+ return (e_dec_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_version */
+/* */
+/* Description : Control call to get codec version */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T get_version(void *codec_obj)
+{
+ ivd_ctl_getversioninfo_ip_t ps_ctl_ip;
+ ivd_ctl_getversioninfo_op_t ps_ctl_op;
+ UWORD8 au1_buf[512];
+ IV_API_CALL_STATUS_T i4_status;
+ ps_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+ ps_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+ ps_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+ ps_ctl_ip.pv_version_buffer = au1_buf;
+ ps_ctl_ip.u4_version_buffer_size = sizeof(au1_buf);
+
+ i4_status =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &(ps_ctl_ip), (void *) &(ps_ctl_op));
+
+ if(i4_status != IV_SUCCESS)
+ {
+ printf(
+ "Error in Getting Version number e_dec_status = %d u4_error_code = "
+ "%x\n",
+ i4_status, ps_ctl_op.u4_error_code);
+ }
+ else
+ {
+ printf("Ittiam Decoder Version number: %s\n", (char *) ps_ctl_ip.pv_version_buffer);
+ }
+ return i4_status;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : codec_exit */
+/* */
+/* Description : handles unrecoverable errors */
+/* Inputs : Error message */
+/* Globals : None */
+/* Processing : Prints error message to console and exits. */
+/* Outputs : Error mesage to the console */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+void codec_exit(CHAR *pc_err_message)
+{
+ printf("%s\n", pc_err_message);
+ exit(-1);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : dump_output */
+/* */
+/* Description : Used to dump output YUV */
+/* Inputs : App context, disp output desc, File pointer */
+/* Globals : None */
+/* Processing : Dumps to a file */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+void dump_output(vid_dec_ctx_t *ps_app_ctx, iv_yuv_buf_t *ps_disp_frm_buf,
+ isvcd_video_decode_op_t *ps_h264d_decode_op, UWORD32 u4_disp_frm_id,
+ FILE *ps_op_file, FILE *ps_qp_file, FILE *ps_mb_type_file, FILE *ps_op_chksum_file,
+ WORD32 i4_op_frm_ts, UWORD32 file_save, UWORD32 chksum_save, UWORD32 mbinfo_save)
+
+{
+ UWORD32 i;
+ iv_yuv_buf_t s_dump_disp_frm_buf;
+ UWORD32 u4_disp_id;
+
+ memset(&s_dump_disp_frm_buf, 0, sizeof(iv_yuv_buf_t));
+
+ if(ps_app_ctx->u4_share_disp_buf)
+ {
+ if(ps_app_ctx->dump_q_wr_idx == MAX_DISP_BUFFERS) ps_app_ctx->dump_q_wr_idx = 0;
+
+ if(ps_app_ctx->dump_q_rd_idx == MAX_DISP_BUFFERS) ps_app_ctx->dump_q_rd_idx = 0;
+
+ ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_wr_idx] = *ps_disp_frm_buf;
+ ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_wr_idx] = u4_disp_frm_id;
+ ps_app_ctx->dump_q_wr_idx++;
+
+ if((WORD32) i4_op_frm_ts >= (WORD32) (ps_app_ctx->disp_delay - 1))
+ {
+ s_dump_disp_frm_buf = ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_rd_idx];
+ u4_disp_id = ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_rd_idx];
+ ps_app_ctx->dump_q_rd_idx++;
+ }
+ else
+ {
+ return;
+ }
+ }
+ else
+ {
+ s_dump_disp_frm_buf = *ps_disp_frm_buf;
+ u4_disp_id = u4_disp_frm_id;
+ }
+
+ release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id);
+
+ if(0 == file_save && 0 == chksum_save && 0 == mbinfo_save) return;
+
+ if(0 != mbinfo_save)
+ {
+ UWORD8 *buf;
+ if(ps_h264d_decode_op->pu1_8x8_blk_qp_map && ps_qp_file)
+ {
+ buf = ps_h264d_decode_op->pu1_8x8_blk_qp_map;
+ fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_qp_map_size, ps_qp_file);
+ fflush(ps_qp_file);
+ }
+ if(ps_h264d_decode_op->pu1_8x8_blk_type_map && ps_mb_type_file)
+ {
+ buf = ps_h264d_decode_op->pu1_8x8_blk_type_map;
+ fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_type_map_size, ps_mb_type_file);
+ fflush(ps_mb_type_file);
+ }
+ }
+ if(NULL == s_dump_disp_frm_buf.pv_y_buf) return;
+
+ if(ps_app_ctx->e_output_chroma_format == IV_YUV_420P)
+ {
+#if DUMP_SINGLE_BUF
+ {
+ UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 80 - (s_dump_disp_frm_buf.u4_y_strd * 80);
+
+ UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 160) +
+ (s_dump_disp_frm_buf.u4_u_ht + 80));
+ fwrite(buf, 1, i4_size, ps_op_file);
+ }
+#else
+ if(0 != file_save && ps_op_file)
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd;
+ }
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_u_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_u_strd;
+ }
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_v_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_v_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_v_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_v_strd;
+ }
+ }
+
+ if(0 != chksum_save && ps_op_chksum_file)
+ {
+ UWORD8 au1_y_chksum[16];
+ UWORD8 au1_u_chksum[16];
+ UWORD8 au1_v_chksum[16];
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_y_buf, s_dump_disp_frm_buf.u4_y_strd,
+ s_dump_disp_frm_buf.u4_y_wd, s_dump_disp_frm_buf.u4_y_ht, au1_y_chksum);
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_u_buf, s_dump_disp_frm_buf.u4_u_strd,
+ s_dump_disp_frm_buf.u4_u_wd, s_dump_disp_frm_buf.u4_u_ht, au1_u_chksum);
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_v_buf, s_dump_disp_frm_buf.u4_v_strd,
+ s_dump_disp_frm_buf.u4_v_wd, s_dump_disp_frm_buf.u4_v_ht, au1_v_chksum);
+
+ fwrite(au1_y_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ fwrite(au1_u_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ fwrite(au1_v_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ }
+#endif
+ }
+ else if((ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_UV) ||
+ (ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_VU))
+ {
+#if DUMP_SINGLE_BUF
+ {
+ UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 24 - (s_dump_disp_frm_buf.u4_y_strd * 40);
+
+ UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 80) +
+ (s_dump_disp_frm_buf.u4_u_ht + 40));
+ fwrite(buf, 1, i4_size, ps_op_file);
+ }
+#else
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd;
+ }
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_u_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_u_strd;
+ }
+ }
+#endif
+ }
+ else if(ps_app_ctx->e_output_chroma_format == IV_RGBA_8888)
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd * 4, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd * 4;
+ }
+ }
+ else
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_strd * 2, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd * 2;
+ }
+ }
+
+ fflush(ps_op_file);
+ fflush(ps_op_chksum_file);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : print_usage */
+/* */
+/* Description : Prints argument format */
+/* */
+/* */
+/* Inputs : */
+/* Globals : */
+/* Processing : Prints argument format */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void print_usage(void)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ printf("\nUsage:\n");
+ while(i < num_entries)
+ {
+ printf("%-32s\t %s", argument_mapping[i].argument_name, argument_mapping[i].description);
+ i++;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+ARGUMENT_T get_argument(CHAR *name)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ while(i < num_entries)
+ {
+ if((0 == strcmp(argument_mapping[i].argument_name, name)) ||
+ ((0 == strcmp(argument_mapping[i].argument_shortname, name)) &&
+ (0 != strcmp(argument_mapping[i].argument_shortname, "--"))))
+ {
+ return argument_mapping[i].argument;
+ }
+ i++;
+ }
+ return INVALID;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value)
+{
+ ARGUMENT_T arg;
+
+ arg = get_argument(argument);
+ switch(arg)
+ {
+ case HELP:
+ print_usage();
+ exit(-1);
+ case VERSION:
+ break;
+ case INPUT_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_ip_fname);
+ // input_passed = 1;
+ break;
+
+ case OUTPUT:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_fname);
+ break;
+
+ case QP_MAP_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_qp_map_fname);
+ break;
+
+ case BLK_TYPE_MAP_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_blk_type_map_fname);
+ break;
+
+ case CHKSUM:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_chksum_fname);
+ break;
+
+ case SAVE_OUTPUT:
+ sscanf(value, "%d", &ps_app_ctx->u4_file_save_flag);
+ break;
+
+ case SAVE_FRAME_INFO:
+ sscanf(value, "%d", &ps_app_ctx->u4_frame_info_enable);
+ break;
+
+ case SAVE_CHKSUM:
+ sscanf(value, "%d", &ps_app_ctx->u4_chksum_save_flag);
+ break;
+
+ case CHROMA_FORMAT:
+ if((strcmp(value, "YUV_420P")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420P;
+ else if((strcmp(value, "YUV_422ILE")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_422ILE;
+ else if((strcmp(value, "RGB_565")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_RGB_565;
+ else if((strcmp(value, "RGBA_8888")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_RGBA_8888;
+ else if((strcmp(value, "YUV_420SP_UV")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_UV;
+ else if((strcmp(value, "YUV_420SP_VU")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_VU;
+ else
+ {
+ printf("\nInvalid colour format setting it to IV_YUV_420P\n");
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420P;
+ }
+
+ break;
+ case NUM_FRAMES:
+ sscanf(value, "%d", &ps_app_ctx->u4_max_frm_ts);
+ break;
+
+ case NUM_CORES:
+ sscanf(value, "%d", &ps_app_ctx->u4_num_cores);
+ break;
+ case DEGRADE_PICS:
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_pics);
+ break;
+ case DEGRADE_TYPE:
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_type);
+ break;
+ case SHARE_DISPLAY_BUF:
+ sscanf(value, "%d", &ps_app_ctx->u4_share_disp_buf);
+ break;
+ case LOOPBACK:
+ sscanf(value, "%d", &ps_app_ctx->loopback);
+ break;
+ case DISPLAY:
+#if defined(SDL_DISPLAY) || defined(FBDEV_DISPLAY) || defined(INTEL_CE5300) || defined(IOS_DISPLAY)
+ sscanf(value, "%d", &ps_app_ctx->display);
+#else
+ ps_app_ctx->display = 0;
+#endif
+ break;
+ case FULLSCREEN:
+ sscanf(value, "%d", &ps_app_ctx->full_screen);
+ break;
+ case FPS:
+ sscanf(value, "%d", &ps_app_ctx->fps);
+ if(ps_app_ctx->fps <= 0) ps_app_ctx->fps = DEFAULT_FPS;
+ break;
+ case ARCH:
+ if((strcmp(value, "ARM_NONEON")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_NONEON;
+ else if((strcmp(value, "ARM_A9Q")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A9Q;
+ else if((strcmp(value, "ARM_A7")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A7;
+ else if((strcmp(value, "ARM_A5")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A5;
+ else if((strcmp(value, "ARM_NEONINTR")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_NEONINTR;
+ else if((strcmp(value, "X86_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_GENERIC;
+ else if((strcmp(value, "X86_SSSE3")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_SSSE3;
+ else if((strcmp(value, "X86_SSE42")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_SSE42;
+ else if((strcmp(value, "X86_AVX2")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_AVX2;
+ else if((strcmp(value, "MIPS_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_MIPS_GENERIC;
+ else if((strcmp(value, "MIPS_32")) == 0)
+ ps_app_ctx->e_arch = ARCH_MIPS_32;
+ else if((strcmp(value, "ARMV8_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC;
+ else
+ {
+ printf("\nInvalid Arch. Setting it to ARM_A9Q\n");
+ ps_app_ctx->e_arch = ARCH_ARM_A9Q;
+ }
+
+ break;
+ case SOC:
+ if((strcmp(value, "GENERIC")) == 0)
+ ps_app_ctx->e_soc = SOC_GENERIC;
+ else if((strcmp(value, "HISI_37X")) == 0)
+ ps_app_ctx->e_soc = SOC_HISI_37X;
+ else
+ {
+ ps_app_ctx->e_soc = atoi(value);
+ /*
+ printf("\nInvalid SOC. Setting it to GENERIC\n");
+ ps_app_ctx->e_soc = SOC_GENERIC;
+ */
+ }
+ break;
+ case PICLEN:
+ sscanf(value, "%d", &ps_app_ctx->u4_piclen_flag);
+ break;
+
+ case PICLEN_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_piclen_fname);
+ break;
+ case DISABLE_DEBLOCK_LEVEL:
+ sscanf(value, "%d", &ps_app_ctx->u4_disable_dblk_level);
+ break;
+
+ case TARGET_LAYER_ID:
+ sscanf(value, "%d", &ps_app_ctx->i4_target_layer_id);
+ break;
+
+ case INVALID:
+ default:
+ printf("Ignoring argument : %s\n", argument);
+ break;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : read_cfg_file */
+/* */
+/* Description : Reads arguments from a configuration file */
+/* */
+/* */
+/* Inputs : ps_app_ctx : Application context */
+/* fp_cfg_file : Configuration file handle */
+/* Globals : */
+/* Processing : Parses the arguments and fills in the application context*/
+/* */
+/* Outputs : Arguments parsed */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void read_cfg_file(vid_dec_ctx_t *ps_app_ctx, FILE *fp_cfg_file)
+{
+ CHAR line[STRLENGTH];
+ CHAR description[STRLENGTH];
+ CHAR value[STRLENGTH];
+ CHAR argument[STRLENGTH];
+ void *ret;
+ while(0 == feof(fp_cfg_file))
+ {
+ line[0] = '\0';
+ ret = fgets(line, STRLENGTH, fp_cfg_file);
+ if(NULL == ret) break;
+ argument[0] = '\0';
+ /* Reading Input File Name */
+ sscanf(line, "%s %s %s", argument, value, description);
+ if(argument[0] == '\0') continue;
+
+ parse_argument(ps_app_ctx, argument, value);
+ }
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_dequeue \endif
+*
+* \brief
+* This function gets a free buffer index where display data can be written
+* This is a blocking call and can be exited by setting quit to true in
+* the application context
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_producer_dequeue(vid_dec_ctx_t *ps_app_ctx)
+{
+ WORD32 idx;
+
+ /* If there is no free buffer wait */
+
+ while(((ps_app_ctx->disp_q_wr_idx + 1) % NUM_DISPLAY_BUFFERS) == ps_app_ctx->disp_q_rd_idx)
+ {
+ ithread_sleep(1000);
+
+ if(ps_app_ctx->quit) return (-1);
+ }
+
+ idx = ps_app_ctx->disp_q_wr_idx;
+ return (idx);
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_queue \endif
+*
+* \brief
+* This function adds buffer which can be displayed
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_producer_queue(vid_dec_ctx_t *ps_app_ctx)
+{
+ ps_app_ctx->disp_q_wr_idx++;
+ if(ps_app_ctx->disp_q_wr_idx == NUM_DISPLAY_BUFFERS) ps_app_ctx->disp_q_wr_idx = 0;
+
+ return (0);
+}
+/*!
+**************************************************************************
+* \if Function name : dispq_consumer_dequeue \endif
+*
+* \brief
+* This function gets a free buffer index where display data can be written
+* This is a blocking call and can be exited by setting quit to true in
+* the application context
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_consumer_dequeue(vid_dec_ctx_t *ps_app_ctx)
+{
+ WORD32 idx;
+
+ /* If there is no free buffer wait */
+
+ while(ps_app_ctx->disp_q_wr_idx == ps_app_ctx->disp_q_rd_idx)
+ {
+ ithread_sleep(1000);
+
+ if(ps_app_ctx->quit) return (-1);
+ }
+
+ idx = ps_app_ctx->disp_q_rd_idx;
+ return (idx);
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_queue \endif
+*
+* \brief
+* This function adds buffer which can be displayed
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_consumer_queue(vid_dec_ctx_t *ps_app_ctx)
+{
+ ps_app_ctx->disp_q_rd_idx++;
+ if(ps_app_ctx->disp_q_rd_idx == NUM_DISPLAY_BUFFERS) ps_app_ctx->disp_q_rd_idx = 0;
+
+ return (0);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : display_thread */
+/* */
+/* Description : Thread to display the frame */
+/* */
+/* */
+/* Inputs : pv_ctx : Application context */
+/* */
+/* Globals : */
+/* Processing : Wait for a buffer to get produced by decoder and display */
+/* that frame */
+/* */
+/* Outputs : */
+/* Returns : None */
+/* */
+/* Issues : Pause followed by quit is making some deadlock condn */
+/* If decoder was lagging initially and then fasten up, */
+/* display will also go at faster rate till it reaches */
+/* equilibrium wrt the initial time */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+WORD32 display_thread(void *pv_ctx)
+{
+ vid_dec_ctx_t *ps_app_ctx = (vid_dec_ctx_t *) pv_ctx;
+
+ UWORD32 frm_duration; /* in us */
+ UWORD32 current_time = 0;
+ UWORD32 expected_time;
+ UWORD32 first_frame_displayed;
+
+#ifdef WINDOWS_TIMER
+ LARGE_INTEGER frequency;
+#endif
+
+#ifdef WINDOWS_TIMER
+ QueryPerformanceFrequency(&frequency);
+#endif
+
+#ifdef PROFILE_ENABLE
+ UWORD32 s_elapsed_time;
+ TIMER s_start_timer;
+ TIMER s_end_timer;
+ TIMER s_first_frame_time;
+#endif
+
+ first_frame_displayed = 0;
+ expected_time = 0;
+ frm_duration = 1000000 / ps_app_ctx->fps;
+
+ /* Init display and allocate display buffers */
+ ps_app_ctx->pv_disp_ctx = (void *) ps_app_ctx->disp_init(
+ ps_app_ctx->u4_pic_wd, ps_app_ctx->u4_pic_ht, ps_app_ctx->i4_screen_wd,
+ ps_app_ctx->i4_screen_ht, ps_app_ctx->u4_pic_wd, ps_app_ctx->u4_pic_ht,
+ ps_app_ctx->full_screen, &ps_app_ctx->quit, &ps_app_ctx->paused);
+ ps_app_ctx->alloc_disp_buffers(ps_app_ctx->pv_disp_ctx);
+
+ ps_app_ctx->display_init_done = 1;
+
+ while(1)
+ {
+ WORD32 rd_idx;
+
+ rd_idx = dispq_consumer_dequeue(ps_app_ctx);
+ if(ps_app_ctx->quit) break;
+
+ ps_app_ctx->display_buffer(ps_app_ctx->pv_disp_ctx, rd_idx);
+
+ if(0 == first_frame_displayed)
+ {
+ GETTIME(&s_first_frame_time);
+ first_frame_displayed = 1;
+ }
+
+ /*********************************************************************/
+ /* Sleep based on the expected time of arrival of current buffer and */
+ /* the Current frame */
+ /*********************************************************************/
+
+ GETTIME(&s_end_timer);
+ ELAPSEDTIME(s_first_frame_time, s_end_timer, current_time, frequency);
+
+ /* time in micro second */
+ expected_time += frm_duration;
+
+ // printf("current_time %d expected_time %d diff %d \n", current_time,
+ // expected_time, (expected_time - current_time));
+ /* sleep for the diff. in time */
+ if(current_time < expected_time)
+ ps_app_ctx->disp_usleep((expected_time - current_time));
+ else
+ expected_time += (current_time - expected_time);
+
+ dispq_consumer_queue(ps_app_ctx);
+ }
+
+ while(0 == ps_app_ctx->display_deinit_flag)
+ {
+ ps_app_ctx->disp_usleep(1000);
+ }
+ ps_app_ctx->disp_deinit(ps_app_ctx->pv_disp_ctx);
+
+ return 0;
+}
+
+void output_write_stall(CHAR *fname, UWORD32 cur_frm_idx)
+{
+ const UWORD8 threshold = 64;
+ CHAR past_fname[1000];
+ FILE *fp_fast_file = NULL;
+
+ if(cur_frm_idx >= threshold)
+ {
+ sprintf(past_fname, fname, cur_frm_idx - threshold);
+ do
+ {
+ fp_fast_file = fopen(past_fname, "rb");
+ if(fp_fast_file != NULL)
+ {
+ fclose(fp_fast_file);
+ /* Wait until the resource is released by a third party app*/
+ ithread_sleep(5000);
+ }
+ else
+ break;
+ } while(1);
+ }
+}
+
+void flush_output(iv_obj_t *codec_obj, vid_dec_ctx_t *ps_app_ctx, ivd_out_bufdesc_t *ps_out_buf,
+ UWORD8 *pu1_bs_buf, UWORD32 *pu4_op_frm_ts, FILE *ps_op_file, FILE *ps_qp_file,
+ FILE *ps_mb_type_file, UWORD8 *pu1_qp_map_buf, UWORD8 *pu1_blk_type_map_buf,
+ FILE *ps_op_chksum_file, UWORD32 u4_ip_frm_ts, UWORD32 u4_bytes_remaining)
+{
+ WORD32 ret;
+
+ do
+ {
+ ivd_ctl_flush_ip_t s_ctl_ip;
+ ivd_ctl_flush_op_t s_ctl_op;
+
+ if(*pu4_op_frm_ts >= (ps_app_ctx->u4_max_frm_ts + ps_app_ctx->disp_delay)) break;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in Setting the decoder in flush mode\n");
+ }
+
+ if(IV_SUCCESS == ret)
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip;
+ isvcd_video_decode_op_t s_h264d_decode_op;
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] =
+ ps_out_buf->u4_min_out_buf_size[0];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] =
+ ps_out_buf->u4_min_out_buf_size[1];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] =
+ ps_out_buf->u4_min_out_buf_size[2];
+
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2];
+ ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs;
+
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /*****************************************************************************/
+ /* API Call: Video Decode */
+ /*****************************************************************************/
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ if(1 == ps_video_decode_op->u4_output_present)
+ {
+ CHAR cur_fname[1000];
+ CHAR *extn = NULL;
+ /* The objective is to dump the decoded frames into separate files
+ * instead of dumping all the frames in one common file. Also, the
+ * number of dumped frames at any given instance of time cannot exceed
+ * 'frame_memory'
+ */
+
+ /*************************************************************************/
+ /* Get SEI MDCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op;
+
+ memset(&s_ctl_get_sei_mdcv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t));
+ memset(&s_ctl_get_sei_mdcv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t));
+
+ s_ctl_get_sei_mdcv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_mdcv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS;
+ s_ctl_get_sei_mdcv_params_ip.u4_size =
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t);
+ s_ctl_get_sei_mdcv_params_op.u4_size =
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_mdcv_params_ip,
+ (void *) &s_ctl_get_sei_mdcv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("MDCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_mdcv_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CLL parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag)
+ {
+ isvcd_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip;
+ isvcd_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op;
+
+ memset(&s_ctl_get_sei_cll_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_cll_params_ip_t));
+ memset(&s_ctl_get_sei_cll_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_cll_params_op_t));
+
+ s_ctl_get_sei_cll_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_cll_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CLL_PARAMS;
+ s_ctl_get_sei_cll_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_ip_t);
+ s_ctl_get_sei_cll_params_op.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_cll_params_ip,
+ (void *) &s_ctl_get_sei_cll_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CLL SEI params not present : Error %x\n",
+ s_ctl_get_sei_cll_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI AVE parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip;
+ isvcd_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op;
+
+ memset(&s_ctl_get_sei_ave_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_ave_params_ip_t));
+ memset(&s_ctl_get_sei_ave_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_ave_params_op_t));
+
+ s_ctl_get_sei_ave_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ave_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_AVE_PARAMS;
+ s_ctl_get_sei_ave_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_ip_t);
+ s_ctl_get_sei_ave_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_ave_params_ip,
+ (void *) &s_ctl_get_sei_ave_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("AVE SEI params not present : Error %x\n",
+ s_ctl_get_sei_ave_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op;
+
+ memset(&s_ctl_get_sei_ccv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_ccv_params_ip_t));
+ memset(&s_ctl_get_sei_ccv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_ccv_params_op_t));
+
+ s_ctl_get_sei_ccv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ccv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CCV_PARAMS;
+ s_ctl_get_sei_ccv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_ip_t);
+ s_ctl_get_sei_ccv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_ccv_params_ip,
+ (void *) &s_ctl_get_sei_ccv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_ccv_params_op.u4_error_code);
+ }
+ }
+
+ if(ps_app_ctx->u4_file_save_flag)
+ {
+ /* Locate the position of extension yuv */
+ extn = strstr(ps_app_ctx->ac_op_fname, "%d");
+ if(extn != NULL)
+ {
+ output_write_stall(ps_app_ctx->ac_op_fname, *pu4_op_frm_ts);
+ /* Generate output file names */
+ sprintf(cur_fname, ps_app_ctx->ac_op_fname, *pu4_op_frm_ts);
+ /* Open Output file */
+ ps_op_file = fopen(cur_fname, "wb");
+ if(NULL == ps_op_file)
+ {
+ CHAR ac_error_str[STRLENGTH];
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open output file %s", cur_fname);
+
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+ dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op,
+ ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_qp_file,
+ ps_mb_type_file, ps_op_chksum_file, *pu4_op_frm_ts,
+ ps_app_ctx->u4_file_save_flag, ps_app_ctx->u4_chksum_save_flag,
+ ps_app_ctx->u4_frame_info_enable);
+ if(extn != NULL) fclose(ps_op_file);
+ (*pu4_op_frm_ts)++;
+ }
+ }
+ } while(IV_SUCCESS == ret);
+}
+
+#ifdef X86_MINGW
+void sigsegv_handler()
+{
+ printf("Segmentation fault, Exiting.. \n");
+ exit(-1);
+}
+#endif
+
+UWORD32 default_get_stride(void) { return 0; }
+
+IV_COLOR_FORMAT_T default_get_color_fmt(void) { return IV_YUV_420P; }
+/*****************************************************************************/
+/* */
+/* Function Name : main */
+/* */
+/* Description : Application to demonstrate codec API */
+/* */
+/* */
+/* Inputs : argc - Number of arguments */
+/* argv[] - Arguments */
+/* Globals : */
+/* Processing : Shows how to use create, process, control and delete */
+/* */
+/* Outputs : Codec output in a file */
+/* Returns : */
+/* */
+/* Issues : Assumes both PROFILE_ENABLE to be */
+/* defined for multithread decode-display working */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/*****************************************************************************/
+#ifdef IOS
+int h264dec_main(char *homedir, char *documentdir, int screen_wd, int screen_ht)
+#else
+int main(WORD32 argc, CHAR *argv[])
+#endif
+{
+ CHAR ac_cfg_fname[STRLENGTH];
+ FILE *fp_cfg_file = NULL;
+ FILE *ps_piclen_file = NULL;
+ FILE *ps_ip_file = NULL;
+ FILE *ps_op_file = NULL;
+ FILE *ps_qp_file = NULL;
+ FILE *ps_mb_type_file = NULL;
+ FILE *ps_op_chksum_file = NULL;
+ WORD32 ret;
+ CHAR ac_error_str[STRLENGTH];
+ vid_dec_ctx_t s_app_ctx;
+ UWORD8 *pu1_bs_buf = NULL;
+ UWORD8 *pu1_qp_map_buf = NULL;
+ UWORD8 *pu1_blk_type_map_buf = NULL;
+
+ ivd_out_bufdesc_t *ps_out_buf;
+ UWORD32 u4_num_bytes_dec = 0;
+ UWORD32 file_pos = 0;
+
+ UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
+
+ WORD32 u4_bytes_remaining = 0;
+ UWORD32 i;
+ UWORD32 u4_ip_buf_len;
+ WORD32 total_bytes_comsumed;
+ UWORD32 max_op_frm_ts;
+ UWORD32 u4_num_disp_bufs_with_dec;
+
+#ifdef PROFILE_ENABLE
+ UWORD32 u4_tot_cycles = 0;
+ UWORD32 frm_cnt = 0;
+ UWORD32 u4_tot_fmt_cycles = 0;
+ UWORD32 peak_window[PEAK_WINDOW_SIZE];
+ UWORD32 peak_window_idx = 0;
+ UWORD32 peak_avg_max = 0;
+#ifdef INTEL_CE5300
+ UWORD32 time_consumed = 0;
+ UWORD32 bytes_consumed = 0;
+#endif
+#endif
+
+#ifdef WINDOWS_TIMER
+ LARGE_INTEGER frequency;
+#endif
+#ifdef PROFILE_ENABLE
+ WORD32 width = 0, height = 0;
+#endif
+ iv_obj_t *codec_obj;
+#if defined(GPU_BUILD) && !defined(X86)
+// int ioctl_init();
+// ioctl_init();
+#endif
+
+#ifdef X86_MINGW
+ // For getting printfs without any delay
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+#endif
+#ifdef IOS
+ sprintf(filename_trace, "%s/iostrace.txt", homedir);
+ printf("\ntrace file name = %s", filename_trace);
+#endif
+
+#ifdef X86_MINGW
+ {
+ signal(SIGSEGV, sigsegv_handler);
+ }
+#endif
+
+#ifndef IOS
+ /* Usage */
+ if(argc < 2)
+ {
+ printf("Using test.cfg as configuration file \n");
+ strcpy(ac_cfg_fname, "test.cfg");
+ }
+ else if(argc == 2)
+ {
+ strcpy(ac_cfg_fname, argv[1]);
+ }
+
+#else
+ strcpy(ac_cfg_fname, "test.cfg");
+
+#endif
+
+ /***********************************************************************/
+ /* Initialize Application parameters */
+ /***********************************************************************/
+
+ strcpy(s_app_ctx.ac_ip_fname, "\0");
+ s_app_ctx.dump_q_wr_idx = 0;
+ s_app_ctx.dump_q_rd_idx = 0;
+ s_app_ctx.display_thread_created = 0;
+ s_app_ctx.disp_q_wr_idx = 0;
+ s_app_ctx.disp_q_rd_idx = 0;
+ s_app_ctx.disp_delay = 0;
+ s_app_ctx.loopback = 0;
+ s_app_ctx.display = 0;
+ s_app_ctx.full_screen = 0;
+ s_app_ctx.u4_piclen_flag = 0;
+ s_app_ctx.fps = DEFAULT_FPS;
+ file_pos = 0;
+ total_bytes_comsumed = 0;
+ u4_ip_frm_ts = 0;
+ u4_op_frm_ts = 0;
+#ifdef PROFILE_ENABLE
+ memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE);
+#endif
+ s_app_ctx.u4_share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF;
+ s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES;
+ s_app_ctx.i4_degrade_type = 0;
+ s_app_ctx.i4_degrade_pics = 0;
+ s_app_ctx.e_arch = ARCH_ARM_A9Q;
+ s_app_ctx.e_soc = SOC_GENERIC;
+ s_app_ctx.i4_target_layer_id = 0;
+
+ s_app_ctx.u4_strd = STRIDE;
+
+ s_app_ctx.display_thread_handle = malloc(ithread_get_handle_size());
+ s_app_ctx.quit = 0;
+ s_app_ctx.paused = 0;
+ // s_app_ctx.u4_output_present = 0;
+ s_app_ctx.u4_chksum_save_flag = 0;
+ s_app_ctx.u4_frame_info_enable = 0;
+
+ s_app_ctx.get_stride = &default_get_stride;
+
+ s_app_ctx.get_color_fmt = &default_get_color_fmt;
+
+ /* Set function pointers for display */
+#ifdef SDL_DISPLAY
+ s_app_ctx.disp_init = &sdl_disp_init;
+ s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &sdl_display;
+ s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers;
+ s_app_ctx.disp_deinit = &sdl_disp_deinit;
+ s_app_ctx.disp_usleep = &sdl_disp_usleep;
+ s_app_ctx.get_color_fmt = &sdl_get_color_fmt;
+ s_app_ctx.get_stride = &sdl_get_stride;
+#endif
+
+#ifdef FBDEV_DISPLAY
+ s_app_ctx.disp_init = &fbd_disp_init;
+ s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &fbd_display;
+ s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers;
+ s_app_ctx.disp_deinit = &fbd_disp_deinit;
+ s_app_ctx.disp_usleep = &fbd_disp_usleep;
+ s_app_ctx.get_color_fmt = &fbd_get_color_fmt;
+ s_app_ctx.get_stride = &fbd_get_stride;
+#endif
+
+#ifdef INTEL_CE5300
+ s_app_ctx.disp_init = &gdl_disp_init;
+ s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &gdl_display;
+ s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers;
+ s_app_ctx.disp_deinit = &gdl_disp_deinit;
+ s_app_ctx.disp_usleep = &gdl_disp_usleep;
+ s_app_ctx.get_color_fmt = &gdl_get_color_fmt;
+ s_app_ctx.get_stride = &gdl_get_stride;
+#endif
+
+#ifdef IOS_DISPLAY
+ s_app_ctx.disp_init = &ios_disp_init;
+ s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &ios_display;
+ s_app_ctx.set_disp_buffers = &ios_set_disp_buffers;
+ s_app_ctx.disp_deinit = &ios_disp_deinit;
+ s_app_ctx.disp_usleep = &ios_disp_usleep;
+ s_app_ctx.get_color_fmt = &ios_get_color_fmt;
+ s_app_ctx.get_stride = &ios_get_stride;
+#endif
+
+ s_app_ctx.display_deinit_flag = 0;
+ s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV;
+ /*************************************************************************/
+ /* Parse arguments */
+ /*************************************************************************/
+
+#ifndef IOS
+ /* Read command line arguments */
+ if(argc > 2)
+ {
+ for(i = 1; i < (UWORD32) argc; i += 2)
+ {
+ if(CONFIG == get_argument(argv[i]))
+ {
+ strcpy(ac_cfg_fname, argv[i + 1]);
+ if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open Configuration file %s", ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+ }
+ else
+ {
+ parse_argument(&s_app_ctx, argv[i], argv[i + 1]);
+ }
+ }
+ }
+ else
+ {
+ if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+ }
+#else
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, ac_cfg_fname);
+ if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+
+#endif
+#ifdef PRINT_PICSIZE
+ /* If the binary is used for only getting number of bytes in each picture,
+ * then disable the following features */
+ s_app_ctx.u4_piclen_flag = 0;
+ s_app_ctx.u4_file_save_flag = 0;
+ s_app_ctx.u4_chksum_save_flag = 0;
+ s_app_ctx.i4_degrade_pics = 0;
+ s_app_ctx.i4_degrade_type = 0;
+ s_app_ctx.loopback = 0;
+ s_app_ctx.u4_share_disp_buf = 0;
+ s_app_ctx.display = 0;
+#endif
+
+ /* If display is enabled, then turn off shared mode and get color format that
+ * is supported by display */
+ if(1 == s_app_ctx.display)
+ {
+ s_app_ctx.u4_share_disp_buf = 0;
+ s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt();
+ }
+ if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0)
+ {
+ printf("\nNo input file given for decoding\n");
+ exit(-1);
+ }
+
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ pu1_qp_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1);
+ pu1_blk_type_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1);
+ }
+
+ /***********************************************************************/
+ /* create the file object for input file */
+ /***********************************************************************/
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir,
+ s_app_ctx.ac_ip_fname);
+ ps_ip_file = fopen(filename_with_path, "rb");
+#else
+ ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb");
+#endif
+ if(NULL == ps_ip_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open input file %s",
+ s_app_ctx.ac_ip_fname);
+ codec_exit(ac_error_str);
+ }
+ /***********************************************************************/
+ /* create the file object for input file */
+ /***********************************************************************/
+ if(1 == s_app_ctx.u4_piclen_flag)
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s",
+ s_app_ctx.ac_piclen_fname);
+ ps_piclen_file = fopen(filename_with_path, "rb");
+#else
+ ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb");
+#endif
+ if(NULL == ps_piclen_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open piclen file %s",
+ s_app_ctx.ac_piclen_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for output file */
+ /***********************************************************************/
+
+ /* If the filename does not contain %d, then output will be dumped to
+ a single file and it is opened here */
+ if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname, "%d") == NULL))
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_op_fname);
+ ps_op_file = fopen(filename_with_path, "wb");
+#else
+ ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb");
+#endif
+
+ if(NULL == ps_op_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open output file %s",
+ s_app_ctx.ac_op_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for mbinfo file */
+ /***********************************************************************/
+
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_qp_map_fname);
+ ps_qp_file = fopen(filename_with_path, "wb");
+
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_blk_type_map_fname);
+ ps_mb_type_file = fopen(filename_with_path, "wb");
+#else
+ ps_qp_file = fopen(s_app_ctx.ac_qp_map_fname, "wb");
+ ps_mb_type_file = fopen(s_app_ctx.ac_blk_type_map_fname, "wb");
+
+#endif
+
+ if(NULL == ps_qp_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_qp map file %s",
+ s_app_ctx.ac_qp_map_fname);
+ }
+ if(NULL == ps_mb_type_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_type map file %s",
+ s_app_ctx.ac_blk_type_map_fname);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for check sum file */
+ /***********************************************************************/
+ if(1 == s_app_ctx.u4_chksum_save_flag)
+ {
+#if IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_op_chksum_fname);
+ ps_op_chksum_file = fopen(filename_with_path, "wb");
+#else
+ ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb");
+#endif
+ if(NULL == ps_op_chksum_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open check sum file %s",
+ s_app_ctx.ac_op_chksum_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+ /***********************************************************************/
+ /* Create decoder instance */
+ /***********************************************************************/
+ {
+ ps_out_buf = (ivd_out_bufdesc_t *) malloc(sizeof(ivd_out_bufdesc_t));
+
+ /*****************************************************************************/
+ /* API Call: Initialize the Decoder */
+ /*****************************************************************************/
+ {
+ isvcd_create_ip_t s_create_ip = {};
+ isvcd_create_op_t s_create_op = {};
+ void *fxns = &ivd_api_function;
+
+ s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = s_app_ctx.u4_share_disp_buf;
+ s_create_ip.s_ivd_create_ip_t.e_output_format =
+ (IV_COLOR_FORMAT_T) s_app_ctx.e_output_chroma_format;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ih264a_aligned_malloc;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ih264a_aligned_free;
+ s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
+ s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(isvcd_create_ip_t);
+ s_create_op.s_ivd_create_op_t.u4_size = sizeof(isvcd_create_op_t);
+ s_create_ip.u4_enable_frame_info = s_app_ctx.u4_frame_info_enable;
+
+ ret = ivd_api_function(NULL, (void *) &s_create_ip, (void *) &s_create_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "Error in Create %8x\n",
+ s_create_op.s_ivd_create_op_t.u4_error_code);
+ codec_exit(ac_error_str);
+ }
+ codec_obj = (iv_obj_t *) s_create_op.s_ivd_create_op_t.pv_handle;
+ codec_obj->pv_fxns = fxns;
+ codec_obj->u4_size = sizeof(iv_obj_t);
+ s_app_ctx.cocodec_obj = codec_obj;
+
+ /*****************************************************************************/
+ /* set stride */
+ /*****************************************************************************/
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting the stride");
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* set target layer */
+ /*************************************************************************/
+ {
+ isvcd_set_target_layer_ip_t s_ctl_set_target_layer_ip;
+ isvcd_set_target_layer_op_t s_ctl_set_target_layer_op;
+
+ s_ctl_set_target_layer_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_target_layer_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) ISVCD_CMD_CTL_SET_TGT_LAYER;
+ s_ctl_set_target_layer_ip.u1_tgt_priority_id = 63;
+ s_ctl_set_target_layer_ip.u1_tgt_temp_id = 7;
+ s_ctl_set_target_layer_ip.u1_tgt_quality_id = 0;
+ s_ctl_set_target_layer_ip.u1_tgt_dep_id = s_app_ctx.i4_target_layer_id;
+ s_ctl_set_target_layer_ip.u4_size = sizeof(isvcd_set_target_layer_ip_t);
+ s_ctl_set_target_layer_op.u4_size = sizeof(isvcd_set_target_layer_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_target_layer_ip,
+ (void *) &s_ctl_set_target_layer_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting target layer id");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* set processsor */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+ isvcd_ctl_set_processor_op_t s_ctl_set_num_processor_op;
+
+ s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_num_processor_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR;
+ s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
+ s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
+ s_ctl_set_num_processor_ip.u4_size = sizeof(isvcd_ctl_set_processor_ip_t);
+ s_ctl_set_num_processor_op.u4_size = sizeof(isvcd_ctl_set_processor_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_num_processor_ip,
+ (void *) &s_ctl_set_num_processor_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting Processor type");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, ps_op_file,
+ ps_qp_file, ps_mb_type_file, pu1_qp_map_buf, pu1_blk_type_map_buf,
+ ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining);
+
+ /*****************************************************************************/
+ /* Decode header to get width and height and buffer sizes */
+ /*****************************************************************************/
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip = {};
+ isvcd_video_decode_op_t s_h264d_decode_op = {};
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting the codec in header decode mode");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /* Allocate input buffer for header */
+ u4_ip_buf_len = 256 * 1024;
+ pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+ if(pu1_bs_buf == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for input buffer of i4_size %d",
+ u4_ip_buf_len);
+ codec_exit(ac_error_str);
+ }
+
+ do
+ {
+ WORD32 numbytes;
+
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining = (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+
+ if((1 == s_app_ctx.u4_piclen_flag) && (u4_bytes_remaining > 0))
+ {
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x01;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x09;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x10;
+ numbytes++;
+
+ u4_bytes_remaining += 6;
+ }
+
+ if(0 == u4_bytes_remaining)
+ {
+ sprintf(ac_error_str, "\nUnable to read from input file");
+ codec_exit(ac_error_str);
+ }
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /*****************************************************************************/
+ /* API Call: Header Decode */
+ /*****************************************************************************/
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in header decode 0x%x\n", ps_video_decode_op->u4_error_code);
+ // codec_exit(ac_error_str);
+ }
+
+ u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed;
+#ifndef PROFILE_ENABLE
+ printf("%d\n", ps_video_decode_op->u4_num_bytes_consumed);
+#endif
+ file_pos += u4_num_bytes_dec;
+ total_bytes_comsumed += u4_num_bytes_dec;
+ } while(ret != IV_SUCCESS);
+
+ /* copy pic_wd and pic_ht to initialize buffers */
+ s_app_ctx.u4_pic_wd = ps_video_decode_op->u4_pic_wd;
+ s_app_ctx.u4_pic_ht = ps_video_decode_op->u4_pic_ht;
+
+ free(pu1_bs_buf);
+
+#if IOS_DISPLAY
+ s_app_ctx.i4_screen_wd = screen_wd;
+ s_app_ctx.i4_screen_ht = screen_ht;
+#endif
+ {
+ ivd_ctl_getbufinfo_ip_t s_ctl_ip;
+ ivd_ctl_getbufinfo_op_t s_ctl_op;
+ WORD32 outlen = 0;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
+ codec_exit(ac_error_str);
+ }
+
+ /* Allocate bitstream buffer */
+ u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0];
+#ifdef ADAPTIVE_TEST
+ u4_ip_buf_len = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 3 >> 1;
+#endif
+ pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+ if(pu1_bs_buf == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for input buffer of i4_size %d",
+ u4_ip_buf_len);
+ codec_exit(ac_error_str);
+ }
+
+ s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
+ /* Allocate output buffer only if display buffers are not shared */
+ /* Or if shared and output is 420P */
+ if((0 == s_app_ctx.u4_share_disp_buf) ||
+ (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
+ {
+#ifdef ADAPTIVE_TEST
+ switch(s_app_ctx.e_output_chroma_format)
+ {
+ case IV_YUV_420P:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT;
+ s_ctl_op.u4_min_out_buf_size[1] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 2;
+ s_ctl_op.u4_min_out_buf_size[2] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 2;
+ break;
+ }
+ case IV_YUV_420SP_UV:
+ case IV_YUV_420SP_VU:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT;
+ s_ctl_op.u4_min_out_buf_size[1] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 1;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_YUV_422ILE:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_RGBA_8888:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 4;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_RGB_565:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ default:
+ break;
+ }
+#endif
+ ps_out_buf->u4_min_out_buf_size[0] = s_ctl_op.u4_min_out_buf_size[0];
+ ps_out_buf->u4_min_out_buf_size[1] = s_ctl_op.u4_min_out_buf_size[1];
+ ps_out_buf->u4_min_out_buf_size[2] = s_ctl_op.u4_min_out_buf_size[2];
+
+ outlen = s_ctl_op.u4_min_out_buf_size[0];
+ if(s_ctl_op.u4_min_num_out_bufs > 1) outlen += s_ctl_op.u4_min_out_buf_size[1];
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2) outlen += s_ctl_op.u4_min_out_buf_size[2];
+
+ ps_out_buf->pu1_bufs[0] = (UWORD8 *) malloc(outlen);
+ if(ps_out_buf->pu1_bufs[0] == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for output buffer of i4_size %d",
+ outlen);
+ codec_exit(ac_error_str);
+ }
+
+ if(s_ctl_op.u4_min_num_out_bufs > 1)
+ ps_out_buf->pu1_bufs[1] =
+ ps_out_buf->pu1_bufs[0] + (s_ctl_op.u4_min_out_buf_size[0]);
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2)
+ ps_out_buf->pu1_bufs[2] =
+ ps_out_buf->pu1_bufs[1] + (s_ctl_op.u4_min_out_buf_size[1]);
+
+ ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
+ }
+
+#ifdef APP_EXTRA_BUFS
+ s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
+ s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
+#endif
+
+ /*****************************************************************************/
+ /* API Call: Allocate display buffers for display buffer shared case */
+ /*****************************************************************************/
+
+ for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
+ {
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
+ s_ctl_op.u4_min_out_buf_size[0];
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
+ s_ctl_op.u4_min_out_buf_size[1];
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
+ s_ctl_op.u4_min_out_buf_size[2];
+
+ outlen = s_ctl_op.u4_min_out_buf_size[0];
+ if(s_ctl_op.u4_min_num_out_bufs > 1) outlen += s_ctl_op.u4_min_out_buf_size[1];
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2) outlen += s_ctl_op.u4_min_out_buf_size[2];
+
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *) malloc(outlen);
+
+ if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for output buffer of i4_size %d",
+ outlen);
+ codec_exit(ac_error_str);
+ }
+
+ if(s_ctl_op.u4_min_num_out_bufs > 1)
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[0] + (s_ctl_op.u4_min_out_buf_size[0]);
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2)
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[1] + (s_ctl_op.u4_min_out_buf_size[1]);
+
+ s_app_ctx.s_disp_buffers[i].u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
+ }
+ s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
+ }
+
+ /* Create display thread and wait for the display buffers to be initialized*/
+ if(1 == s_app_ctx.display)
+ {
+ if(0 == s_app_ctx.display_thread_created)
+ {
+ s_app_ctx.display_init_done = 0;
+ ithread_create(s_app_ctx.display_thread_handle, NULL, (void *) &display_thread,
+ (void *) &s_app_ctx);
+ s_app_ctx.display_thread_created = 1;
+
+ while(1)
+ {
+ if(s_app_ctx.display_init_done) break;
+
+ ithread_msleep(1);
+ }
+ }
+
+ s_app_ctx.u4_strd = s_app_ctx.get_stride();
+ }
+ }
+
+ /*************************************************************************/
+ /* Get actual number of output buffers requried, which is dependent */
+ /* on ps_bitstrm properties such as width, height and level etc */
+ /* This is needed mainly for shared display mode */
+ /*************************************************************************/
+
+ /*****************************************************************************/
+ /* API Call: Send the allocated display buffers to codec */
+ /*****************************************************************************/
+ {
+ ivd_set_display_frame_ip_t s_set_display_frame_ip;
+ ivd_set_display_frame_op_t s_set_display_frame_op;
+
+ s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME;
+ s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t);
+ s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t);
+
+ s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf;
+
+ memcpy(&(s_set_display_frame_ip.s_disp_buffer), &(s_app_ctx.s_disp_buffers),
+ s_app_ctx.num_disp_buf * sizeof(ivd_out_bufdesc_t));
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_set_display_frame_ip,
+ (void *) &s_set_display_frame_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Set display frame");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get frame dimensions for display buffers such as x_offset,y_offset */
+ /* etc. This information might be needed to set display buffer */
+ /* offsets in case of shared display buffer mode */
+ /*************************************************************************/
+ {
+ isvcd_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip;
+ isvcd_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op;
+
+ s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_frame_dimensions_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS;
+ s_ctl_get_frame_dimensions_ip.u4_size = sizeof(isvcd_ctl_get_frame_dimensions_ip_t);
+ s_ctl_get_frame_dimensions_op.u4_size = sizeof(isvcd_ctl_get_frame_dimensions_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_frame_dimensions_ip,
+ (void *) &s_ctl_get_frame_dimensions_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Get buffer Dimensions");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get VUI parameters */
+ /*************************************************************************/
+ {
+ isvcd_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
+ isvcd_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
+
+ s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_vui_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_VUI_PARAMS;
+ s_ctl_get_vui_params_ip.u4_size = sizeof(isvcd_ctl_get_vui_params_ip_t);
+ s_ctl_get_vui_params_op.u4_size = sizeof(isvcd_ctl_get_vui_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_vui_params_ip,
+ (void *) &s_ctl_get_vui_params_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Get VUI params");
+ // codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Set the decoder in frame decode mode. It was set in header decode */
+ /* mode earlier */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Set Parameters");
+ // codec_exit(ac_error_str);
+ }
+ }
+ /*************************************************************************/
+ /* If required disable deblocking and sao at given level */
+ /*************************************************************************/
+
+ set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics);
+#ifdef WINDOWS_TIMER
+ QueryPerformanceFrequency(&frequency);
+#endif
+#ifndef PRINT_PICSIZE
+ get_version(codec_obj);
+#endif
+
+ max_op_frm_ts = s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay;
+
+ if(max_op_frm_ts < s_app_ctx.disp_delay)
+ max_op_frm_ts = 0xffffffff; /* clip as overflow has occured*/
+
+ max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0) ? (max_op_frm_ts) : 0xffffffff;
+
+ u4_num_disp_bufs_with_dec = 0;
+
+ while(u4_op_frm_ts < max_op_frm_ts)
+ {
+#ifdef TEST_FLUSH
+ if(u4_ip_frm_ts == FLUSH_FRM_CNT)
+ {
+ ivd_ctl_flush_ip_t s_ctl_ip;
+ ivd_ctl_flush_op_t s_ctl_op;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in Setting the decoder in flush mode\n");
+ }
+ // file_pos = 0;
+
+ // fseek(ps_ip_file, file_pos, SEEK_SET);
+ }
+#endif
+ if(u4_num_disp_bufs_with_dec < s_app_ctx.num_disp_buf)
+ {
+ release_disp_frame(codec_obj, u4_num_disp_bufs_with_dec);
+ u4_num_disp_bufs_with_dec++;
+ }
+
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+#ifdef DYNAMIC_NUMCORES
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd = IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = 1 + 3 * (u4_ip_frm_ts % 2);
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+#endif
+ /***********************************************************************/
+ /* Seek the file to start of current frame, this is equavelent of */
+ /* having a parcer which tells the start of current frame */
+ /***********************************************************************/
+ {
+ WORD32 numbytes;
+
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining = (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+
+ // AUD_PIC_BOUNDARY
+ if((1 == s_app_ctx.u4_piclen_flag) && (u4_bytes_remaining > 0))
+ {
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x01;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x09;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x10;
+ numbytes++;
+
+ u4_bytes_remaining += 6;
+ }
+
+ if(u4_bytes_remaining == 0)
+ {
+ if(1 == s_app_ctx.loopback)
+ {
+ file_pos = 0;
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining =
+ (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+ }
+ else
+ break;
+ }
+ }
+
+ /*********************************************************************/
+ /* Following calls can be enabled at diffent times */
+ /*********************************************************************/
+#if ENABLE_DEGRADE
+ if(u4_op_frm_ts >= 10000) disable_deblocking(codec_obj, 4);
+
+ if(u4_op_frm_ts == 30000) enable_deblocking(codec_obj);
+
+ if(u4_op_frm_ts == 10000) enable_skippb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 60000) disable_skippb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 30000) enable_skipb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 60000) disable_skipb_frames(codec_obj);
+#endif
+
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip = {};
+ isvcd_video_decode_op_t s_h264d_decode_op = {};
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+#ifdef PROFILE_ENABLE
+ UWORD32 s_elapsed_time;
+ TIMER s_start_timer;
+ TIMER s_end_timer;
+#endif
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] =
+ ps_out_buf->u4_min_out_buf_size[0];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] =
+ ps_out_buf->u4_min_out_buf_size[1];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] =
+ ps_out_buf->u4_min_out_buf_size[2];
+
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2];
+ ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs;
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /* Get display buffer pointers */
+ if(1 == s_app_ctx.display)
+ {
+ WORD32 wr_idx;
+
+ wr_idx = dispq_producer_dequeue(&s_app_ctx);
+
+ if(s_app_ctx.quit) break;
+
+ s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx,
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[0],
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[1],
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[2]);
+ }
+
+ /*****************************************************************************/
+ /* API Call: Video Decode */
+ /*****************************************************************************/
+
+ GETTIME(&s_start_timer);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ GETTIME(&s_end_timer);
+ ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency);
+#ifdef PROFILE_ENABLE
+ {
+ UWORD32 peak_avg, id;
+ u4_tot_cycles += s_elapsed_time;
+ peak_window[peak_window_idx++] = s_elapsed_time;
+ if(peak_window_idx == PEAK_WINDOW_SIZE) peak_window_idx = 0;
+ peak_avg = 0;
+ for(id = 0; id < PEAK_WINDOW_SIZE; id++)
+ {
+ peak_avg += peak_window[id];
+ }
+ peak_avg /= PEAK_WINDOW_SIZE;
+ if(peak_avg > peak_avg_max) peak_avg_max = peak_avg;
+ frm_cnt++;
+
+ printf(
+ "FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d "
+ "PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n",
+ frm_cnt, s_elapsed_time, u4_tot_cycles / frm_cnt, peak_avg_max,
+ ps_video_decode_op->u4_output_present,
+ ps_video_decode_op->u4_num_bytes_consumed);
+ }
+#else
+ printf("%d\n", ps_video_decode_op->u4_num_bytes_consumed);
+#endif
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in video Frame decode : ret %x Error %x\n", ret,
+ ps_video_decode_op->u4_error_code);
+ }
+
+ if((IV_SUCCESS != ret) &&
+ ((ps_video_decode_op->u4_error_code & 0xFF) == IVD_RES_CHANGED))
+ {
+ ivd_ctl_reset_ip_t s_ctl_ip;
+ ivd_ctl_reset_op_t s_ctl_op;
+
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts,
+ ps_op_file, ps_qp_file, ps_mb_type_file, pu1_qp_map_buf,
+ pu1_blk_type_map_buf, ps_op_chksum_file, u4_ip_frm_ts,
+ u4_bytes_remaining);
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+ (void *) &s_ctl_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Reset");
+ codec_exit(ac_error_str);
+ }
+
+ /*when reset all buffers are released by lib*/
+ u4_num_disp_bufs_with_dec = 0;
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+ /*************************************************************************/
+ /* set processsor */
+ /*************************************************************************/
+
+ {
+ isvcd_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+ isvcd_ctl_set_processor_op_t s_ctl_set_num_processor_op;
+
+ s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_num_processor_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR;
+ s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
+ s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
+ s_ctl_set_num_processor_ip.u4_size = sizeof(isvcd_ctl_set_processor_ip_t);
+ s_ctl_set_num_processor_op.u4_size = sizeof(isvcd_ctl_set_processor_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_set_num_processor_ip,
+ (void *) &s_ctl_set_num_processor_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting Processor type");
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* Get SEI MDCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op;
+
+ memset(&s_ctl_get_sei_mdcv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t));
+ memset(&s_ctl_get_sei_mdcv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t));
+
+ s_ctl_get_sei_mdcv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_mdcv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS;
+ s_ctl_get_sei_mdcv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t);
+ s_ctl_get_sei_mdcv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_mdcv_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_mdcv_params_ip,
+ (void *) &s_ctl_get_sei_mdcv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("MDCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_mdcv_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CLL parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag)
+ {
+ isvcd_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip;
+ isvcd_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op;
+
+ memset(&s_ctl_get_sei_cll_params_ip, 0, sizeof(isvcd_ctl_get_sei_cll_params_ip_t));
+ memset(&s_ctl_get_sei_cll_params_op, 0, sizeof(isvcd_ctl_get_sei_cll_params_op_t));
+
+ s_ctl_get_sei_cll_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_cll_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CLL_PARAMS;
+ s_ctl_get_sei_cll_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_ip_t);
+ s_ctl_get_sei_cll_params_op.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_cll_params_ip,
+ (void *) &s_ctl_get_sei_cll_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CLL SEI params not present : Error %x\n",
+ s_ctl_get_sei_cll_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI AVE parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip;
+ isvcd_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op;
+
+ memset(&s_ctl_get_sei_ave_params_ip, 0, sizeof(isvcd_ctl_get_sei_ave_params_ip_t));
+ memset(&s_ctl_get_sei_ave_params_op, 0, sizeof(isvcd_ctl_get_sei_ave_params_op_t));
+
+ s_ctl_get_sei_ave_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ave_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_AVE_PARAMS;
+ s_ctl_get_sei_ave_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_ip_t);
+ s_ctl_get_sei_ave_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_ave_params_ip,
+ (void *) &s_ctl_get_sei_ave_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("AVE SEI params not present : Error %x\n",
+ s_ctl_get_sei_ave_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op;
+
+ memset(&s_ctl_get_sei_ccv_params_ip, 0, sizeof(isvcd_ctl_get_sei_ccv_params_ip_t));
+ memset(&s_ctl_get_sei_ccv_params_op, 0, sizeof(isvcd_ctl_get_sei_ccv_params_op_t));
+
+ s_ctl_get_sei_ccv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ccv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CCV_PARAMS;
+ s_ctl_get_sei_ccv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_ip_t);
+ s_ctl_get_sei_ccv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_ccv_params_ip,
+ (void *) &s_ctl_get_sei_ccv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_ccv_params_op.u4_error_code);
+ }
+ }
+
+ if((1 == s_app_ctx.display) && (1 == ps_video_decode_op->u4_output_present))
+ {
+ dispq_producer_queue(&s_app_ctx);
+ }
+
+ if(IV_B_FRAME == ps_video_decode_op->e_pic_type) s_app_ctx.b_pic_present |= 1;
+
+ u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed;
+
+ file_pos += u4_num_bytes_dec;
+ total_bytes_comsumed += u4_num_bytes_dec;
+ u4_ip_frm_ts++;
+
+ if(1 == ps_video_decode_op->u4_output_present)
+ {
+ CHAR cur_fname[1000];
+ CHAR *extn = NULL;
+ /* The objective is to dump the decoded frames into separate files instead
+ * of dumping all the frames in one common file. Also, the number of
+ * dumped frames at any given instance of time cannot exceed
+ * 'frame_memory'
+ */
+ if(s_app_ctx.u4_file_save_flag)
+ {
+ /* Locate the position of extension yuv */
+ extn = strstr(s_app_ctx.ac_op_fname, "%d");
+ if(extn != NULL)
+ {
+ output_write_stall(s_app_ctx.ac_op_fname, u4_op_frm_ts);
+ /* Generate output file names */
+ sprintf(cur_fname, s_app_ctx.ac_op_fname, u4_op_frm_ts);
+ /* Open Output file */
+ ps_op_file = fopen(cur_fname, "wb");
+ if(NULL == ps_op_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open output file %s", cur_fname);
+
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+#ifdef PROFILE_ENABLE
+ width = ps_video_decode_op->s_disp_frm_buf.u4_y_wd;
+ height = ps_video_decode_op->s_disp_frm_buf.u4_y_ht;
+#endif
+ dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op,
+ ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_qp_file,
+ ps_mb_type_file, ps_op_chksum_file, u4_op_frm_ts,
+ s_app_ctx.u4_file_save_flag, s_app_ctx.u4_chksum_save_flag,
+ s_app_ctx.u4_frame_info_enable);
+
+ u4_op_frm_ts++;
+ if(extn != NULL) fclose(ps_op_file);
+ }
+ else
+ {
+ if((ps_video_decode_op->u4_error_code >> IVD_FATALERROR) & 1)
+ {
+ printf("Fatal error\n");
+ break;
+ }
+ }
+ }
+ }
+
+ /***********************************************************************/
+ /* To get the last decoded frames, call process with NULL input */
+ /***********************************************************************/
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, ps_op_file,
+ ps_qp_file, ps_mb_type_file, pu1_qp_map_buf, pu1_blk_type_map_buf,
+ ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining);
+
+ /* set disp_end u4_flag */
+ s_app_ctx.quit = 1;
+
+#ifdef PROFILE_ENABLE
+ printf("Summary\n");
+ printf("Input filename : %s\n", s_app_ctx.ac_ip_fname);
+ printf("Output Width : %-4d\n", width);
+ printf("Output Height : %-4d\n", height);
+
+ if(frm_cnt)
+ {
+ double avg = u4_tot_cycles / frm_cnt;
+ double bytes_avg = total_bytes_comsumed / frm_cnt;
+ double bitrate = (bytes_avg * 8 * s_app_ctx.fps) / 1000000;
+ printf("Bitrate @ %2d fps(mbps) : %-6.2f\n", s_app_ctx.fps, bitrate);
+ printf("Average decode time(micro sec) : %-6d\n", (WORD32) avg);
+ printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE,
+ (WORD32) peak_avg_max);
+ avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / frm_cnt;
+
+ if(0 == s_app_ctx.u4_share_disp_buf)
+ printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg);
+ else
+ printf("FPS achieved : %-3.2f\n", 1000000 / avg);
+ }
+#endif
+ /***********************************************************************/
+ /* Clear the decoder, close all the files, free all the memory */
+ /***********************************************************************/
+ if(1 == s_app_ctx.display)
+ {
+ s_app_ctx.display_deinit_flag = 1;
+ /* wait for display to finish */
+ if(s_app_ctx.display_thread_created)
+ {
+ ithread_join(s_app_ctx.display_thread_handle, NULL);
+ }
+ free(s_app_ctx.display_thread_handle);
+ }
+
+ {
+ ivd_delete_ip_t s_delete_dec_ip;
+ ivd_delete_op_t s_delete_dec_op;
+
+ s_delete_dec_ip.e_cmd = IVD_CMD_DELETE;
+ s_delete_dec_ip.u4_size = sizeof(ivd_delete_ip_t);
+ s_delete_dec_op.u4_size = sizeof(ivd_delete_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_delete_dec_ip,
+ (void *) &s_delete_dec_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Codec delete");
+ codec_exit(ac_error_str);
+ }
+ }
+ /***********************************************************************/
+ /* Close all the files and free all the memory */
+ /***********************************************************************/
+ {
+ fclose(ps_ip_file);
+
+ if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname, "%d") == NULL))
+ {
+ fclose(ps_op_file);
+ }
+ if(1 == s_app_ctx.u4_chksum_save_flag)
+ {
+ fclose(ps_op_chksum_file);
+ }
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ if(NULL != ps_qp_file)
+ {
+ fclose(ps_qp_file);
+ }
+ if(NULL != ps_mb_type_file)
+ {
+ fclose(ps_mb_type_file);
+ }
+ }
+ }
+
+ if(0 == s_app_ctx.u4_share_disp_buf)
+ {
+ free(ps_out_buf->pu1_bufs[0]);
+ }
+
+ for(i = 0; i < s_app_ctx.num_disp_buf; i++)
+ {
+ free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]);
+ }
+
+ free(ps_out_buf);
+ free(pu1_bs_buf);
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ if(pu1_qp_map_buf)
+ {
+ free(pu1_qp_map_buf);
+ }
+ if(pu1_blk_type_map_buf)
+ {
+ free(pu1_blk_type_map_buf);
+ }
+ }
+
+ if(s_app_ctx.display_thread_handle) free(s_app_ctx.display_thread_handle);
+
+ return (0);
+}
diff --git a/test/svcdec/svcdec.cmake b/test/svcdec/svcdec.cmake
new file mode 100644
index 0000000..53e1457
--- /dev/null
+++ b/test/svcdec/svcdec.cmake
@@ -0,0 +1,4 @@
+list(APPEND SVC_DEC_APP_SRCS "${AVC_ROOT}/test/svcdec/main.c")
+
+libavc_add_executable(svcdec libsvcdec SOURCES ${SVC_DEC_APP_SRCS})
+target_compile_definitions(svcdec PRIVATE PROFILE_ENABLE MD5_DISABLE)
diff --git a/test/svcenc/app.h b/test/svcenc/app.h
new file mode 100644
index 0000000..682557c
--- /dev/null
+++ b/test/svcenc/app.h
@@ -0,0 +1,417 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/*****************************************************************************/
+/* */
+/* File Name : app.h */
+/* */
+/* Description : This file contains all the necessary structure and */
+/* enumeration definitions needed for the Application */
+/* */
+/* List of Functions : */
+/* */
+/* Issues / Problems : None */
+/* */
+/* Revision History : */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 26 08 2010 Ittiam Draft */
+/* */
+/*****************************************************************************/
+
+#ifndef _SVCE_APP_H_
+#define _SVCE_APP_H_
+
+#include <stdbool.h>
+#include <sys/time.h>
+
+#include "iv2.h"
+#include "ive2.h"
+
+/*****************************************************************************/
+/* Function Macros */
+/*****************************************************************************/
+#define MAX(a, b) ((a) > (b)) ? (a) : (b)
+#define MIN(a, b) ((a) < (b)) ? (a) : (b)
+
+#define ALIGN16(x) ((((x) + 15) >> 4) << 4)
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+#define DEFAULT_NUM_INPUT_BUFS 32
+#define DEFAULT_MAX_INPUT_BUFS 32
+
+#define DEFAULT_NUM_OUTPUT_BUFS 32
+#define DEFAULT_MAX_OUTPUT_BUFS 32
+
+#define DEFAULT_NUM_RECON_BUFS 32
+#define DEFAULT_MAX_RECON_BUFS DEFAULT_NUM_RECON_BUFS
+
+#define DEFAULT_NUM_NALU_INFO_BUFS 32
+#define DEFAULT_MAX_NALU_INFO_BUFS 32
+
+#define LEN_STATUS_BUFFER (10 * 1024)
+#define MAX_VBV_BUFF_SIZE (120 * 16384)
+#define MAX_NUM_IO_BUFS 3
+
+#define DEFAULT_MAX_REF_FRM 2
+#define DEFAULT_MAX_REORDER_FRM 0
+#define DEFAULT_QP_MIN 4
+#define DEFAULT_QP_MAX 51
+#define DEFAULT_MAX_BITRATE 240000000
+#define DEFAULT_NUM_BFRAMES 0
+#define DEFAULT_MAX_SRCH_RANGE_X 256
+#define DEFAULT_MAX_SRCH_RANGE_Y 256
+#define DEFAULT_MAX_FRAMERATE 120000
+#define DEFAULT_NUM_CORES 1
+#define DEFAULT_NUM_CORES_PRE_ENC 0
+#define DEFAULT_FPS 30
+#define DEFAULT_ENC_SPEED 100
+#define DEFAULT_MEM_REC_CNT 0
+#define DEFAULT_RECON_ENABLE 0
+#define DEFAULT_NALU_INFO_EXPORT_ENABLE 0
+#define DEFAULT_CHKSUM_ENABLE 0
+#define DEFAULT_START_FRM 0
+#define DEFAULT_NUM_FRMS 100
+#define DEFAULT_INP_COLOR_FMT IV_YUV_420P
+#define DEFAULT_RECON_COLOR_FMT IV_YUV_420P
+#define DEFAULT_LOOPBACK 0
+#define DEFAULT_SRC_FRAME_RATE 50
+#define DEFAULT_TGT_FRAME_RATE 50
+#define DEFAULT_MAX_WD 1920
+#define DEFAULT_MAX_HT 1920
+#define DEFAULT_MAX_LEVEL 51
+#define DEFAULT_STRIDE 0
+#define DEFAULT_WD 1920
+#define DEFAULT_HT 1080
+#define DEFAULT_PSNR_ENABLE 0
+#define DEFAULT_ME_SPEED 100
+#define DEFAULT_ENABLE_FAST_SAD 0
+#define DEFAULT_ENABLE_ALT_REF 0
+#define DEFAULT_RC 0
+#define DEFAULT_BITRATE 6000000
+#define DEFAULT_I_QP 25
+#define DEFAULT_I_QP_MAX DEFAULT_QP_MAX
+#define DEFAULT_I_QP_MIN 0
+#define DEFAULT_P_QP 28
+#define DEFAULT_P_QP_MAX DEFAULT_QP_MAX
+#define DEFAULT_P_QP_MIN 0
+#define DEFAULT_B_QP 28
+#define DEFAULT_B_QP_MAX DEFAULT_QP_MAX
+#define DEFAULT_B_QP_MIN 0
+#define DEFAULT_AIR 0
+#define DEFAULT_AIR_REFRESH_PERIOD 30
+#define DEFAULT_SRCH_RNG_X 64
+#define DEFAULT_SRCH_RNG_Y 48
+#define DEFAULT_I_INTERVAL 50
+#define DEFAULT_IDR_INTERVAL 100
+#define DEFAULT_B_FRAMES 0
+#define DEFAULT_DISABLE_DEBLK_LEVEL 4
+#define DEFAULT_HPEL 1
+#define DEFAULT_QPEL 1
+#define DEFAULT_I4 1
+#define DEFAULT_EPROFILE IV_PROFILE_BASE
+#define DEFAULT_SLICE_MODE 0
+#define DEFAULT_SLICE_PARAM 256
+#define DEFAULT_ENTROPY_CODING_MODE 1
+#define DEFAULT_NUM_TEMPORAL_LAYERS 1
+#define DEFAULT_NUM_SPATIAL_LAYERS 1
+#define DEFAULT_SPATIAL_RES_RATIO 2.0
+
+#define DEFAULT_MAX_DISPLAY_MASTERING_LUMINANCE 50000
+#define DEFAULT_MIN_DISPLAY_MASTERING_LUMINANCE 1
+
+#define STRLENGTH 500
+
+/* specifies the number of colour primary components of the mastering
+ display */
+#define NUM_SEI_MDCV_PRIMARIES 3
+
+/* specifies the number of colour primary components of the nominal
+ content colour volume */
+#define NUM_SEI_CCV_PRIMARIES 3
+
+/*****************************************************************************/
+/* profile Macros */
+/*****************************************************************************/
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS
+typedef LARGE_INTEGER TIMER;
+#else
+typedef struct timeval TIMER;
+#endif
+#else
+typedef int32_t TIMER;
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS
+#define GETTIME(timer) QueryPerformanceCounter(timer);
+#else
+#define GETTIME(timer) gettimeofday(timer, NULL);
+#endif
+
+#ifdef WINDOWS
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ { \
+ TIMER s_temp_time; \
+ s_temp_time.LowPart = s_end_timer.LowPart - s_start_timer.LowPart; \
+ s_elapsed_time = \
+ (UWORD32) (((DOUBLE) s_temp_time.LowPart / (DOUBLE) frequency.LowPart) * 1000000); \
+ }
+#else
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ s_elapsed_time = ((s_end_timer.tv_sec - s_start_timer.tv_sec) * 1000000) + \
+ (s_end_timer.tv_usec - s_start_timer.tv_usec);
+#endif
+#else
+#define GETTIME(timer)
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency)
+#endif
+
+/*****************************************************************************/
+/* Structure definitions */
+/*****************************************************************************/
+typedef struct
+{
+ UWORD8 *pu1_buf;
+ UWORD32 u4_buf_size;
+ UWORD32 u4_timestamp_low;
+ UWORD32 u4_timestamp_high;
+ UWORD32 u4_is_free;
+ void *pv_mb_info;
+ void *pv_pic_info;
+} input_buf_t;
+
+typedef struct
+{
+ UWORD8 *pu1_buf;
+ UWORD32 u4_buf_size;
+ UWORD32 u4_timestamp_low;
+ UWORD32 u4_timestamp_high;
+ UWORD32 u4_is_free;
+} output_buf_t;
+
+typedef struct
+{
+ UWORD8 *pu1_buf;
+ UWORD32 u4_buf_size;
+ UWORD32 u4_timestamp_low;
+ UWORD32 u4_timestamp_high;
+ UWORD32 u4_is_free;
+} recon_buf_t;
+
+typedef struct nalu_info_buf_t
+{
+ UWORD8 *pu1_buf;
+
+ UWORD32 u4_buf_size;
+
+ bool b_is_free;
+} nalu_info_buf_t;
+
+typedef struct
+{
+ iv_obj_t *ps_enc;
+ iv_mem_rec_t *ps_mem_rec;
+ UWORD32 u4_num_mem_rec;
+ UWORD32 u4_recon_enable;
+ UWORD32 u4_chksum_enable;
+ UWORD32 u4_nalu_info_export_enable;
+ UWORD32 u4_mb_info_type;
+ UWORD32 u4_pic_info_type;
+ UWORD32 u4_mb_info_size;
+ UWORD32 u4_pic_info_size;
+ UWORD32 u4_start_frm;
+ UWORD32 u4_max_num_frms;
+ UWORD32 u4_total_bytes;
+ UWORD32 u4_pics_cnt;
+ IV_COLOR_FORMAT_T e_inp_color_fmt;
+ IV_COLOR_FORMAT_T e_recon_color_fmt;
+ IV_ARCH_T e_arch;
+ IV_SOC_T e_soc;
+
+ WORD32 header_generated;
+ void *pv_codec_obj;
+
+ UWORD32 u4_num_cores;
+ UWORD32 u4_pre_enc_me;
+ UWORD32 u4_pre_enc_ipe;
+ CHAR ac_ip_fname[STRLENGTH];
+ CHAR ac_op_fname[STRLENGTH];
+ CHAR ac_recon_fname[STRLENGTH];
+ CHAR ac_nalu_info_csv_fname[STRLENGTH];
+ CHAR ac_chksum_fname[STRLENGTH];
+ CHAR ac_mb_info_fname[STRLENGTH];
+ CHAR ac_pic_info_fname[STRLENGTH];
+
+ FILE *fp_ip;
+ FILE *fp_op;
+ FILE *fp_recon;
+ FILE *fp_nalu_info;
+ FILE *fp_chksum;
+ FILE *fp_psnr_ip;
+ FILE *fp_mb_info;
+ FILE *fp_pic_info;
+ FILE *fp_dump_op;
+
+ UWORD32 u4_loopback;
+ UWORD32 u4_max_frame_rate;
+ UWORD32 u4_src_frame_rate;
+ UWORD32 u4_tgt_frame_rate;
+ UWORD32 u4_max_wd;
+ UWORD32 u4_max_ht;
+ UWORD32 u4_max_level;
+
+ UWORD32 u4_strd;
+
+ UWORD32 u4_wd;
+ UWORD32 u4_ht;
+
+ UWORD32 u4_enc_wd;
+ UWORD32 u4_enc_ht;
+
+ UWORD32 u4_psnr_enable;
+
+ UWORD32 u4_enc_speed;
+ UWORD32 u4_me_speed;
+ UWORD32 u4_enable_fast_sad;
+ UWORD32 u4_enable_alt_ref;
+ UWORD32 u4_rc;
+ UWORD32 *pu4_max_bitrate;
+ UWORD32 *pu4_bitrate;
+ UWORD32 *pu4_i_qp, *pu4_i_qp_max, *pu4_i_qp_min;
+ UWORD32 *pu4_p_qp, *pu4_p_qp_max, *pu4_p_qp_min;
+ UWORD32 *pu4_b_qp, *pu4_b_qp_max, *pu4_b_qp_min;
+ UWORD32 u4_air;
+ UWORD32 u4_air_refresh_period;
+ UWORD32 u4_srch_rng_x;
+ UWORD32 u4_srch_rng_y;
+ UWORD32 u4_i_interval;
+ UWORD32 u4_idr_interval;
+ UWORD32 u4_b_frames;
+ UWORD32 u4_num_bframes;
+ UWORD32 u4_disable_deblock_level;
+ UWORD32 u4_hpel;
+ UWORD32 u4_qpel;
+ UWORD32 u4_enable_intra_4x4;
+ IV_PROFILE_T e_profile;
+
+ UWORD32 u4_slice_mode;
+ UWORD32 u4_slice_param;
+ UWORD32 u4_entropy_coding_mode;
+
+ void *pv_input_thread_handle;
+ void *pv_output_thread_handle;
+ void *pv_recon_thread_handle;
+
+ isvce_ctl_getbufinfo_op_t s_get_buf_info_op;
+ input_buf_t as_input_buf[DEFAULT_MAX_INPUT_BUFS];
+ output_buf_t as_output_buf[DEFAULT_MAX_OUTPUT_BUFS];
+ recon_buf_t as_recon_buf[DEFAULT_MAX_RECON_BUFS];
+ nalu_info_buf_t as_nalu_info_bufs[DEFAULT_MAX_NALU_INFO_BUFS];
+
+ DOUBLE adbl_psnr[3];
+ UWORD32 u4_psnr_cnt;
+ UWORD8 *pu1_psnr_buf;
+ UWORD8 u4_psnr_buf_size;
+
+ UWORD32 *pu4_vbv_buffer_delay;
+
+ TIMER enc_start_time;
+ TIMER enc_last_time;
+ WORD32 avg_time;
+
+ UWORD32 u4_sei_mdcv_params_present_flag;
+ UWORD32 au4_display_primaries_x[NUM_SEI_MDCV_PRIMARIES];
+ UWORD32 au4_display_primaries_y[NUM_SEI_MDCV_PRIMARIES];
+ UWORD32 u4_white_point_x;
+ UWORD32 u4_white_point_y;
+ UWORD32 u4_max_display_mastering_luminance;
+ UWORD32 u4_min_display_mastering_luminance;
+
+ UWORD32 u4_sei_cll_params_present_flag;
+ UWORD32 u4_max_content_light_level;
+ UWORD32 u4_max_pic_average_light_level;
+
+ UWORD32 u4_sei_ave_params_present_flag;
+ UWORD32 u4_ambient_illuminance;
+ UWORD32 u4_ambient_light_x;
+ UWORD32 u4_ambient_light_y;
+
+ UWORD32 u4_sei_ccv_params_present_flag;
+ UWORD32 u4_ccv_cancel_flag;
+ UWORD32 u4_ccv_persistence_flag;
+ UWORD32 u4_ccv_primaries_present_flag;
+ UWORD32 u4_ccv_min_luminance_value_present_flag;
+ UWORD32 u4_ccv_max_luminance_value_present_flag;
+ UWORD32 u4_ccv_avg_luminance_value_present_flag;
+ UWORD32 u4_ccv_reserved_zero_2bits;
+ WORD32 ai4_ccv_primaries_x[NUM_SEI_CCV_PRIMARIES];
+ WORD32 ai4_ccv_primaries_y[NUM_SEI_CCV_PRIMARIES];
+ UWORD32 u4_ccv_min_luminance_value;
+ UWORD32 u4_ccv_max_luminance_value;
+ UWORD32 u4_ccv_avg_luminance_value;
+ UWORD32 u4_use_default_vui;
+
+ isvce_ctl_set_sei_mdcv_params_ip_t s_sei_mdcv_params;
+ isvce_ctl_set_sei_cll_params_ip_t s_sei_cll_params;
+ isvce_ctl_set_sei_ave_params_ip_t s_sei_ave_params;
+
+ UWORD8 u1_num_temporal_layers;
+ UWORD8 u1_num_spatial_layers;
+ DOUBLE d_spatial_res_ratio;
+
+} app_ctxt_t;
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+void codec_exit(CHAR *pc_err_message);
+void allocate_input(app_ctxt_t *ps_app_ctxt);
+void allocate_output(app_ctxt_t *ps_app_ctxt);
+void allocate_recon(app_ctxt_t *ps_app_ctxt);
+
+IV_STATUS_T read_input(FILE *fp, iv_raw_buf_t *ps_raw_buf);
+IV_STATUS_T write_recon(FILE *fp, iv_raw_buf_t *ps_raw_buf);
+IV_STATUS_T write_output(FILE *fp, UWORD8 *pu1_buf, WORD32 num_bytes);
+
+IV_STATUS_T read_mb_info(app_ctxt_t *ps_app_ctxt, void *pv_mb_info);
+IV_STATUS_T read_pic_info(app_ctxt_t *ps_app_ctxt, void *pv_pic_info);
+
+void *isvca_aligned_malloc(WORD32 alignment, WORD32 size);
+void isvca_aligned_free(void *pv_buf);
+
+void free_input(app_ctxt_t *ps_app_ctxt);
+void free_recon(app_ctxt_t *ps_app_ctxt);
+void free_output(app_ctxt_t *ps_app_ctxt);
+
+void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_raw_buf, UWORD8 *pu1_buf,
+ IV_COLOR_FORMAT_T e_color_fmt);
+
+#ifndef MD5_DISABLE
+void calc_md5_cksum(UWORD8 *pu1_inbuf, UWORD32 u4_stride, UWORD32 u4_width, UWORD32 u4_height,
+ UWORD8 *pu1_cksum_p);
+#else
+#define calc_md5_cksum(a, b, c, d, e)
+#endif
+
+#endif
diff --git a/test/svcenc/enc.cfg b/test/svcenc/enc.cfg
new file mode 100644
index 0000000..ba62199
--- /dev/null
+++ b/test/svcenc/enc.cfg
@@ -0,0 +1,47 @@
+--input input_qvga.yuv
+--output output.264
+--recon recon.yuv
+--chksum chksum.md5
+--chksum_enable 0
+--recon_enable 0
+--input_chroma_format YUV_420P
+--recon_chroma_format YUV_420P
+--qp_i 24
+--qp_p 27
+--qp_b 29
+--qp_i_min 4
+--qp_i_max 49
+--qp_p_min 4
+--qp_p_max 49
+--qp_b_min 4
+--qp_b_max 49
+--max_wd 1920
+--max_ht 1080
+--psnr 0
+--slice 0
+--slice_param 0
+--num_frames -1
+--search_range_x 16
+--search_range_y 16
+--width 320
+--height 240
+--src_framerate 30
+--tgt_framerate 30
+--num_cores 4
+--rc 2
+--bitrate 256000
+--vbv_delay 1000
+--disable_deblock_level 0
+--intra_4x4_enable 1
+--i_interval 1000
+--me_speed 100
+--hpel 1
+--fast_sad 0
+--speed NORMAL
+--max_level 41
+--idr_interval 1000
+--entropy 0
+--bframes 0
+--adaptive_intra_refresh 0
+--air_refresh_period 30
+
diff --git a/test/svcenc/input.c b/test/svcenc/input.c
new file mode 100644
index 0000000..47ed17a
--- /dev/null
+++ b/test/svcenc/input.c
@@ -0,0 +1,300 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+/* User include files */
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "app.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Function Definitions */
+/*****************************************************************************/
+
+IV_STATUS_T read_pic_info(app_ctxt_t *ps_app_ctxt, void *pv_pic_info)
+{
+ IV_STATUS_T ret = IV_SUCCESS;
+ WORD32 size, bytes;
+
+ switch(ps_app_ctxt->u4_pic_info_type)
+ {
+ case 1:
+ size = sizeof(isvce_pic_info1_t);
+ ps_app_ctxt->u4_pic_info_size = sizeof(isvce_pic_info1_t);
+ break;
+ case 2:
+ size = sizeof(isvce_pic_info2_t);
+ ps_app_ctxt->u4_pic_info_size = sizeof(isvce_pic_info2_t);
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ bytes = (WORD32) fread(pv_pic_info, 1, size, ps_app_ctxt->fp_pic_info);
+ if(bytes != size) ret = IV_FAIL;
+
+ return ret;
+}
+
+IV_STATUS_T read_mb_info(app_ctxt_t *ps_app_ctxt, void *pv_mb_info)
+{
+ IV_STATUS_T ret = IV_SUCCESS;
+ WORD32 num_mbs;
+ WORD32 size;
+ WORD32 bytes;
+
+ num_mbs = ALIGN16(ps_app_ctxt->u4_wd) * ALIGN16(ps_app_ctxt->u4_ht);
+ num_mbs /= 256;
+
+ switch(ps_app_ctxt->u4_mb_info_type)
+ {
+ case 1:
+ size = sizeof(isvce_mb_info1_t) * num_mbs;
+ ps_app_ctxt->u4_mb_info_size = sizeof(isvce_mb_info1_t);
+ break;
+ case 2:
+ size = sizeof(isvce_mb_info2_t) * num_mbs;
+ ps_app_ctxt->u4_mb_info_size = sizeof(isvce_mb_info2_t);
+ break;
+ case 3:
+ size = sizeof(isvce_mb_info3_t) * num_mbs;
+ ps_app_ctxt->u4_mb_info_size = sizeof(isvce_mb_info3_t);
+ break;
+ case 4:
+ size = sizeof(isvce_mb_info4_t) * num_mbs;
+ ps_app_ctxt->u4_mb_info_size = sizeof(isvce_mb_info4_t);
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ bytes = (WORD32) fread(pv_mb_info, 1, size, ps_app_ctxt->fp_mb_info);
+ if(bytes != size) ret = IV_FAIL;
+
+ return ret;
+}
+
+IV_STATUS_T read_input(FILE *fp, iv_raw_buf_t *ps_raw_buf)
+{
+ WORD32 bytes;
+ WORD32 wd, ht, strd;
+ UWORD8 *pu1_buf;
+ WORD32 i;
+ WORD32 comp;
+ WORD32 num_comp;
+
+ if(IV_YUV_422ILE == ps_raw_buf->e_color_fmt)
+ {
+ wd = ps_raw_buf->au4_wd[0];
+ ht = ps_raw_buf->au4_ht[0];
+ strd = ps_raw_buf->au4_strd[0];
+ pu1_buf = ps_raw_buf->apv_bufs[0];
+
+ for(i = 0; i < ht; i++)
+ {
+ bytes = (WORD32) fread(pu1_buf, sizeof(UWORD8), wd, fp);
+ if(bytes != wd)
+ {
+ return (IV_FAIL);
+ }
+ pu1_buf += strd;
+ }
+ }
+ else
+ {
+ num_comp = 2;
+
+ if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3;
+
+ for(comp = 0; comp < num_comp; comp++)
+ {
+ wd = ps_raw_buf->au4_wd[comp];
+ ht = ps_raw_buf->au4_ht[comp];
+ strd = ps_raw_buf->au4_strd[comp];
+ pu1_buf = ps_raw_buf->apv_bufs[comp];
+
+ for(i = 0; i < ht; i++)
+ {
+ bytes = (WORD32) fread(pu1_buf, sizeof(UWORD8), wd, fp);
+ if(bytes != wd)
+ {
+ return (IV_FAIL);
+ }
+ pu1_buf += strd;
+ }
+ }
+ }
+ return IV_SUCCESS;
+}
+
+IV_STATUS_T dump_input(FILE *fp, iv_raw_buf_t *ps_raw_buf)
+{
+ WORD32 bytes;
+ WORD32 wd, ht, strd;
+ UWORD8 *pu1_buf;
+ WORD32 i;
+ WORD32 comp;
+ WORD32 num_comp;
+
+ if(IV_YUV_422ILE == ps_raw_buf->e_color_fmt)
+ {
+ wd = ps_raw_buf->au4_wd[0];
+ ht = ps_raw_buf->au4_ht[0];
+ strd = ps_raw_buf->au4_strd[0];
+ pu1_buf = ps_raw_buf->apv_bufs[0];
+
+ for(i = 0; i < ht; i++)
+ {
+ bytes = (WORD32) fwrite(pu1_buf, sizeof(UWORD8), wd, fp);
+ if(bytes != wd)
+ {
+ return (IV_FAIL);
+ }
+ pu1_buf += strd;
+ }
+ }
+ else
+ {
+ num_comp = 2;
+
+ if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3;
+
+ for(comp = 0; comp < num_comp; comp++)
+ {
+ wd = ps_raw_buf->au4_wd[comp];
+ ht = ps_raw_buf->au4_ht[comp];
+ strd = ps_raw_buf->au4_strd[comp];
+ pu1_buf = ps_raw_buf->apv_bufs[comp];
+
+ for(i = 0; i < ht; i++)
+ {
+ bytes = (WORD32) fwrite(pu1_buf, sizeof(UWORD8), wd, fp);
+ if(bytes != wd)
+ {
+ return (IV_FAIL);
+ }
+ pu1_buf += strd;
+ }
+ }
+ }
+ return IV_SUCCESS;
+}
+
+void allocate_input(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 pic_size;
+ WORD32 luma_size;
+ WORD32 chroma_size;
+ WORD32 num_mbs;
+ WORD32 i;
+ UWORD8 *pu1_buf[3];
+
+ isvce_ctl_getbufinfo_op_t *ps_get_buf_info_op = &ps_app_ctxt->s_get_buf_info_op;
+
+ num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, ps_get_buf_info_op->s_ive_op.u4_min_inp_bufs);
+ num_bufs = MIN(DEFAULT_MAX_INPUT_BUFS, num_bufs);
+
+ /* Size of buffer */
+ luma_size = ps_app_ctxt->u4_wd * ps_app_ctxt->u4_ht;
+ chroma_size = luma_size >> 1;
+ pic_size = luma_size + chroma_size;
+
+ num_mbs = ALIGN16(ps_app_ctxt->u4_max_wd) * ALIGN16(ps_app_ctxt->u4_max_ht);
+ num_mbs /= 256;
+
+ /* Memset the input buffer array to set is_free to 0 */
+ memset(ps_app_ctxt->as_input_buf, 0, sizeof(input_buf_t) * DEFAULT_MAX_INPUT_BUFS);
+
+ for(i = 0; i < num_bufs; i++)
+ {
+ pu1_buf[0] = (UWORD8 *) isvca_aligned_malloc(16, pic_size);
+ if(NULL == pu1_buf[0])
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for input buffer of size %d\n", pic_size);
+ codec_exit(ac_error);
+ }
+ ps_app_ctxt->as_input_buf[i].pu1_buf = pu1_buf[0];
+
+ pu1_buf[0] = (UWORD8 *) isvca_aligned_malloc(16, num_mbs * sizeof(isvce_api_mb_info_t));
+ if(NULL == pu1_buf[0])
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for mb info buffer of size %d\n",
+ (WORD32) (num_mbs * sizeof(isvce_api_mb_info_t)));
+ codec_exit(ac_error);
+ }
+ ps_app_ctxt->as_input_buf[i].pv_mb_info = pu1_buf[0];
+ pu1_buf[0] = (UWORD8 *) isvca_aligned_malloc(16, sizeof(isvce_pic_info2_t));
+ if(NULL == pu1_buf[0])
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for pic info buffer of size %d\n",
+ (WORD32) sizeof(isvce_pic_info2_t));
+ codec_exit(ac_error);
+ }
+ ps_app_ctxt->as_input_buf[i].pv_pic_info = pu1_buf[0];
+ ps_app_ctxt->as_input_buf[i].u4_buf_size = pic_size;
+ ps_app_ctxt->as_input_buf[i].u4_is_free = 1;
+ }
+ return;
+}
+
+void free_input(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 i;
+
+ num_bufs = MAX(DEFAULT_NUM_INPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_inp_bufs);
+ num_bufs = MIN(DEFAULT_MAX_INPUT_BUFS, num_bufs);
+
+ for(i = 0; i < num_bufs; i++)
+ {
+ isvca_aligned_free(ps_app_ctxt->as_input_buf[i].pu1_buf);
+ isvca_aligned_free(ps_app_ctxt->as_input_buf[i].pv_mb_info);
+ isvca_aligned_free(ps_app_ctxt->as_input_buf[i].pv_pic_info);
+ }
+ return;
+}
diff --git a/test/svcenc/main.c b/test/svcenc/main.c
new file mode 100644
index 0000000..db53278
--- /dev/null
+++ b/test/svcenc/main.c
@@ -0,0 +1,3253 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "app.h"
+#include "psnr.h"
+
+#ifndef MD5_DISABLE
+void calc_md5_cksum(UWORD8 *pu1_inbuf, UWORD32 u4_stride, UWORD32 u4_width, UWORD32 u4_height,
+ UWORD8 *pu1_cksum_p);
+#else
+#define calc_md5_cksum(a, b, c, d, e)
+#endif
+
+/*****************************************************************************/
+/* Enums */
+/*****************************************************************************/
+typedef enum
+{
+ INVALID,
+ HELP,
+ INPUT_FILE,
+ OUTPUT_FILE,
+ RECON_FILE,
+ RECON_ENABLE,
+ NALU_INFO_EXPORT_ENABLE,
+ NALU_INFO_CSV,
+ CHKSUM_ENABLE,
+ CHKSUM_FILE,
+ INPUT_CHROMA_FORMAT,
+ RECON_CHROMA_FORMAT,
+ MAX_WD,
+ MAX_HT,
+ WD,
+ HT,
+ MAX_LEVEL,
+ ENC_SPEED,
+ ME_SPEED,
+ START_FRM,
+ NUM_FRMS,
+ MAX_FRAMERATE,
+ SRC_FRAMERATE,
+ TGT_FRAMERATE,
+ RC,
+ MAX_BITRATE,
+ BITRATE,
+ I_QP,
+ P_QP,
+ B_QP,
+ I_QP_MAX,
+ P_QP_MAX,
+ B_QP_MAX,
+ I_QP_MIN,
+ P_QP_MIN,
+ B_QP_MIN,
+ ENTROPY,
+ AIR,
+ AIR_REFRESH_PERIOD,
+ ARCH,
+ SOC,
+ NUMCORES,
+ PRE_ENC_ME,
+ PRE_ENC_IPE,
+ HPEL,
+ QPEL,
+ SRCH_RNG_X,
+ SRCH_RNG_Y,
+ I_INTERVAL,
+ IDR_INTERVAL,
+ B_FRMS,
+ NUM_B_FRMS,
+ DISABLE_DBLK,
+ PROFILE,
+ FAST_SAD,
+ ALT_REF,
+ DISABLE_DEBLOCK_LEVEL,
+ PSNR,
+ SLICE_MODE,
+ SLICE_PARAM,
+ CONFIG,
+ LOOPBACK,
+ VBV_DELAY,
+ INTRA_4x4_ENABLE,
+ MB_INFO_FILE,
+ MB_INFO_TYPE,
+ PIC_INFO_FILE,
+ PIC_INFO_TYPE,
+ DISABLE_VUI,
+ NUM_TEMPORAL_LAYERS,
+ NUM_SPATIAL_LAYERS,
+ SPATIAL_RES_RATIO,
+} ARGUMENT_T;
+
+typedef struct
+{
+ CHAR argument_shortname[8];
+ CHAR argument_name[128];
+ ARGUMENT_T argument;
+ CHAR description[512];
+} argument_t;
+
+static const argument_t argument_mapping[] = {
+ {"--", "--help", HELP, "Print this help\n"},
+ {"-i", "--input", INPUT_FILE, "Input file\n"},
+ {"-o", "--output", OUTPUT_FILE, "Output file\n"},
+ {"--", "--recon_enable", RECON_ENABLE, "Recon enable flag\n"},
+ {"--", "--nalu_info_export", NALU_INFO_EXPORT_ENABLE, "Enable NALU Info export\n"},
+ {"--", "--nalu_info_csv", NALU_INFO_CSV, "Path to NALU Info CSV File\n"},
+ {"-r", "--recon", RECON_FILE, "Recon file \n"},
+ {"--", "--input_chroma_format", INPUT_CHROMA_FORMAT,
+ "Input Chroma format Supported values YUV_420P, YUV_420SP_UV, "
+ "YUV_420SP_VU\n"},
+ {"--", "--recon_chroma_format", RECON_CHROMA_FORMAT,
+ "Recon Chroma format Supported values YUV_420P, YUV_420SP_UV, "
+ "YUV_420SP_VU\n"},
+ {"-w", "--width", WD, "Width of input file\n"},
+ {"-h", "--height", HT, "Height file\n"},
+ {"--", "--start_frame", START_FRM, "Starting frame number\n"},
+ {"-f", "--num_frames", NUM_FRMS, "Number of frames to be encoded\n"},
+ {"--", "--rc", RC,
+ "Rate control mode 0: Constant Qp, 1: Storage, 2: CBR non low delay, 3: "
+ "CBR low delay \n"},
+ {"--", "--max_framerate", MAX_FRAMERATE, "Maximum frame rate \n"},
+ {"--", "--tgt_framerate", TGT_FRAMERATE, "Target frame rate \n"},
+ {"--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n"},
+ {"--", "--i_interval", I_INTERVAL, "Intra frame interval \n"},
+ {"--", "--idr_interval", IDR_INTERVAL, "IDR frame interval \n"},
+ {"--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n"},
+ {"--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n"},
+ {"--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n"},
+ {"--", "--fast_sad", FAST_SAD, " Flag for faster sad execution\n"},
+ {"--", "--alt_ref", ALT_REF, "Flag to enable alternate refernce frames\n"},
+ {"--", "--hpel", HPEL, "Flag to enable/disable Quarter pel estimation \n"},
+ {"--", "--qpel", QPEL, "Flag to enable/disable Quarter pel estimation \n"},
+ {"--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL,
+ "Disable deblock level - 0 : Enables deblock completely, 1: enables for I "
+ "and 8th frame , 2: Enables for I only, 3 : disables completely\n"},
+ {"--", "--search_range_x", SRCH_RNG_X, "Search range for X \n"},
+ {"--", "--search_range_y", SRCH_RNG_Y, "Search range for Y \n"},
+ {"--", "--psnr", PSNR, "Enable PSNR computation (Disable while benchmarking performance) \n"},
+ {"--", "--pre_enc_me", PRE_ENC_ME, "Flag to enable/disable Pre Enc Motion Estimation\n"},
+ {"--", "--pre_enc_ipe", PRE_ENC_IPE,
+ "Flag to enable/disable Pre Enc Intra prediction Estimation\n"},
+ {"-n", "--num_cores", NUMCORES, "Number of cores to be used\n"},
+ {"--", "--adaptive_intra_refresh", AIR, "Adaptive Intra Refresh enable/disable\n"},
+ {"--", "--air_refresh_period", AIR_REFRESH_PERIOD, "adaptive intra refresh period\n"},
+ {"--", "--slice", SLICE_MODE,
+ "Slice mode- 0 :No slice, 1: Bytes per slice, 2: MB/CTB per slice \n"},
+ {"--", "--slice_param", SLICE_PARAM,
+ "Slice param value based on slice mode. Slice mode of 1 implies number of "
+ "bytes per slice, 2 implies number of MBs/CTBs, for 0 value is neglected "
+ "\n"},
+ {"--", "--max_wd", MAX_WD, "Maximum width (Default: 1920) \n"},
+ {"--", "--max_ht", MAX_HT, "Maximum height (Default: 1088)\n"},
+ {"--", "--max_level", MAX_LEVEL, "Maximum Level (Default: 50)\n"},
+ {"--", "--arch", ARCH,
+ "Set Architecture. Supported values ARCH_GENERIC, ARM_A9Q, ARM_A7, "
+ "ARM_A5, "
+ "ARM_NEONINTR, X86_SSSE3, X86_SSE42 \n"},
+ {"--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n"},
+ {"--", "--chksum", CHKSUM_FILE, "Save Check sum file for recon data\n"},
+ {"--", "--chksum_enable", CHKSUM_ENABLE, "Recon MD5 Checksum file\n"},
+ {"-c", "--config", CONFIG, "config file (Default: enc.cfg)\n"},
+ {"--", "--loopback", LOOPBACK, "Enable encoding in a loop\n"},
+ {"--", "--profile", PROFILE, "Profile mode: Supported values BASE, MAIN, HIGH\n"},
+ {"--", "--max_bitrate", MAX_BITRATE, "Max bitrate\n"},
+ {"--", "--bitrate", BITRATE, "Target bitrate\n"},
+ {"--", "--qp_i", I_QP, "QP for I frames\n"},
+ {"--", "--qp_p", P_QP, "QP for P frames\n"},
+ {"--", "--qp_b", B_QP, "QP for B frames\n"},
+ {"--", "--qp_i_max", I_QP_MAX, "Max QP for I frames\n"},
+ {"--", "--qp_p_max", P_QP_MAX, "Max QP for P frames\n"},
+ {"--", "--qp_b_max", B_QP_MAX, "Max QP for B frames\n"},
+ {"--", "--qp_i_min", I_QP_MIN, "Min QP for I frames\n"},
+ {"--", "--qp_p_min", P_QP_MIN, "Min QP for P frames\n"},
+ {"--", "--qp_b_min", B_QP_MIN, "Min QP for B frames\n"},
+ {"--", "--entropy", ENTROPY, "Entropy coding mode(0: CAVLC or 1: CABAC)\n"},
+ {"--", "--vbv_delay", VBV_DELAY, "VBV buffer delay\n"},
+ {"-i4", "--intra_4x4_enable", INTRA_4x4_ENABLE, "Intra 4x4 enable \n"},
+ {"--", "--mb_info_file", MB_INFO_FILE, "MB info file\n"},
+ {"--", "--mb_info_type", MB_INFO_TYPE, "MB info type\n"},
+ {"--", "--pic_info_file", PIC_INFO_FILE, "Pic info file\n"},
+ {"--", "--pic_info_type", PIC_INFO_TYPE, "Pic info type\n"},
+ {"--", "--num_temporal_layers", NUM_TEMPORAL_LAYERS, "SVC Parameter : Num temporal layers\n"},
+ {"--", "--num_spatial_layers", NUM_SPATIAL_LAYERS, "SVC Parameter : Num spatial layers\n"},
+ {"--", "--spatial_res_ratio", SPATIAL_RES_RATIO,
+ "SVC Parameter : Resolution ratio between successive spatial layers\n"},
+ {"--", "--disable_vui", DISABLE_VUI, "disable vui\n"},
+};
+
+void *isvca_aligned_malloc(WORD32 alignment, WORD32 size)
+{
+ void *buf = NULL;
+
+ if(0 != posix_memalign(&buf, alignment, size))
+ {
+ return NULL;
+ }
+ return buf;
+}
+
+void isvca_aligned_free(void *pv_buf) { free(pv_buf); }
+
+/*****************************************************************************/
+/* */
+/* Function Name : codec_exit */
+/* */
+/* Description : handles unrecoverable errors */
+/* Inputs : Error message */
+/* Globals : None */
+/* Processing : Prints error message to console and exits. */
+/* Outputs : Error message to the console */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 06 2006 Sankar Creation */
+/* */
+/*****************************************************************************/
+void codec_exit(CHAR *pc_err_message)
+{
+ printf("%s\n", pc_err_message);
+ exit(-1);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : codec_exit */
+/* */
+/* Description : handles unrecoverable errors */
+/* Inputs : Error message */
+/* Globals : None */
+/* Processing : Prints error message to console and exits. */
+/* Outputs : Error mesage to the console */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 06 2006 Sankar Creation */
+/* */
+/*****************************************************************************/
+IV_COLOR_FORMAT_T get_chroma_fmt(CHAR *value)
+{
+ IV_COLOR_FORMAT_T e_chroma_format;
+ if((strcmp(value, "YUV_420P")) == 0)
+ e_chroma_format = IV_YUV_420P;
+ else if((strcmp(value, "YUV_422ILE")) == 0)
+ e_chroma_format = IV_YUV_422ILE;
+ else if((strcmp(value, "RGB_565")) == 0)
+ e_chroma_format = IV_RGB_565;
+ else if((strcmp(value, "RGBA_8888")) == 0)
+ e_chroma_format = IV_RGBA_8888;
+ else if((strcmp(value, "YUV_420SP_UV")) == 0)
+ e_chroma_format = IV_YUV_420SP_UV;
+ else if((strcmp(value, "YUV_420SP_VU")) == 0)
+ e_chroma_format = IV_YUV_420SP_VU;
+ else
+ {
+ printf("\nInvalid colour format setting it to IV_YUV_420P\n");
+ e_chroma_format = IV_YUV_420P;
+ }
+ return e_chroma_format;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : codec_exit */
+/* */
+/* Description : handles unrecoverable errors */
+/* Inputs : Error message */
+/* Globals : None */
+/* Processing : Prints error message to console and exits. */
+/* Outputs : Error mesage to the console */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 07 06 2006 Sankar Creation */
+/* */
+/*****************************************************************************/
+IVE_SPEED_CONFIG get_speed_preset(CHAR *value)
+{
+ IVE_SPEED_CONFIG e_enc_speed_preset;
+ if((strcmp(value, "CONFIG")) == 0)
+ e_enc_speed_preset = IVE_CONFIG;
+ else if((strcmp(value, "SLOWEST")) == 0)
+ e_enc_speed_preset = IVE_SLOWEST;
+ else if((strcmp(value, "NORMAL")) == 0)
+ e_enc_speed_preset = IVE_NORMAL;
+ else if((strcmp(value, "FAST")) == 0)
+ e_enc_speed_preset = IVE_FAST;
+ else if((strcmp(value, "HIGH_SPEED")) == 0)
+ e_enc_speed_preset = IVE_HIGH_SPEED;
+ else if((strcmp(value, "FASTEST")) == 0)
+ e_enc_speed_preset = IVE_FASTEST;
+ else
+ {
+ printf("\nInvalid speed preset, setting it to IVE_FASTEST\n");
+ e_enc_speed_preset = IVE_FASTEST;
+ }
+ return e_enc_speed_preset;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : print_usage */
+/* */
+/* Description : Prints argument format */
+/* */
+/* */
+/* Inputs : */
+/* Globals : */
+/* Processing : Prints argument format */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+
+void print_usage(void)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ printf("\nUsage:\n");
+ while(i < num_entries)
+ {
+ printf("%-32s\t %s", argument_mapping[i].argument_name, argument_mapping[i].description);
+ i++;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+ARGUMENT_T get_argument(CHAR *name)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ while(i < num_entries)
+ {
+ if((0 == strcmp(argument_mapping[i].argument_name, name)) ||
+ ((0 == strcmp(argument_mapping[i].argument_shortname, name)) &&
+ (0 != strcmp(argument_mapping[i].argument_shortname, "--"))))
+ {
+ return argument_mapping[i].argument;
+ }
+ i++;
+ }
+ return INVALID;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+void parse_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value)
+{
+ ARGUMENT_T arg = get_argument(argument);
+
+ switch(arg)
+ {
+ case HELP:
+ print_usage();
+ exit(-1);
+ break;
+ case SLICE_MODE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_slice_mode);
+ break;
+ case SLICE_PARAM:
+ sscanf(value, "%d", &ps_app_ctxt->u4_slice_param);
+ break;
+ case INPUT_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_ip_fname);
+ break;
+
+ case OUTPUT_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_op_fname);
+ break;
+
+ case RECON_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_recon_fname);
+ break;
+
+ case RECON_ENABLE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_recon_enable);
+ break;
+
+ case NALU_INFO_EXPORT_ENABLE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_nalu_info_export_enable);
+ break;
+
+ case NALU_INFO_CSV:
+ sscanf(value, "%s", ps_app_ctxt->ac_nalu_info_csv_fname);
+ break;
+
+ case CHKSUM_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_chksum_fname);
+ break;
+
+ case CHKSUM_ENABLE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_chksum_enable);
+ break;
+
+ case MB_INFO_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_mb_info_fname);
+ break;
+
+ case MB_INFO_TYPE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_mb_info_type);
+ break;
+
+ case PIC_INFO_FILE:
+ sscanf(value, "%s", ps_app_ctxt->ac_pic_info_fname);
+ break;
+
+ case PIC_INFO_TYPE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_pic_info_type);
+ break;
+
+ case INPUT_CHROMA_FORMAT:
+ ps_app_ctxt->e_inp_color_fmt = get_chroma_fmt(value);
+ break;
+
+ case RECON_CHROMA_FORMAT:
+ ps_app_ctxt->e_recon_color_fmt = get_chroma_fmt(value);
+ break;
+
+ case MAX_WD:
+ sscanf(value, "%d", &ps_app_ctxt->u4_max_wd);
+ break;
+
+ case MAX_HT:
+ sscanf(value, "%d", &ps_app_ctxt->u4_max_ht);
+ break;
+
+ case WD:
+ sscanf(value, "%d", &ps_app_ctxt->u4_wd);
+ break;
+
+ case HT:
+ sscanf(value, "%d", &ps_app_ctxt->u4_ht);
+ break;
+
+ case MAX_LEVEL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_max_level);
+ break;
+
+ case ENC_SPEED:
+ ps_app_ctxt->u4_enc_speed = get_speed_preset(value);
+ break;
+
+ case ME_SPEED:
+ sscanf(value, "%d", &ps_app_ctxt->u4_me_speed);
+ break;
+
+ case START_FRM:
+ sscanf(value, "%d", &ps_app_ctxt->u4_start_frm);
+ break;
+
+ case NUM_FRMS:
+ sscanf(value, "%d", &ps_app_ctxt->u4_max_num_frms);
+ break;
+
+ case MAX_FRAMERATE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_max_frame_rate);
+ if(ps_app_ctxt->u4_max_frame_rate <= 0)
+ ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE;
+ break;
+
+ case SRC_FRAMERATE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_src_frame_rate);
+ if(ps_app_ctxt->u4_src_frame_rate <= 0)
+ ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
+ break;
+
+ case TGT_FRAMERATE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_tgt_frame_rate);
+ if(ps_app_ctxt->u4_tgt_frame_rate <= 0)
+ ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
+ break;
+
+ case RC:
+ sscanf(value, "%d", &ps_app_ctxt->u4_rc);
+ break;
+
+ case ENTROPY:
+ sscanf(value, "%d", &ps_app_ctxt->u4_entropy_coding_mode);
+ break;
+
+ case AIR:
+ sscanf(value, "%d", &ps_app_ctxt->u4_air);
+ break;
+
+ case ARCH:
+ if((strcmp(value, "ARCH_GENERIC")) == 0)
+ ps_app_ctxt->e_arch = ARCH_X86_GENERIC;
+ else if((strcmp(value, "ARM_A9Q")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_A9Q;
+ else if((strcmp(value, "ARM_A7")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_A7;
+ else if((strcmp(value, "ARM_A5")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_A5;
+ else if((strcmp(value, "ARM_NEONINTR")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_NEONINTR;
+ else if((strcmp(value, "X86_SSSE3")) == 0)
+ ps_app_ctxt->e_arch = ARCH_X86_SSSE3;
+ else if((strcmp(value, "X86_SSE42")) == 0)
+ ps_app_ctxt->e_arch = ARCH_X86_SSE42;
+ else if((strcmp(value, "ARM_A53")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_A53;
+ else if((strcmp(value, "ARM_A57")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_A57;
+ else if((strcmp(value, "ARM_V8_NEON")) == 0)
+ ps_app_ctxt->e_arch = ARCH_ARM_V8_NEON;
+ else
+ {
+ printf("\nInvalid Arch. Setting it to ARM_A9Q\n");
+ ps_app_ctxt->e_arch = ARCH_ARM_A9Q;
+ }
+
+ break;
+ case SOC:
+ if((strcmp(value, "GENERIC")) == 0)
+ ps_app_ctxt->e_soc = SOC_GENERIC;
+ else if((strcmp(value, "HISI_37X")) == 0)
+ ps_app_ctxt->e_soc = SOC_HISI_37X;
+ else
+ {
+ ps_app_ctxt->e_soc = SOC_GENERIC;
+ }
+ break;
+
+ case NUMCORES:
+ sscanf(value, "%d", &ps_app_ctxt->u4_num_cores);
+ break;
+
+ case LOOPBACK:
+ sscanf(value, "%d", &ps_app_ctxt->u4_loopback);
+ break;
+
+ case PRE_ENC_ME:
+ sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_me);
+ break;
+
+ case PRE_ENC_IPE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_ipe);
+ break;
+
+ case HPEL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_hpel);
+ break;
+
+ case QPEL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_qpel);
+ break;
+
+ case SRCH_RNG_X:
+ sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_x);
+ break;
+
+ case SRCH_RNG_Y:
+ sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_y);
+ break;
+
+ case I_INTERVAL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_i_interval);
+ break;
+
+ case IDR_INTERVAL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval);
+ break;
+
+ case NUM_B_FRMS:
+ sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes);
+ break;
+
+ case DISABLE_DEBLOCK_LEVEL:
+ sscanf(value, "%d", &ps_app_ctxt->u4_disable_deblock_level);
+ break;
+
+ case FAST_SAD:
+ sscanf(value, "%d", &ps_app_ctxt->u4_enable_fast_sad);
+ break;
+
+ case ALT_REF:
+ sscanf(value, "%d", &ps_app_ctxt->u4_enable_alt_ref);
+ break;
+
+ case AIR_REFRESH_PERIOD:
+ sscanf(value, "%d", &ps_app_ctxt->u4_air_refresh_period);
+ break;
+
+ case PROFILE:
+ if((strcmp(value, "BASE")) == 0)
+ ps_app_ctxt->e_profile = IV_PROFILE_BASE;
+ else if((strcmp(value, "MAIN")) == 0)
+ ps_app_ctxt->e_profile = IV_PROFILE_MAIN;
+ else if((strcmp(value, "HIGH")) == 0)
+ ps_app_ctxt->e_profile = IV_PROFILE_HIGH;
+ else
+ {
+ printf("\nInvalid profile. Setting it to BASE\n");
+ ps_app_ctxt->e_profile = IV_PROFILE_BASE;
+ }
+ break;
+
+ case PSNR:
+ sscanf(value, "%d", &ps_app_ctxt->u4_psnr_enable);
+ break;
+
+ case INTRA_4x4_ENABLE:
+ sscanf(value, "%d", &ps_app_ctxt->u4_enable_intra_4x4);
+ break;
+
+ case DISABLE_VUI:
+ sscanf(value, "%d", &ps_app_ctxt->u4_use_default_vui);
+ break;
+
+ case NUM_TEMPORAL_LAYERS:
+ {
+ sscanf(value, "%hhu", &ps_app_ctxt->u1_num_temporal_layers);
+ break;
+ }
+
+ case NUM_SPATIAL_LAYERS:
+ {
+ sscanf(value, "%hhu", &ps_app_ctxt->u1_num_spatial_layers);
+ break;
+ }
+
+ case SPATIAL_RES_RATIO:
+ {
+ sscanf(value, "%lf", &ps_app_ctxt->d_spatial_res_ratio);
+ break;
+ }
+
+ case MAX_BITRATE:
+ case BITRATE:
+ case I_QP:
+ case I_QP_MAX:
+ case I_QP_MIN:
+ case P_QP:
+ case P_QP_MAX:
+ case P_QP_MIN:
+ case B_QP:
+ case B_QP_MAX:
+ case B_QP_MIN:
+ case VBV_DELAY:
+ break;
+
+ case INVALID:
+ default:
+ printf("Ignoring argument : %s\n", argument);
+ break;
+ }
+}
+
+void parse_rc_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value)
+{
+#define ITERATE_TO_NEXT_ARG() \
+ while(*value != ',' && *value != '-' && *value != '\0') \
+ { \
+ value++; \
+ } \
+ if((*value == '-' || *value == '\0') && i + 1 < u1_num_spatial_layers) break; \
+ value++;
+
+ ARGUMENT_T arg;
+ int i = 0;
+ UWORD8 u1_num_spatial_layers = ps_app_ctxt->u1_num_spatial_layers;
+
+ arg = get_argument(argument);
+ switch(arg)
+ {
+ case MAX_BITRATE:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_max_bitrate[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case BITRATE:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_bitrate[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case I_QP:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_i_qp[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case I_QP_MAX:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_i_qp_max[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case I_QP_MIN:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_i_qp_min[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case P_QP:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_p_qp[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case P_QP_MAX:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_p_qp_max[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case P_QP_MIN:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_p_qp_min[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case B_QP:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_b_qp[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case B_QP_MAX:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_b_qp_max[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case B_QP_MIN:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_b_qp_min[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ case VBV_DELAY:
+ for(i = 0; i < u1_num_spatial_layers; i++)
+ {
+ sscanf(value, "%d", &ps_app_ctxt->pu4_vbv_buffer_delay[i]);
+ ITERATE_TO_NEXT_ARG();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : read_cfg_file */
+/* */
+/* Description : Reads arguments from a configuration file */
+/* */
+/* */
+/* Inputs : ps_app_ctxt : Application context */
+/* fp_cfg_file : Configuration file handle */
+/* Globals : */
+/* Processing : Parses the arguments and fills in the application context*/
+/* */
+/* Outputs : Arguments parsed */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+void read_cfg_file(app_ctxt_t *ps_app_ctxt, FILE *fp_cfg)
+{
+ CHAR line[STRLENGTH];
+ CHAR description[STRLENGTH];
+ CHAR value[STRLENGTH];
+ CHAR argument[STRLENGTH];
+
+ while(0 == (feof(fp_cfg)))
+ {
+ int ret;
+ line[0] = '\0';
+ if(NULL == fgets(line, sizeof(line), fp_cfg)) break;
+ argument[0] = '\0';
+ /* Reading Input File Name */
+ ret = sscanf(line, "%s %s %s", argument, value, description);
+ if(ret < 2) continue;
+
+ parse_argument(ps_app_ctxt, argument, value);
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : read_cfg_file_rc_params */
+/* */
+/* Description : Reads RC specific arguments from a configuration file */
+/* */
+/* */
+/* Inputs : ps_app_ctxt : Application context */
+/* fp_cfg_file : Configuration file handle */
+/* Globals : */
+/* Processing : Parses the arguments and fills in the application context*/
+/* */
+/* Outputs : Arguments parsed */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+void read_cfg_file_rc_params(app_ctxt_t *ps_app_ctxt, FILE *fp_cfg)
+{
+ CHAR line[STRLENGTH];
+ CHAR description[STRLENGTH];
+ CHAR value[STRLENGTH];
+ CHAR argument[STRLENGTH];
+
+ while(0 == (feof(fp_cfg)))
+ {
+ int ret;
+ line[0] = '\0';
+ if(NULL == fgets(line, sizeof(line), fp_cfg)) break;
+ argument[0] = '\0';
+ /* Reading Input File Name */
+ ret = sscanf(line, "%s %s %s", argument, value, description);
+ if(ret < 2) continue;
+
+ parse_rc_argument(ps_app_ctxt, argument, value);
+ }
+}
+
+void invalid_argument_exit(CHAR *pc_err_message)
+{
+ print_usage();
+ codec_exit(pc_err_message);
+}
+
+void validate_params(app_ctxt_t *ps_app_ctxt)
+{
+ CHAR ac_error[STRLENGTH];
+
+ if(ps_app_ctxt->ac_ip_fname[0] == '\0')
+ {
+ invalid_argument_exit("Specify input file");
+ }
+ if(ps_app_ctxt->ac_op_fname[0] == '\0')
+ {
+ invalid_argument_exit("Specify output file");
+ }
+ if((1 == ps_app_ctxt->u4_recon_enable) && (ps_app_ctxt->ac_recon_fname[0] == '\0'))
+ {
+ invalid_argument_exit("Specify recon file");
+ }
+ if((1 == ps_app_ctxt->u4_nalu_info_export_enable) &&
+ (ps_app_ctxt->ac_nalu_info_csv_fname[0] == '\0'))
+ {
+ invalid_argument_exit("Specify NALU Info CSV File");
+ }
+ if((1 == ps_app_ctxt->u4_chksum_enable) && (ps_app_ctxt->ac_chksum_fname[0] == '\0'))
+ {
+ invalid_argument_exit("Specify checksum file");
+ }
+ if(0 >= (WORD32) ps_app_ctxt->u4_wd)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Invalid width: %d", ps_app_ctxt->u4_wd);
+ invalid_argument_exit(ac_error);
+ }
+ if(0 >= (WORD32) ps_app_ctxt->u4_ht)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Invalid height: %d", ps_app_ctxt->u4_ht);
+ invalid_argument_exit(ac_error);
+ }
+
+ if(0 == (WORD32) ps_app_ctxt->u4_max_num_frms)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Invalid number of frames to be encoded: %d",
+ ps_app_ctxt->u4_max_num_frms);
+ invalid_argument_exit(ac_error);
+ }
+ if((0 != (WORD32) ps_app_ctxt->u4_entropy_coding_mode) &&
+ (1 != (WORD32) ps_app_ctxt->u4_entropy_coding_mode))
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Invalid entropy codeing mode: %d",
+ ps_app_ctxt->u4_entropy_coding_mode);
+ invalid_argument_exit(ac_error);
+ }
+}
+
+void init_default_params(app_ctxt_t *ps_app_ctxt)
+{
+ ps_app_ctxt->ps_enc = NULL;
+ ps_app_ctxt->ps_mem_rec = NULL;
+ ps_app_ctxt->u4_num_mem_rec = DEFAULT_MEM_REC_CNT;
+ ps_app_ctxt->u4_recon_enable = DEFAULT_RECON_ENABLE;
+ ps_app_ctxt->u4_nalu_info_export_enable = DEFAULT_NALU_INFO_EXPORT_ENABLE;
+ ps_app_ctxt->u4_chksum_enable = DEFAULT_CHKSUM_ENABLE;
+ ps_app_ctxt->u4_mb_info_type = 0;
+ ps_app_ctxt->u4_pic_info_type = 0;
+ ps_app_ctxt->u4_mb_info_size = 0;
+ ps_app_ctxt->u4_pic_info_size = 0;
+ ps_app_ctxt->u4_start_frm = DEFAULT_START_FRM;
+ ps_app_ctxt->u4_max_num_frms = DEFAULT_NUM_FRMS;
+ ps_app_ctxt->avg_time = 0;
+ ps_app_ctxt->u4_pics_cnt = 0;
+ ps_app_ctxt->e_inp_color_fmt = DEFAULT_INP_COLOR_FMT;
+ ps_app_ctxt->e_recon_color_fmt = DEFAULT_RECON_COLOR_FMT;
+ ps_app_ctxt->e_arch = ARCH_X86_SSE42;
+ ps_app_ctxt->e_soc = SOC_GENERIC;
+ ps_app_ctxt->header_generated = 0;
+ ps_app_ctxt->pv_codec_obj = NULL;
+ ps_app_ctxt->u4_num_cores = DEFAULT_NUM_CORES;
+ ps_app_ctxt->u4_pre_enc_me = 0;
+ ps_app_ctxt->u4_pre_enc_ipe = 0;
+ ps_app_ctxt->ac_ip_fname[0] = '\0';
+ ps_app_ctxt->ac_op_fname[0] = '\0';
+ ps_app_ctxt->ac_recon_fname[0] = '\0';
+ ps_app_ctxt->ac_nalu_info_csv_fname[0] = '\0';
+ ps_app_ctxt->ac_chksum_fname[0] = '\0';
+ ps_app_ctxt->ac_mb_info_fname[0] = '\0';
+ ps_app_ctxt->fp_ip = NULL;
+ ps_app_ctxt->fp_op = NULL;
+ ps_app_ctxt->fp_recon = NULL;
+ ps_app_ctxt->fp_nalu_info = NULL;
+ ps_app_ctxt->fp_chksum = NULL;
+ ps_app_ctxt->fp_psnr_ip = NULL;
+ ps_app_ctxt->fp_mb_info = NULL;
+ ps_app_ctxt->fp_pic_info = NULL;
+ ps_app_ctxt->u4_loopback = DEFAULT_LOOPBACK;
+ ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE;
+ ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
+ ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
+ ps_app_ctxt->u4_max_wd = DEFAULT_MAX_WD;
+ ps_app_ctxt->u4_max_ht = DEFAULT_MAX_HT;
+ ps_app_ctxt->u4_max_level = DEFAULT_MAX_LEVEL;
+ ps_app_ctxt->u4_strd = DEFAULT_STRIDE;
+ ps_app_ctxt->u4_wd = DEFAULT_WD;
+ ps_app_ctxt->u4_ht = DEFAULT_HT;
+ ps_app_ctxt->u4_psnr_enable = DEFAULT_PSNR_ENABLE;
+ ps_app_ctxt->u4_enc_speed = IVE_SLOWEST;
+ ps_app_ctxt->u4_me_speed = DEFAULT_ME_SPEED;
+ ps_app_ctxt->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD;
+ ps_app_ctxt->u4_enable_alt_ref = DEFAULT_ENABLE_ALT_REF;
+ ps_app_ctxt->u4_rc = DEFAULT_RC;
+ ps_app_ctxt->u4_num_bframes = DEFAULT_NUM_BFRAMES;
+ ps_app_ctxt->u4_air = DEFAULT_AIR;
+ ps_app_ctxt->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD;
+ ps_app_ctxt->u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
+ ps_app_ctxt->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
+ ps_app_ctxt->u4_i_interval = DEFAULT_I_INTERVAL;
+ ps_app_ctxt->u4_idr_interval = DEFAULT_IDR_INTERVAL;
+ ps_app_ctxt->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL;
+ ps_app_ctxt->u4_hpel = DEFAULT_HPEL;
+ ps_app_ctxt->u4_qpel = DEFAULT_QPEL;
+ ps_app_ctxt->u4_enable_intra_4x4 = DEFAULT_I4;
+ ps_app_ctxt->e_profile = DEFAULT_EPROFILE;
+ ps_app_ctxt->u4_slice_mode = DEFAULT_SLICE_MODE;
+ ps_app_ctxt->u4_slice_param = DEFAULT_SLICE_PARAM;
+ ps_app_ctxt->pv_input_thread_handle = NULL;
+ ps_app_ctxt->pv_output_thread_handle = NULL;
+ ps_app_ctxt->pv_recon_thread_handle = NULL;
+ ps_app_ctxt->adbl_psnr[0] = 0.0;
+ ps_app_ctxt->adbl_psnr[1] = 0.0;
+ ps_app_ctxt->adbl_psnr[2] = 0.0;
+ ps_app_ctxt->u4_psnr_cnt = 0;
+ ps_app_ctxt->pu1_psnr_buf = NULL;
+ ps_app_ctxt->u4_psnr_buf_size = 0;
+ ps_app_ctxt->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE;
+ ps_app_ctxt->u1_num_temporal_layers = DEFAULT_NUM_TEMPORAL_LAYERS;
+ ps_app_ctxt->u1_num_spatial_layers = DEFAULT_NUM_SPATIAL_LAYERS;
+ ps_app_ctxt->d_spatial_res_ratio = DEFAULT_SPATIAL_RES_RATIO;
+ ps_app_ctxt->u4_use_default_vui = 1;
+}
+
+static void set_dimensions(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_dimensions_ip_t s_frame_dimensions_ip;
+ isvce_ctl_set_dimensions_op_t s_frame_dimensions_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DIMENSIONS};
+
+ s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht;
+ s_frame_dimensions_ip.s_ive_ip.u4_wd = ps_app_ctxt->u4_wd;
+
+ s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_dimensions_ip_t);
+ s_frame_dimensions_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_dimensions_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_frame_dimensions_ip, &s_frame_dimensions_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set frame dimensions = 0x%x\n",
+ s_frame_dimensions_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+static void get_enc_dimensions(app_ctxt_t *ps_app_ctxt)
+{
+ isvce_ctl_get_enc_dimensions_ip_t s_ip;
+ isvce_ctl_get_enc_dimensions_op_t s_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GET_ENC_FRAME_DIMENSIONS};
+
+ s_ip.u4_inp_frame_wd = ps_app_ctxt->u4_wd;
+ s_ip.u4_inp_frame_ht = ps_app_ctxt->u4_ht;
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_ip, &s_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to get enc frame dimensions = 0x%x\n",
+ s_op.u4_error_code);
+
+ codec_exit(ac_error);
+ }
+
+ ps_app_ctxt->u4_enc_wd = s_op.u4_enc_frame_wd;
+ ps_app_ctxt->u4_enc_ht = s_op.u4_enc_frame_ht;
+}
+
+void set_frame_rate(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_frame_rate_ip_t s_frame_rate_ip;
+ isvce_ctl_set_frame_rate_op_t s_frame_rate_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMERATE};
+
+ s_frame_rate_ip.s_ive_ip.u4_src_frame_rate = ps_app_ctxt->u4_src_frame_rate;
+ s_frame_rate_ip.s_ive_ip.u4_tgt_frame_rate = ps_app_ctxt->u4_tgt_frame_rate;
+
+ s_frame_rate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_frame_rate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_frame_rate_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_rate_ip_t);
+ s_frame_rate_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_rate_op_t);
+
+ status =
+ isvce_api_function(ps_app_ctxt->ps_enc, &s_frame_rate_ip, &s_frame_rate_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set frame rate = 0x%x\n",
+ s_frame_rate_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_ipe_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_ipe_params_ip_t s_ipe_params_ip;
+ isvce_ctl_set_ipe_params_op_t s_ipe_params_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_IPE_PARAMS};
+
+ s_ipe_params_ip.s_ive_ip.u4_enable_intra_4x4 = ps_app_ctxt->u4_enable_intra_4x4;
+ s_ipe_params_ip.s_ive_ip.u4_enc_speed_preset = ps_app_ctxt->u4_enc_speed;
+
+ s_ipe_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_ipe_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_ipe_params_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_ipe_params_ip_t);
+ s_ipe_params_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_ipe_params_op_t);
+
+ status =
+ isvce_api_function(ps_app_ctxt->ps_enc, &s_ipe_params_ip, &s_ipe_params_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set ipe params = 0x%x\n",
+ s_ipe_params_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_bit_rate(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_bitrate_ip_t s_bitrate_ip;
+ isvce_ctl_set_bitrate_op_t s_bitrate_op;
+
+ IV_STATUS_T status;
+ WORD8 i;
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_BITRATE};
+
+ s_bitrate_ip.pu4_target_bitrate =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ s_bitrate_ip.pu4_target_bitrate[i] = ps_app_ctxt->pu4_bitrate[i];
+ }
+
+ s_bitrate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_bitrate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_bitrate_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_bitrate_ip_t);
+ s_bitrate_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_bitrate_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_bitrate_ip, &s_bitrate_op, &s_api_cmds);
+
+ isvca_aligned_free(s_bitrate_ip.pu4_target_bitrate);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set bit rate = 0x%x\n",
+ s_bitrate_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_frame_type(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high,
+ IV_PICTURE_CODING_TYPE_T e_frame_type)
+{
+ isvce_ctl_set_frame_type_ip_t s_frame_type_ip;
+ isvce_ctl_set_frame_type_op_t s_frame_type_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMETYPE};
+
+ s_frame_type_ip.s_ive_ip.e_frame_type = e_frame_type;
+
+ s_frame_type_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_frame_type_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_frame_type_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_type_ip_t);
+ s_frame_type_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_type_op_t);
+
+ status =
+ isvce_api_function(ps_app_ctxt->ps_enc, &s_frame_type_ip, &s_frame_type_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set frame type = 0x%x\n",
+ s_frame_type_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_qp(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_qp_ip_t s_qp_ip;
+ isvce_ctl_set_qp_op_t s_qp_op;
+
+ IV_STATUS_T status;
+ WORD8 i;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_QP};
+
+ s_qp_ip.pu4_i_qp =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_i_qp_max =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_i_qp_min =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+
+ s_qp_ip.pu4_p_qp =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_p_qp_max =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_p_qp_min =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+
+ s_qp_ip.pu4_b_qp =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_b_qp_max =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+ s_qp_ip.pu4_b_qp_min =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ s_qp_ip.pu4_i_qp[i] = ps_app_ctxt->pu4_i_qp[i];
+ s_qp_ip.pu4_i_qp_max[i] = ps_app_ctxt->pu4_i_qp_max[i];
+ s_qp_ip.pu4_i_qp_min[i] = ps_app_ctxt->pu4_i_qp_min[i];
+
+ s_qp_ip.pu4_p_qp[i] = ps_app_ctxt->pu4_p_qp[i];
+ s_qp_ip.pu4_p_qp_max[i] = ps_app_ctxt->pu4_p_qp_max[i];
+ s_qp_ip.pu4_p_qp_min[i] = ps_app_ctxt->pu4_p_qp_min[i];
+
+ s_qp_ip.pu4_b_qp[i] = ps_app_ctxt->pu4_b_qp[i];
+ s_qp_ip.pu4_b_qp_max[i] = ps_app_ctxt->pu4_b_qp_max[i];
+ s_qp_ip.pu4_b_qp_min[i] = ps_app_ctxt->pu4_b_qp_min[i];
+ }
+
+ s_qp_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_qp_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_qp_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_qp_ip_t);
+ s_qp_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_qp_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_qp_ip, &s_qp_op, &s_api_cmds);
+
+ isvca_aligned_free(s_qp_ip.pu4_i_qp);
+ isvca_aligned_free(s_qp_ip.pu4_i_qp_min);
+ isvca_aligned_free(s_qp_ip.pu4_i_qp_max);
+
+ isvca_aligned_free(s_qp_ip.pu4_p_qp);
+ isvca_aligned_free(s_qp_ip.pu4_p_qp_min);
+ isvca_aligned_free(s_qp_ip.pu4_p_qp_max);
+
+ isvca_aligned_free(s_qp_ip.pu4_b_qp);
+ isvca_aligned_free(s_qp_ip.pu4_b_qp_min);
+ isvca_aligned_free(s_qp_ip.pu4_b_qp_max);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set qp 0x%x\n",
+ s_qp_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_enc_mode(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high,
+ IVE_ENC_MODE_T e_enc_mode)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_enc_mode_ip_t s_enc_mode_ip;
+ isvce_ctl_set_enc_mode_op_t s_enc_mode_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ENC_MODE};
+
+ s_enc_mode_ip.s_ive_ip.e_enc_mode = e_enc_mode;
+
+ s_enc_mode_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_enc_mode_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_enc_mode_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_enc_mode_ip_t);
+ s_enc_mode_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_enc_mode_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_enc_mode_ip, &s_enc_mode_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set in header encode mode = 0x%x\n",
+ s_enc_mode_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_vbv_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_vbv_params_ip_t s_vbv_ip;
+ isvce_ctl_set_vbv_params_op_t s_vbv_op;
+
+ IV_STATUS_T status;
+ int i;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VBV_PARAMS};
+
+ s_vbv_ip.pu4_vbv_buffer_delay =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * ps_app_ctxt->u1_num_spatial_layers);
+
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ s_vbv_ip.pu4_vbv_buffer_delay[i] = ps_app_ctxt->pu4_vbv_buffer_delay[i];
+ }
+
+ s_vbv_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_vbv_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_vbv_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_vbv_params_ip_t);
+ s_vbv_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_vbv_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_vbv_ip, &s_vbv_op, &s_api_cmds);
+
+ isvca_aligned_free(s_vbv_ip.pu4_vbv_buffer_delay);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set VBC params = 0x%x\n",
+ s_vbv_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_air_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ isvce_ctl_set_air_params_ip_t s_air_ip;
+ isvce_ctl_set_air_params_op_t s_air_op;
+
+ IV_STATUS_T status;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_AIR_PARAMS};
+
+ s_air_ip.s_ive_ip.e_air_mode = ps_app_ctxt->u4_air;
+ s_air_ip.s_ive_ip.u4_air_refresh_period = ps_app_ctxt->u4_air_refresh_period;
+
+ s_air_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_air_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_air_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_air_params_ip_t);
+ s_air_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_air_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_air_ip, &s_air_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set air params = 0x%x\n",
+ s_air_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_me_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_me_params_ip_t s_me_params_ip;
+ isvce_ctl_set_me_params_op_t s_me_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ME_PARAMS};
+
+ s_me_params_ip.s_ive_ip.u4_enable_fast_sad = ps_app_ctxt->u4_enable_fast_sad;
+ s_me_params_ip.s_ive_ip.u4_enable_alt_ref = ps_app_ctxt->u4_enable_alt_ref;
+
+ s_me_params_ip.s_ive_ip.u4_enable_hpel = ps_app_ctxt->u4_hpel;
+ s_me_params_ip.s_ive_ip.u4_enable_qpel = ps_app_ctxt->u4_qpel;
+ s_me_params_ip.s_ive_ip.u4_me_speed_preset = ps_app_ctxt->u4_me_speed;
+ s_me_params_ip.s_ive_ip.u4_srch_rng_x = ps_app_ctxt->u4_srch_rng_x;
+ s_me_params_ip.s_ive_ip.u4_srch_rng_y = ps_app_ctxt->u4_srch_rng_y;
+
+ s_me_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_me_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_me_params_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_me_params_ip_t);
+ s_me_params_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_me_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_me_params_ip, &s_me_params_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set me params = 0x%x\n",
+ s_me_params_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_gop_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_gop_params_ip_t s_gop_params_ip;
+ isvce_ctl_set_gop_params_op_t s_gop_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_GOP_PARAMS};
+
+ s_gop_params_ip.s_ive_ip.u4_i_frm_interval = ps_app_ctxt->u4_i_interval;
+ s_gop_params_ip.s_ive_ip.u4_idr_frm_interval = ps_app_ctxt->u4_idr_interval;
+
+ s_gop_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_gop_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_gop_params_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_gop_params_ip_t);
+ s_gop_params_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_gop_params_op_t);
+
+ status =
+ isvce_api_function(ps_app_ctxt->ps_enc, &s_gop_params_ip, &s_gop_params_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set ME params = 0x%x\n",
+ s_gop_params_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_profile_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_profile_params_ip_t s_profile_params_ip;
+ isvce_ctl_set_profile_params_op_t s_profile_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_PROFILE_PARAMS};
+
+ s_profile_params_ip.s_ive_ip.e_profile = ps_app_ctxt->e_profile;
+
+ s_profile_params_ip.s_ive_ip.u4_entropy_coding_mode = ps_app_ctxt->u4_entropy_coding_mode;
+
+ s_profile_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_profile_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_profile_params_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_profile_params_ip_t);
+ s_profile_params_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_profile_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_profile_params_ip, &s_profile_params_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set profile params = 0x%x\n",
+ s_profile_params_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_deblock_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_deblock_params_ip_t s_deblock_params_ip;
+ isvce_ctl_set_deblock_params_op_t s_deblock_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS};
+
+ s_deblock_params_ip.s_ive_ip.u4_disable_deblock_level = ps_app_ctxt->u4_disable_deblock_level;
+
+ s_deblock_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high;
+ s_deblock_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_deblock_params_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_deblock_params_ip_t);
+ s_deblock_params_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_deblock_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_deblock_params_ip, &s_deblock_params_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to enable/disable deblock params = 0x%x\n",
+ s_deblock_params_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_vui_params(app_ctxt_t *ps_app_ctxt)
+{
+ IV_STATUS_T status;
+
+ isvce_vui_ip_t s_vui_params_ip;
+ isvce_vui_op_t s_vui_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VUI_PARAMS};
+
+ s_vui_params_ip.u1_aspect_ratio_info_present_flag = 0;
+ s_vui_params_ip.u1_aspect_ratio_idc = 0;
+ s_vui_params_ip.u2_sar_width = 0;
+ s_vui_params_ip.u2_sar_height = 0;
+ s_vui_params_ip.u1_overscan_info_present_flag = 0;
+ s_vui_params_ip.u1_overscan_appropriate_flag = 0;
+ s_vui_params_ip.u1_video_signal_type_present_flag = 1;
+ s_vui_params_ip.u1_video_format = 0;
+ s_vui_params_ip.u1_video_full_range_flag = 0;
+ s_vui_params_ip.u1_colour_description_present_flag = 0;
+ s_vui_params_ip.u1_colour_primaries = 0;
+ s_vui_params_ip.u1_transfer_characteristics = 0;
+ s_vui_params_ip.u1_matrix_coefficients = 0;
+ s_vui_params_ip.u1_chroma_loc_info_present_flag = 0;
+ s_vui_params_ip.u1_chroma_sample_loc_type_top_field = 0;
+ s_vui_params_ip.u1_chroma_sample_loc_type_bottom_field = 0;
+ s_vui_params_ip.u1_vui_timing_info_present_flag = 0;
+ s_vui_params_ip.u4_vui_num_units_in_tick = 0;
+ s_vui_params_ip.u4_vui_time_scale = 0;
+ s_vui_params_ip.u1_fixed_frame_rate_flag = 0;
+ s_vui_params_ip.u1_nal_hrd_parameters_present_flag = 0;
+ s_vui_params_ip.u1_vcl_hrd_parameters_present_flag = 0;
+ s_vui_params_ip.u1_low_delay_hrd_flag = 0;
+ s_vui_params_ip.u1_pic_struct_present_flag = 0;
+ s_vui_params_ip.u1_bitstream_restriction_flag = 0;
+ s_vui_params_ip.u1_motion_vectors_over_pic_boundaries_flag = 0;
+ s_vui_params_ip.u1_max_bytes_per_pic_denom = 0;
+ s_vui_params_ip.u1_max_bits_per_mb_denom = 0;
+ s_vui_params_ip.u1_log2_max_mv_length_horizontal = 0;
+ s_vui_params_ip.u1_log2_max_mv_length_vertical = 0;
+ s_vui_params_ip.u1_num_reorder_frames = 0;
+ s_vui_params_ip.u1_max_dec_frame_buffering = 0;
+
+ s_vui_params_ip.u4_size = sizeof(isvce_vui_ip_t);
+ s_vui_params_op.u4_size = sizeof(isvce_vui_op_t);
+
+ status =
+ isvce_api_function(ps_app_ctxt->ps_enc, &s_vui_params_ip, &s_vui_params_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set vui params = 0x%x\n",
+ s_vui_params_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+}
+
+void set_sei_mdcv_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ WORD32 i4_count;
+ IV_STATUS_T status;
+
+ isvce_ctl_set_sei_mdcv_params_ip_t s_sei_mdcv_params_ip;
+ isvce_ctl_set_sei_mdcv_params_op_t s_sei_mdcv_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS};
+
+ s_sei_mdcv_params_ip.u1_sei_mdcv_params_present_flag =
+ (UWORD8) ps_app_ctxt->u4_sei_mdcv_params_present_flag;
+
+ for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
+ {
+ s_sei_mdcv_params_ip.au2_display_primaries_x[i4_count] =
+ (UWORD16) ps_app_ctxt->au4_display_primaries_x[i4_count];
+ s_sei_mdcv_params_ip.au2_display_primaries_y[i4_count] =
+ (UWORD16) ps_app_ctxt->au4_display_primaries_y[i4_count];
+ }
+
+ s_sei_mdcv_params_ip.u2_white_point_x = (UWORD16) ps_app_ctxt->u4_white_point_x;
+ s_sei_mdcv_params_ip.u2_white_point_y = (UWORD16) ps_app_ctxt->u4_white_point_y;
+ s_sei_mdcv_params_ip.u4_max_display_mastering_luminance =
+ ps_app_ctxt->u4_max_display_mastering_luminance;
+ s_sei_mdcv_params_ip.u4_min_display_mastering_luminance =
+ ps_app_ctxt->u4_min_display_mastering_luminance;
+
+ s_sei_mdcv_params_ip.u4_timestamp_high = u4_timestamp_high;
+ s_sei_mdcv_params_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_sei_mdcv_params_ip.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_ip_t);
+ s_sei_mdcv_params_op.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_op_t);
+
+ if((ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[0] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_x[0]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[1] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_x[1]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[2] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_x[2]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[0] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_y[0]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[1] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_y[1]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[2] !=
+ s_sei_mdcv_params_ip.au2_display_primaries_y[2]) ||
+ (ps_app_ctxt->s_sei_mdcv_params.u2_white_point_x != s_sei_mdcv_params_ip.u2_white_point_x) ||
+ (ps_app_ctxt->s_sei_mdcv_params.u2_white_point_y != s_sei_mdcv_params_ip.u2_white_point_x) ||
+ (ps_app_ctxt->s_sei_mdcv_params.u4_max_display_mastering_luminance !=
+ s_sei_mdcv_params_ip.u4_max_display_mastering_luminance) ||
+ (ps_app_ctxt->s_sei_mdcv_params.u4_min_display_mastering_luminance !=
+ s_sei_mdcv_params_ip.u4_min_display_mastering_luminance))
+ {
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_sei_mdcv_params_ip,
+ &s_sei_mdcv_params_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ printf("Unable to set sei mdcv params = 0x%x\n", s_sei_mdcv_params_op.u4_error_code);
+ }
+ ps_app_ctxt->s_sei_mdcv_params = s_sei_mdcv_params_ip;
+ }
+}
+
+void set_sei_cll_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_sei_cll_params_ip_t s_sei_cll_params_ip;
+ isvce_ctl_set_sei_cll_params_op_t s_sei_cll_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS};
+
+ s_sei_cll_params_ip.u1_sei_cll_params_present_flag =
+ (UWORD8) ps_app_ctxt->u4_sei_cll_params_present_flag;
+
+ s_sei_cll_params_ip.u2_max_content_light_level =
+ (UWORD16) ps_app_ctxt->u4_max_content_light_level;
+ s_sei_cll_params_ip.u2_max_pic_average_light_level =
+ (UWORD16) ps_app_ctxt->u4_max_pic_average_light_level;
+
+ s_sei_cll_params_ip.u4_timestamp_high = u4_timestamp_high;
+ s_sei_cll_params_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_sei_cll_params_ip.u4_size = sizeof(isvce_ctl_set_sei_cll_params_ip_t);
+ s_sei_cll_params_op.u4_size = sizeof(isvce_ctl_set_sei_cll_params_op_t);
+
+ if((ps_app_ctxt->s_sei_cll_params.u2_max_content_light_level !=
+ s_sei_cll_params_ip.u2_max_content_light_level) ||
+ (ps_app_ctxt->s_sei_cll_params.u2_max_pic_average_light_level !=
+ s_sei_cll_params_ip.u2_max_pic_average_light_level))
+ {
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_sei_cll_params_ip, &s_sei_cll_params_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ printf("Unable to set sei cll params = 0x%x\n", s_sei_cll_params_op.u4_error_code);
+ }
+ ps_app_ctxt->s_sei_cll_params = s_sei_cll_params_ip;
+ }
+}
+
+void set_sei_ave_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ IV_STATUS_T status;
+
+ isvce_ctl_set_sei_ave_params_ip_t s_sei_ave_params_ip;
+ isvce_ctl_set_sei_ave_params_op_t s_sei_ave_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS};
+
+ s_sei_ave_params_ip.u1_sei_ave_params_present_flag =
+ (UWORD8) ps_app_ctxt->u4_sei_ave_params_present_flag;
+
+ s_sei_ave_params_ip.u4_ambient_illuminance = ps_app_ctxt->u4_ambient_illuminance;
+ s_sei_ave_params_ip.u2_ambient_light_x = (UWORD16) ps_app_ctxt->u4_ambient_light_x;
+ s_sei_ave_params_ip.u2_ambient_light_y = (UWORD16) ps_app_ctxt->u4_ambient_light_y;
+
+ s_sei_ave_params_ip.u4_timestamp_high = u4_timestamp_high;
+ s_sei_ave_params_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_sei_ave_params_ip.u4_size = sizeof(isvce_ctl_set_sei_ave_params_ip_t);
+ s_sei_ave_params_op.u4_size = sizeof(isvce_ctl_set_sei_ave_params_op_t);
+
+ if((ps_app_ctxt->s_sei_ave_params.u4_ambient_illuminance !=
+ s_sei_ave_params_ip.u4_ambient_illuminance) ||
+ (ps_app_ctxt->s_sei_ave_params.u2_ambient_light_x !=
+ s_sei_ave_params_ip.u2_ambient_light_x) ||
+ (ps_app_ctxt->s_sei_ave_params.u2_ambient_light_y != s_sei_ave_params_ip.u2_ambient_light_y))
+ {
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_sei_ave_params_ip, &s_sei_ave_params_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ printf("Unable to set sei ave params = 0x%x\n", s_sei_ave_params_op.u4_error_code);
+ }
+ ps_app_ctxt->s_sei_ave_params = s_sei_ave_params_ip;
+ }
+}
+
+void set_sei_ccv_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low,
+ UWORD32 u4_timestamp_high)
+{
+ WORD32 i4_count;
+ IV_STATUS_T status;
+
+ isvce_ctl_set_sei_ccv_params_ip_t s_sei_ccv_params_ip;
+ isvce_ctl_set_sei_ccv_params_op_t s_sei_ccv_params_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS};
+
+ s_sei_ccv_params_ip.u1_sei_ccv_params_present_flag =
+ (UWORD8) ps_app_ctxt->u4_sei_ccv_params_present_flag;
+
+ s_sei_ccv_params_ip.u1_ccv_cancel_flag = (UWORD8) ps_app_ctxt->u4_ccv_cancel_flag;
+ s_sei_ccv_params_ip.u1_ccv_persistence_flag = (UWORD8) ps_app_ctxt->u4_ccv_persistence_flag;
+ s_sei_ccv_params_ip.u1_ccv_primaries_present_flag =
+ (UWORD8) ps_app_ctxt->u4_ccv_primaries_present_flag;
+ s_sei_ccv_params_ip.u1_ccv_min_luminance_value_present_flag =
+ (UWORD8) ps_app_ctxt->u4_ccv_min_luminance_value_present_flag;
+ s_sei_ccv_params_ip.u1_ccv_max_luminance_value_present_flag =
+ (UWORD8) ps_app_ctxt->u4_ccv_max_luminance_value_present_flag;
+ s_sei_ccv_params_ip.u1_ccv_avg_luminance_value_present_flag =
+ (UWORD8) ps_app_ctxt->u4_ccv_avg_luminance_value_present_flag;
+ s_sei_ccv_params_ip.u1_ccv_reserved_zero_2bits =
+ (UWORD8) ps_app_ctxt->u4_ccv_reserved_zero_2bits;
+
+ for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
+ {
+ s_sei_ccv_params_ip.ai4_ccv_primaries_x[i4_count] =
+ ps_app_ctxt->ai4_ccv_primaries_x[i4_count];
+ s_sei_ccv_params_ip.ai4_ccv_primaries_y[i4_count] =
+ ps_app_ctxt->ai4_ccv_primaries_y[i4_count];
+ }
+
+ s_sei_ccv_params_ip.u4_ccv_min_luminance_value = ps_app_ctxt->u4_ccv_min_luminance_value;
+ s_sei_ccv_params_ip.u4_ccv_max_luminance_value = ps_app_ctxt->u4_ccv_max_luminance_value;
+ s_sei_ccv_params_ip.u4_ccv_avg_luminance_value = ps_app_ctxt->u4_ccv_avg_luminance_value;
+
+ s_sei_ccv_params_ip.u4_timestamp_high = u4_timestamp_high;
+ s_sei_ccv_params_ip.u4_timestamp_low = u4_timestamp_low;
+
+ s_sei_ccv_params_ip.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_ip_t);
+ s_sei_ccv_params_op.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_op_t);
+
+ status = isvce_api_function(ps_app_ctxt->ps_enc, &s_sei_ccv_params_ip, &s_sei_ccv_params_op,
+ &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ printf("Unable to set sei ccv params = 0x%x\n", s_sei_ccv_params_op.u4_error_code);
+ }
+}
+
+static void allocate_nalu_info_bufs(app_ctxt_t *ps_app_ctxt)
+{
+ UWORD32 i;
+
+ UWORD32 u4_num_bufs =
+ sizeof(ps_app_ctxt->as_nalu_info_bufs) / sizeof(ps_app_ctxt->as_nalu_info_bufs[0]);
+
+ for(i = 0; i < u4_num_bufs; i++)
+ {
+ ps_app_ctxt->as_nalu_info_bufs[i].u4_buf_size =
+ ps_app_ctxt->s_get_buf_info_op.u4_min_nalu_info_buf_size;
+ ps_app_ctxt->as_nalu_info_bufs[i].b_is_free = true;
+
+ ps_app_ctxt->as_nalu_info_bufs[i].pu1_buf =
+ (UWORD8 *) isvca_aligned_malloc(16, ps_app_ctxt->as_nalu_info_bufs[i].u4_buf_size);
+ }
+}
+
+static void free_nalu_info_bufs(app_ctxt_t *ps_app_ctxt)
+{
+ UWORD32 i;
+
+ UWORD32 u4_num_bufs =
+ sizeof(ps_app_ctxt->as_nalu_info_bufs) / sizeof(ps_app_ctxt->as_nalu_info_bufs[0]);
+
+ for(i = 0; i < u4_num_bufs; i++)
+ {
+ isvca_aligned_free(ps_app_ctxt->as_nalu_info_bufs[i].pu1_buf);
+ ps_app_ctxt->as_nalu_info_bufs[i].b_is_free = false;
+ }
+}
+
+#define PEAK_WINDOW_SIZE 8
+
+void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
+{
+ isvce_video_encode_ip_t s_video_encode_ip;
+ isvce_video_encode_op_t s_video_encode_op;
+
+ ive_video_encode_ip_t *ps_video_encode_ip = &s_video_encode_ip.s_ive_ip;
+ ive_video_encode_op_t *ps_video_encode_op = &s_video_encode_op.s_ive_op;
+
+ iv_raw_buf_t *ps_inp_raw_buf = &ps_video_encode_ip->s_inp_buf;
+
+ IV_STATUS_T status = IV_SUCCESS;
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_ENCODE, ISVCE_CMD_CT_NA};
+
+ WORD32 i, is_last = 0, num_bytes = 0;
+ UWORD32 u4_total_time = 0;
+ UWORD8 *pu1_buf = NULL;
+ UWORD32 u4_timestamp_low, u4_timestamp_high;
+ void *pv_mb_info = NULL, *pv_pic_info = NULL;
+ WORD32 *pi4_nalu_info_buf_ids = isvca_aligned_malloc(
+ 16, ps_app_ctxt->u1_num_spatial_layers * sizeof(pi4_nalu_info_buf_ids[0]));
+
+#ifdef PROFILE_ENABLE
+ TIMER curtime;
+ WORD32 peak_window[PEAK_WINDOW_SIZE] = {0};
+ WORD32 peak_window_idx = 0;
+#endif
+ WORD32 peak_avg_max = 0, timetaken = 0;
+ iv_raw_buf_t s_inp_buf, s_recon_buf;
+ CHAR ac_error[2 * STRLENGTH];
+
+ u4_timestamp_low = 0;
+ u4_timestamp_high = 0;
+
+ /*************************************************************************/
+ /* Allocate I/O Buffers */
+ /*************************************************************************/
+ allocate_input(ps_app_ctxt);
+ allocate_output(ps_app_ctxt);
+ allocate_recon(ps_app_ctxt);
+ allocate_nalu_info_bufs(ps_app_ctxt);
+
+ s_video_encode_ip.ps_nalu_info_buf = isvca_aligned_malloc(
+ 16, sizeof(isvce_nalu_info_buf_t) * ps_app_ctxt->u1_num_spatial_layers);
+ s_video_encode_op.ps_nalu_info_buf = isvca_aligned_malloc(
+ 16, sizeof(isvce_nalu_info_buf_t) * ps_app_ctxt->u1_num_spatial_layers);
+
+ /* init psnr */
+ init_psnr(ps_app_ctxt);
+
+ /* open file pointers */
+ ps_app_ctxt->fp_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb");
+ if(NULL == ps_app_ctxt->fp_ip)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open input file for reading: %s",
+ ps_app_ctxt->ac_ip_fname);
+ invalid_argument_exit(ac_error);
+ }
+
+ ps_app_ctxt->fp_op = fopen(ps_app_ctxt->ac_op_fname, "wb");
+ if(NULL == ps_app_ctxt->fp_op)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open output file for writing: %s",
+ ps_app_ctxt->ac_op_fname);
+ invalid_argument_exit(ac_error);
+ }
+
+ if(1 == ps_app_ctxt->u4_recon_enable)
+ {
+ ps_app_ctxt->fp_recon = fopen(ps_app_ctxt->ac_recon_fname, "wb");
+ if(NULL == ps_app_ctxt->fp_recon)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open recon file for writing: %s",
+ ps_app_ctxt->ac_recon_fname);
+ invalid_argument_exit(ac_error);
+ }
+ }
+
+ if(1 == ps_app_ctxt->u4_nalu_info_export_enable)
+ {
+ ps_app_ctxt->fp_nalu_info = fopen(ps_app_ctxt->ac_nalu_info_csv_fname, "w");
+
+ if(NULL == ps_app_ctxt->fp_nalu_info)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Unable to open NALU Info CSV file for writing: %s",
+ ps_app_ctxt->ac_nalu_info_csv_fname);
+ invalid_argument_exit(ac_error);
+ }
+
+ fprintf(ps_app_ctxt->fp_nalu_info,
+ "type,length,SId,TID,isIDR,isFirstSliceInLayer,isLastSliceInLayer\n");
+ }
+
+ if(1 == ps_app_ctxt->u4_chksum_enable)
+ {
+ ps_app_ctxt->fp_chksum = fopen(ps_app_ctxt->ac_chksum_fname, "wb");
+ if(NULL == ps_app_ctxt->fp_chksum)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open checksum file for writing: %s",
+ ps_app_ctxt->ac_chksum_fname);
+ invalid_argument_exit(ac_error);
+ }
+ }
+
+ /* If PSNR is enabled, open input file again and hold a different file pointer
+ * This makes it easy to compute PSNR without adding dependency between input
+ * and recon threads
+ */
+ if(1 == ps_app_ctxt->u4_psnr_enable)
+ {
+ ps_app_ctxt->fp_psnr_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb");
+ if(NULL == ps_app_ctxt->fp_psnr_ip)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open input file for reading: %s",
+ ps_app_ctxt->ac_ip_fname);
+ invalid_argument_exit(ac_error);
+ }
+ }
+
+ if(0 != ps_app_ctxt->u4_mb_info_type)
+ {
+ ps_app_ctxt->fp_mb_info = fopen(ps_app_ctxt->ac_mb_info_fname, "rb");
+ if(NULL == ps_app_ctxt->fp_mb_info)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open MB info file for reading: %s",
+ ps_app_ctxt->ac_mb_info_fname);
+ invalid_argument_exit(ac_error);
+ }
+ }
+ if(ps_app_ctxt->u4_pic_info_type)
+ {
+ ps_app_ctxt->fp_pic_info = fopen(ps_app_ctxt->ac_pic_info_fname, "rb");
+ if(NULL == ps_app_ctxt->fp_pic_info)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to open Pic info file for reading: %s",
+ ps_app_ctxt->ac_pic_info_fname);
+ invalid_argument_exit(ac_error);
+ }
+ }
+
+ GETTIME(&ps_app_ctxt->enc_start_time);
+ ps_app_ctxt->enc_last_time = ps_app_ctxt->enc_start_time;
+
+ while(1)
+ {
+ WORD32 i4_count;
+
+ /* Default sei params values*/
+ ps_app_ctxt->u4_sei_mdcv_params_present_flag = 0;
+ if(1 == ps_app_ctxt->u4_sei_mdcv_params_present_flag)
+ {
+ for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
+ {
+ ps_app_ctxt->au4_display_primaries_x[i4_count] = 0;
+ ps_app_ctxt->au4_display_primaries_y[i4_count] = 0;
+ }
+ ps_app_ctxt->u4_white_point_x = 0;
+ ps_app_ctxt->u4_white_point_y = 0;
+ ps_app_ctxt->u4_max_display_mastering_luminance =
+ DEFAULT_MAX_DISPLAY_MASTERING_LUMINANCE;
+ ps_app_ctxt->u4_min_display_mastering_luminance =
+ DEFAULT_MIN_DISPLAY_MASTERING_LUMINANCE;
+ set_sei_mdcv_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
+ }
+
+ ps_app_ctxt->u4_sei_cll_params_present_flag = 0;
+ if(1 == ps_app_ctxt->u4_sei_cll_params_present_flag)
+ {
+ ps_app_ctxt->u4_max_content_light_level = 0;
+ ps_app_ctxt->u4_max_pic_average_light_level = 0;
+ set_sei_cll_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
+ }
+
+ ps_app_ctxt->u4_sei_ave_params_present_flag = 0;
+ if(1 == ps_app_ctxt->u4_sei_ave_params_present_flag)
+ {
+ ps_app_ctxt->u4_ambient_illuminance = 1;
+ ps_app_ctxt->u4_ambient_light_x = 0;
+ ps_app_ctxt->u4_ambient_light_y = 0;
+ set_sei_ave_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
+ }
+
+ ps_app_ctxt->u4_sei_ccv_params_present_flag = 0;
+ if(1 == ps_app_ctxt->u4_sei_ccv_params_present_flag)
+ {
+ ps_app_ctxt->u4_ccv_cancel_flag = 0;
+ ps_app_ctxt->u4_ccv_persistence_flag = 1;
+ ps_app_ctxt->u4_ccv_primaries_present_flag = 1;
+ ps_app_ctxt->u4_ccv_min_luminance_value_present_flag = 1;
+ ps_app_ctxt->u4_ccv_max_luminance_value_present_flag = 1;
+ ps_app_ctxt->u4_ccv_avg_luminance_value_present_flag = 1;
+ ps_app_ctxt->u4_ccv_reserved_zero_2bits = 0;
+ for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
+ {
+ ps_app_ctxt->ai4_ccv_primaries_x[i4_count] = 1;
+ ps_app_ctxt->ai4_ccv_primaries_y[i4_count] = 1;
+ }
+ ps_app_ctxt->u4_ccv_min_luminance_value = 1;
+ ps_app_ctxt->u4_ccv_max_luminance_value = 1;
+ ps_app_ctxt->u4_ccv_avg_luminance_value = 1;
+ set_sei_ccv_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high);
+ }
+
+ /******************************************************************************/
+ /****************** Input Initialization
+ * **************************************/
+ /******************************************************************************/
+
+ for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++)
+ {
+ if(ps_app_ctxt->as_input_buf[i].u4_is_free)
+ {
+ pu1_buf = ps_app_ctxt->as_input_buf[i].pu1_buf;
+ pv_mb_info = ps_app_ctxt->as_input_buf[i].pv_mb_info;
+ pv_pic_info = ps_app_ctxt->as_input_buf[i].pv_pic_info;
+ ps_app_ctxt->as_input_buf[i].u4_is_free = 0;
+ break;
+ }
+ }
+
+ if(i == DEFAULT_MAX_INPUT_BUFS)
+ {
+ printf("\n Unable to find a free input buffer!!");
+ exit(0);
+ }
+
+ ps_video_encode_ip->u4_size = sizeof(isvce_video_encode_ip_t);
+ ps_video_encode_op->u4_size = sizeof(isvce_video_encode_op_t);
+
+ ps_video_encode_ip->pv_bufs = pu1_buf;
+ ps_video_encode_ip->pv_mb_info = pv_mb_info;
+ ps_video_encode_ip->pv_pic_info = pv_pic_info;
+ ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;
+ /*
+ * Since the buffers are used for reading,
+ * And after each row we have a stride we nned to calculate
+ * the luma size according to the stride
+ */
+ ps_inp_raw_buf->e_color_fmt = ps_app_ctxt->e_inp_color_fmt;
+
+ /* Initialize for 420SP */
+ if(IV_YUV_420SP_UV == ps_app_ctxt->e_inp_color_fmt ||
+ IV_YUV_420SP_VU == ps_app_ctxt->e_inp_color_fmt)
+ {
+ /*init luma buffer*/
+ ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
+
+ /*Init chroma buffer*/
+ pu1_buf += ps_app_ctxt->u4_strd * ps_app_ctxt->u4_ht;
+ ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
+
+ ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd;
+ ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd;
+
+ ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht;
+ ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2;
+
+ ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd;
+ ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd;
+ }
+ else if(IV_YUV_420P == ps_app_ctxt->e_inp_color_fmt)
+ {
+ /* init buffers */
+ ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
+ pu1_buf += (ps_app_ctxt->u4_wd) * ps_app_ctxt->u4_ht;
+ ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
+ pu1_buf += (ps_app_ctxt->u4_wd >> 1) * (ps_app_ctxt->u4_ht >> 1);
+ ps_inp_raw_buf->apv_bufs[2] = pu1_buf;
+
+ ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd;
+ ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2;
+ ps_inp_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2;
+
+ ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht;
+ ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2;
+ ps_inp_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2;
+
+ ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd;
+ ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd / 2;
+ ps_inp_raw_buf->au4_strd[2] = ps_app_ctxt->u4_strd / 2;
+ }
+ else if(IV_YUV_422ILE == ps_app_ctxt->e_inp_color_fmt)
+ {
+ /*init luma buffer*/
+ ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
+
+ ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd * 2;
+
+ ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht;
+
+ ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd * 2;
+ }
+
+ /*
+ * Here we read input and other associated buffers. Regardless of success
+ * we will proceed from here as we will need extra calls to flush out
+ * input queue in encoder. Note that this is not necessary. You can just
+ * send encode calls till with valid output and recon buffers till the
+ * queue is flushed.
+ */
+ while(1)
+ {
+ IV_STATUS_T mb_info_status = IV_SUCCESS, pic_info_status = IV_SUCCESS;
+
+ status = read_input(ps_app_ctxt->fp_ip, ps_inp_raw_buf);
+
+ if(ps_app_ctxt->u4_mb_info_type != 0)
+ {
+ mb_info_status = read_mb_info(ps_app_ctxt, pv_mb_info);
+ }
+ if(ps_app_ctxt->u4_pic_info_type != 0)
+ {
+ pic_info_status = read_pic_info(ps_app_ctxt, pv_pic_info);
+ }
+ if((IV_SUCCESS != status) || (IV_SUCCESS != mb_info_status) ||
+ (IV_SUCCESS != pic_info_status))
+ {
+ if(0 == ps_app_ctxt->u4_loopback)
+ {
+ is_last = 1;
+ break;
+ }
+ else
+ fseek(ps_app_ctxt->fp_ip, 0, SEEK_SET);
+ }
+ break;
+ }
+
+ /******************************************************************************/
+ /****************** Output Initialization
+ * *************************************/
+ /******************************************************************************/
+ for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++)
+ {
+ if(ps_app_ctxt->as_output_buf[i].u4_is_free)
+ {
+ ps_app_ctxt->as_output_buf[i].u4_is_free = 0;
+
+ ps_video_encode_ip->s_out_buf.pv_buf = ps_app_ctxt->as_output_buf[i].pu1_buf;
+ ps_video_encode_ip->s_out_buf.u4_bytes = 0;
+ ps_video_encode_ip->s_out_buf.u4_bufsize =
+ ps_app_ctxt->as_output_buf[i].u4_buf_size;
+ }
+ }
+
+ /******************************************************************************/
+ /****************** Recon Initialization
+ * **************************************/
+ /******************************************************************************/
+ init_raw_buf_descr(ps_app_ctxt, &s_recon_buf, ps_app_ctxt->as_recon_buf[0].pu1_buf,
+ ps_app_ctxt->e_recon_color_fmt);
+
+ /******************************************************************************/
+ /****************** Output Initialization
+ * *************************************/
+ /******************************************************************************/
+ {
+ UWORD8 u1_num_layer_bufs_assigned = 0;
+
+ for(i = 0; i < DEFAULT_MAX_NALU_INFO_BUFS; i++)
+ {
+ if(ps_app_ctxt->as_nalu_info_bufs[i].b_is_free)
+ {
+ ps_app_ctxt->as_nalu_info_bufs[i].b_is_free = false;
+ pi4_nalu_info_buf_ids[u1_num_layer_bufs_assigned] = i;
+
+ s_video_encode_ip.ps_nalu_info_buf[u1_num_layer_bufs_assigned].pu1_buf =
+ ps_app_ctxt->as_nalu_info_bufs[i].pu1_buf;
+ s_video_encode_ip.ps_nalu_info_buf[u1_num_layer_bufs_assigned].u4_num_bytes = 0;
+ s_video_encode_ip.ps_nalu_info_buf[u1_num_layer_bufs_assigned].u4_buf_size =
+ ps_app_ctxt->as_nalu_info_bufs[i].u4_buf_size;
+
+ u1_num_layer_bufs_assigned++;
+
+ if(u1_num_layer_bufs_assigned >= ps_app_ctxt->u1_num_spatial_layers)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if(ps_app_ctxt->u4_psnr_enable)
+ init_raw_buf_descr(ps_app_ctxt, &s_inp_buf, ps_app_ctxt->pu1_psnr_buf,
+ ps_app_ctxt->e_inp_color_fmt);
+
+ ps_video_encode_ip->s_recon_buf = s_recon_buf;
+
+ /******************************************************************************/
+ /************************* Un Initialized
+ * *************************************/
+ /******************************************************************************/
+ if(0 == ps_app_ctxt->u4_loopback)
+ {
+ /* If input file is read completely and loopback is not enabled,
+ * then exit the loop */
+ if(feof(ps_app_ctxt->fp_ip))
+ {
+ is_last = 1;
+ }
+ }
+
+ /* If last frame, send input null to get back encoded frames */
+ if(is_last == 1 || ((ps_app_ctxt->u4_max_num_frms) <= u4_timestamp_low))
+ {
+ is_last = 1;
+ ps_inp_raw_buf->apv_bufs[0] = NULL;
+ ps_inp_raw_buf->apv_bufs[1] = NULL;
+ ps_inp_raw_buf->apv_bufs[2] = NULL;
+ }
+
+ ps_video_encode_ip->u4_is_last = is_last;
+ ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type;
+ ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;
+
+ ps_video_encode_op->s_out_buf.pv_buf = NULL;
+
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ s_video_encode_op.ps_nalu_info_buf[i].pu1_buf = NULL;
+ }
+
+ ps_video_encode_ip->u4_timestamp_high = u4_timestamp_high;
+ ps_video_encode_ip->u4_timestamp_low = u4_timestamp_low;
+
+ GETTIME(&ps_app_ctxt->enc_last_time);
+
+ status = isvce_api_function(ps_enc, &s_video_encode_ip, &s_video_encode_op, &s_api_cmds);
+
+ if(IV_SUCCESS != status)
+ {
+ printf("Encode Frame failed = 0x%x\n", s_video_encode_op.s_ive_op.u4_error_code);
+ break;
+ }
+
+#ifdef PROFILE_ENABLE
+ GETTIME(&curtime);
+ ELAPSEDTIME(ps_app_ctxt->enc_last_time, curtime, timetaken, frequency);
+ ps_app_ctxt->enc_last_time = curtime;
+
+ {
+ WORD32 peak_avg, id;
+ u4_total_time += timetaken;
+ peak_window[peak_window_idx++] = timetaken;
+ if(peak_window_idx == PEAK_WINDOW_SIZE) peak_window_idx = 0;
+ peak_avg = 0;
+ for(id = 0; id < PEAK_WINDOW_SIZE; id++)
+ {
+ peak_avg += peak_window[id];
+ }
+ peak_avg /= PEAK_WINDOW_SIZE;
+ if(peak_avg > peak_avg_max) peak_avg_max = peak_avg;
+ }
+#endif
+
+ /******************************************************************************/
+ /****************** Writing Output
+ * ********************************************/
+ /******************************************************************************/
+ num_bytes = 0;
+
+ if(ps_video_encode_op->output_present)
+ {
+ num_bytes = ps_video_encode_op->s_out_buf.u4_bytes;
+ pu1_buf = (UWORD8 *) ps_video_encode_op->s_out_buf.pv_buf;
+
+ status = write_output(ps_app_ctxt->fp_op, pu1_buf, num_bytes);
+
+ if(IV_SUCCESS != status)
+ {
+ printf("Error: Unable to write to output file\n");
+ break;
+ }
+ }
+
+ for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++)
+ {
+ if(ps_app_ctxt->as_output_buf[i].pu1_buf == ps_video_encode_op->s_out_buf.pv_buf)
+ {
+ ps_app_ctxt->as_output_buf[i].u4_is_free = 1;
+
+ break;
+ }
+ }
+
+ if(ps_app_ctxt->u4_nalu_info_export_enable && s_video_encode_op.b_is_nalu_info_present)
+ {
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ fprintf(ps_app_ctxt->fp_nalu_info, "%s",
+ s_video_encode_op.ps_nalu_info_buf[i].pu1_buf);
+ }
+ }
+
+ if(ps_video_encode_op->s_inp_buf.apv_bufs[0])
+ {
+ for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++)
+ {
+ if(ps_app_ctxt->as_input_buf[i].pu1_buf ==
+ ps_video_encode_op->s_inp_buf.apv_bufs[0])
+ {
+ ps_app_ctxt->as_input_buf[i].u4_is_free = 1;
+ break;
+ }
+ }
+ }
+
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ ps_app_ctxt->as_nalu_info_bufs[pi4_nalu_info_buf_ids[i]].b_is_free = true;
+ }
+
+ /**********************************************************************
+ * Print stats
+ **********************************************************************/
+ {
+ UWORD8 u1_pic_type[][5] = {"IDR", "I", "P", "B", "NA"};
+ WORD32 lookup_idx = 0;
+
+ if(s_video_encode_op.s_ive_op.u4_encoded_frame_type == IV_IDR_FRAME)
+ {
+ lookup_idx = 0;
+ }
+ else if(s_video_encode_op.s_ive_op.u4_encoded_frame_type == IV_I_FRAME)
+ {
+ lookup_idx = 1;
+ }
+ else if(s_video_encode_op.s_ive_op.u4_encoded_frame_type == IV_P_FRAME)
+ {
+ lookup_idx = 2;
+ }
+ else if(s_video_encode_op.s_ive_op.u4_encoded_frame_type == IV_B_FRAME)
+ {
+ lookup_idx = 3;
+ }
+ else if(s_video_encode_op.s_ive_op.u4_encoded_frame_type == IV_NA_FRAME)
+ {
+ lookup_idx = 4;
+ }
+
+ if(s_video_encode_op.s_ive_op.u4_encoded_frame_type != IV_NA_FRAME)
+ {
+ ps_app_ctxt->u4_pics_cnt++;
+ ps_app_ctxt->avg_time = u4_total_time / ps_app_ctxt->u4_pics_cnt;
+ ps_app_ctxt->u4_total_bytes = ps_video_encode_op->s_out_buf.u4_bytes;
+ }
+
+ if(ps_app_ctxt->u4_psnr_enable == 0)
+ {
+ printf("[%s] PicNum %4d ", u1_pic_type[lookup_idx], ps_app_ctxt->u4_pics_cnt);
+ printf(" Bytes : %6d \t", ps_app_ctxt->u4_total_bytes);
+ printf(
+ "TimeTaken(microsec): %6d "
+ "AvgTime: %6d PeakAvgTimeMax: %6d\n",
+ timetaken, ps_app_ctxt->avg_time, peak_avg_max);
+ }
+ }
+
+ /* For psnr computation, we need to read the correct input frame and
+ * compare with recon. The difficulty with doing it is that we only know
+ * that the frame number of recon is monotonically increasing. There
+ * may be gaps in the recon if any pre or post enc skip happens. There are
+ * 3 senarios
+ * 1) A frame is encoded -> returns the pic type
+ * 2) A frame is not encoded -> Encoder is waiting, the frame may get
+ * encoded later
+ * 3) A frame is not encoded -> A post enc or pre enc skip happend. The
+ * frame is not going to be encoded
+ *
+ * The 1st and 2nd scenarios are easy, since we just needs to increment
+ * recon cnt whenever we get a valid recon. This cnt can we used to
+ * sync the recon and input
+ * 3rd scenario in conjuction with 2nd will pose problems. Even if
+ * the returning frame is NA, we donot know we should increment the
+ * recon cnt or not becasue it can be case 2 or case 3.
+ *
+ * Solutions:
+ * -------------------------
+ * One way to over come this will be to return more information as of
+ * the frame type. We can send if a frame was skipped as a part of the
+ * return frame type.
+ * This will not work. Since the output and recon are not in sync, we
+ * cannot use the current output frame type to determine if a recon
+ * is present currently or not. We need some other way to acheive this.
+ *
+ * Other way to do this which is cleaner and maintains the seperation
+ * between recon and the ouptut is to set the width [& height] of output
+ * recon buffer to be zero. Hence we will in effect be saying :"look there
+ * is a recon, but due to frame not being encoded it is having a width 0".
+ * To be more clear we need to make height also to be zero.
+ *
+ * But are we using these variables for allocating and deallocating
+ * the buffers some where ? No we are not. The buffer gets re-init
+ * at every encode call
+ *
+ * Fixes
+ * ------------------------
+ * Currently the recon buff width and height are set in the encoder.
+ * This will not work now because since recon and input are not
+ * in sync. Hence a recon buff sent at time stamp x will get used to
+ * fill recon of input at time stamp y (x > y). If we reduced the
+ * frame dimensions in between, the recon buffer will not have enough
+ * space. Hence we need to set the with and height appropriatley inside
+ * lib itself.
+ */
+
+ if(ps_app_ctxt->u4_recon_enable || ps_app_ctxt->u4_chksum_enable ||
+ ps_app_ctxt->u4_psnr_enable)
+ {
+ if(ps_video_encode_op->dump_recon)
+ {
+ s_recon_buf = ps_video_encode_op->s_recon_buf;
+
+ /* Read input for psnr computuation */
+ if(ps_app_ctxt->u4_psnr_enable) read_input(ps_app_ctxt->fp_psnr_ip, &s_inp_buf);
+
+ /* if we have a valid recon buffer do the assocated tasks */
+ if(s_recon_buf.au4_wd[0])
+ {
+ /* Dump recon when enabled, and output bytes != 0 */
+ if(ps_app_ctxt->u4_recon_enable)
+ {
+ status = write_recon(ps_app_ctxt->fp_recon, &s_recon_buf);
+ if(IV_SUCCESS != status)
+ {
+ printf("Error: Unable to write to recon file\n");
+ break;
+ }
+ }
+
+ if(ps_app_ctxt->u4_psnr_enable)
+ {
+ compute_psnr(ps_app_ctxt, &s_recon_buf, &s_inp_buf);
+ }
+
+ if(ps_app_ctxt->u4_chksum_enable)
+ {
+ WORD32 comp, num_comp = 2;
+
+ if(IV_YUV_420P == s_recon_buf.e_color_fmt) num_comp = 3;
+
+ for(comp = 0; comp < num_comp; comp++)
+ {
+ UWORD8 au1_chksum[16];
+ calc_md5_cksum((UWORD8 *) s_recon_buf.apv_bufs[comp],
+ s_recon_buf.au4_strd[comp], s_recon_buf.au4_wd[comp],
+ s_recon_buf.au4_ht[comp], au1_chksum);
+ fwrite(au1_chksum, sizeof(UWORD8), 16, ps_app_ctxt->fp_chksum);
+ }
+ }
+ }
+ }
+ }
+
+ u4_timestamp_low++;
+
+ /* Break if all the encoded frames are taken from encoder */
+ if(1 == ps_video_encode_op->u4_is_last)
+ {
+ break;
+ }
+ }
+
+ /* Pic count is 1 more than actual num frames encoded, because last call is to
+ * just get the output */
+ ps_app_ctxt->u4_pics_cnt--;
+
+ if(ps_app_ctxt->u4_psnr_enable)
+ {
+ print_average_psnr(ps_app_ctxt);
+ }
+
+ /* house keeping operations */
+ fclose(ps_app_ctxt->fp_ip);
+ fclose(ps_app_ctxt->fp_op);
+ if(1 == ps_app_ctxt->u4_recon_enable)
+ {
+ fclose(ps_app_ctxt->fp_recon);
+ }
+ if(1 == ps_app_ctxt->u4_nalu_info_export_enable)
+ {
+ fclose(ps_app_ctxt->fp_nalu_info);
+ }
+ if(1 == ps_app_ctxt->u4_chksum_enable)
+ {
+ fclose(ps_app_ctxt->fp_chksum);
+ }
+ if(1 == ps_app_ctxt->u4_psnr_enable)
+ {
+ fclose(ps_app_ctxt->fp_psnr_ip);
+ }
+
+ if(0 != ps_app_ctxt->u4_mb_info_type)
+ {
+ fclose(ps_app_ctxt->fp_mb_info);
+ }
+ if(ps_app_ctxt->u4_pic_info_type)
+ {
+ fclose(ps_app_ctxt->fp_pic_info);
+ }
+
+ free_input(ps_app_ctxt);
+ free_output(ps_app_ctxt);
+ free_recon(ps_app_ctxt);
+ free_nalu_info_bufs(ps_app_ctxt);
+
+ isvca_aligned_free(s_video_encode_ip.ps_nalu_info_buf);
+ isvca_aligned_free(s_video_encode_op.ps_nalu_info_buf);
+
+ isvca_aligned_free(pi4_nalu_info_buf_ids);
+}
+
+void init_default_rc_params(app_ctxt_t *ps_app_ctxt)
+{
+ UWORD8 i;
+ for(i = 0; i < ps_app_ctxt->u1_num_spatial_layers; i++)
+ {
+ ps_app_ctxt->pu4_max_bitrate[i] = DEFAULT_MAX_BITRATE;
+ ps_app_ctxt->pu4_bitrate[i] = DEFAULT_BITRATE;
+ ps_app_ctxt->pu4_i_qp[i] = DEFAULT_I_QP;
+ ps_app_ctxt->pu4_p_qp[i] = DEFAULT_P_QP;
+ ps_app_ctxt->pu4_b_qp[i] = DEFAULT_B_QP;
+ ps_app_ctxt->pu4_i_qp_min[i] = DEFAULT_QP_MIN;
+ ps_app_ctxt->pu4_i_qp_max[i] = DEFAULT_QP_MAX;
+ ps_app_ctxt->pu4_p_qp_min[i] = DEFAULT_QP_MIN;
+ ps_app_ctxt->pu4_p_qp_max[i] = DEFAULT_QP_MAX;
+ ps_app_ctxt->pu4_b_qp_min[i] = DEFAULT_QP_MIN;
+ ps_app_ctxt->pu4_b_qp_max[i] = DEFAULT_QP_MAX;
+ ps_app_ctxt->pu4_vbv_buffer_delay[i] = 1000;
+ }
+
+ ps_app_ctxt->u4_total_bytes = 0;
+}
+
+/* Allocate memory to dynamic arrays holding RC information */
+void alloc_rc_params(app_ctxt_t *ps_app_ctxt)
+{
+ UWORD8 u1_num_spatial_layers = ps_app_ctxt->u1_num_spatial_layers;
+ ps_app_ctxt->pu4_max_bitrate =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_bitrate =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_i_qp =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_p_qp =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_b_qp =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_i_qp_min =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_i_qp_max =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_p_qp_min =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_p_qp_max =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_b_qp_min =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_b_qp_max =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+ ps_app_ctxt->pu4_vbv_buffer_delay =
+ (UWORD32 *) isvca_aligned_malloc(16, sizeof(UWORD32) * u1_num_spatial_layers);
+}
+
+/* Free memory allocated to dynamic arrays holding RC information */
+void free_rc_params(app_ctxt_t *ps_app_ctxt)
+{
+ isvca_aligned_free(ps_app_ctxt->pu4_max_bitrate);
+ isvca_aligned_free(ps_app_ctxt->pu4_bitrate);
+ isvca_aligned_free(ps_app_ctxt->pu4_i_qp);
+ isvca_aligned_free(ps_app_ctxt->pu4_p_qp);
+ isvca_aligned_free(ps_app_ctxt->pu4_b_qp);
+ isvca_aligned_free(ps_app_ctxt->pu4_i_qp_min);
+ isvca_aligned_free(ps_app_ctxt->pu4_i_qp_max);
+ isvca_aligned_free(ps_app_ctxt->pu4_p_qp_min);
+ isvca_aligned_free(ps_app_ctxt->pu4_p_qp_max);
+ isvca_aligned_free(ps_app_ctxt->pu4_b_qp_min);
+ isvca_aligned_free(ps_app_ctxt->pu4_b_qp_max);
+ isvca_aligned_free(ps_app_ctxt->pu4_vbv_buffer_delay);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : main */
+/* */
+/* Description : Application to demonstrate codec API */
+/* */
+/* */
+/* Inputs : argc - Number of arguments */
+/* argv[] - Arguments */
+/* Globals : */
+/* Processing : Shows how to use create, process, control and delete */
+/* */
+/* Outputs : Codec output in a file */
+/* Returns : */
+/* */
+/* Issues : Assumes both PROFILE_ENABLE to be */
+/* defined for multithread decode-display working */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 20 11 2013 100189 Initial Version */
+/*****************************************************************************/
+#ifdef IOS
+int h264enc_main(char *homedir, char *documentdir, int screen_wd, int screen_ht)
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ /* Config Parameters for Encoding */
+ app_ctxt_t s_app_ctxt;
+
+ /* error string */
+ CHAR ac_error[2 * STRLENGTH];
+
+ /* config file name */
+ CHAR ac_cfg_fname[STRLENGTH];
+
+ /* error status */
+ IV_STATUS_T status = IV_SUCCESS;
+#ifdef IOS
+ /* temp var */
+ CHAR filename_with_path[STRLENGTH];
+#endif
+ WORD32 num_mem_recs;
+ iv_obj_t *ps_enc;
+ WORD32 i;
+ FILE *fp_cfg = NULL;
+
+#ifdef X86_MINGW
+
+ /* For getting printfs without any delay in eclipse */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+#endif
+
+ init_default_params(&s_app_ctxt);
+
+#ifndef IOS
+
+ /* Usage */
+ if(argc < 2)
+ {
+ printf("Using enc.cfg as configuration file \n");
+ strcpy(ac_cfg_fname, "enc.cfg");
+ }
+ else if(argc == 2)
+ {
+ if(!strcmp(argv[1], "--help"))
+ {
+ print_usage();
+ exit(-1);
+ }
+ strcpy(ac_cfg_fname, argv[1]);
+ }
+
+#else
+ strcpy(ac_cfg_fname, "test.cfg");
+
+#endif
+
+ /*************************************************************************/
+ /* Parse arguments */
+ /*************************************************************************/
+
+#ifndef IOS
+
+ /* Read command line arguments */
+ if(argc > 2)
+ {
+ for(i = 1; i + 1 < argc; i += 2)
+ {
+ if(CONFIG == get_argument(argv[i]))
+ {
+ strcpy(ac_cfg_fname, argv[i + 1]);
+ if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error);
+ }
+ read_cfg_file(&s_app_ctxt, fp_cfg);
+ fclose(fp_cfg);
+ }
+ else
+ {
+ parse_argument(&s_app_ctxt, argv[i], argv[i + 1]);
+ }
+ }
+ }
+ else
+ {
+ if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error);
+ }
+ read_cfg_file(&s_app_ctxt, fp_cfg);
+ fclose(fp_cfg);
+ }
+
+ alloc_rc_params(&s_app_ctxt);
+ init_default_rc_params(&s_app_ctxt);
+
+ if(argc > 2)
+ {
+ for(i = 1; i + 1 < argc; i += 2)
+ {
+ if(CONFIG == get_argument(argv[i]))
+ {
+ strcpy(ac_cfg_fname, argv[i + 1]);
+ if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error);
+ }
+ read_cfg_file_rc_params(&s_app_ctxt, fp_cfg);
+ fclose(fp_cfg);
+ }
+ else
+ {
+ parse_rc_argument(&s_app_ctxt, argv[i], argv[i + 1]);
+ }
+ }
+ }
+ else
+ {
+ if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error);
+ }
+ read_cfg_file_rc_params(&s_app_ctxt, fp_cfg);
+ fclose(fp_cfg);
+ }
+
+#else
+
+ sprintf(filename_with_path, "%s/%s", homedir, "enc.cfg");
+ if((fp_cfg = fopen(filename_with_path, "r")) == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error);
+ }
+ read_cfg_file(&s_app_ctxt, fp_cfg);
+ fclose(fp_cfg);
+
+#endif
+
+ validate_params(&s_app_ctxt);
+
+ s_app_ctxt.u4_max_wd = MAX(s_app_ctxt.u4_max_wd, s_app_ctxt.u4_wd);
+ s_app_ctxt.u4_max_ht = MAX(s_app_ctxt.u4_max_ht, s_app_ctxt.u4_ht);
+
+ /*************************************************************************/
+ /* Getting Number of MemRecords */
+ /*************************************************************************/
+ {
+ isvce_num_mem_rec_ip_t s_num_mem_rec_ip;
+ isvce_num_mem_rec_op_t s_num_mem_rec_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_GET_NUM_MEM_REC, ISVCE_CMD_CT_NA};
+
+ s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(isvce_num_mem_rec_ip_t);
+ s_num_mem_rec_op.s_ive_op.u4_size = sizeof(isvce_num_mem_rec_op_t);
+
+ status = isvce_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Get number of memory records failed = 0x%x\n",
+ s_num_mem_rec_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+
+ s_app_ctxt.u4_num_mem_rec = num_mem_recs = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec;
+ }
+
+ /* Allocate array to hold memory records */
+ s_app_ctxt.ps_mem_rec = (iv_mem_rec_t *) malloc(num_mem_recs * sizeof(iv_mem_rec_t));
+ if(NULL == s_app_ctxt.ps_mem_rec)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Unable to allocate memory for hold memory records: Size %d",
+ (WORD32) (num_mem_recs * sizeof(iv_mem_rec_t)));
+ codec_exit(ac_error);
+ }
+
+ {
+ iv_mem_rec_t *ps_mem_rec;
+ ps_mem_rec = s_app_ctxt.ps_mem_rec;
+ for(i = 0; i < num_mem_recs; i++)
+ {
+ ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
+ ps_mem_rec->pv_base = NULL;
+ ps_mem_rec->u4_mem_size = 0;
+ ps_mem_rec->u4_mem_alignment = 0;
+ ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
+
+ ps_mem_rec++;
+ }
+ }
+
+ /*************************************************************************/
+ /* Getting MemRecords Attributes */
+ /*************************************************************************/
+ {
+ isvce_fill_mem_rec_ip_t s_fill_mem_rec_ip;
+ isvce_fill_mem_rec_op_t s_fill_mem_rec_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_FILL_NUM_MEM_REC, ISVCE_CMD_CT_NA};
+
+ s_fill_mem_rec_ip.s_ive_ip.u4_size = sizeof(isvce_fill_mem_rec_ip_t);
+ s_fill_mem_rec_op.s_ive_op.u4_size = sizeof(isvce_fill_mem_rec_op_t);
+
+ s_fill_mem_rec_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec;
+ s_fill_mem_rec_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht;
+ s_fill_mem_rec_ip.u4_wd = s_app_ctxt.u4_wd;
+ s_fill_mem_rec_ip.u4_ht = s_app_ctxt.u4_ht;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level;
+ s_fill_mem_rec_ip.s_ive_ip.e_color_format = DEFAULT_INP_COLOR_FMT;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
+ s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
+ s_fill_mem_rec_ip.s_svc_inp_params.u1_num_temporal_layers =
+ s_app_ctxt.u1_num_temporal_layers;
+ s_fill_mem_rec_ip.s_svc_inp_params.u1_num_spatial_layers = s_app_ctxt.u1_num_spatial_layers;
+ s_fill_mem_rec_ip.s_svc_inp_params.d_spatial_res_ratio = s_app_ctxt.d_spatial_res_ratio;
+
+ status = isvce_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Fill memory records failed = 0x%x\n",
+ s_fill_mem_rec_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+ }
+
+ /*************************************************************************/
+ /* Allocating Memory for Mem Records */
+ /*************************************************************************/
+ {
+ WORD32 total_size;
+ iv_mem_rec_t *ps_mem_rec;
+ total_size = 0;
+
+ ps_mem_rec = s_app_ctxt.ps_mem_rec;
+ for(i = 0; i < num_mem_recs; i++)
+ {
+ ps_mem_rec->pv_base =
+ isvca_aligned_malloc(ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
+ if(ps_mem_rec->pv_base == NULL)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failure for mem record id %d size %d\n", i,
+ ps_mem_rec->u4_mem_size);
+ codec_exit(ac_error);
+ }
+ total_size += ps_mem_rec->u4_mem_size;
+
+ ps_mem_rec++;
+ }
+ printf("\nTotal memory for codec %d\n", total_size);
+ }
+
+ /*************************************************************************/
+ /* Codec Instance Creation */
+ /*************************************************************************/
+ {
+ isvce_init_ip_t s_init_ip;
+ isvce_init_op_t s_init_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_INIT, ISVCE_CMD_CT_NA};
+
+ ps_enc = s_app_ctxt.ps_mem_rec[0].pv_base;
+ ps_enc->u4_size = sizeof(iv_obj_t);
+ ps_enc->pv_fxns = isvce_api_function;
+ s_app_ctxt.ps_enc = ps_enc;
+
+ s_init_ip.pu4_max_bitrate =
+ isvca_aligned_malloc(16, sizeof(UWORD32) * s_app_ctxt.u1_num_spatial_layers);
+
+ s_init_ip.s_ive_ip.u4_size = sizeof(isvce_init_ip_t);
+ s_init_op.s_ive_op.u4_size = sizeof(isvce_init_op_t);
+
+ s_init_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec;
+ s_init_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec;
+ s_init_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd;
+ s_init_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht;
+ s_init_ip.u4_wd = s_app_ctxt.u4_wd;
+ s_init_ip.u4_ht = s_app_ctxt.u4_ht;
+ s_init_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
+ s_init_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
+ s_init_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level;
+ s_init_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt;
+
+ if(s_app_ctxt.u4_recon_enable || s_app_ctxt.u4_psnr_enable || s_app_ctxt.u4_chksum_enable)
+ {
+ s_init_ip.s_ive_ip.u4_enable_recon = 1;
+ }
+ else
+ {
+ s_init_ip.s_ive_ip.u4_enable_recon = 0;
+ }
+
+ s_init_ip.b_nalu_info_export_enable = !!s_app_ctxt.u4_nalu_info_export_enable;
+ s_init_ip.s_ive_ip.e_recon_color_fmt = s_app_ctxt.e_recon_color_fmt;
+ s_init_ip.s_ive_ip.e_rc_mode = s_app_ctxt.u4_rc;
+ s_init_ip.s_ive_ip.u4_max_framerate = s_app_ctxt.u4_max_frame_rate;
+ for(i = 0; i < s_app_ctxt.u1_num_spatial_layers; i++)
+ {
+ s_init_ip.pu4_max_bitrate[i] = s_app_ctxt.pu4_max_bitrate[i];
+ }
+ s_init_ip.s_ive_ip.u4_num_bframes = s_app_ctxt.u4_num_bframes;
+ s_init_ip.s_ive_ip.e_content_type = IV_PROGRESSIVE;
+ s_init_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
+ s_init_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
+ s_init_ip.s_ive_ip.e_slice_mode = s_app_ctxt.u4_slice_mode;
+ s_init_ip.s_ive_ip.u4_slice_param = s_app_ctxt.u4_slice_param;
+ s_init_ip.s_ive_ip.e_arch = s_app_ctxt.e_arch;
+ s_init_ip.s_ive_ip.e_soc = s_app_ctxt.e_soc;
+ s_init_ip.b_use_default_vui = s_app_ctxt.u4_use_default_vui;
+
+ s_init_ip.s_svc_inp_params.u1_num_temporal_layers = s_app_ctxt.u1_num_temporal_layers;
+ s_init_ip.s_svc_inp_params.u1_num_spatial_layers = s_app_ctxt.u1_num_spatial_layers;
+ s_init_ip.s_svc_inp_params.d_spatial_res_ratio = s_app_ctxt.d_spatial_res_ratio;
+
+ status = isvce_api_function(ps_enc, &s_init_ip, &s_init_op, &s_api_cmds);
+
+ isvca_aligned_free(s_init_ip.pu4_max_bitrate);
+
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Init memory records failed = 0x%x\n",
+ s_init_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+ }
+
+ /*************************************************************************/
+ /* set processor details */
+ /*************************************************************************/
+ {
+ isvce_ctl_set_num_cores_ip_t s_ctl_set_num_cores_ip;
+ isvce_ctl_set_num_cores_op_t s_ctl_set_num_cores_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_NUM_CORES};
+
+ s_ctl_set_num_cores_ip.s_ive_ip.u4_num_cores = s_app_ctxt.u4_num_cores;
+ s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_high = 0;
+ s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_low = 0;
+ s_ctl_set_num_cores_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_num_cores_ip_t);
+
+ s_ctl_set_num_cores_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_num_cores_op_t);
+
+ status = isvce_api_function(ps_enc, (void *) &s_ctl_set_num_cores_ip,
+ (void *) &s_ctl_set_num_cores_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to set processor params = 0x%x\n",
+ s_ctl_set_num_cores_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get Codec Version */
+ /*************************************************************************/
+ {
+ isvce_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip;
+ isvce_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op;
+
+ CHAR ac_version_string[STRLENGTH];
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETVERSION};
+
+ s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *) ac_version_string;
+ s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string);
+ s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getversioninfo_ip_t);
+ s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(isvce_ctl_getversioninfo_op_t);
+
+ status = isvce_api_function(ps_enc, (void *) &s_ctl_set_getversioninfo_ip,
+ (void *) &s_ctl_set_getversioninfo_op, &s_api_cmds);
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to get codec version = 0x%x\n",
+ s_ctl_set_getversioninfo_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+ printf("CODEC VERSION %s\n", ac_version_string);
+ }
+
+ /*************************************************************************/
+ /* Get I/O Buffer Requirement */
+ /*************************************************************************/
+ {
+ isvce_ctl_getbufinfo_ip_t s_get_buf_info_ip;
+ isvce_ctl_getbufinfo_op_t s_get_buf_info_op;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETBUFINFO};
+
+ s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getbufinfo_ip_t);
+ s_get_buf_info_op.s_ive_op.u4_size = sizeof(isvce_ctl_getbufinfo_op_t);
+
+ s_get_buf_info_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht;
+ s_get_buf_info_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd;
+ s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt;
+
+ status = isvce_api_function(ps_enc, &s_get_buf_info_ip, &s_get_buf_info_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Unable to get I/O buffer requirements = 0x%x\n",
+ s_get_buf_info_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+ s_app_ctxt.s_get_buf_info_op = s_get_buf_info_op;
+ }
+
+ /*****************************************************************************/
+ /* Add the following initializations based on the parameters in context */
+ /*****************************************************************************/
+
+ /*****************************************************************************/
+ /* Video control Set Frame dimensions */
+ /*****************************************************************************/
+ set_dimensions(&s_app_ctxt, 0, 0);
+ s_app_ctxt.u4_strd = s_app_ctxt.u4_wd;
+
+ /*****************************************************************************/
+ /* Video control Set Frame rates */
+ /*****************************************************************************/
+ set_frame_rate(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set IPE Params */
+ /*****************************************************************************/
+ set_ipe_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set Bitrate */
+ /*****************************************************************************/
+ set_bit_rate(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set QP */
+ /*****************************************************************************/
+ set_qp(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set AIR params */
+ /*****************************************************************************/
+ set_air_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set VBV params */
+ /*****************************************************************************/
+ set_vbv_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set Motion estimation params */
+ /*****************************************************************************/
+ set_me_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set GOP params */
+ /*****************************************************************************/
+ set_gop_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set Deblock params */
+ /*****************************************************************************/
+ set_deblock_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set Profile params */
+ /*****************************************************************************/
+ set_profile_params(&s_app_ctxt, 0, 0);
+
+ /*****************************************************************************/
+ /* Video control Set in Encode header mode */
+ /*****************************************************************************/
+ set_enc_mode(&s_app_ctxt, 0, 0, IVE_ENC_MODE_PICTURE);
+
+ /*****************************************************************************/
+ /* Video usability information */
+ /*****************************************************************************/
+ set_vui_params(&s_app_ctxt);
+
+#ifdef IOS
+ /* Correct file paths */
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_ip_fname);
+ strcpy(s_app_ctxt.ac_ip_fname, filename_with_path);
+
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_op_fname);
+ strcpy(s_app_ctxt.ac_op_fname, filename_with_path);
+
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_recon_fname);
+ strcpy(s_app_ctxt.ac_recon_fname, filename_with_path);
+
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_chksum_fname);
+ strcpy(s_app_ctxt.ac_chksum_fname, filename_with_path);
+
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_mb_info_fname);
+ strcpy(s_app_ctxt.ac_mb_info_fname, filename_with_path);
+
+ sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_pic_info_fname);
+ strcpy(s_app_ctxt.ac_pic_info_fname, filename_with_path);
+#endif
+
+ get_enc_dimensions(&s_app_ctxt);
+
+ /*************************************************************************/
+ /* begin encoding */
+ /*************************************************************************/
+
+ synchronous_encode(ps_enc, &s_app_ctxt);
+
+ {
+ printf("\nEncoding Completed\n");
+ printf("Summary\n");
+ printf("Input filename : %s\n", s_app_ctxt.ac_ip_fname);
+ printf("Output filename : %s\n", s_app_ctxt.ac_op_fname);
+ printf("Output Width : %-4d\n", s_app_ctxt.u4_wd);
+ printf("Output Height : %-4d\n", s_app_ctxt.u4_ht);
+
+ {
+ DOUBLE bytes_per_frame;
+ DOUBLE bytes_per_second;
+ WORD32 achieved_bitrate;
+ if(s_app_ctxt.u4_pics_cnt != 0)
+ {
+ bytes_per_frame = (s_app_ctxt.u4_total_bytes) / (s_app_ctxt.u4_pics_cnt);
+ }
+ else
+ {
+ bytes_per_frame = 0;
+ }
+ bytes_per_second = (bytes_per_frame * s_app_ctxt.u4_tgt_frame_rate);
+ achieved_bitrate = (WORD32) (bytes_per_second * 8);
+ printf("Target Bitrate (bps) : %-4d\n", s_app_ctxt.pu4_bitrate[0]);
+ printf("Achieved Bitrate (bps) : %-4d\n", achieved_bitrate);
+ }
+
+ printf("Average Time per Frame : %-4d\n", s_app_ctxt.avg_time);
+ printf("Achieved FPS : %-4.2f\n", 1000000.0 / s_app_ctxt.avg_time);
+ }
+
+ free_rc_params(&s_app_ctxt);
+
+ /*************************************************************************/
+ /* Close Codec Instance */
+ /*************************************************************************/
+ {
+ isvce_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
+ isvce_retrieve_mem_rec_op_t s_retrieve_mem_op;
+ iv_mem_rec_t *ps_mem_rec;
+
+ isvce_api_cmds_t s_api_cmds = {ISVCE_CMD_RETRIEVE_MEMREC, ISVCE_CMD_CT_NA};
+
+ s_retrieve_mem_ip.s_ive_ip.u4_size = sizeof(isvce_retrieve_mem_rec_ip_t);
+ s_retrieve_mem_op.s_ive_op.u4_size = sizeof(isvce_retrieve_mem_rec_op_t);
+
+ s_retrieve_mem_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec;
+
+ status = isvce_api_function(ps_enc, &s_retrieve_mem_ip, &s_retrieve_mem_op, &s_api_cmds);
+
+ if(status != IV_SUCCESS)
+ {
+ snprintf(ac_error, sizeof(ac_error) - 1, "Unable to retrieve memory records = 0x%x\n",
+ s_retrieve_mem_op.s_ive_op.u4_error_code);
+ codec_exit(ac_error);
+ }
+
+ /* Free memory records */
+ ps_mem_rec = s_app_ctxt.ps_mem_rec;
+ for(i = 0; i < num_mem_recs; i++)
+ {
+ isvca_aligned_free(ps_mem_rec->pv_base);
+ ps_mem_rec++;
+ }
+
+ free(s_app_ctxt.ps_mem_rec);
+ }
+
+ return 0;
+}
+
+#ifdef ANDROID_NDK
+int raise(int a)
+{
+ printf("Divide by zero\n");
+ return 0;
+}
+void __aeabi_assert(const char *assertion, const char *file, unsigned int line) {}
+#endif
diff --git a/test/svcenc/output.c b/test/svcenc/output.c
new file mode 100644
index 0000000..d124a2d
--- /dev/null
+++ b/test/svcenc/output.c
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "app.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+#define PEAK_WINDOW_SIZE 8
+/*****************************************************************************/
+/* Macros */
+/*****************************************************************************/
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+IV_STATUS_T write_output(FILE *fp, UWORD8 *pu1_buf, WORD32 num_bytes)
+{
+ WORD32 bytes;
+
+ bytes = (WORD32) fwrite(pu1_buf, sizeof(UWORD8), num_bytes, fp);
+ if(bytes != num_bytes) return IV_FAIL;
+ fflush(fp);
+
+ return IV_SUCCESS;
+}
+
+void allocate_output(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 i;
+ UWORD8 *pu1_buf;
+ WORD32 buf_size;
+ num_bufs =
+ MAX(DEFAULT_NUM_OUTPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs);
+ num_bufs = MIN(DEFAULT_MAX_OUTPUT_BUFS, num_bufs);
+
+ buf_size = ps_app_ctxt->s_get_buf_info_op.s_ive_op.au4_min_out_buf_size[0];
+ /* Memset the output buffer array to set is_free to 0 */
+ memset(ps_app_ctxt->as_output_buf, 0, sizeof(ps_app_ctxt->as_output_buf));
+
+ for(i = 0; i < num_bufs; i++)
+ {
+ pu1_buf = (UWORD8 *) isvca_aligned_malloc(16, buf_size);
+ if(NULL == pu1_buf)
+ {
+ CHAR ac_error[2 * STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for output buffer of size %d\n", buf_size);
+ codec_exit(ac_error);
+ }
+ ps_app_ctxt->as_output_buf[i].pu1_buf = pu1_buf;
+ ps_app_ctxt->as_output_buf[i].u4_buf_size = buf_size;
+ ps_app_ctxt->as_output_buf[i].u4_is_free = 1;
+ }
+}
+
+void free_output(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 i;
+
+ num_bufs =
+ MAX(DEFAULT_NUM_OUTPUT_BUFS, ps_app_ctxt->s_get_buf_info_op.s_ive_op.u4_min_out_bufs);
+ num_bufs = MIN(DEFAULT_MAX_OUTPUT_BUFS, num_bufs);
+ for(i = 0; i < num_bufs; i++)
+ {
+ isvca_aligned_free(ps_app_ctxt->as_output_buf[i].pu1_buf);
+ }
+}
diff --git a/test/svcenc/psnr.c b/test/svcenc/psnr.c
new file mode 100644
index 0000000..f207d23
--- /dev/null
+++ b/test/svcenc/psnr.c
@@ -0,0 +1,245 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "app.h"
+#include "psnr.h"
+
+/*****************************************************************************/
+/* */
+/* Function Name : init_psnr */
+/* */
+/* Description : Initialize PSNR for the Y, U, V component */
+/* */
+/* Inputs : */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : */
+/* */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 28 12 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void init_psnr(app_ctxt_t *ps_app_ctxt)
+{
+ ps_app_ctxt->adbl_psnr[0] = 0;
+ ps_app_ctxt->adbl_psnr[1] = 0;
+ ps_app_ctxt->adbl_psnr[2] = 0;
+ ps_app_ctxt->u4_psnr_cnt = 0;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : compute_psnr */
+/* */
+/* Description : Computes the PSNR for the Y, U, V component */
+/* */
+/* Inputs : */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : */
+/* */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 28 12 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t *ps_buf2)
+{
+ WORD32 i, j;
+ WORD32 comp;
+ DOUBLE df_psnr[3];
+ WORD32 wd, ht, strd1, strd2;
+ UWORD8 *pu1_buf1, *pu1_buf2;
+ WORD32 incr1, incr2;
+
+ printf("\nPicNum %4d\t ", ps_app_ctxt->u4_psnr_cnt);
+
+ for(comp = 0; comp < 3; comp++)
+ {
+ df_psnr[comp] = 0;
+ pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[comp];
+ pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[comp];
+ wd = ps_buf1->au4_wd[comp];
+ ht = ps_buf1->au4_ht[comp];
+ strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp];
+ strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp];
+ incr1 = 1;
+ incr2 = 1;
+
+ if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt) || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt))
+ {
+ switch(comp)
+ {
+ case 0:
+ pu1_buf1 = ps_buf1->apv_bufs[0];
+ break;
+ case 1:
+ if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
+ pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1];
+ else
+ pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1] + 1;
+ incr1 = 2;
+ wd = ps_buf1->au4_wd[0] >> 1;
+ ht = ps_buf1->au4_ht[0] >> 1;
+ break;
+ case 2:
+ if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
+ pu1_buf1 = (UWORD8 *) ps_buf1->apv_bufs[1] + 1;
+ else
+ pu1_buf1 = ps_buf1->apv_bufs[1];
+ incr1 = 2;
+ wd = ps_buf1->au4_wd[0] >> 1;
+ ht = ps_buf1->au4_ht[0] >> 1;
+ strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1];
+ break;
+ }
+ }
+ if((IV_YUV_420SP_UV == ps_buf2->e_color_fmt) || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt))
+ {
+ switch(comp)
+ {
+ case 0:
+ pu1_buf2 = ps_buf2->apv_bufs[0];
+ break;
+ case 1:
+ if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
+ pu1_buf2 = ps_buf2->apv_bufs[1];
+ else
+ pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[1] + 1;
+ incr2 = 2;
+ wd = ps_buf2->au4_wd[0] >> 1;
+ ht = ps_buf2->au4_ht[0] >> 1;
+
+ break;
+ case 2:
+ if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
+ pu1_buf2 = (UWORD8 *) ps_buf2->apv_bufs[1] + 1;
+ else
+ pu1_buf2 = ps_buf2->apv_bufs[1];
+ incr2 = 2;
+ wd = ps_buf2->au4_wd[0] >> 1;
+ ht = ps_buf2->au4_ht[0] >> 1;
+ strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1];
+
+ break;
+ }
+ }
+
+ for(i = 0; i < ht; i++)
+ {
+ for(j = 0; j < wd; j++)
+ {
+ WORD32 diff;
+ diff = (*pu1_buf1 - *pu1_buf2);
+ pu1_buf1 += incr1;
+ pu1_buf2 += incr2;
+ df_psnr[comp] += diff * diff;
+ }
+ pu1_buf1 += strd1;
+ pu1_buf2 += strd2;
+ }
+ df_psnr[comp] /= (wd * ht);
+ if(df_psnr[comp])
+ df_psnr[comp] = 20 * log10(255 / sqrt(df_psnr[comp]));
+ else
+ df_psnr[comp] = 100;
+
+ ps_app_ctxt->adbl_psnr[comp] += df_psnr[comp];
+ switch(comp)
+ {
+ case 0:
+ printf("Y :");
+ break;
+ case 1:
+ printf("U :");
+ break;
+ case 2:
+ printf("V :");
+ break;
+ default:
+ break;
+ }
+ printf("%2.2f\t", df_psnr[comp]);
+ }
+
+ ps_app_ctxt->u4_psnr_cnt++;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : print_average_psnr */
+/* */
+/* Description : Computes the average PSNR for the Y, U, V component */
+/* */
+/* Inputs : */
+/* */
+/* Globals : */
+/* */
+/* Processing : */
+/* */
+/* Outputs : */
+/* */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 28 12 2005 Ittiam Draft */
+/* */
+/*****************************************************************************/
+void print_average_psnr(app_ctxt_t *ps_app_ctxt)
+{
+ printf("\n");
+
+ printf("Avg PSNR Y : %-2.2f\n",
+ (ps_app_ctxt->adbl_psnr[0] / ps_app_ctxt->u4_psnr_cnt));
+ printf("Avg PSNR U : %-2.2f\n",
+ (ps_app_ctxt->adbl_psnr[1] / ps_app_ctxt->u4_psnr_cnt));
+ printf("Avg PSNR V : %-2.2f\n",
+ (ps_app_ctxt->adbl_psnr[2] / ps_app_ctxt->u4_psnr_cnt));
+}
diff --git a/test/svcenc/psnr.h b/test/svcenc/psnr.h
new file mode 100644
index 0000000..51082d2
--- /dev/null
+++ b/test/svcenc/psnr.h
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/****************************************************************************/
+/* */
+/* File Name : psnr.h */
+/* */
+/* Description : Contains functions for psnr computation */
+/* */
+/* List of Functions : */
+/* compute_psnr */
+/* print_average_psnr */
+/* Issues / Problems : */
+/* */
+/* Revision History : */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes) */
+/* */
+/****************************************************************************/
+#ifndef _SVCE_APP_PSNR_H_
+#define _SVCE_APP_PSNR_H_
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+void init_psnr(app_ctxt_t *ps_app_ctxt);
+
+void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t *ps_buf2);
+
+void print_average_psnr(app_ctxt_t *ps_app_ctxt);
+
+#if COMPUTE_PSNR
+
+#define GET_AVERAGE_PSNR_Y(print) print_average_psnr(print)
+
+#else /* COMPUTE_PSNR */
+
+#define GET_AVERAGE_PSNR_Y(print) 0
+
+#endif /* COMPUTE_PSNR */
+
+#endif
diff --git a/test/svcenc/recon.c b/test/svcenc/recon.c
new file mode 100644
index 0000000..c43d39e
--- /dev/null
+++ b/test/svcenc/recon.c
@@ -0,0 +1,215 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+/*****************************************************************************/
+/* File Includes */
+/*****************************************************************************/
+
+/* System include files */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+/* User include files */
+
+#include "ih264_typedefs.h"
+#include "iv2.h"
+#include "ive2.h"
+#include "isvce.h"
+#include "app.h"
+
+/*****************************************************************************/
+/* Constant Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Macros */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Function Declarations */
+/*****************************************************************************/
+
+IV_STATUS_T write_recon(FILE *fp, iv_raw_buf_t *ps_raw_buf)
+{
+ WORD32 bytes;
+ WORD32 wd, ht;
+ UWORD8 *pu1_buf;
+ WORD32 i;
+ WORD32 comp;
+ WORD32 num_comp;
+
+ num_comp = 2;
+ if(IV_YUV_420P == ps_raw_buf->e_color_fmt) num_comp = 3;
+
+ for(comp = 0; comp < num_comp; comp++)
+ {
+ wd = ps_raw_buf->au4_wd[comp];
+ ht = ps_raw_buf->au4_ht[comp];
+ pu1_buf = ps_raw_buf->apv_bufs[comp];
+ for(i = 0; i < ht; i++)
+ {
+ bytes = (WORD32) fwrite(pu1_buf, sizeof(UWORD8), wd, fp);
+ if(bytes != wd)
+ {
+ return (IV_FAIL);
+ }
+ pu1_buf += wd;
+ }
+ }
+
+ fflush(fp);
+ return IV_SUCCESS;
+}
+
+void allocate_recon(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 pic_size;
+ WORD32 luma_size;
+ WORD32 chroma_size;
+ WORD32 i;
+ UWORD8 *pu1_buf;
+
+ num_bufs = DEFAULT_NUM_RECON_BUFS;
+
+ assert(ps_app_ctxt->s_get_buf_info_op.u4_rec_comp_cnt == 3);
+
+ /* Size of buffer for YUV420/420SP */
+ luma_size = ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[0];
+ chroma_size = ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[1] +
+ ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[2];
+ pic_size = luma_size + chroma_size;
+
+ for(i = 0; i < num_bufs; i++)
+ {
+ pu1_buf = (UWORD8 *) isvca_aligned_malloc(16, pic_size);
+
+ if(NULL == pu1_buf)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for recon buffer of size %d\n", pic_size);
+ codec_exit(ac_error);
+ }
+
+ ps_app_ctxt->as_recon_buf[i].pu1_buf = pu1_buf;
+ ps_app_ctxt->as_recon_buf[i].u4_buf_size = pic_size;
+ ps_app_ctxt->as_recon_buf[i].u4_is_free = 1;
+ }
+
+ if(ps_app_ctxt->u4_psnr_enable)
+ {
+ pu1_buf = (UWORD8 *) isvca_aligned_malloc(16, pic_size);
+
+ if(NULL == pu1_buf)
+ {
+ CHAR ac_error[STRLENGTH];
+ snprintf(ac_error, sizeof(ac_error) - 1,
+ "Allocation failed for recon buffer of size %d\n", pic_size);
+ codec_exit(ac_error);
+ }
+
+ ps_app_ctxt->pu1_psnr_buf = pu1_buf;
+ ps_app_ctxt->u4_psnr_buf_size = pic_size;
+ }
+}
+
+void free_recon(app_ctxt_t *ps_app_ctxt)
+{
+ WORD32 num_bufs;
+ WORD32 i;
+
+ num_bufs = DEFAULT_NUM_RECON_BUFS;
+
+ for(i = 0; i < num_bufs; i++)
+ {
+ isvca_aligned_free(ps_app_ctxt->as_recon_buf[i].pu1_buf);
+ }
+
+ if(ps_app_ctxt->u4_psnr_enable)
+ {
+ isvca_aligned_free(ps_app_ctxt->pu1_psnr_buf);
+ }
+}
+
+void init_raw_buf_descr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_raw_buf, UWORD8 *pu1_buf,
+ IV_COLOR_FORMAT_T e_color_fmt)
+{
+ WORD32 luma_size;
+ WORD32 au4_chroma_sizes[2];
+
+ assert(IV_YUV_420P == e_color_fmt);
+
+ luma_size = ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[0];
+ au4_chroma_sizes[0] = ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[1];
+ au4_chroma_sizes[1] = ps_app_ctxt->s_get_buf_info_op.au4_min_rec_buf_size[2];
+
+ ps_raw_buf->apv_bufs[0] = pu1_buf;
+ pu1_buf += luma_size;
+
+ ps_raw_buf->apv_bufs[1] = pu1_buf;
+ pu1_buf += au4_chroma_sizes[0];
+
+ ps_raw_buf->apv_bufs[2] = NULL;
+ if(IV_YUV_420P == e_color_fmt)
+ {
+ ps_raw_buf->apv_bufs[2] = pu1_buf;
+ }
+
+ ps_raw_buf->e_color_fmt = e_color_fmt;
+ ps_raw_buf->au4_wd[0] = ps_app_ctxt->u4_enc_wd;
+ ps_raw_buf->au4_ht[0] = ps_app_ctxt->u4_enc_ht;
+ ps_raw_buf->au4_strd[0] = ps_app_ctxt->u4_enc_wd;
+
+ /* Initialize for 420SP */
+ {
+ ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_enc_wd;
+ ps_raw_buf->au4_wd[2] = 0;
+
+ ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_enc_ht / 2;
+ ps_raw_buf->au4_ht[2] = 0;
+
+ ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_enc_wd;
+ ps_raw_buf->au4_strd[2] = 0;
+ }
+
+ if(IV_YUV_420P == e_color_fmt)
+ {
+ ps_raw_buf->au4_wd[1] = ps_app_ctxt->u4_enc_wd / 2;
+ ps_raw_buf->au4_wd[2] = ps_app_ctxt->u4_enc_wd / 2;
+
+ ps_raw_buf->au4_ht[1] = ps_app_ctxt->u4_enc_ht / 2;
+ ps_raw_buf->au4_ht[2] = ps_app_ctxt->u4_enc_ht / 2;
+
+ ps_raw_buf->au4_strd[1] = ps_app_ctxt->u4_enc_wd / 2;
+ ps_raw_buf->au4_strd[2] = ps_app_ctxt->u4_enc_wd / 2;
+ }
+ /* If stride is not initialized, then use width as stride */
+ if(0 == ps_raw_buf->au4_strd[0])
+ {
+ ps_raw_buf->au4_strd[0] = ps_raw_buf->au4_wd[0];
+ ps_raw_buf->au4_strd[1] = ps_raw_buf->au4_wd[1];
+ ps_raw_buf->au4_strd[2] = ps_raw_buf->au4_wd[2];
+ }
+
+ ps_raw_buf->u4_size = sizeof(iv_raw_buf_t);
+}
diff --git a/test/svcenc/svcenc.cmake b/test/svcenc/svcenc.cmake
new file mode 100644
index 0000000..0ea599f
--- /dev/null
+++ b/test/svcenc/svcenc.cmake
@@ -0,0 +1,12 @@
+list(
+ APPEND
+ SVCENC_SRCS
+ "${AVC_ROOT}/test/svcenc/main.c"
+ "${AVC_ROOT}/test/svcenc/input.c"
+ "${AVC_ROOT}/test/svcenc/output.c"
+ "${AVC_ROOT}/test/svcenc/psnr.c"
+ "${AVC_ROOT}/test/svcenc/recon.c")
+
+libavc_add_executable(svcenc libsvcenc SOURCES ${SVCENC_SRCS} INCLUDES
+ "${AVC_ROOT}/test/svcenc/")
+target_compile_definitions(svcenc PRIVATE PROFILE_ENABLE MD5_DISABLE)