diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:51:41 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:51:41 +0000 |
commit | 540d27a2de23560cc382f87769b14f2916c555f4 (patch) | |
tree | e24bd4baf4dd84f3fc623805b221f96e03f5d119 | |
parent | 4a8de53b16cb0df3061b942b183c1c3da641001b (diff) | |
parent | d33677ac9e7ec4f9152cbfe28d04bd22e363f2e2 (diff) | |
download | libhevc-540d27a2de23560cc382f87769b14f2916c555f4.tar.gz |
Snap for 10453563 from d33677ac9e7ec4f9152cbfe28d04bd22e363f2e2 to mainline-media-releaseaml_med_341011000aml_med_340922010
Change-Id: I8d9d663c8319b320f0f5e5ef9536bb407f33937d
25 files changed, 1025 insertions, 294 deletions
@@ -401,6 +401,16 @@ cc_library_static { "common/x86/ihevc_tables_x86_intr.c", ], }, + riscv64: { + local_include_dirs: [ + "common/riscv64", + ], + + srcs: [ + "decoder/riscv64/ihevcd_function_selector.c", + "decoder/riscv64/ihevcd_function_selector_generic.c", + ], + }, }, sanitize: { @@ -786,6 +796,11 @@ cc_library_static { ], }, + riscv64: { + local_include_dirs: [ + "common/riscv64", + ], + }, }, sanitize: { integer_overflow: true, diff --git a/FrameInfo.md b/FrameInfo.md new file mode 100755 index 0000000..618e1aa --- /dev/null +++ b/FrameInfo.md @@ -0,0 +1,21 @@ +## Frame Info exported from libHEVC + +### Introduction +QP and CU type maps for H265 are defined for each 8x8 coding unit. +The QP values defined as unsigned 8-bit numbers can range from <1, 51> and CU type can be +INTER/INTRA/SKIP. HEVC defines them in ihevc_defs.h as PRED_MODE_INTER = 0, PRED_MODE_INTRA = 1 +and PRED_MODE_SKIP = 2. +Set the “u4_frame_info_enable” flag to enable encoder/decoder to populate and return the qp values +and CU type data in its output structure ihevcd_cxa_video_decode_op_t via pu1_8x8_blk_qp_map and +pu1_8x8_blk_type_map. + +### Mapping to the frame +Within a video sequence, CTUs of a fixed size (16x16, 32x32, or 64x64) can be further divided into +CUs of size as low as 8x8 pixels. A CU’s number of QP entries (each for 8x8 blocks) can range from +1 to 64. A frame with a resolution of WdxHt has a total of (align8(Wd) x align8(Ht)) / 64 entries +for QP and CU type map each. Qp and CU type values for each 8x8 block are stored in raster scan +order. Refer to ihevcd_cxa.h for details. + +### Plugin/Application +The encoder/decoder keeps the QP and CU type map as a part of its output handle. The plugins can +access these data through the output structure. @@ -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) 2012, Ittiam Systems Pvt Ltd, Bangalore + + 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. @@ -1,3 +1,16 @@ +name: "libhevc" +description: "Android fork of the libhevc library." + third_party { + url { + type: GIT + value: "https://github.com/ittiam-systems/libhevc.git" + } + version: "a3cac8c9d79968772272fff97a98d4edaf3132c1" license_type: NOTICE + last_upgrade_date { + year: 2023 + month: 03 + day: 04 + } } diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 57b939f..1476f19 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -32,8 +32,6 @@ endfunction() # Adds defintions for all targets function(libhevc_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/ivd.h b/common/ivd.h index a3dae2d..6e08f91 100644 --- a/common/ivd.h +++ b/common/ivd.h @@ -67,7 +67,8 @@ typedef enum ARCH_X86_SSE42, ARCH_X86_AVX2, ARCH_MIPS_GENERIC = 0x200, - ARCH_MIPS_32 + ARCH_MIPS_32, + ARCH_RISCV64_GENERIC = 0x400, }IVD_ARCH_T; /* IVD_SOC_T: SOC Enumeration */ diff --git a/common/mips/ihevc_platform_macros.h b/common/mips/ihevc_platform_macros.h deleted file mode 100644 index d94a3f4..0000000 --- a/common/mips/ihevc_platform_macros.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -* -* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore -* -* 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. -* -******************************************************************************/ -/** -******************************************************************************* -* @file -* ihevc_platform_macros.h -* -* @brief -* Platform specific Macro definitions used in the codec -* -* @author -* Ittiam -* -* @remarks -* None -* -******************************************************************************* -*/ -#ifndef _IHEVC_PLATFORM_MACROS_H_ -#define _IHEVC_PLATFORM_MACROS_H_ - - -#define CLIP_U8(x) CLIP3((x), 0, 255) -#define CLIP_S8(x) CLIP3((x), -128, 127) - -#define CLIP_U10(x) CLIP3((x), 0, 1023); -#define CLIP_S10(x) CLIP3((x), -512, 511); - -#define CLIP_U12(x) CLIP3((x), 0, 4095); -#define CLIP_S12(x) CLIP3((x), -2048, 2047); - -#define CLIP_U16(x) CLIP3((x), 0, 65535) -#define CLIP_S16(x) CLIP3((x), -32768, 32767) - -#define ITT_BIG_ENDIAN(x) ((x << 24)) | \ - ((x & 0x0000ff00) << 8) | \ - ((x & 0x00ff0000) >> 8) | \ - ((UWORD32)x >> 24); - -#define SHL(x,y) (((y) < 32) ? ((x) << (y)) : 0) -#define SHR(x,y) (((y) < 32) ? ((x) >> (y)) : 0) - -#define SHR_NEG(val,shift) ((shift>0)?(val>>shift):(val<<(-shift))) -#define SHL_NEG(val,shift) ((shift<0)?(val>>(-shift)):(val<<shift)) - -static inline UWORD32 CLZ(UWORD32 u4_word) -{ - if(u4_word) - return (__builtin_clz(u4_word)); - else - return 31; -} - -static inline UWORD32 CLZNZ(UWORD32 u4_word) -{ - return (__builtin_clz(u4_word)); -} - -static inline UWORD32 CTZ(UWORD32 u4_word) -{ - if(0 == u4_word) - return 31; - else - { - unsigned int index; - index = __builtin_ctz(u4_word); - return (UWORD32)index; - } -} - -#define POPCNT_U32(x) __builtin_popcount(x) - -#define NOP(nop_cnt) {UWORD32 nop_i; for (nop_i = (nop_cnt) ; nop_i > 0 ; nop_i--) asm("nop");} - -#define INLINE - -#define MEM_ALIGN8 __attribute__ ((aligned (8))) -#define MEM_ALIGN16 __attribute__ ((aligned (16))) -#define MEM_ALIGN32 __attribute__ ((aligned (32))) - -#define DATA_SYNC() __sync_synchronize() - -#endif /* _IHEVC_PLATFORM_MACROS_H_ */ diff --git a/common/mips/ihevc_func_selector.h b/common/riscv64/ihevc_func_selector.h index 8188178..20a5a66 100644 --- a/common/mips/ihevc_func_selector.h +++ b/common/riscv64/ihevc_func_selector.h @@ -89,7 +89,7 @@ #define SAO_EDGE_OFFSET_CLASS3_CHROMA C #define INTRA_PRED_LUMA_REF_SUBSTITUTION C -#define INTRA_PRED_REF_FILTERING C +#define INTRA_PRED_REF_FILTERING C #define INTRA_PRED_LUMA_PLANAR C #define INTRA_PRED_LUMA_DC C #define INTRA_PRED_LUMA_HORZ C @@ -152,21 +152,21 @@ #define QUANT_32X32 C /* Chroma interleaved*/ -#define CHROMA_RESI_TRANS_QUANT_4X4 C -#define CHROMA_RESI_TRANS_QUANT_8X8 C -#define CHROMA_RESI_TRANS_QUANT_16X16 C +#define CHROMA_RESI_TRANS_QUANT_4X4 C +#define CHROMA_RESI_TRANS_QUANT_8X8 C +#define CHROMA_RESI_TRANS_QUANT_16X16 C -#define CHROMA_RESI_QUANT_4X4 C -#define CHROMA_RESI_QUANT_8X8 C -#define CHROMA_RESI_QUANT_16X16 C +#define CHROMA_RESI_QUANT_4X4 C +#define CHROMA_RESI_QUANT_8X8 C +#define CHROMA_RESI_QUANT_16X16 C -#define CHROMA_RESI_TRANS_4X4 C -#define CHROMA_RESI_TRANS_8X8 C -#define CHROMA_RESI_TRANS_16X16 C +#define CHROMA_RESI_TRANS_4X4 C +#define CHROMA_RESI_TRANS_8X8 C +#define CHROMA_RESI_TRANS_16X16 C -#define CHROMA_RESI_4X4 C -#define CHROMA_RESI_8X8 C -#define CHROMA_RESI_16X16 C +#define CHROMA_RESI_4X4 C +#define CHROMA_RESI_8X8 C +#define CHROMA_RESI_16X16 C /* Inverse transform functions */ /* Luma */ @@ -201,21 +201,21 @@ #define ITRANS_32X32 C /* Chroma interleaved */ -#define CHROMA_IQUANT_ITRANS_RECON_4X4 C -#define CHROMA_IQUANT_ITRANS_RECON_8X8 C -#define CHROMA_IQUANT_ITRANS_RECON_16X16 C +#define CHROMA_IQUANT_ITRANS_RECON_4X4 C +#define CHROMA_IQUANT_ITRANS_RECON_8X8 C +#define CHROMA_IQUANT_ITRANS_RECON_16X16 C -#define CHROMA_IQUANT_RECON_4X4 C -#define CHROMA_IQUANT_RECON_8X8 C -#define CHROMA_IQUANT_RECON_16X16 C +#define CHROMA_IQUANT_RECON_4X4 C +#define CHROMA_IQUANT_RECON_8X8 C +#define CHROMA_IQUANT_RECON_16X16 C -#define CHROMA_ITRANS_RECON_4X4 C -#define CHROMA_ITRANS_RECON_8X8 C -#define CHROMA_ITRANS_RECON_16X16 C +#define CHROMA_ITRANS_RECON_4X4 C +#define CHROMA_ITRANS_RECON_8X8 C +#define CHROMA_ITRANS_RECON_16X16 C -#define CHROMA_RECON_4X4 C -#define CHROMA_RECON_8X8 C -#define CHROMA_RECON_16X16 C +#define CHROMA_RECON_4X4 C +#define CHROMA_RECON_8X8 C +#define CHROMA_RECON_16X16 C #define IHEVC_MEMCPY C #define IHEVC_MEMSET C diff --git a/common/riscv64/ihevc_platform_macros.h b/common/riscv64/ihevc_platform_macros.h new file mode 100644 index 0000000..41d20ca --- /dev/null +++ b/common/riscv64/ihevc_platform_macros.h @@ -0,0 +1,174 @@ +/****************************************************************************** +* +* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore +* +* 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. +* +******************************************************************************/ +/** +******************************************************************************* +* @file +* ihevc_platform_macros.h +* +* @brief +* Platform specific Macro definitions used in the codec +* +* @author +* Ittiam +* +* @remarks +* None +* +******************************************************************************* +*/ +#ifndef _IHEVC_PLATFORM_MACROS_H_ +#define _IHEVC_PLATFORM_MACROS_H_ + +#define CLIP_U8(x) CLIP3((x), 0, 255) +#define CLIP_S8(x) CLIP3((x), -128, 127) + +#define CLIP_U10(x) CLIP3((x), 0, 1023); +#define CLIP_S10(x) CLIP3((x), -512, 511); + +#define CLIP_U12(x) CLIP3((x), 0, 4095); +#define CLIP_S12(x) CLIP3((x), -2048, 2047); + +#define CLIP_U14(x) CLIP3((x), 0, 16383); +#define CLIP_S14(x) CLIP3((x), -8192, 8191); + +#define CLIP_U16(x) CLIP3((x), 0, 65535) +#define CLIP_S16(x) CLIP3((x), -32768, 32767) + +#define ITT_BIG_ENDIAN(x) ((x & 0x000000ff) << 24) | \ + ((x & 0x0000ff00) << 8) | \ + ((x & 0x00ff0000) >> 8) | \ + ((UWORD32)x >> 24); + +#define SHL(x,y) (((y) < 32) ? ((x) << (y)) : 0) +#define SHR(x,y) (((y) < 32) ? ((x) >> (y)) : 0) + +#define SHR_NEG(val,shift) ((shift>0)?(val>>shift):(val<<(-shift))) +#define SHL_NEG(val,shift) ((shift<0)?(val>>(-shift)):(val<<shift)) + +#define INLINE inline + +#define POPCNT_U32(x) __builtin_popcount(x) + +static INLINE UWORD32 CLZ(UWORD32 u4_word) +{ + if(u4_word) + return (__builtin_clz(u4_word)); + else + return 31; +} + +static INLINE UWORD32 CLZNZ(UWORD32 u4_word) +{ + return (__builtin_clz(u4_word)); +} + +static INLINE UWORD32 CTZ(UWORD32 u4_word) +{ + if(0 == u4_word) + return 31; + else + { + unsigned int index; + index = __builtin_ctz(u4_word); + return (UWORD32)index; + } +} + +#define DATA_SYNC() __sync_synchronize() + +/** +****************************************************************************** + * @brief returns postion of msb bit for 32bit input +****************************************************************************** + */ +#define GET_POS_MSB_32(r,word) \ +{ \ + if(word) \ + { \ + r = 31 - __builtin_clz(word); \ + } \ + else \ + { \ + r = -1; \ + } \ +} + +/** +****************************************************************************** + * @brief returns postion of msb bit for 64bit input +****************************************************************************** + */ +#define GET_POS_MSB_64(r,word) \ +{ \ + if(word) \ + { \ + r = 63 - __builtin_clzll(word); \ + } \ + else \ + { \ + r = -1; \ + } \ +} + + +/** +****************************************************************************** + * @brief returns max number of bits required to represent input word (max 32bits) +****************************************************************************** + */ +#define GETRANGE(r,word) \ +{ \ + if(word) \ + { \ + r = 32 - __builtin_clz(word); \ + } \ + else \ + { \ + r = 1; \ + } \ +} + + +/** +***************************************************************************************************** +* @brief returns max number of bits required to represent input unsigned long long word (max 64bits) +***************************************************************************************************** +*/ +#define GETRANGE64(r,llword) \ +{ \ + if(llword) \ + { \ + r = 64 - __builtin_clzll(llword); \ + } \ + else \ + { \ + r = 1; \ + } \ +} + + + +#define NOP(nop_cnt) {UWORD32 nop_i; for (nop_i = 0; nop_i < nop_cnt; nop_i++) asm("nop");} + + + +#define MEM_ALIGN8 __attribute__ ((aligned (8))) +#define MEM_ALIGN16 __attribute__ ((aligned (16))) +#define MEM_ALIGN32 __attribute__ ((aligned (32))) + +#endif /* _IHEVC_PLATFORM_MACROS_H_ */ diff --git a/decoder/ihevcd_api.c b/decoder/ihevcd_api.c index d8ee57d..031808d 100644 --- a/decoder/ihevcd_api.c +++ b/decoder/ihevcd_api.c @@ -417,8 +417,7 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, if(ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ihevcd_cxa_video_decode_ip_t) && ps_ip->s_ivd_video_decode_ip_t.u4_size - != offsetof(ivd_video_decode_ip_t, - s_out_buffer)) + != sizeof(ivd_video_decode_ip_t)) { ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; @@ -430,8 +429,7 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, if(ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ihevcd_cxa_video_decode_op_t) && ps_op->s_ivd_video_decode_op_t.u4_size - != offsetof(ivd_video_decode_op_t, - u4_output_present)) + != sizeof(ivd_video_decode_op_t)) { ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; @@ -440,6 +438,16 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, return (IV_FAIL); } + if(((codec_t *)(ps_handle->pv_codec_handle))->u1_enable_cu_info + && !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 |= + IHEVCD_FRAME_INFO_OP_BUF_NULL; + return (IV_FAIL); + } + } break; @@ -494,7 +502,9 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op; if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size - != sizeof(ihevcd_cxa_ctl_set_config_ip_t)) + != sizeof(ihevcd_cxa_ctl_set_config_ip_t) && + ps_ip->s_ivd_ctl_set_config_ip_t.u4_size + != sizeof(ivd_ctl_set_config_ip_t)) { ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; @@ -1196,6 +1206,11 @@ WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj, ps_codec->i4_share_disp_buf = 0; } + if (ps_create_ip->s_ivd_create_ip_t.u4_size == sizeof(ihevcd_cxa_create_ip_t)) + { + ps_codec->u1_enable_cu_info = ps_create_ip->u4_enable_frame_info; + } + ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format; ps_codec->pf_aligned_alloc = pf_aligned_alloc; @@ -1906,7 +1921,7 @@ WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec) qp_const_flag_size /= 8; /* QP changes at CU level - So store at 8x8 level */ - num_8x8 = (ht * wd) / (MIN_CU_SIZE * MIN_CU_SIZE); + num_8x8 = (wd * ht) / (MIN_CU_SIZE * MIN_CU_SIZE); qp_size = num_8x8; /* To hold vertical boundary strength */ @@ -2019,6 +2034,22 @@ WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec) memset(pv_buf, 0, size); ps_codec->pv_tu_data = pv_buf; + /* CU info map to store qp and CU type at 8x8 level */ + if(ps_codec->u1_enable_cu_info) + { + size = ((wd * ht) / (MIN_CU_SIZE * MIN_CU_SIZE)) * BUF_MGR_MAX_CNT; + + pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + ps_codec->pu1_qp_map_base = pv_buf; + + pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + ps_codec->pu1_cu_type_map_base = pv_buf; + } + { sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); @@ -2141,6 +2172,11 @@ WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec) ALIGNED_FREE(ps_codec, ps_codec->pv_mv_bank_buf_base); ALIGNED_FREE(ps_codec, ps_codec->pu1_ref_pic_buf_base); ALIGNED_FREE(ps_codec, ps_codec->pu1_cur_chroma_ref_buf); + if(ps_codec->u1_enable_cu_info) + { + ALIGNED_FREE(ps_codec, ps_codec->pu1_qp_map_base); + ALIGNED_FREE(ps_codec, ps_codec->pu1_cu_type_map_base); + } ps_codec->u4_allocate_dynamic_done = 0; return IV_SUCCESS; diff --git a/decoder/ihevcd_cxa.h b/decoder/ihevcd_cxa.h index f81a7eb..7baf480 100644 --- a/decoder/ihevcd_cxa.h +++ b/decoder/ihevcd_cxa.h @@ -130,6 +130,16 @@ typedef enum { IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC, /** + * Frame info output buffer null + */ + IHEVCD_FRAME_INFO_OP_BUF_NULL, + + /** + * Frame info insufficient buffer + */ + IHEVCD_INSUFFICIENT_METADATA_BUFFER, + + /** * Generic failure */ IHEVCD_FAIL = 0x7FFFFFFF @@ -161,6 +171,11 @@ typedef struct { typedef struct { ivd_create_ip_t s_ivd_create_ip_t; + + /** + * enable_frm_info + */ + UWORD32 u4_enable_frame_info; }ihevcd_cxa_create_ip_t; @@ -178,8 +193,60 @@ typedef struct { * ivd_video_decode_ip_t */ ivd_video_decode_ip_t s_ivd_video_decode_ip_t; + + /** + * 8x8 block QP map + */ + UWORD8 *pu1_8x8_blk_qp_map; + + /** + * 8x8 block type map + */ + UWORD8 *pu1_8x8_blk_type_map; + + /** + * 8x8 block QP map size + */ + UWORD32 u4_8x8_blk_qp_map_size; + + /** + * 8x8 block type map size + */ + UWORD32 u4_8x8_blk_type_map_size; }ihevcd_cxa_video_decode_ip_t; +/*********************************************************************************/ +/* QP and CU/Block type maps are defined for each 8x8 coding unit. */ +/* QP can range from <1, 51> and block type can be INTER/INTRA/SKIP. */ +/* */ +/* A frame with a resolution of WdxHt has a total of */ +/* (align8(Wd) x align8(Ht)) / 64 entries for QP and Block type map each. */ +/* */ +/* For example, for a frame of size 60x60 shown in the figure down, both */ +/* maps (QP and Block 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 { @@ -187,6 +254,26 @@ typedef struct { * ivd_video_decode_op_t */ ivd_video_decode_op_t s_ivd_video_decode_op_t; + + /** + * 8x8 block QP map + */ + UWORD8 *pu1_8x8_blk_qp_map; + + /** + * 8x8 block type map + */ + UWORD8 *pu1_8x8_blk_type_map; + + /** + * 8x8 block QP map size + */ + UWORD32 u4_8x8_blk_qp_map_size; + + /** + * 8x8 block type map size + */ + UWORD32 u4_8x8_blk_type_map_size; }ihevcd_cxa_video_decode_op_t; diff --git a/decoder/ihevcd_decode.c b/decoder/ihevcd_decode.c index 1eabb3b..d9ee1c0 100644 --- a/decoder/ihevcd_decode.c +++ b/decoder/ihevcd_decode.c @@ -183,10 +183,20 @@ static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error) ******************************************************************************* */ static void ihevcd_fill_outargs(codec_t *ps_codec, - ivd_video_decode_ip_t *ps_dec_ip, - ivd_video_decode_op_t *ps_dec_op) + void *pv_api_ip, + void *pv_api_op) { + ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip; + ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op; + ivd_video_decode_ip_t *ps_dec_ip; + ivd_video_decode_op_t *ps_dec_op; + + ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip; + ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op; + ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t; + ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t; + ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code); ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes - ps_codec->i4_bytes_remaining; @@ -353,6 +363,47 @@ static void ihevcd_fill_outargs(codec_t *ps_codec, ps_codec->i4_flush_mode = 0; } + if(ps_codec->u1_enable_cu_info && ps_dec_op->u4_output_present) + { + WORD32 info_map_dst_strd = ALIGN8(ps_codec->i4_wd) >> 3; + WORD32 info_map_src_strd = ALIGN64(ps_codec->i4_wd) >> 3; + WORD32 info_map_ht = ALIGN8(ps_codec->i4_ht); + UWORD32 info_map_size = (ALIGN8(ps_codec->i4_wd) * info_map_ht) >> 6; + WORD32 vert_8x8; + UWORD8 *pu1_out_qp_map, *pu1_qp_map; + UWORD8 *pu1_out_blk_type_map, *pu1_type_map; + + if(ps_hevcd_dec_ip->pu1_8x8_blk_qp_map) + { + ps_hevcd_dec_op->pu1_8x8_blk_qp_map = ps_hevcd_dec_ip->pu1_8x8_blk_qp_map; + ps_hevcd_dec_op->u4_8x8_blk_qp_map_size = info_map_size; + + pu1_out_qp_map = ps_hevcd_dec_op->pu1_8x8_blk_qp_map; + pu1_qp_map = ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_qp_map; + for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++) + { + memcpy(pu1_out_qp_map, pu1_qp_map, info_map_dst_strd); + pu1_out_qp_map += info_map_dst_strd; + pu1_qp_map += info_map_src_strd; + } + } + + if(ps_hevcd_dec_ip->pu1_8x8_blk_type_map) + { + ps_hevcd_dec_op->pu1_8x8_blk_type_map = ps_hevcd_dec_ip->pu1_8x8_blk_type_map; + ps_hevcd_dec_op->u4_8x8_blk_type_map_size = info_map_size; + + pu1_out_blk_type_map = ps_hevcd_dec_op->pu1_8x8_blk_type_map; + pu1_type_map = + ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_cu_type_map; + for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++) + { + memcpy(pu1_out_blk_type_map, pu1_type_map, info_map_dst_strd); + pu1_out_blk_type_map += info_map_dst_strd; + pu1_type_map += info_map_src_strd; + } + } + } } /** @@ -387,6 +438,9 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) { WORD32 ret = IV_SUCCESS; codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); + ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {}; + ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip; + ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op; ivd_video_decode_ip_t *ps_dec_ip; ivd_video_decode_op_t *ps_dec_op; @@ -399,11 +453,18 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_codec->i4_bytes_remaining = 0; ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; - ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; + memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size); + s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t); + + ps_hevcd_dec_ip = &s_hevcd_dec_ip; + ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t; + + ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op; + ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t; { UWORD32 u4_size = ps_dec_op->u4_size; - memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t)); + memset(ps_hevcd_dec_op, 0, u4_size); ps_dec_op->u4_size = u4_size; //Restore size field } if(ps_codec->i4_init_done != 1) @@ -420,6 +481,21 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) return IV_FAIL; } + if(ps_codec->u1_enable_cu_info && ps_codec->i4_sps_done) + { + UWORD32 blk_qp_map_size = ps_hevcd_dec_ip->u4_8x8_blk_qp_map_size; + UWORD32 blk_type_map_size = ps_hevcd_dec_ip->u4_8x8_blk_type_map_size; + UWORD32 blk_8x8_map_size = (ALIGN8(ps_codec->i4_wd) * ALIGN8(ps_codec->i4_ht)) >> 6; + + if ((ps_hevcd_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) || + (ps_hevcd_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 |= IHEVCD_INSUFFICIENT_METADATA_BUFFER; + return IV_FAIL; + } + } + /* If reset flag is set, flush the existing buffers */ if(ps_codec->i4_reset_flag) { @@ -532,7 +608,7 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_codec->i4_disp_buf_id, BUF_MGR_DISP); } - ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op); + ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op); if(1 == ps_dec_op->u4_output_present) { @@ -936,7 +1012,7 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) /* Increment the number of pictures decoded */ ps_codec->u4_pic_cnt++; } - ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op); + ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op); if(1 == ps_dec_op->u4_output_present) { diff --git a/decoder/ihevcd_defs.h b/decoder/ihevcd_defs.h index 0dea27c..47fff65 100644 --- a/decoder/ihevcd_defs.h +++ b/decoder/ihevcd_defs.h @@ -102,6 +102,11 @@ */ #define MAX_REF_CNT 32 +/** + * Maximum number of CU info buffers + */ +#define MAX_CU_INFO_BUF_CNT MAX_REF_CNT + /*****************************************************************************/ /* Num cores releated defs */ /*****************************************************************************/ diff --git a/decoder/ihevcd_parse_headers.c b/decoder/ihevcd_parse_headers.c index f70e150..0ce1b27 100644 --- a/decoder/ihevcd_parse_headers.c +++ b/decoder/ihevcd_parse_headers.c @@ -1943,6 +1943,7 @@ IHEVCD_ERROR_T ihevcd_parse_sps(codec_t *ps_codec) ps_codec->i4_wd = ps_sps->i2_pic_width_in_luma_samples; ps_codec->i4_ht = ps_sps->i2_pic_height_in_luma_samples; + ps_codec->u4_num_8x8_blks = ALIGN64(ps_codec->i4_wd) * ALIGN64(ps_codec->i4_ht) >> 6; { WORD32 ref_strd; diff --git a/decoder/ihevcd_parse_slice.c b/decoder/ihevcd_parse_slice.c index a3e1e69..d6f74f9 100644 --- a/decoder/ihevcd_parse_slice.c +++ b/decoder/ihevcd_parse_slice.c @@ -1851,6 +1851,7 @@ IHEVCD_ERROR_T ihevcd_parse_coding_quadtree(codec_t *ps_codec, } else { + WORD32 qp = ps_codec->s_parse.u4_qp; /* Set current group QP if current CU is aligned with the group */ { WORD32 cu_pos_x = ps_codec->s_parse.s_cu.i4_pos_x << 3; @@ -1880,7 +1881,6 @@ IHEVCD_ERROR_T ihevcd_parse_coding_quadtree(codec_t *ps_codec, WORD32 qpg_x; WORD32 qpg_y; WORD32 i, j; - WORD32 qp; WORD32 cur_cu_offset; tu_t *ps_tu = ps_codec->s_parse.ps_tu; WORD32 cb_size = 1 << ps_codec->s_parse.s_cu.i4_log2_cb_size; @@ -1942,6 +1942,32 @@ IHEVCD_ERROR_T ihevcd_parse_coding_quadtree(codec_t *ps_codec, } } + /* Populate CU_info maps for current CU*/ + if(ps_codec->u1_enable_cu_info) + { + WORD32 cu_info_map_stride = ALIGN64(ps_codec->i4_wd) >> 3; + UWORD8 num_8x8_blks = 1 << (log2_cb_size - 3); + WORD32 vert_8x8, horz_8x8; + UWORD8 *pu1_cur_cu_type_map = + ps_codec->as_buf_id_info_map[ps_codec->as_process[0]. + i4_cur_pic_buf_id].pu1_cu_type_map; + UWORD8 *pu1_cur_qp_map = + ps_codec->as_buf_id_info_map[ps_codec->as_process[0].i4_cur_pic_buf_id].pu1_qp_map; + UWORD8 *pu1_cur_type_cu = pu1_cur_cu_type_map + (x0 >> 3) + + (y0 >> 3) * cu_info_map_stride; + UWORD8 *pu1_cur_qp_cu = pu1_cur_qp_map + (x0 >> 3) + + (y0 >> 3) * cu_info_map_stride; + for(vert_8x8 = 0; vert_8x8 < num_8x8_blks; vert_8x8++) + { + for(horz_8x8 = 0; horz_8x8 < num_8x8_blks; horz_8x8++) + { + pu1_cur_qp_cu[horz_8x8] = qp; + pu1_cur_type_cu[horz_8x8] = ps_codec->s_parse.s_cu.i4_pred_mode; + } + pu1_cur_qp_cu += cu_info_map_stride; + pu1_cur_type_cu += cu_info_map_stride; + } + } } diff --git a/decoder/ihevcd_structs.h b/decoder/ihevcd_structs.h index 407818a..cbc86af 100644 --- a/decoder/ihevcd_structs.h +++ b/decoder/ihevcd_structs.h @@ -1556,6 +1556,22 @@ typedef struct WORD32 i4_nctb; }process_ctxt_t; +/** + * Reference mapping from pic_buf_id to pointers to corresponding qp_map and CU_type_map + */ +typedef struct +{ + /** + * qp_map buffer + */ + UWORD8 *pu1_qp_map; + + /** + * CU_type buffer + */ + UWORD8 *pu1_cu_type_map; +}ref_map_t; + typedef void (*pf_inter_pred)(void *, void *, WORD32, @@ -2006,6 +2022,31 @@ struct _codec_t UWORD32 u4_ts; /** + * Enable CU_info + */ + UWORD8 u1_enable_cu_info; + + /** + * Ref mapping from pic_buf_id to corresponding CU_info maps + */ + ref_map_t as_buf_id_info_map[MAX_CU_INFO_BUF_CNT]; + + /** + * Total no of 8x8 blocks in luma samples + */ + WORD32 u4_num_8x8_blks; + + /** + * Pointer to base of qp_map buffer array + */ + UWORD8 *pu1_qp_map_base; + + /** + * Pointer to base of CU_type_map buffer array + */ + UWORD8 *pu1_cu_type_map_base; + + /** * Pointer to base of Video parameter set structure array */ vps_t *ps_vps_base; diff --git a/decoder/ihevcd_utils.c b/decoder/ihevcd_utils.c index b914a9b..563d948 100755 --- a/decoder/ihevcd_utils.c +++ b/decoder/ihevcd_utils.c @@ -1265,6 +1265,18 @@ IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec) } } + if(ps_codec->u1_enable_cu_info) + { + ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map = + ps_codec->pu1_qp_map_base + (cur_pic_buf_id * ps_codec->u4_num_8x8_blks); + ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_cu_type_map = + ps_codec->pu1_cu_type_map_base + (cur_pic_buf_id * ps_codec->u4_num_8x8_blks); + memset(ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map, + 0, ps_codec->u4_num_8x8_blks); + memset(ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map, + 0, ps_codec->u4_num_8x8_blks); + } + ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma; ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma; diff --git a/decoder/mips/ihevcd_function_selector.c b/decoder/riscv64/ihevcd_function_selector.c index da734d7..a2a13ed 100644 --- a/decoder/mips/ihevcd_function_selector.c +++ b/decoder/riscv64/ihevcd_function_selector.c @@ -58,28 +58,19 @@ #include "ihevcd_function_selector.h" #include "ihevcd_structs.h" -void ihevcd_init_function_ptr_mips_generic(codec_t *ps_codec); -void ihevcd_init_function_ptr_mips_32(codec_t *ps_codec); - void ihevcd_init_function_ptr(void *pv_codec) { codec_t *ps_codec = (codec_t *)pv_codec; switch(ps_codec->e_processor_arch) { -#if ENABLE_MIPS32_SIMD - case ARCH_MIPS_32: - ihevcd_init_function_ptr_mips_32(ps_codec); - break; -#endif - case ARCH_MIPS_GENERIC: default: - ihevcd_init_function_ptr_mips_generic(ps_codec); - break; + case ARCH_RISCV64_GENERIC: + ihevcd_init_function_ptr_generic(pv_codec); } } void ihevcd_init_arch(void *pv_codec) { codec_t *ps_codec = (codec_t *)pv_codec; - ps_codec->e_processor_arch = ARCH_MIPS_32; + ps_codec->e_processor_arch = ARCH_RISCV64_GENERIC; } diff --git a/decoder/mips/ihevcd_function_selector_mips_generic.c b/decoder/riscv64/ihevcd_function_selector_generic.c index 88c56f4..f8b53ad 100644 --- a/decoder/mips/ihevcd_function_selector_mips_generic.c +++ b/decoder/riscv64/ihevcd_function_selector_generic.c @@ -18,10 +18,10 @@ /** ******************************************************************************* * @file -* ihevcd_function_selector_noneon.c +* ihevcd_function_selector.c * * @brief -* Contains functions to initialize noneon function pointers used in hevc +* Contains functions to initialize function pointers used in hevc * * @author * Naveen @@ -58,8 +58,10 @@ #include "ihevcd_function_selector.h" #include "ihevcd_structs.h" -void ihevcd_init_function_ptr_mips_generic(codec_t *ps_codec) +void ihevcd_init_function_ptr_generic(void *pv_codec) { + codec_t *ps_codec = (codec_t *)pv_codec; + ps_codec->s_func_selector.ihevc_deblk_chroma_horz_fptr = &ihevc_deblk_chroma_horz; ps_codec->s_func_selector.ihevc_deblk_chroma_vert_fptr = &ihevc_deblk_chroma_vert; ps_codec->s_func_selector.ihevc_deblk_luma_vert_fptr = &ihevc_deblk_luma_vert; diff --git a/encoder/ihevce_encode_header_sei_vui.c b/encoder/ihevce_encode_header_sei_vui.c index 68cef99..2b294d3 100644 --- a/encoder/ihevce_encode_header_sei_vui.c +++ b/encoder/ihevce_encode_header_sei_vui.c @@ -1608,7 +1608,7 @@ WORD32 ihevce_generate_sei( /*************************************************************************************************/ /* NOTE: Need to terminate and start new SEI message after active parameter set SEI */ /* Buffering period/pic timing SEI refering to active SPS cannot be embedded in same SEI message */ - /* This is because SPS is activated in HM deocder after completely parsing full SEI message. */ + /* This is because SPS is activated in HM decoder after completely parsing full SEI message. */ /*************************************************************************************************/ if(1) /* Insert New SEI for buffering period after active parameter set SEI */ { diff --git a/encoder/ihevce_profile.h b/encoder/ihevce_profile.h index b9282a9..5b836d9 100644 --- a/encoder/ihevce_profile.h +++ b/encoder/ihevce_profile.h @@ -36,7 +36,9 @@ /*****************************************************************************/ /* Constant Macros */ /*****************************************************************************/ +#ifndef PROFILE_ENABLE #define PROFILE_ENABLE 0 +#endif typedef struct { diff --git a/encoder/ihevce_rc_interface.c b/encoder/ihevce_rc_interface.c index 71be434..ada9190 100644 --- a/encoder/ihevce_rc_interface.c +++ b/encoder/ihevce_rc_interface.c @@ -3817,7 +3817,7 @@ picture_type_e ihevce_rc_conv_pic_type( WORD32 i4_is_bottom_field, WORD32 i4_top_field_first) { - picture_type_e rc_pic_type = pic_type; + picture_type_e rc_pic_type = (picture_type_e)pic_type; /*interlaced pictype are not supported*/ if(pic_type > 9 && i4_temporal_layer_id > 3) /**/ { diff --git a/fuzzer/hevc_dec_fuzzer.cpp b/fuzzer/hevc_dec_fuzzer.cpp index 5561bb1..8dec5da 100644 --- a/fuzzer/hevc_dec_fuzzer.cpp +++ b/fuzzer/hevc_dec_fuzzer.cpp @@ -111,8 +111,8 @@ Codec::~Codec() {} void Codec::createCodec() { IV_API_CALL_STATUS_T ret; - ihevcd_cxa_create_ip_t create_ip; - ihevcd_cxa_create_op_t create_op; + ihevcd_cxa_create_ip_t create_ip{}; + ihevcd_cxa_create_op_t create_op{}; void *fxns = (void *)&ivd_api_function; create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE; @@ -134,8 +134,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); @@ -145,8 +145,8 @@ void Codec::deleteCodec() { } 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; @@ -157,8 +157,8 @@ void Codec::resetCodec() { } void Codec::setCores() { - ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_ip; - ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_op; + ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_ip{}; + ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_op{}; s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; s_ctl_ip.e_sub_cmd = @@ -171,8 +171,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; @@ -187,8 +187,8 @@ void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode) { } void Codec::setArchitecture(IVD_ARCH_T arch) { - ihevcd_cxa_ctl_set_processor_ip_t s_ctl_ip; - ihevcd_cxa_ctl_set_processor_op_t s_ctl_op; + ihevcd_cxa_ctl_set_processor_ip_t s_ctl_ip{}; + ihevcd_cxa_ctl_set_processor_op_t s_ctl_op{}; s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; s_ctl_ip.e_sub_cmd = @@ -258,8 +258,8 @@ 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)); @@ -300,8 +300,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; + 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)); diff --git a/test/decoder/hevcdec.cmake b/test/decoder/hevcdec.cmake index 7eccf9d..bc38001 100644 --- a/test/decoder/hevcdec.cmake +++ b/test/decoder/hevcdec.cmake @@ -1,2 +1,4 @@ libhevc_add_executable(hevcdec libhevcdec SOURCES ${HEVC_ROOT}/test/decoder/main.c) +target_compile_definitions(hevcdec + PRIVATE PROFILE_ENABLE MD5_DISABLE) diff --git a/test/decoder/main.c b/test/decoder/main.c index 3773056..421f81f 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -175,6 +175,7 @@ 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; @@ -198,6 +199,8 @@ typedef struct 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]; @@ -250,8 +253,11 @@ typedef enum VERSION, INPUT_FILE, OUTPUT, + QP_MAP_FILE, + BLK_TYPE_MAP_FILE, CHKSUM, SAVE_OUTPUT, + SAVE_FRAME_INFO, SAVE_CHKSUM, CHROMA_FORMAT, NUM_FRAMES, @@ -294,6 +300,10 @@ static const argument_t argument_mapping[] = "Input file\n" }, { "-o", "--output", OUTPUT, "Output file\n" }, + { "--", "--qp_map_file", QP_MAP_FILE, + "QP map file\n\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, @@ -302,6 +312,8 @@ static const argument_t argument_mapping[] = "Output MD5 Checksum file\n" }, { "-s", "--save_output", SAVE_OUTPUT, "Save Output file\n" }, + { "--", "--save_frame_info", SAVE_FRAME_INFO, + "Enable frame_info\n" }, { "--", "--save_chksum", SAVE_CHKSUM, "Save Check sum file\n" }, { "--", "--chroma_format", CHROMA_FORMAT, @@ -866,12 +878,16 @@ void codec_exit(CHAR *pc_err_message) /*****************************************************************************/ void dump_output(vid_dec_ctx_t *ps_app_ctx, iv_yuv_buf_t *ps_disp_frm_buf, + ihevcd_cxa_video_decode_op_t *ps_hevcd_decode_op, UWORD32 u4_disp_frm_id, FILE *ps_op_file, + FILE *ps_qp_file, + FILE *ps_cu_type_file, FILE *ps_op_chksum_file, WORD32 i4_op_frm_ts, UWORD32 file_save, - UWORD32 chksum_save) + UWORD32 chksum_save, + UWORD32 cu_info_save) { @@ -918,9 +934,26 @@ void dump_output(vid_dec_ctx_t *ps_app_ctx, release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id); - if(0 == file_save && 0 == chksum_save) + if(0 == file_save && 0 == chksum_save && 0 == cu_info_save) return; + if(0 != cu_info_save) + { + UWORD8 *buf; + if(ps_hevcd_decode_op->pu1_8x8_blk_qp_map && ps_qp_file) + { + buf = ps_hevcd_decode_op->pu1_8x8_blk_qp_map; + fwrite(buf, 1, ps_hevcd_decode_op->u4_8x8_blk_qp_map_size, ps_qp_file); + fflush(ps_qp_file); + } + if(ps_hevcd_decode_op->pu1_8x8_blk_type_map && ps_cu_type_file) + { + buf = ps_hevcd_decode_op->pu1_8x8_blk_type_map; + fwrite(buf, 1, ps_hevcd_decode_op->u4_8x8_blk_type_map_size, ps_cu_type_file); + fflush(ps_cu_type_file); + } + } + if(NULL == s_dump_disp_frm_buf.pv_y_buf) return; @@ -1162,22 +1195,34 @@ void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) case VERSION: break; case INPUT_FILE: - sscanf(value, "%s", ps_app_ctx->ac_ip_fname); + snprintf(value, STRLENGTH, "%s", ps_app_ctx->ac_ip_fname); //input_passed = 1; break; case OUTPUT: - sscanf(value, "%s", ps_app_ctx->ac_op_fname); + snprintf(value, STRLENGTH, "%s", ps_app_ctx->ac_op_fname); + break; + + case QP_MAP_FILE: + snprintf(value, STRLENGTH, "%s", ps_app_ctx->ac_qp_map_fname); + break; + + case BLK_TYPE_MAP_FILE: + snprintf(value, STRLENGTH, "%s", ps_app_ctx->ac_blk_type_map_fname); break; case CHKSUM: - sscanf(value, "%s", ps_app_ctx->ac_op_chksum_fname); + snprintf(value, 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; @@ -1287,7 +1332,7 @@ void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) break; case PICLEN_FILE: - sscanf(value, "%s", ps_app_ctx->ac_piclen_fname); + snprintf(value, STRLENGTH, "%s", ps_app_ctx->ac_piclen_fname); break; case INVALID: @@ -1596,6 +1641,10 @@ void flush_output(iv_obj_t *codec_obj, UWORD8 *pu1_bs_buf, UWORD32 *pu4_op_frm_ts, FILE *ps_op_file, + FILE *ps_qp_file, + FILE *ps_cu_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) @@ -1625,45 +1674,55 @@ void flush_output(iv_obj_t *codec_obj, if(IV_SUCCESS == ret) { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; - - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = + ihevcd_cxa_video_decode_ip_t s_hevcd_video_decode_ip = {}; + ihevcd_cxa_video_decode_op_t s_hevcd_video_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = + &s_hevcd_video_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = + &s_hevcd_video_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(ihevcd_cxa_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]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf->u4_min_out_buf_size[1]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf->u4_min_out_buf_size[2]; - s_video_decode_ip.s_out_buffer.pu1_bufs[0] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0]; - s_video_decode_ip.s_out_buffer.pu1_bufs[1] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1]; - s_video_decode_ip.s_out_buffer.pu1_bufs[2] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2]; - s_video_decode_ip.s_out_buffer.u4_num_bufs = + ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs; - s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); + ps_video_decode_op->u4_size = sizeof(ihevcd_cxa_video_decode_op_t); + s_hevcd_video_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_hevcd_video_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_hevcd_video_decode_ip.u4_8x8_blk_qp_map_size = + (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_hevcd_video_decode_ip.u4_8x8_blk_type_map_size = + (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; /*****************************************************************************/ /* API Call: Video Decode */ /*****************************************************************************/ - ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_hevcd_video_decode_ip, + (void *)&s_hevcd_video_decode_op); - if(1 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { - dump_output(ps_app_ctx, &(s_video_decode_op.s_disp_frm_buf), - s_video_decode_op.u4_disp_buf_id, ps_op_file, - ps_op_chksum_file, + dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + &s_hevcd_video_decode_op, ps_video_decode_op->u4_disp_buf_id, + ps_op_file, ps_qp_file, ps_cu_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_chksum_save_flag, ps_app_ctx->u4_frame_info_enable); (*pu4_op_frm_ts)++; } @@ -1725,6 +1784,8 @@ int main(WORD32 argc, CHAR *argv[]) FILE *ps_piclen_file = NULL; FILE *ps_ip_file = NULL; FILE *ps_op_file = NULL; + FILE *ps_qp_file = NULL; + FILE *ps_cu_type_file = NULL; FILE *ps_op_chksum_file = NULL; WORD32 ret; CHAR ac_error_str[STRLENGTH]; @@ -1742,6 +1803,8 @@ int main(WORD32 argc, CHAR *argv[]) UWORD32 u4_ip_buf_len; UWORD32 frm_cnt = 0; WORD32 total_bytes_comsumed; + UWORD8 *pu1_qp_map_buf = NULL; + UWORD8 *pu1_blk_type_map_buf = NULL; #ifdef PROFILE_ENABLE UWORD32 u4_tot_cycles = 0; @@ -1815,6 +1878,7 @@ int main(WORD32 argc, CHAR *argv[]) s_app_ctx.display = 0; s_app_ctx.full_screen = 0; s_app_ctx.u4_piclen_flag = 0; + s_app_ctx.u4_frame_info_enable = 0; s_app_ctx.fps = DEFAULT_FPS; file_pos = 0; total_bytes_comsumed = 0; @@ -1900,11 +1964,12 @@ int main(WORD32 argc, CHAR *argv[]) { if(CONFIG == get_argument(argv[i])) { - strcpy(ac_cfg_fname, argv[i + 1]); + strncpy(ac_cfg_fname, argv[i + 1], STRLENGTH); + ac_cfg_fname[STRLENGTH - 1] = '\0'; if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", - ac_cfg_fname); + 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); @@ -1920,7 +1985,7 @@ int main(WORD32 argc, CHAR *argv[]) { if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s", ac_cfg_fname); codec_exit(ac_error_str); } @@ -1928,10 +1993,10 @@ int main(WORD32 argc, CHAR *argv[]) fclose(fp_cfg_file); } #else - sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, ac_cfg_fname); if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s", ac_cfg_fname); codec_exit(ac_error_str); @@ -1964,19 +2029,24 @@ int main(WORD32 argc, CHAR *argv[]) exit(-1); } + if(1 == s_app_ctx.u4_frame_info_enable) + { + pu1_qp_map_buf = calloc(ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 6, 1); + pu1_blk_type_map_buf = calloc(ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 6, 1); + } /***********************************************************************/ /* create the file object for input file */ /***********************************************************************/ #ifdef IOS - sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname); + 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) { - sprintf(ac_error_str, "Could not open input file %s", + 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); } @@ -1986,14 +2056,14 @@ int main(WORD32 argc, CHAR *argv[]) if(1 == s_app_ctx.u4_piclen_flag) { #ifdef IOS - sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, 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) { - sprintf(ac_error_str, "Could not open piclen file %s", + 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); } @@ -2005,7 +2075,7 @@ int main(WORD32 argc, CHAR *argv[]) if(1 == s_app_ctx.u4_file_save_flag) { #ifdef IOS - sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname); + 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"); @@ -2013,26 +2083,52 @@ int main(WORD32 argc, CHAR *argv[]) if(NULL == ps_op_file) { - sprintf(ac_error_str, "Could not open output file %s", + 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 cuinfo 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_cu_type_file = fopen(filename_with_path, "wb"); +#else + ps_qp_file = fopen(s_app_ctx.ac_qp_map_fname, "wb"); + ps_cu_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 output file %s", s_app_ctx.ac_qp_map_fname); + } + if(NULL == ps_cu_type_file) + { + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open output 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 - sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname); + 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) { - sprintf(ac_error_str, "Could not open check sum file %s", + 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); } @@ -2060,6 +2156,7 @@ int main(WORD32 argc, CHAR *argv[]) s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL; s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ihevcd_cxa_create_ip_t); s_create_op.s_ivd_create_op_t.u4_size = sizeof(ihevcd_cxa_create_op_t); + s_create_ip.u4_enable_frame_info = s_app_ctx.u4_frame_info_enable; @@ -2128,39 +2225,45 @@ int main(WORD32 argc, CHAR *argv[]) } - flush_output(codec_obj, &s_app_ctx, ps_out_buf, - pu1_bs_buf, &u4_op_frm_ts, - ps_op_file, ps_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_cu_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 */ /*****************************************************************************/ { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; + ihevcd_cxa_video_decode_ip_t s_hevcd_video_decode_ip = {}; + ihevcd_cxa_video_decode_op_t s_hevcd_video_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = + &s_hevcd_video_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = + &s_hevcd_video_decode_op.s_ivd_video_decode_op_t; { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ihevcd_cxa_ctl_set_config_ip_t s_hevcd_ctl_ip = {}; + ihevcd_cxa_ctl_set_config_op_t s_hevcd_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_hevcd_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_hevcd_ctl_op.s_ivd_ctl_set_config_op_t; - - s_ctl_ip.u4_disp_wd = STRIDE; + ps_ctl_ip->u4_disp_wd = STRIDE; if(1 == s_app_ctx.display) - s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); + ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride(); - 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 = IVD_DECODE_HEADER; - 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); + 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(ihevcd_cxa_ctl_set_config_ip_t); - ret = ivd_cxa_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + ps_ctl_op->u4_size = sizeof(ihevcd_cxa_ctl_set_config_op_t); + + ret = ivd_cxa_api_function((iv_obj_t*)codec_obj, (void *)&s_hevcd_ctl_ip, + (void *)&s_hevcd_ctl_op); if(ret != IV_SUCCESS) { sprintf(ac_error_str, @@ -2206,37 +2309,44 @@ int main(WORD32 argc, CHAR *argv[]) codec_exit(ac_error_str); } - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_op.u4_size = sizeof(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(ihevcd_cxa_video_decode_ip_t); + + ps_video_decode_op->u4_size = sizeof(ihevcd_cxa_video_decode_op_t); + s_hevcd_video_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_hevcd_video_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_hevcd_video_decode_ip.u4_8x8_blk_qp_map_size = + (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_hevcd_video_decode_ip.u4_8x8_blk_type_map_size = + (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; /*****************************************************************************/ /* API Call: Header Decode */ /*****************************************************************************/ - ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_hevcd_video_decode_ip, + (void *)&s_hevcd_video_decode_op); if(ret != IV_SUCCESS) { sprintf(ac_error_str, "\nError in header decode %x", - s_video_decode_op.u4_error_code); + ps_video_decode_op->u4_error_code); // codec_exit(ac_error_str); } - u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; + u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed; #ifndef PROFILE_ENABLE - printf("%d\n",s_video_decode_op.u4_num_bytes_consumed); + 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 = s_video_decode_op.u4_pic_wd; - s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht; + 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); @@ -2698,8 +2808,12 @@ int main(WORD32 argc, CHAR *argv[]) { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; + ihevcd_cxa_video_decode_ip_t s_hevcd_video_decode_ip = {}; + ihevcd_cxa_video_decode_op_t s_hevcd_video_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = + &s_hevcd_video_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = + &s_hevcd_video_decode_op.s_ivd_video_decode_op_t; #ifdef PROFILE_ENABLE UWORD32 s_elapsed_time; TIMER s_start_timer; @@ -2707,27 +2821,34 @@ int main(WORD32 argc, CHAR *argv[]) #endif - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = + 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(ihevcd_cxa_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]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf->u4_min_out_buf_size[1]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf->u4_min_out_buf_size[2]; - s_video_decode_ip.s_out_buffer.pu1_bufs[0] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0]; - s_video_decode_ip.s_out_buffer.pu1_bufs[1] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1]; - s_video_decode_ip.s_out_buffer.pu1_bufs[2] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2]; - s_video_decode_ip.s_out_buffer.u4_num_bufs = + ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs; - s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); + + ps_video_decode_op->u4_size = sizeof(ihevcd_cxa_video_decode_op_t); + s_hevcd_video_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_hevcd_video_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_hevcd_video_decode_ip.u4_8x8_blk_qp_map_size = + (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_hevcd_video_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) @@ -2740,9 +2861,9 @@ int main(WORD32 argc, CHAR *argv[]) break; s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx, - &s_video_decode_ip.s_out_buffer.pu1_bufs[0], - &s_video_decode_ip.s_out_buffer.pu1_bufs[1], - &s_video_decode_ip.s_out_buffer.pu1_bufs[2]); + &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]); } /*****************************************************************************/ @@ -2751,8 +2872,8 @@ int main(WORD32 argc, CHAR *argv[]) GETTIME(&s_start_timer); - ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_hevcd_video_decode_ip, + (void *)&s_hevcd_video_decode_op); GETTIME(&s_end_timer); @@ -2774,13 +2895,16 @@ int main(WORD32 argc, CHAR *argv[]) 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, s_video_decode_op.u4_output_present, s_video_decode_op.u4_num_bytes_consumed); + 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); } #ifdef INTEL_CE5300 time_consumed += s_elapsed_time; - bytes_consumed += s_video_decode_op.u4_num_bytes_consumed; + bytes_consumed += ps_video_decode_op->u4_num_bytes_consumed; if(!(frm_cnt % (s_app_ctx.fps))) { time_consumed = time_consumed / s_app_ctx.fps; @@ -2792,25 +2916,25 @@ int main(WORD32 argc, CHAR *argv[]) } #endif #else - printf("%d\n", s_video_decode_op.u4_num_bytes_consumed); + 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, - s_video_decode_op.u4_error_code); + ps_video_decode_op->u4_error_code); } if((IV_SUCCESS != ret) && - ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED)) + ((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_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_cu_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; @@ -2875,7 +2999,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI mastering display color volume parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { ihevcd_cxa_ctl_get_sei_mastering_params_ip_t s_ctl_get_sei_mastering_params_ip; @@ -2902,36 +3026,36 @@ int main(WORD32 argc, CHAR *argv[]) if((1 == s_app_ctx.display) && - (1 == s_video_decode_op.u4_output_present)) + (1 == ps_video_decode_op->u4_output_present)) { dispq_producer_queue(&s_app_ctx); } - if(IV_B_FRAME == s_video_decode_op.e_pic_type) + if(IV_B_FRAME == ps_video_decode_op->e_pic_type) s_app_ctx.b_pic_present |= 1; - u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; + 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 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { - width = s_video_decode_op.s_disp_frm_buf.u4_y_wd; - height = s_video_decode_op.s_disp_frm_buf.u4_y_ht; - dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf), - s_video_decode_op.u4_disp_buf_id, ps_op_file, - ps_op_chksum_file, + width = ps_video_decode_op->s_disp_frm_buf.u4_y_wd; + height = ps_video_decode_op->s_disp_frm_buf.u4_y_ht; + dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + &s_hevcd_video_decode_op, ps_video_decode_op->u4_disp_buf_id, + ps_op_file, ps_qp_file, ps_cu_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_chksum_save_flag, s_app_ctx.u4_frame_info_enable); u4_op_frm_ts++; } else { - if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) + if((ps_video_decode_op->u4_error_code >> IVD_FATALERROR) & 1) { printf("Fatal error\n"); break; @@ -2944,10 +3068,11 @@ int main(WORD32 argc, CHAR *argv[]) /***********************************************************************/ /* 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_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_cu_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 flag */ s_app_ctx.quit = 1; @@ -3020,6 +3145,13 @@ int main(WORD32 argc, CHAR *argv[]) { 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_cu_type_file) + fclose(ps_cu_type_file); + } } @@ -3035,6 +3167,13 @@ int main(WORD32 argc, CHAR *argv[]) 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); |