From 748aa1e4597a2b0e4c20d30867879780648e0f6a Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 6 Mar 2020 21:23:46 -0800 Subject: Remove mips workarounds. Test: treehugger Change-Id: I3396db9548fe941759a6e8f546b81a10b1a7de01 --- Android.bp | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/Android.bp b/Android.bp index 681d33c..a02b20b 100644 --- a/Android.bp +++ b/Android.bp @@ -159,18 +159,6 @@ cc_library_static { ], }, - mips: { - local_include_dirs: ["common/mips"], - - srcs: ["decoder/mips/ih264d_function_selector.c"], - }, - - mips64: { - local_include_dirs: ["common/mips"], - - srcs: ["decoder/mips/ih264d_function_selector.c"], - }, - x86: { cflags: [ "-DX86", @@ -416,24 +404,6 @@ cc_library_static { ], }, - mips: { - local_include_dirs: [ - "common/mips", - "encoder/mips", - ], - - srcs: ["encoder/mips/ih264e_function_selector.c"], - }, - - mips64: { - local_include_dirs: [ - "common/mips", - "encoder/mips", - ], - - srcs: ["encoder/mips/ih264e_function_selector.c"], - }, - x86: { cflags: [ "-DX86", -- cgit v1.2.3 From 669c6bb63c1b9f3b65100170d880af9695f055dd Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 16 Apr 2020 18:48:27 +0900 Subject: Set min_sdk_version to be part of mainline modules Modules contributing mainline modules (APK/APEX) should set min_sdk_version as well as apex_available. For now setting min_sdk_version doesn't change build outputs. But build-time checks will be added soon. Bug: 152655956 Test: m Change-Id: I6cfff21dcaf861392f8b69d97195831cdda4c1be --- Android.bp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Android.bp b/Android.bp index a02b20b..343b234 100644 --- a/Android.bp +++ b/Android.bp @@ -1,8 +1,11 @@ cc_library_static { name: "libavcdec", vendor_available: true, - host_supported:true, - shared_libs: ["liblog", "libcutils",], + host_supported: true, + shared_libs: [ + "liblog", + "libcutils", + ], cflags: [ "-fPIC", @@ -229,13 +232,20 @@ cc_library_static { // cfi: true, blacklist: "libavc_blacklist.txt", }, + apex_available: [ + "com.android.media.swcodec", + ], + min_sdk_version: "29", } cc_library_static { name: "libavcenc", vendor_available: true, host_supported: true, - shared_libs: ["liblog", "libcutils",], + shared_libs: [ + "liblog", + "libcutils", + ], cflags: [ "-DNDEBUG", @@ -482,6 +492,10 @@ cc_library_static { // cfi: true, blacklist: "libavc_blacklist.txt", }, + apex_available: [ + "com.android.media.swcodec", + ], + min_sdk_version: "29", } subdirs = ["test"] -- cgit v1.2.3 From 89a120262ab7668c86773419acb5053639358f96 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 24 Apr 2020 21:39:20 +0900 Subject: mark libavc and libavcenc available to the platform The library is installed to the platform via the dependency chain: android.hardware.media.omx@1.0-service -> libstagefright_soft_avcdec -> libavc and -> libstagefright_soft_avcenc -> libavcenc Bug: 153073816 Test: m Change-Id: Ib206ae858601b0dca6dccb09e8c53028feef0362 --- Android.bp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Android.bp b/Android.bp index 343b234..500bbf6 100644 --- a/Android.bp +++ b/Android.bp @@ -233,6 +233,7 @@ cc_library_static { blacklist: "libavc_blacklist.txt", }, apex_available: [ + "//apex_available:platform", // used by libstagefright_soft_avcdec "com.android.media.swcodec", ], min_sdk_version: "29", @@ -493,6 +494,7 @@ cc_library_static { blacklist: "libavc_blacklist.txt", }, apex_available: [ + "//apex_available:platform", //due to libstagefright_soft_avcenc "com.android.media.swcodec", ], min_sdk_version: "29", -- cgit v1.2.3 From 67c86e8bb834faf0534642ad910c5384af28913b Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Tue, 28 Apr 2020 09:09:00 -0700 Subject: Add METADATA to libavc: Apache2=NOTICE Bug: 68860345 Bug: 69058154 Bug: 151953481 Test: no code changes Change-Id: I7b68ffa24730dce2b2bc7d460444200c5497c3ec --- METADATA | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 METADATA diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..d97975c --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} -- cgit v1.2.3 From 5a52ec8cdddfe3a2fd0759078c2faed913eaead4 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Thu, 28 May 2020 14:20:18 -0700 Subject: Added fuzz_config field in avc_dec_fuzzer Test: ./avc_dec_fuzzer Bug: 157680018 Change-Id: Ia06f33596cacb8b5d856ff778135fc4a78e2fb66 --- fuzzer/Android.bp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index 8540107..95eab84 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -13,4 +13,10 @@ cc_fuzz { enabled: false, }, }, + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, } -- cgit v1.2.3 From 083b9fc086e2b905d7e69fd7fe7d1ae563ba0934 Mon Sep 17 00:00:00 2001 From: Aasaipriya Chandran Date: Wed, 10 Jun 2020 13:42:04 +0530 Subject: Decoder: Fix Null dereference Add checks to validate long term index and max long term index parsed in MMCO commands. Bug: 140358770 Bug: 140680655 Bug: 148772548 Bug: 152148135 Bug: 152434373 Bug: 152550528 Test: poc in bug Change-Id: I9052ce7721491fdd5fb4807ec33e399cee8c70cf --- decoder/ih264d_dpb_manager.h | 3 ++- decoder/ih264d_dpb_mgr.c | 39 ++++++++++++++++++++++++++++++++------- decoder/ih264d_utils.c | 3 ++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/decoder/ih264d_dpb_manager.h b/decoder/ih264d_dpb_manager.h index a9539c8..3bf00b7 100644 --- a/decoder/ih264d_dpb_manager.h +++ b/decoder/ih264d_dpb_manager.h @@ -50,6 +50,7 @@ #define RESET_NONREF_PICTURES 7 #define RESET_ALL_PICTURES 8 +#define NO_LONG_TERM_INDICIES 255 struct field_t { /* picNum of tbe reference field */ @@ -93,7 +94,7 @@ typedef struct struct dpb_info_t as_dpb_info[MAX_REF_BUFS]; /** Physical storage for dpbInfo for ref bufs */ UWORD8 u1_num_st_ref_bufs; /** Number of short term ref. buffers */ UWORD8 u1_num_lt_ref_bufs; /** Number of long term ref. buffer */ - UWORD8 u1_max_lt_pic_idx_plus1; /** Maximum long term pictures - 0 to max_long_term_pic_idx */ + UWORD8 u1_max_lt_frame_idx; /** Maximum long term frame index */ UWORD8 u1_num_gaps; /** Total number of outstanding gaps */ void * pv_codec_handle; /* For Error Handling */ WORD32 i4_max_frm_num; /** Max frame number */ diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c index 0b8426b..28c9619 100644 --- a/decoder/ih264d_dpb_mgr.c +++ b/decoder/ih264d_dpb_mgr.c @@ -851,6 +851,8 @@ WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx) */ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) { + dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps; + dec_seq_params_t *ps_sps = ps_pps->ps_sps; dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch); dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; @@ -890,7 +892,7 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) { UWORD32 u4_mmco; UWORD32 u4_diff_pic_num; - UWORD32 u4_lt_idx, u4_max_lt_idx; + UWORD32 u4_lt_idx, u4_max_lt_idx_plus1; u4_mmco = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); @@ -933,9 +935,14 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) case SET_MAX_LT_INDEX: { - u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst, - pu4_bitstrm_buf); - ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx; + u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames) + { + /* Invalid max LT ref index */ + return -1; + } + ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1; break; } case RESET_REF_PICTURES: @@ -959,7 +966,6 @@ WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) j++; } ps_dpb_cmds->u1_num_of_commands = j; - } } ps_dpb_cmds->u1_dpb_commands_read = 1; @@ -1243,6 +1249,13 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, } 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; + } + if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) { ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, @@ -1257,7 +1270,7 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, { UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs; 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_pic_idx_plus1 + if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx && uc_numLT > 0) { struct dpb_info_t *ps_nxtDPB; @@ -1302,13 +1315,25 @@ WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, ps_nxtDPB->ps_prev_long = NULL; } } - ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx; + 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: { 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; + } ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, u4_cur_pic_num); if(ret != OK) diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 35cd7b9..1fe9a5b 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -509,6 +509,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) ps_dec->ps_cur_pic, ps_dec->u1_pic_buf_id, ps_cur_slice->u2_frame_num); + ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES; } else { @@ -527,7 +528,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) ps_cur_slice->u2_frame_num, 0, ps_cur_slice->u1_field_pic_flag); - ps_dec->ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = 1; + ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = 0; } } } -- cgit v1.2.3 From 7bc9d4d29a00f38f9fd427004f59ae3a8533b930 Mon Sep 17 00:00:00 2001 From: Hamsalekha S Date: Wed, 10 Jun 2020 12:16:40 +0530 Subject: Decoder: Fix heap buffer overflow. Fix bitstream buffer overflow in the function ih264d_parse_sei_message Bug: 152895390 Test: POC in bug Change-Id: I41ff1f7b2834c2d09e546b8e3d37e4cd4abfa28d --- decoder/ih264d_bitstrm.h | 9 ++++++--- decoder/ih264d_cabac.c | 2 +- decoder/ih264d_parse_headers.c | 4 ++-- decoder/ih264d_sei.c | 20 ++++++++++++++++---- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/decoder/ih264d_bitstrm.h b/decoder/ih264d_bitstrm.h index 49cd5e7..8bb06fb 100644 --- a/decoder/ih264d_bitstrm.h +++ b/decoder/ih264d_bitstrm.h @@ -57,7 +57,7 @@ typedef struct { UWORD32 u4_ofst; /* Offset in the buffer for the current bit */ UWORD32 *pu4_buffer; /* Bitstream Buffer */ - UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */ + UWORD32 u4_max_ofst; /* points to first bit beyond the buffer */ void * pv_codec_handle; /* For Error Handling */ } dec_bit_stream_t; @@ -88,10 +88,13 @@ WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *, WORD32); ************************************************************************** */ -#define MORE_RBSP_DATA(ps_bitstrm) \ - (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst) + #define EXCEED_OFFSET(ps_bitstrm) \ (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) +#define CHECK_BITS_SUFFICIENT(ps_bitstrm, bits_to_read) \ + (ps_bitstrm->u4_ofst + bits_to_read <= ps_bitstrm->u4_max_ofst) +#define MORE_RBSP_DATA(ps_bitstrm) \ + CHECK_BITS_SUFFICIENT(ps_bitstrm, 1) void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm); UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm); diff --git a/decoder/ih264d_cabac.c b/decoder/ih264d_cabac.c index 38028ae..ef1fafc 100644 --- a/decoder/ih264d_cabac.c +++ b/decoder/ih264d_cabac.c @@ -69,7 +69,7 @@ WORD32 ih264d_init_cabac_dec_envirnoment(decoding_envirnoment_t * ps_cab_env, 32); FLUSHBITS(ps_bitstrm->u4_ofst, 9) - if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_FLUSHBITS_T; ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index f286e29..9220707 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -463,7 +463,7 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) /* In case bitstream read has exceeded the filled size, then return an error */ - if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst + 8) + if(EXCEED_OFFSET(ps_bitstrm)) { return ERROR_INV_SPS_PPS_T; } @@ -1093,7 +1093,7 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /* In case bitstream read has exceeded the filled size, then return an error */ - if (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + if (EXCEED_OFFSET(ps_bitstrm)) { return ERROR_INV_SPS_PPS_T; } diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c index 4375671..ac4d056 100644 --- a/decoder/ih264d_sei.c +++ b/decoder/ih264d_sei.c @@ -759,8 +759,12 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, { ui4_payload_type = 0; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) + { + return ERROR_EOB_GETBITS_T; + } u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); - while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm)) + while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) { u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); ui4_payload_type += 255; @@ -768,14 +772,22 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, ui4_payload_type += u4_bits; ui4_payload_size = 0; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) + { + return ERROR_EOB_GETBITS_T; + } u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); - while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm)) + while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) { u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); ui4_payload_size += 255; } ui4_payload_size += u4_bits; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, (ui4_payload_size << 3))) + { + return ERROR_EOB_GETBITS_T; + } i4_status = ih264d_parse_sei_payload(ps_bitstrm, ui4_payload_type, ui4_payload_size, ps_dec); if(i4_status != OK) @@ -789,7 +801,7 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, H264_DEC_DEBUG_PRINT("\nError in parsing SEI message"); } while(0 == ih264d_check_byte_aligned(ps_bitstrm) - && !EXCEED_OFFSET(ps_bitstrm)) + && CHECK_BITS_SUFFICIENT(ps_bitstrm, 1)) { u4_bits = ih264d_get_bit_h264(ps_bitstrm); if(u4_bits) @@ -799,7 +811,7 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, } } } - while(ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst); + while(MORE_RBSP_DATA(ps_bitstrm)); return (i4_status); } -- cgit v1.2.3 From a0036e742b076775cd39aa21822a0c858592323b Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 8 Jul 2020 17:20:27 -0700 Subject: decoder: Allow stride to be smaller than decode width When cropping is enabled, application can request a stride that is larger than display width but smaller than decode width. Bug: 160397536 Test: stagefright -sS Change-Id: I453b2de0474f3ae4d021084729c33d52fc1090dc --- decoder/ih264d_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 3a73938..3dfcbf2 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -3253,7 +3253,7 @@ WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) ret = IV_FAIL; } - if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_pic_wd) + if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width) { ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd; } -- cgit v1.2.3 From 6d44b362b97d2262225519f4354d8173f3ab9b53 Mon Sep 17 00:00:00 2001 From: Pirama Arumuga Nainar Date: Tue, 28 Jul 2020 14:27:20 -0700 Subject: Use blocklist sub-property in sanitize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update language to comply with Android’s inclusive language guidance See https://source.android.com/setup/contribute/respectful-code for reference Bug: 161896447 Bug: 162245450 Test: build topic Change-Id: Id7e09811092c8f026e1006d2a1d8355c444081a6 --- Android.bp | 4 ++-- libavc_blacklist.txt | 34 ---------------------------------- libavc_blocklist.txt | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 36 deletions(-) delete mode 100644 libavc_blacklist.txt create mode 100644 libavc_blocklist.txt diff --git a/Android.bp b/Android.bp index 500bbf6..5ba9c7a 100644 --- a/Android.bp +++ b/Android.bp @@ -230,7 +230,7 @@ cc_library_static { misc_undefined: ["bounds"], // Enable CFI if this becomes a shared library. // cfi: true, - blacklist: "libavc_blacklist.txt", + blocklist: "libavc_blocklist.txt", }, apex_available: [ "//apex_available:platform", // used by libstagefright_soft_avcdec @@ -491,7 +491,7 @@ cc_library_static { misc_undefined: ["bounds"], // Enable CFI if this becomes a shared library. // cfi: true, - blacklist: "libavc_blacklist.txt", + blocklist: "libavc_blocklist.txt", }, apex_available: [ "//apex_available:platform", //due to libstagefright_soft_avcenc diff --git a/libavc_blacklist.txt b/libavc_blacklist.txt deleted file mode 100644 index 5bb3630..0000000 --- a/libavc_blacklist.txt +++ /dev/null @@ -1,34 +0,0 @@ -[cfi] -src:*external/libavc/* - -[integer] -# decoder/ih264d_dpb_mgr.c:1174: 2 - 3 cannot be represented in type 'unsigned int' -fun:ih264d_do_mmco_buffer -# decoder/ih264d_parse_bslice.c:1388:21: 1 + 4294967295 cannot be represented in type 'unsigned int' -# decoder/ih264d_parse_bslice.c:1391:22: 1 + 4294967295 cannot be represented in type 'unsigned int' -fun:ih264d_decode_bslice -# decoder/ih264d_utils.c:389: 0 - 1 cannot be represented in type 'unsigned int' -fun:ih264d_decode_pic_order_cnt -# decoder/ih264d_vui.c:76: 1 + 4294967295 cannot be represented in type 'unsigned int' -fun:ih264d_parse_hrd_parametres -# decoder/ih264d_dpb_mgr.c:751: 4294967295 + 1 cannot be represented in type 'unsigned int' -# decoder/ih264d_dpb_mgr.c:755: 1 - 16 cannot be represented in type 'unsigned int' -# decoder/ih264d_dpb_mgr.c:762: 4294967295 + 1 cannot be represented in type 'unsigned int' -fun:ih264d_ref_idx_reordering -# decoder/ih264d_process_bslice.c:785: 5 - 4294967242 cannot be represented in type 'unsigned int' -# decoder/ih264d_process_bslice.c:796: 3 - 4294967242 cannot be represented in type 'unsigned int' -fun:ih264d_decode_temporal_direct -# encoder/ime.c:153: 0 - 1 cannot be represented in type 'UWORD32' -fun:ime_diamond_search_16x16 -# encoder/irc_rate_control_api.c:1251: 1000 * 1065353216 cannot be represented in type 'unsigned int' -fun:irc_change_frame_rate -# encoder/irc_rate_control_api.c:310: 6000000 * 1000 cannot be represented in type 'unsigned int' -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 - -# Performance related -fun:ih264e_pack_c_mb -fun:ime_compute_satqd_16x16_lumainter_a9q diff --git a/libavc_blocklist.txt b/libavc_blocklist.txt new file mode 100644 index 0000000..5bb3630 --- /dev/null +++ b/libavc_blocklist.txt @@ -0,0 +1,34 @@ +[cfi] +src:*external/libavc/* + +[integer] +# decoder/ih264d_dpb_mgr.c:1174: 2 - 3 cannot be represented in type 'unsigned int' +fun:ih264d_do_mmco_buffer +# decoder/ih264d_parse_bslice.c:1388:21: 1 + 4294967295 cannot be represented in type 'unsigned int' +# decoder/ih264d_parse_bslice.c:1391:22: 1 + 4294967295 cannot be represented in type 'unsigned int' +fun:ih264d_decode_bslice +# decoder/ih264d_utils.c:389: 0 - 1 cannot be represented in type 'unsigned int' +fun:ih264d_decode_pic_order_cnt +# decoder/ih264d_vui.c:76: 1 + 4294967295 cannot be represented in type 'unsigned int' +fun:ih264d_parse_hrd_parametres +# decoder/ih264d_dpb_mgr.c:751: 4294967295 + 1 cannot be represented in type 'unsigned int' +# decoder/ih264d_dpb_mgr.c:755: 1 - 16 cannot be represented in type 'unsigned int' +# decoder/ih264d_dpb_mgr.c:762: 4294967295 + 1 cannot be represented in type 'unsigned int' +fun:ih264d_ref_idx_reordering +# decoder/ih264d_process_bslice.c:785: 5 - 4294967242 cannot be represented in type 'unsigned int' +# decoder/ih264d_process_bslice.c:796: 3 - 4294967242 cannot be represented in type 'unsigned int' +fun:ih264d_decode_temporal_direct +# encoder/ime.c:153: 0 - 1 cannot be represented in type 'UWORD32' +fun:ime_diamond_search_16x16 +# encoder/irc_rate_control_api.c:1251: 1000 * 1065353216 cannot be represented in type 'unsigned int' +fun:irc_change_frame_rate +# encoder/irc_rate_control_api.c:310: 6000000 * 1000 cannot be represented in type 'unsigned int' +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 + +# Performance related +fun:ih264e_pack_c_mb +fun:ime_compute_satqd_16x16_lumainter_a9q -- cgit v1.2.3 From 358b09305aeeb440d3f5e16cc335df0734136052 Mon Sep 17 00:00:00 2001 From: Shivaansh Agrawal Date: Wed, 22 Jul 2020 13:11:55 +0530 Subject: decoder: fix integer overflow when setting i4_prev_max_display_seq reset ps_dec->i4_prev_max_display_seq if out of int32 range to avoid overflow Bug: 143791121 Bug: 143791161 Test: POC in bug description Change-Id: I3d8df556b003a7c739716bb33262ab3a6ca7b2d9 --- decoder/ih264d_parse_slice.c | 12 ++++++------ decoder/ih264d_utils.c | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 927f1c0..d807f11 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -826,8 +826,8 @@ WORD32 ih264d_end_of_pic_dispbuf_mgr(dec_struct_t * ps_dec) ps_cur_pic->u2_crop_offset_uv = ps_dec->u2_crop_offset_uv; ps_cur_pic->u1_pic_type = 0; { - UWORD64 i8_display_poc; - i8_display_poc = (UWORD64)ps_dec->i4_prev_max_display_seq + + WORD64 i8_display_poc; + i8_display_poc = (WORD64)ps_dec->i4_prev_max_display_seq + ps_dec->ps_cur_pic->i4_poc; if(IS_OUT_OF_RANGE_S32(i8_display_poc)) { @@ -1495,13 +1495,13 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, /* IDR Picture or POC wrap around */ if(i4_poc == 0) { - UWORD64 u8_temp; - u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq + 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 = (u8_temp > 0x7fffffff)? - 0 : u8_temp; + ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)? + 0 : i8_temp; ps_dec->i4_max_poc = 0; } } diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 1fe9a5b..141a111 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -1301,7 +1301,7 @@ void ih264d_release_display_bufs(dec_struct_t *ps_dec) WORD32 i4_min_poc; WORD32 i4_min_poc_buf_id; WORD32 i4_min_index; - UWORD64 u8_temp; + WORD64 i8_temp; dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; @@ -1348,11 +1348,11 @@ void ih264d_release_display_bufs(dec_struct_t *ps_dec) } } ps_dpb_mgr->i1_poc_buf_id_entries = 0; - u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc + 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 = (u8_temp > 0x7fffffff)? - 0 : u8_temp; + ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)? + 0 : i8_temp; ps_dec->i4_max_poc = 0; } @@ -1624,13 +1624,13 @@ WORD32 ih264d_decode_gaps_in_frame_num(dec_struct_t *ps_dec, /* IDR Picture or POC wrap around */ if(i4_poc == 0) { - UWORD64 u8_temp; - u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq + 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 = (u8_temp > 0x7fffffff)? - 0 : u8_temp; + ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)? + 0 : i8_temp; ps_dec->i4_max_poc = 0; } @@ -1648,8 +1648,8 @@ WORD32 ih264d_decode_gaps_in_frame_num(dec_struct_t *ps_dec, } { - UWORD64 i8_display_poc; - i8_display_poc = (UWORD64)ps_dec->i4_prev_max_display_seq + + 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)) { -- cgit v1.2.3 From 0b601e1a4fb246ce7c60aa101af5af4edd0a842d Mon Sep 17 00:00:00 2001 From: Hamsalekha S Date: Wed, 10 Jun 2020 12:16:40 +0530 Subject: Decoder: Fix heap buffer overflow. Fix bitstream buffer overflow in the function ih264d_parse_sei_message Bug: 152895390 Test: POC in bug Change-Id: I41ff1f7b2834c2d09e546b8e3d37e4cd4abfa28d --- decoder/ih264d_bitstrm.h | 9 ++++++--- decoder/ih264d_cabac.c | 2 +- decoder/ih264d_parse_headers.c | 4 ++-- decoder/ih264d_sei.c | 20 ++++++++++++++++---- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/decoder/ih264d_bitstrm.h b/decoder/ih264d_bitstrm.h index 49cd5e7..8bb06fb 100644 --- a/decoder/ih264d_bitstrm.h +++ b/decoder/ih264d_bitstrm.h @@ -57,7 +57,7 @@ typedef struct { UWORD32 u4_ofst; /* Offset in the buffer for the current bit */ UWORD32 *pu4_buffer; /* Bitstream Buffer */ - UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */ + UWORD32 u4_max_ofst; /* points to first bit beyond the buffer */ void * pv_codec_handle; /* For Error Handling */ } dec_bit_stream_t; @@ -88,10 +88,13 @@ WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *, WORD32); ************************************************************************** */ -#define MORE_RBSP_DATA(ps_bitstrm) \ - (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst) + #define EXCEED_OFFSET(ps_bitstrm) \ (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) +#define CHECK_BITS_SUFFICIENT(ps_bitstrm, bits_to_read) \ + (ps_bitstrm->u4_ofst + bits_to_read <= ps_bitstrm->u4_max_ofst) +#define MORE_RBSP_DATA(ps_bitstrm) \ + CHECK_BITS_SUFFICIENT(ps_bitstrm, 1) void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm); UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm); diff --git a/decoder/ih264d_cabac.c b/decoder/ih264d_cabac.c index 38028ae..ef1fafc 100644 --- a/decoder/ih264d_cabac.c +++ b/decoder/ih264d_cabac.c @@ -69,7 +69,7 @@ WORD32 ih264d_init_cabac_dec_envirnoment(decoding_envirnoment_t * ps_cab_env, 32); FLUSHBITS(ps_bitstrm->u4_ofst, 9) - if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + if(EXCEED_OFFSET(ps_bitstrm)) return ERROR_EOB_FLUSHBITS_T; ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index f286e29..9220707 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -463,7 +463,7 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) /* In case bitstream read has exceeded the filled size, then return an error */ - if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst + 8) + if(EXCEED_OFFSET(ps_bitstrm)) { return ERROR_INV_SPS_PPS_T; } @@ -1093,7 +1093,7 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /* In case bitstream read has exceeded the filled size, then return an error */ - if (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + if (EXCEED_OFFSET(ps_bitstrm)) { return ERROR_INV_SPS_PPS_T; } diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c index 4375671..ac4d056 100644 --- a/decoder/ih264d_sei.c +++ b/decoder/ih264d_sei.c @@ -759,8 +759,12 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, { ui4_payload_type = 0; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) + { + return ERROR_EOB_GETBITS_T; + } u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); - while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm)) + while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) { u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); ui4_payload_type += 255; @@ -768,14 +772,22 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, ui4_payload_type += u4_bits; ui4_payload_size = 0; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) + { + return ERROR_EOB_GETBITS_T; + } u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); - while(0xff == u4_bits && !EXCEED_OFFSET(ps_bitstrm)) + while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8)) { u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); ui4_payload_size += 255; } ui4_payload_size += u4_bits; + if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, (ui4_payload_size << 3))) + { + return ERROR_EOB_GETBITS_T; + } i4_status = ih264d_parse_sei_payload(ps_bitstrm, ui4_payload_type, ui4_payload_size, ps_dec); if(i4_status != OK) @@ -789,7 +801,7 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, H264_DEC_DEBUG_PRINT("\nError in parsing SEI message"); } while(0 == ih264d_check_byte_aligned(ps_bitstrm) - && !EXCEED_OFFSET(ps_bitstrm)) + && CHECK_BITS_SUFFICIENT(ps_bitstrm, 1)) { u4_bits = ih264d_get_bit_h264(ps_bitstrm); if(u4_bits) @@ -799,7 +811,7 @@ WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, } } } - while(ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst); + while(MORE_RBSP_DATA(ps_bitstrm)); return (i4_status); } -- cgit v1.2.3 From dfd1f2ff70714a4598c10430fe1f740187e0b019 Mon Sep 17 00:00:00 2001 From: Shivaansh Agrawal Date: Tue, 28 Jul 2020 21:01:38 +0530 Subject: Decoder: Fix integer overflow in poc calculation Passed error and standard compliance tests with integer and address sanitizers. Bug: 143791063 Test: POC in bug description Change-Id: Idbba64cfb397b8af3ccd5770ce115fadd0d9112c --- decoder/ih264d_parse_pslice.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index 9b9256b..43979dc 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -1494,7 +1494,11 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec, ps_dec->p_motion_compensate = ih264d_motion_compensate_bp; if(ps_dec->ps_cur_pic != NULL) - poc = ps_dec->ps_cur_pic->i4_poc + 2; + { + 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++) -- cgit v1.2.3 From 08b77b23518a3418d2aab55cadb535bd8f1819a9 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Tue, 2 Jul 2019 15:28:05 -0700 Subject: Decoder: Integer overflow fixes in parsing Qp and weights Error checks for syntax elements related to QP, luma and chroma prediction weights have been modified to fix overflow Bug: 136568141 Bug: 143801227 Bug: 143791288 Test: POC in bug description Change-Id: I88e886ba4bcda69079f1b0a8344005fe1aa51366 --- decoder/ih264d_defs.h | 5 +++-- decoder/ih264d_parse_bslice.c | 9 +++++---- decoder/ih264d_parse_headers.c | 14 ++++++++------ decoder/ih264d_parse_islice.c | 11 ++++++----- decoder/ih264d_parse_pslice.c | 9 +++++---- decoder/ih264d_process_pslice.c | 16 ++++++++-------- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h index 2758a59..a9b2064 100644 --- a/decoder/ih264d_defs.h +++ b/decoder/ih264d_defs.h @@ -597,8 +597,9 @@ enum #define DISP_BOT_FLD_FIRST 2 /** Misc error resilience requirements*/ -#define MASK_LOG2_WEIGHT_DENOM 0xFFFFFFF8 -#define MASK_PRED_WEIGHT_OFFSET 0xFFFFFF00 +#define MAX_LOG2_WEIGHT_DENOM 7 +#define PRED_WEIGHT_MIN (-128) +#define PRED_WEIGHT_MAX 127 #define MAX_REDUNDANT_PIC_CNT 127 diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c index 0af4214..b7d3d52 100644 --- a/decoder/ih264d_parse_bslice.c +++ b/decoder/ih264d_parse_bslice.c @@ -34,6 +34,7 @@ */ #include +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1600,13 +1601,13 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) } /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + 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 = i_temp; + ps_slice->u1_slice_qp = i8_temp; COPYTHECONTEXT("SH: slice_qp_delta", (WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp)); diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 674f4c3..7d83d42 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -35,6 +35,7 @@ #include "ih264_typedefs.h" #include "ih264_macros.h" #include "ih264_platform_macros.h" +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_structs.h" #include "ih264d_parse_cavlc.h" @@ -363,20 +364,21 @@ 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; - i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + WORD64 i8_temp = (WORD64)26 + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T; - ps_pps->u1_pic_init_qp = i_temp; + ps_pps->u1_pic_init_qp = i8_temp; COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26); - i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T; - ps_pps->u1_pic_init_qs = i_temp; + 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); diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c index 46a87d1..0b8111a 100644 --- a/decoder/ih264d_parse_islice.c +++ b/decoder/ih264d_parse_islice.c @@ -33,9 +33,10 @@ * \author NS ************************************************************************** */ +#include +#include "ih264_defs.h" #include "ih264d_error_handler.h" #include "ih264d_debug.h" -#include #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1399,11 +1400,11 @@ WORD32 ih264d_parse_islice(dec_struct_t *ps_dec, /* G050 */ /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + 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 = i_temp; + ps_slice->u1_slice_qp = i8_temp; COPYTHECONTEXT("SH: slice_qp_delta", ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp); diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index 9b9256b..141ba0c 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -35,6 +35,7 @@ */ #include +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -2126,13 +2127,13 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) } /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + 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_cur_slice->u1_slice_qp = i_temp; + 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)); diff --git a/decoder/ih264d_process_pslice.c b/decoder/ih264d_process_pslice.c index ed4cbbe..39000ad 100644 --- a/decoder/ih264d_process_pslice.c +++ b/decoder/ih264d_process_pslice.c @@ -829,7 +829,7 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, WORD32 i_temp; u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + if(u4_temp > MAX_LOG2_WEIGHT_DENOM) { return ERROR_PRED_WEIGHT_TABLE_T; } @@ -838,7 +838,7 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, ui32_y_def_weight_ofst = (1 << uc_luma_log2_weight_denom); u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + if(u4_temp > MAX_LOG2_WEIGHT_DENOM) { return ERROR_PRED_WEIGHT_TABLE_T; } @@ -864,14 +864,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, { i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weight = i_temp; COPYTHECONTEXT("SH: luma_weight_l0",c_weight); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offset = i_temp; COPYTHECONTEXT("SH: luma_offset_l0",c_offset); @@ -894,14 +894,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, { i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weightCb = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCb); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offsetCb = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCb); @@ -911,14 +911,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weightCr = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCr); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offsetCr = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCr); -- cgit v1.2.3 From f792904577da8d8194e0809c542754190596f9fa Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 12 Aug 2020 18:59:56 -0700 Subject: decoder: Update reorder depth to account for display latency Decoder returns output with an additional latency of 2. reorder depth retured is now updated to account for this extra latency Also move reorder_depth initialization to parse_sps() Instead of initializing reorder_depth after decoding first picture, initialize it in parse_sps(). Bug: 163127030 Test: poc in bug Test: atest android.mediav2.cts Change-Id: I94b35b2c5df5c910d0159548b168617946a19cc2 --- decoder/ih264d_defs.h | 5 +++++ decoder/ih264d_parse_headers.c | 17 +++++++++++++++++ decoder/ih264d_utils.c | 1 - 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h index 2758a59..73604f1 100644 --- a/decoder/ih264d_defs.h +++ b/decoder/ih264d_defs.h @@ -45,6 +45,11 @@ #define FMT_CONV_NUM_ROWS 16 +/** Decoder currently has an additional latency of 2 pictures when + * returning output for display + */ +#define DISPLAY_LATENCY 2 + /** Bit manipulation macros */ #define CHECKBIT(a,i) ((a) & (1 << i)) #define CLEARBIT(a,i) ((a) &= ~(1 << i)) diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 674f4c3..793f604 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -1091,6 +1091,23 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /*--------------------------------------------------------------------*/ /* 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_dec->i4_reorder_depth = reorder_depth + DISPLAY_LATENCY; + } ps_dec->u2_disp_height = i4_cropped_ht; ps_dec->u2_disp_width = i4_cropped_wd; diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 1fe9a5b..b3f4593 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -770,7 +770,6 @@ WORD32 ih264d_init_pic(dec_struct_t *ps_dec, else ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames * 2 + 2; } - ps_dec->i4_reorder_depth = ps_dec->i4_display_delay; if(IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) ps_dec->i4_display_delay = 0; -- cgit v1.2.3 From 8217d22de96aac2c3ece79c53ac824fc1bcacef1 Mon Sep 17 00:00:00 2001 From: Manisha Jajoo Date: Fri, 7 Aug 2020 14:29:57 +0530 Subject: Decoder: Fix unsigned integer overflow Fix integer overflow issues in parse functions Test: poc in bug Bug: 143791646 Bug: 150045816 Change-Id: Ie0bde7a5cf266fe327b1d5e43fffe28f6e402188 --- decoder/ih264d_parse_bslice.c | 25 +++++++++--------- decoder/ih264d_parse_headers.c | 59 ++++++++++++++++++++++-------------------- decoder/ih264d_parse_pslice.c | 14 +++++----- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c index b7d3d52..8b50372 100644 --- a/decoder/ih264d_parse_bslice.c +++ b/decoder/ih264d_parse_bslice.c @@ -1355,6 +1355,7 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) 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, ui_temp1; WORD32 i_temp; WORD32 ret; @@ -1381,31 +1382,31 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_slice->u1_num_ref_idx_active_override_flag); - u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; - ui_temp1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1]; + 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) { - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + u8_ref_idx_l0 = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", - u4_temp - 1); - ui_temp1 = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + 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", - ui_temp1 - 1); + u8_ref_idx_l1 - 1); } { - UWORD8 u1_max_ref_idx = MAX_FRAMES; + UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS; if(ps_slice->u1_field_pic_flag) { - u1_max_ref_idx = MAX_FRAMES << 1; + u1_max_ref_idx = H264_MAX_REF_PICS << 1; } - if((u4_temp > u1_max_ref_idx) || (ui_temp1 > u1_max_ref_idx) - || (u4_temp < 1) || (ui_temp1 < 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] = u4_temp; - ps_slice->u1_num_ref_idx_lx_active[1] = ui_temp1; + ps_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0; + ps_slice->u1_num_ref_idx_lx_active[1] = u8_ref_idx_l1; } diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 2b277b9..db1f2e8 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -276,6 +276,7 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) 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; @@ -328,30 +329,28 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode num_slice_groups_minus1 */ /*--------------------------------------------------------------------*/ - u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; - if(u4_temp != 1) + u8_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1; + if(u8_temp != 1) { - UWORD32 i4_error_code; - i4_error_code = ERROR_FEATURE_UNAVAIL; - return i4_error_code; + return ERROR_FEATURE_UNAVAIL; } - ps_pps->u1_num_slice_groups = u4_temp; + ps_pps->u1_num_slice_groups = u8_temp; COPYTHECONTEXT("PPS: num_slice_groups_minus1",ps_pps->u1_num_slice_groups -1); /*--------------------------------------------------------------------*/ /* Other parameter set values */ /*--------------------------------------------------------------------*/ - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > H264_MAX_REF_IDX) + 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] = u4_temp; + ps_pps->u1_num_ref_idx_lx_active[0] = u8_temp; COPYTHECONTEXT("PPS: num_ref_idx_l0_active_minus1", ps_pps->u1_num_ref_idx_lx_active[0] - 1); - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > H264_MAX_REF_IDX) + 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] = u4_temp; + ps_pps->u1_num_ref_idx_lx_active[1] = u8_temp; COPYTHECONTEXT("PPS: num_ref_idx_l1_active_minus1", ps_pps->u1_num_ref_idx_lx_active[1] - 1); @@ -573,6 +572,7 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_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; @@ -763,12 +763,12 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode MaxFrameNum */ /*--------------------------------------------------------------------*/ - u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > MAX_BITS_IN_FRAME_NUM) + 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 = u4_temp; + ps_seq->u1_bits_in_frm_num = u8_temp; COPYTHECONTEXT("SPS: log2_max_frame_num_minus4", (ps_seq->u1_bits_in_frm_num - 4)); @@ -789,14 +789,14 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1; if(ps_seq->u1_pic_order_cnt_type == 0) { - u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > MAX_BITS_IN_POC_LSB) + 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 = u4_temp; - ps_seq->i4_max_pic_order_cntLsb = (1 << u4_temp); - COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u4_temp - 4)); + ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = 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) { @@ -856,20 +856,23 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode FrameWidth and FrameHeight and related values */ /*--------------------------------------------------------------------*/ - u4_pic_width_in_mbs = 1 - + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + 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 = u8_temp; COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1", u4_pic_width_in_mbs - 1); - u4_pic_height_in_map_units = 1 + ih264d_uev(pu4_bitstrm_ofst, - pu4_bitstrm_buf); - - /* Check for unsupported resolutions*/ - if((u4_pic_width_in_mbs > (H264_MAX_FRAME_WIDTH >> 4)) || - (u4_pic_height_in_map_units > (H264_MAX_FRAME_HEIGHT >> 4))) + 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 = 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; diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index fa2a2a8..6f8df9e 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -1927,6 +1927,7 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; //ps_dec->ps_cur_sps->u1_mb_aff_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; @@ -1955,22 +1956,19 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_cur_slice->u1_num_ref_idx_active_override_flag); - u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; + 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) { - u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; + u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1; } { - - - - UWORD8 u1_max_ref_idx = MAX_FRAMES << u1_field_pic_flag; - if(u4_temp > u1_max_ref_idx || u4_temp < 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] = u4_temp; + ps_cur_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0; COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1); -- cgit v1.2.3 From 31e921e47ad064ca791bb8ded98a307283516e42 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Thu, 6 Aug 2020 14:15:27 -0700 Subject: Include a shared media team OWNERS for easier management Bug: 162786146 Test: n Change-Id: I6679f2b77066f8624fc1549ebcf40ddca4fcb730 --- OWNERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OWNERS b/OWNERS index acffb3a..b2faa25 100644 --- a/OWNERS +++ b/OWNERS @@ -1,4 +1,4 @@ -marcone@google.com +# owners for external/libavc +include platform/frameworks/av:/media/janitors/OWNERS-codecs essick@google.com -lajos@google.com -hkuang@google.com +hkuang@google.com \ No newline at end of file -- cgit v1.2.3 From 2a28c97cd6ad36675007f536d580c968b73c04ba Mon Sep 17 00:00:00 2001 From: Shivaansh Agrawal Date: Thu, 27 Aug 2020 19:17:35 +0530 Subject: Decoder: Fix NPD issue in mmco function Skip mmco buffer operations if mmco error in sequence Bug: 168426116 Bug: 168426117 Test: POC in bug description Change-Id: Ia4f3f48137152e211322ed97f2fafab2f45cb2c3 --- decoder/ih264d_dpb_manager.h | 1 + decoder/ih264d_dpb_mgr.c | 2 ++ decoder/ih264d_utils.c | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/decoder/ih264d_dpb_manager.h b/decoder/ih264d_dpb_manager.h index 3bf00b7..5747016 100644 --- a/decoder/ih264d_dpb_manager.h +++ b/decoder/ih264d_dpb_manager.h @@ -106,6 +106,7 @@ typedef struct WORD8 i1_gaps_deleted; UWORD16 u2_pic_wd; UWORD16 u2_pic_ht; + UWORD8 u1_mmco_error_in_seq; }dpb_manager_t; /** Structure store the MMC Commands */ diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c index 28c9619..ce977d7 100644 --- a/decoder/ih264d_dpb_mgr.c +++ b/decoder/ih264d_dpb_mgr.c @@ -88,6 +88,7 @@ void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr) ps_dpb_mgr->ps_dpb_ht_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; for(i = 0; i < MAX_FRAMES; i++) @@ -647,6 +648,7 @@ void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr) 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_ht_head = NULL; + ps_dpb_mgr->u1_mmco_error_in_seq = 0; /* release all gaps */ ps_dpb_mgr->u1_num_gaps = 0; diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 0893c3f..b7e68b1 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -501,6 +501,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) { if(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) { + ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = 0; if(ps_dec->ps_dpb_cmds->u1_long_term_reference_flag == 0) { ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); @@ -538,16 +539,17 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) { UWORD16 u2_pic_num = ps_cur_slice->u2_frame_num; - /* ignore DPB errors */ - ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr, - ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num, - (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1), - ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic, - ps_dec->u1_pic_buf_id, - ps_cur_slice->u1_field_pic_flag, - ps_dec->e_dec_status); - - + if(!ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq) + { + WORD32 ret = ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr, + ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num, + (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1), + ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic, + ps_dec->u1_pic_buf_id, + ps_cur_slice->u1_field_pic_flag, + ps_dec->e_dec_status); + ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = ret != OK; + } } } ih264d_update_default_index_list(ps_dec->ps_dpb_mgr); -- cgit v1.2.3 From fcf0c2774c265fe1aca527f5622c8c8a9d67bd23 Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Fri, 31 Jul 2020 18:20:19 +0530 Subject: Decoder: Fix integer overflow when scaling motion vectors Typecast to 64-bits for valid overflowing arithmetic operations Bug: 143791664 Bug: 150044751 Test: poc in bug description Change-Id: I1b938c7c2d4d817979fff65ab271a42f6bdc3e89 --- decoder/ih264d_parse_bslice.c | 30 +++++++++++++++--------------- decoder/ih264d_process_bslice.c | 38 ++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c index b7d3d52..1961cac 100644 --- a/decoder/ih264d_parse_bslice.c +++ b/decoder/ih264d_parse_bslice.c @@ -1197,8 +1197,8 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) UWORD8 i, j; struct pic_buffer_t *ps_pic_buff0, *ps_pic_buff1; WORD16 i2_dist_scale_factor; - WORD16 i16_tb, i16_td, i16_tx; - WORD32 i4_tb, i4_td; + WORD16 i2_tb, i2_td, i2_tx; + WORD64 i8_tb, i8_td; WORD32 i4_poc0, i4_poc1; UWORD32 ui_temp0, ui_temp1; UWORD8 uc_num_ref_idx_l0_active, uc_num_ref_idx_l1_active; @@ -1220,13 +1220,13 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) if(i4_poc1 != i4_poc0) { - i4_tb = ps_dec->ps_cur_pic->i4_poc - i4_poc0; - i16_tb = CLIP_S8(i4_tb); - i4_td = i4_poc1 - i4_poc0; - i16_td = CLIP_S8(i4_td); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i8_tb = (WORD64)ps_dec->ps_cur_pic->i4_poc - i4_poc0; + i2_tb = CLIP_S8(i8_tb); + i8_td = (WORD64)i4_poc1 - i4_poc0; + i2_td = CLIP_S8(i8_td); + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1))) / i2_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); + (((i2_tb * i2_tx) + 32) >> 6)); if(/*((u4_poc1 - u4_poc0) == 0) ||*/ (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) @@ -1290,14 +1290,14 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) i4_poc1 = ps_pic_buff1->i4_poc; if(i4_poc1 != i4_poc0) { - i4_tb = i4_cur_poc - i4_poc0; - i16_tb = CLIP_S8(i4_tb); - i4_td = i4_poc1 - i4_poc0; - i16_td = CLIP_S8(i4_td); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) - / i16_td; + i8_tb = (WORD64)i4_cur_poc - i4_poc0; + i2_tb = CLIP_S8(i8_tb); + i8_td = (WORD64)i4_poc1 - i4_poc0; + i2_td = CLIP_S8(i8_td); + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1))) + / i2_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); + (((i2_tb * i2_tx) + 32) >> 6)); if(/*((u4_poc1 - u4_poc0) == 0) ||*/ (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) diff --git a/decoder/ih264d_process_bslice.c b/decoder/ih264d_process_bslice.c index 5dfba33..fffa586 100644 --- a/decoder/ih264d_process_bslice.c +++ b/decoder/ih264d_process_bslice.c @@ -756,7 +756,7 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, } { WORD16 i16_td; - WORD32 diff; + WORD64 diff; if(c_refFrm0 >= 0) { i2_mv_x0 = ps_mv->i2_mv[0]; @@ -782,7 +782,7 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, i2_mv_y0 *= 2; } - diff = pic1_poc - pic0_poc; + diff = (WORD64)pic1_poc - pic0_poc; i16_td = CLIP_S8(diff); if((ps_pic_buff0->u1_is_short == 0) || (i16_td == 0)) { @@ -791,21 +791,21 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, } else { - WORD16 i16_tb, i16_tx, i2_dist_scale_factor, i16_temp; + WORD16 i2_tb, i2_tx, i2_dist_scale_factor, i2_temp; - diff = cur_poc - pic0_poc; - i16_tb = CLIP_S8(diff); + diff = (WORD64)cur_poc - pic0_poc; + i2_tb = CLIP_S8(diff); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); - i16_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8; - i2_mv_x1 = i16_temp - i2_mv_x0; - i2_mv_x0 = i16_temp; - - i16_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8; - i2_mv_y1 = i16_temp - i2_mv_y0; - i2_mv_y0 = i16_temp; + (((i2_tb * i2_tx) + 32) >> 6)); + i2_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_x1 = i2_temp - i2_mv_x0; + i2_mv_x0 = i2_temp; + + i2_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_y1 = i2_temp - i2_mv_y0; + i2_mv_y0 = i2_temp; } { mv_pred_t *ps_mv; @@ -2304,8 +2304,9 @@ void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, { if(ABS(ps_col_pic->i4_top_field_order_cnt - - ps_dec->ps_cur_pic->i4_poc) >= - ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + - (WORD64)ps_dec->ps_cur_pic->i4_poc) >= + ABS((WORD64)ps_dec->ps_cur_pic->i4_poc + - ps_col_pic->i4_bottom_field_order_cnt)) { ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; } @@ -2336,8 +2337,9 @@ void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, if(u1_is_cur_mb_fld == 0) { if(ABS(ps_col_pic->i4_top_field_order_cnt - - ps_dec->ps_cur_pic->i4_poc) >= - ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + - (WORD64)ps_dec->ps_cur_pic->i4_poc) >= + ABS((WORD64)ps_dec->ps_cur_pic->i4_poc + - ps_col_pic->i4_bottom_field_order_cnt)) { u2_sub_mb_ofst += 0x10; } -- cgit v1.2.3 From 443b1026982b03e719f1d66b06c8f2219f423f9d Mon Sep 17 00:00:00 2001 From: Sachin Kumar Garg Date: Thu, 15 Oct 2020 23:36:54 +0530 Subject: Added avc_enc_fuzzer Test: ./avc_enc_fuzzer Bug: 170942938 Change-Id: I35ecdbad6bbd41684b81efe73a0f87f74e1ef8bb --- fuzzer/Android.bp | 22 + fuzzer/README.md | 132 ++++++ fuzzer/avc_enc_fuzzer.cpp | 1001 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1155 insertions(+) create mode 100644 fuzzer/avc_enc_fuzzer.cpp diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index 95eab84..cb9d246 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -20,3 +20,25 @@ cc_fuzz { componentid: 155276, }, } + +cc_fuzz { + name: "avc_enc_fuzzer", + host_supported: true, + srcs: [ + "avc_enc_fuzzer.cpp", + ], + static_libs: [ + "libavcenc", + "liblog", + ], + cflags: [ + "-Wall", + "-Werror", + ], + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, +} diff --git a/fuzzer/README.md b/fuzzer/README.md index a42e8b5..8e29ec6 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -64,6 +64,138 @@ To run on host $ $ANDROID_HOST_OUT/fuzz/avc_dec_fuzzer CORPUS_DIR ``` + +# Fuzzer for libavc encoder + +## Plugin Design Considerations +The fuzzer plugin for AVC is designed based on the understanding of the +codec and tries to achieve the following: + +##### Maximize code coverage +The configuration parameters are not hardcoded, but instead selected based on +incoming data. This ensures more code paths are reached by the fuzzer. + +AVC supports the following parameters: +1. Frame Width (parameter name: `u4_wd`) +2. Frame Height (parameter name: `u4_ht`) +3. Input color format (parameter name: `e_inp_color_fmt`) +4. Architecture type (parameter name: `e_arch`) +5. Rate control mode (parameter name: `e_rc_mode`) +6. Number of cores (parameter name: `u4_num_cores`) +7. Maximum B frames (parameter name: `u4_num_bframes`) +8. Encoder speed preset (parameter name: `u4_enc_speed_preset`) +9. enable constrained intra prediction (parameter name: `u4_constrained_intra_pred`) +10. enable intra 4x4 (parameter name: `u4_enable_intra_4x4`) +11. Qp for I frames (parameter name: `u4_i_qp`) +12. Qp for P frames (parameter name: `u4_p_qp`) +13. Qp for B frames (parameter name: `u4_b_qp`) +14. Target Bitrate (parameter name: `u4_target_bitrate`) +15. Intra refresh period in frames (parameter name: `u4_air_refresh_period`) +16. Enable half pel ME (parameter name: `u4_enable_hpel`) +17. Enable quarter pel ME (parameter name: `u4_enable_qpel`) +18. ME speed preset (parameter name: `u4_me_speed_preset`) +19. Adaptive intra refresh mode (parameter name: `e_air_mode`) +20. Disable deblock level (parameter name: `u4_disable_deblock_level`) +21. Max search range in X direction (parameter name: `u4_srch_rng_x`) +22. Max search range in Y direction (parameter name: `u4_srch_rng_y`) +23. I frame interval (parameter name: `u4_i_frm_interval`) +24. IDR frame interval (parameter name: `u4_idr_frm_interval`) +25. Enable mastering display color volume info (parameter name: `u1_sei_mdcv_params_present_flag`) +26. Enable content light level info (parameter name: `u1_sei_cll_params_present_flag`) +27. Enable ambient viewing environment info (parameter name: `u1_sei_ave_params_present_flag`) +28. Enable content color volume info (parameter name: `u1_sei_ccv_params_present_flag`) +29. Profile (parameter name: `e_profile`) +30. Enable aspect_ratio info (parameter name: `u1_aspect_ratio_info_present_flag`) +31. Enable NAL HRD parameters presence (parameter name: `u1_nal_hrd_parameters_present_flag`) +32. Enable VCL HRD parameters presence (parameter name: `u1_vcl_hrd_parameters_present_flag`) +33. Enable force IDR frame (parameter name: `mIsForceIdrEnabled`) +34. Enable dynamic bitrate change (parameter name: `mIsDynamicBitRateChangeEnabled`) +35. Enable dynamic framerate change (parameter name: `mIsDynamicFrameRateChangeEnabled`) +36. Force IDR frame number (parameter name: `mForceIdrInterval`) +37. Frame number for dynamic bitrate (parameter name: `mDynamicBitRateInterval`) +38. Frame number for dynamic framerate (parameter name: `mDynamicFrameRateInterval`) + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +| `u4_wd` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data | +| `u4_ht` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data | +| `e_inp_color_fmt` | 0. `IV_YUV_420P` 1. `IV_YUV_420SP_UV` 2. `IV_YUV_422ILE` 3. `IV_YUV_420SP_VU` | All the bits of 5th byte of data | +| `e_arch` | 0. `ARCH_ARM_NONEON` 1. `ARCH_NA` | bit 0 and 1 of 6th byte of data | +| `e_rc_mode` | 0. `IVE_RC_NONE` 1. `IVE_RC_STORAGE` 2. `IVE_RC_CBR_NON_LOW_DELAY` 3. `IVE_RC_CBR_LOW_DELAY` | All the bits of 7th byte of data modulus 4 | +| `u4_num_cores` | 0. `0` 1. `1` 2. `2` 3. `3`| bit 0 and 1 of 8th byte of data | +| `u4_num_bframes` | In the range `0 to 7` | bit 0, 1 and 2 of 9th byte of data | +| `u4_enc_speed_preset` | 0. `IVE_CONFIG` 1. `IVE_SLOWEST` 2. `IVE_NORMAL` 3. `IVE_FAST` 4. `IVE_HIGH_SPEED` 5. `IVE_FASTEST` | All the bits of 10th byte of data modulus 6 | +| `u4_constrained_intra_pred` | 0. `0` 1. `1` | bit 0 of 11th byte of data | +| `u4_enable_intra_4x4` | 0. `0` 1. `1` | bit 0 of 12th byte of data | +| `u4_i_qp` | In the range `4 to 51` | All the bits of 13th byte of data | +| `u4_p_qp` | In the range `4 to 51` | All the bits of 14th byte of data | +| `u4_b_qp` | In the range `4 to 51` | All the bits of 15th byte of data | +| `u4_target_bitrate` | In the range `0 to 500000000` | All the bits of 16th and 17th byte of data | +| `u4_target_bitrate` | In the range `0 to 255` | All the bits of 18th byte of data | +| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data | +| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data | +| `u4_enable_hpel` | 0. `0` 1. `1` | bit 0 of 20th byte of data | +| `u4_enable_qpel` | 0. `0` 1. `1` | bit 0 of 21st byte of data | +| `u4_me_speed_preset` | 0. `0` 1. `50` 2. `75` 3. `100` | All the bits of 22nd byte of data modulus 4 | +| `e_air_mode` | 0. `IVE_AIR_MODE_NONE` 1. `IVE_AIR_MODE_CYCLIC` 2. `IVE_AIR_MODE_RANDOM` | All the bits of 23rd byte of data modulus 3 | +| `u4_disable_deblock_level` | 0. `0` 1. `1` 2. `2` 3. `3` | bit 0 and 1 of 24th byte of data | +| `u4_srch_rng_x` | In the range `0 to 255` | All the bits of 25th byte of data | +| `u4_srch_rng_y` | In the range `0 to 255`| All the bits of 26th byte of data | +| `u4_i_frm_interval` | In the range `1 to 256` | All the bits of 27th byte of data | +| `u4_idr_frm_interval` | In the range `1 to 256` | All the bits of 28th byte of data | +| `u1_sei_mdcv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 29th byte of data | +| `u1_sei_cll_params_present_flag` | 0. `0` 1. `1` | bit 0 of 30th byte of data | +| `u1_sei_ave_params_present_flag` | 0. `0` 1. `1` | bit 0 of 31st byte of data | +| `u1_sei_ccv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 32nd byte of data | +| `e_profile` | 0. `IV_PROFILE_BASE` 1. `IV_PROFILE_MAIN` | bit 0 and 1 of 33th byte of data modulus 2 | +| `u1_aspect_ratio_info_present_flag` | 0. `0` 1. `1` | bit 0 of 34th byte of data | +| `u1_nal_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 35th byte of data | +| `u1_vcl_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 36th byte of data | +| `mIsForceIdrEnabled` | 0. `0` 1. `1` | bit 0 of 37th byte of data | +| `mIsDynamicBitRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 38th byte of data | +| `mIsDynamicFrameRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 39th byte of data | +| `mForceIdrInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 40th byte of data | +| `mDynamicBitRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 41st byte of data | +| `mDynamicFrameRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 42nd byte of data | + +This also ensures that the plugin is always deterministic for any given input. + +##### Maximize utilization of input data +The plugin feeds the entire input data to the codec using a loop. +If the encode operation was successful, the input is advanced by the frame size. +If the encode operation was un-successful, the input is still advanced by frame size so +that the fuzzer can proceed to feed the next frame. + +This ensures that the plugin tolerates any kind of input (empty, huge, +malformed, etc) and doesnt `exit()` on any input and thereby increasing the +chance of identifying vulnerabilities. + +## Build + +This describes steps to build avc_enc_fuzzer binary. + +### Android + +#### Steps to build +Build the fuzzer +``` + $ mm -j$(nproc) avc_enc_fuzzer +``` + +#### Steps to run +Create a directory CORPUS_DIR and copy some yuv files to that folder +Push this directory to device. + +To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR +``` +To run on host +``` + $ $ANDROID_HOST_OUT/fuzz/x86_64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR +``` + ## References: * http://llvm.org/docs/LibFuzzer.html * https://github.com/google/oss-fuzz diff --git a/fuzzer/avc_enc_fuzzer.cpp b/fuzzer/avc_enc_fuzzer.cpp new file mode 100644 index 0000000..e01f6a5 --- /dev/null +++ b/fuzzer/avc_enc_fuzzer.cpp @@ -0,0 +1,1001 @@ +/****************************************************************************** + * + * 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 +#include + +#include "ih264_defs.h" +#include "ih264_typedefs.h" +#include "ih264e.h" +#include "ih264e_error.h" +#define ive_api_function ih264e_api_function + +constexpr uint32_t kHeaderLength = 0x800; +constexpr int16_t kCompressionRatio = 1; + +constexpr int kMeSpeedPreset[] = {0, 50, 75, 100}; +constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE, IVE_AIR_MODE_CYCLIC, IVE_AIR_MODE_RANDOM}; +constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL, + IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST}; +constexpr IV_PROFILE_T kProfle[] = {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, IV_YUV_422ILE, + IV_YUV_420SP_VU}; + +constexpr size_t kAirModeNum = std::size(kAirMode); +constexpr size_t kEncSpeedNum = std::size(kEncSpeed); +constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset); +constexpr size_t kProfleNum = std::size(kProfle); +constexpr size_t kRCModeNum = std::size(kRCMode); +constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats); +constexpr size_t kMinQP = 4; +constexpr size_t kMaxWidth = 10240; +constexpr size_t kMaxHeight = 10240; +constexpr size_t kMaxBitrate = 500000000; + +enum { + 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_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_LAST +}; + +class Codec { + public: + Codec() = default; + ~Codec() { deInitEncoder(); } + bool initEncoder(const uint8_t **pdata, size_t *psize); + void encodeFrames(const uint8_t *data, size_t size); + void deInitEncoder(); + + private: + void setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data); + 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(); + bool mHalfPelEnable = 1; + bool mQPelEnable = 1; + bool mIntra4x4 = 0; + bool mEnableFastSad = 0; + bool mEnableAltRef = 0; + bool mConstrainedIntraFlag = 0; + bool mSeiCllFlag = 1; + bool mSeiAveFlag = 1; + bool mSeiCcvFlag = 1; + bool mSeiMdcvFlag = 1; + bool mAspectRatioFlag = 0; + bool mNalHrdFlag = 0; + bool mVclHrdFlag = 0; + bool mIsForceIdrEnabled = false; + bool mIsDynamicBitRateChangeEnabled = false; + bool mIsDynamicFrameRateChangeEnabled = false; + uint32_t mWidth = 2560; + uint32_t mHeight = 2560; + uint32_t mAvcEncLevel = 41; + uint32_t mNumMemRecords = 0; + uint32_t mNumCores = 1; + uint32_t mBframes = 0; + uint32_t mSliceParam = 256; + uint32_t mMeSpeedPreset = 100; + uint32_t mIInterval = 60; + uint32_t mIDRInterval = 60; + uint32_t mDisableDeblockLevel = 0; + uint32_t m_I_QP = 22; + uint32_t m_P_QP = 28; + uint32_t m_B_QP = 22; + uint32_t mIntraRefresh = 30; + uint32_t mSearchRangeX = 64; + uint32_t mSearchRangeY = 48; + uint32_t mForceIdrInterval = 0; // in number of frames + uint32_t mDynamicBitRateInterval = 0; // in number of frames + uint32_t mDynamicFrameRateInterval = 0; // in number of frames + uint64_t mBitrate = 6000000; + float mFrameRate = 30; + iv_obj_t *mCodecCtx = nullptr; + iv_mem_rec_t *mMemRecords = nullptr; + IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE; + IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL; + IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE; + IV_ARCH_T mArch = ARCH_NA; + IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE; + IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P; + IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P; + IV_PROFILE_T mProfile = IV_PROFILE_BASE; +}; + +bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) { + uint8_t *data = const_cast(*pdata); + mWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth; + mHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight; + + mIvVideoColorFormat = + kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum]; + mArch = ((data[IDX_ARCH_TYPE] & 0x03) == 0x00) ? ARCH_ARM_NONEON : ARCH_NA; + mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum]; + mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1; + mBframes = data[IDX_NUM_B_FRAMES] & 0x07; + 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] % (MAX_H264_QP - kMinQP)) + kMinQP; + m_P_QP = (data[IDX_P_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; + m_B_QP = (data[IDX_B_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; + mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate; + mFrameRate = data[IDX_FRAME_RATE]; + 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 = data[IDX_DISABLE_DEBLOCK_LEVEL] & 0x03; + 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 = kProfle[data[IDX_PROFILE] % kProfleNum]; + 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; + + /* Getting Number of MemRecords */ + iv_num_mem_rec_ip_t sNumMemRecIp{}; + iv_num_mem_rec_op_t sNumMemRecOp{}; + + sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t); + sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t); + sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC; + + if (IV_SUCCESS != ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp)) { + return false; + } + mNumMemRecords = sNumMemRecOp.u4_num_mem_rec; + mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); + if (!mMemRecords) { + return false; + } + iv_mem_rec_t *psMemRec; + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + psMemRec->u4_size = sizeof(iv_mem_rec_t); + psMemRec->pv_base = nullptr; + psMemRec->u4_mem_size = 0; + psMemRec->u4_mem_alignment = 0; + psMemRec->e_mem_type = IV_NA_MEM_TYPE; + ++psMemRec; + } + + /* Getting MemRecords Attributes */ + iv_fill_mem_rec_ip_t sFillMemRecIp{}; + iv_fill_mem_rec_op_t sFillMemRecOp{}; + + sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t); + sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t); + + sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC; + sFillMemRecIp.ps_mem_rec = mMemRecords; + sFillMemRecIp.u4_num_mem_rec = mNumMemRecords; + sFillMemRecIp.u4_max_wd = mWidth; + sFillMemRecIp.u4_max_ht = mHeight; + sFillMemRecIp.u4_max_level = mAvcEncLevel; + sFillMemRecIp.e_color_format = IV_YUV_420SP_VU; + sFillMemRecIp.u4_max_ref_cnt = 2; + sFillMemRecIp.u4_max_reorder_cnt = 0; + sFillMemRecIp.u4_max_srch_rng_x = 256; + sFillMemRecIp.u4_max_srch_rng_y = 256; + + if (IV_SUCCESS != ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp)) { + return false; + } + /* Allocating Memory for Mem Records */ + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size); + if (!psMemRec->pv_base) { + return false; + } + ++psMemRec; + } + + /* Codec Instance Creation */ + ive_init_ip_t sInitIp{}; + ive_init_op_t sInitOp{}; + + mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; + mCodecCtx->u4_size = sizeof(iv_obj_t); + mCodecCtx->pv_fxns = (void *)ive_api_function; + + sInitIp.u4_size = sizeof(ive_init_ip_t); + sInitOp.u4_size = sizeof(ive_init_op_t); + + sInitIp.e_cmd = IV_CMD_INIT; + sInitIp.u4_num_mem_rec = mNumMemRecords; + sInitIp.ps_mem_rec = mMemRecords; + sInitIp.u4_max_wd = mWidth; + sInitIp.u4_max_ht = mHeight; + sInitIp.u4_max_ref_cnt = 2; + sInitIp.u4_max_reorder_cnt = 0; + sInitIp.u4_max_level = mAvcEncLevel; + sInitIp.e_inp_color_fmt = mIvVideoColorFormat; + sInitIp.u4_enable_recon = 0; + sInitIp.e_recon_color_fmt = mReconFormat; + sInitIp.e_rc_mode = mRCMode; + sInitIp.u4_max_framerate = 120000; + sInitIp.u4_max_bitrate = 240000000; + sInitIp.u4_num_bframes = mBframes; + sInitIp.e_content_type = IV_PROGRESSIVE; + sInitIp.u4_max_srch_rng_x = 256; + sInitIp.u4_max_srch_rng_y = 256; + sInitIp.e_slice_mode = mSliceMode; + sInitIp.u4_slice_param = mSliceParam; + sInitIp.e_arch = mArch; + sInitIp.e_soc = SOC_GENERIC; + + if (IV_SUCCESS != ive_api_function(mCodecCtx, &sInitIp, &sInitOp)) { + return false; + } + + logVersion(); + setDefault(); + getBufInfo(); + setNumCores(); + setDimensions(); + setFrameRate(); + setIpeParams(); + setBitRate(); + setQp(); + setAirParams(); + setVbvParams(); + setMeParams(); + setGopParams(); + setDeblockParams(); + setVuiParams(); + setSeiMdcvParams(); + setSeiCllParams(); + setSeiAveParams(); + setSeiCcvParams(); + setProfileParams(); + setEncMode(IVE_ENC_MODE_HEADER); + + *pdata += IDX_LAST; + *psize -= IDX_LAST; + return true; +} + +void Codec::setDimensions() { + ive_ctl_set_dimensions_ip_t sDimensionsIp{}; + ive_ctl_set_dimensions_op_t sDimensionsOp{}; + + sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; + sDimensionsIp.u4_ht = mHeight; + sDimensionsIp.u4_wd = mWidth; + + sDimensionsIp.u4_timestamp_high = -1; + sDimensionsIp.u4_timestamp_low = -1; + + sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t); + sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t); + + ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp); + return; +} + +void Codec::setNumCores() { + ive_ctl_set_num_cores_ip_t sNumCoresIp{}; + ive_ctl_set_num_cores_op_t sNumCoresOp{}; + + sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL; + sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; + sNumCoresIp.u4_num_cores = mNumCores; + + sNumCoresIp.u4_timestamp_high = -1; + sNumCoresIp.u4_timestamp_low = -1; + + sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t); + sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t); + + ive_api_function(mCodecCtx, (void *)&sNumCoresIp, (void *)&sNumCoresOp); + return; +} + +void Codec::setDefault() { + ive_ctl_setdefault_ip_t sDefaultIp{}; + ive_ctl_setdefault_op_t sDefaultOp{}; + + sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT; + + sDefaultIp.u4_timestamp_high = -1; + sDefaultIp.u4_timestamp_low = -1; + + sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t); + sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t); + + ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp); + return; +} + +void Codec::getBufInfo() { + ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp{}; + ih264e_ctl_getbufinfo_op_t sGetBufInfoOp{}; + + sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); + sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); + + sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; + sGetBufInfoIp.s_ive_ip.u4_max_ht = mHeight; + sGetBufInfoIp.s_ive_ip.u4_max_wd = mWidth; + sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat; + + ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp); + return; +} + +void Codec::setFrameRate() { + ive_ctl_set_frame_rate_ip_t sFrameRateIp{}; + ive_ctl_set_frame_rate_op_t sFrameRateOp{}; + + sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; + sFrameRateIp.u4_src_frame_rate = mFrameRate; + sFrameRateIp.u4_tgt_frame_rate = mFrameRate; + + sFrameRateIp.u4_timestamp_high = -1; + sFrameRateIp.u4_timestamp_low = -1; + + sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t); + sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t); + + ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp); + return; +} + +void Codec::setIpeParams() { + ive_ctl_set_ipe_params_ip_t sIpeParamsIp{}; + ive_ctl_set_ipe_params_op_t sIpeParamsOp{}; + + sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4; + sIpeParamsIp.u4_enc_speed_preset = mEncSpeed; + sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag; + + sIpeParamsIp.u4_timestamp_high = -1; + sIpeParamsIp.u4_timestamp_low = -1; + + sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t); + sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t); + + ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp); + return; +} + +void Codec::setBitRate() { + ive_ctl_set_bitrate_ip_t sBitrateIp{}; + ive_ctl_set_bitrate_op_t sBitrateOp{}; + + sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; + sBitrateIp.u4_target_bitrate = mBitrate; + + sBitrateIp.u4_timestamp_high = -1; + sBitrateIp.u4_timestamp_low = -1; + + sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t); + sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t); + + ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp); + return; +} + +void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) { + ive_ctl_set_frame_type_ip_t sFrameTypeIp{}; + ive_ctl_set_frame_type_op_t sFrameTypeOp{}; + + sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; + sFrameTypeIp.e_frame_type = eFrameType; + + sFrameTypeIp.u4_timestamp_high = -1; + sFrameTypeIp.u4_timestamp_low = -1; + + sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t); + sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t); + + ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp); + return; +} + +void Codec::setQp() { + ive_ctl_set_qp_ip_t s_QpIp{}; + ive_ctl_set_qp_op_t s_QpOp{}; + + s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL; + s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP; + + s_QpIp.u4_i_qp = m_I_QP; + s_QpIp.u4_i_qp_max = MAX_H264_QP; + s_QpIp.u4_i_qp_min = kMinQP; + + s_QpIp.u4_p_qp = m_P_QP; + s_QpIp.u4_p_qp_max = MAX_H264_QP; + s_QpIp.u4_p_qp_min = kMinQP; + + s_QpIp.u4_b_qp = m_B_QP; + s_QpIp.u4_b_qp_max = MAX_H264_QP; + s_QpIp.u4_b_qp_min = kMinQP; + + s_QpIp.u4_timestamp_high = -1; + s_QpIp.u4_timestamp_low = -1; + + s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t); + s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t); + + ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp); + return; +} + +void Codec::setEncMode(IVE_ENC_MODE_T eEncMode) { + ive_ctl_set_enc_mode_ip_t sEncModeIp{}; + ive_ctl_set_enc_mode_op_t sEncModeOp{}; + + sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; + sEncModeIp.e_enc_mode = eEncMode; + + sEncModeIp.u4_timestamp_high = -1; + sEncModeIp.u4_timestamp_low = -1; + + sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t); + sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t); + + ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp); + return; +} + +void Codec::setVbvParams() { + ive_ctl_set_vbv_params_ip_t sVbvIp{}; + ive_ctl_set_vbv_params_op_t sVbvOp{}; + + sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; + sVbvIp.u4_vbv_buf_size = 0; + sVbvIp.u4_vbv_buffer_delay = 1000; + + sVbvIp.u4_timestamp_high = -1; + sVbvIp.u4_timestamp_low = -1; + + sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t); + sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t); + + ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp); + return; +} + +void Codec::setAirParams() { + ive_ctl_set_air_params_ip_t sAirIp{}; + ive_ctl_set_air_params_op_t sAirOp{}; + + sAirIp.e_cmd = IVE_CMD_VIDEO_CTL; + sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; + sAirIp.e_air_mode = mAirMode; + sAirIp.u4_air_refresh_period = mIntraRefresh; + + sAirIp.u4_timestamp_high = -1; + sAirIp.u4_timestamp_low = -1; + + sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t); + sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t); + + ive_api_function(mCodecCtx, &sAirIp, &sAirOp); + return; +} + +void Codec::setMeParams() { + ive_ctl_set_me_params_ip_t sMeParamsIp{}; + ive_ctl_set_me_params_op_t sMeParamsOp{}; + + sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; + sMeParamsIp.u4_enable_fast_sad = mEnableFastSad; + sMeParamsIp.u4_enable_alt_ref = mEnableAltRef; + + sMeParamsIp.u4_enable_hpel = mHalfPelEnable; + sMeParamsIp.u4_enable_qpel = mQPelEnable; + sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset; + sMeParamsIp.u4_srch_rng_x = mSearchRangeX; + sMeParamsIp.u4_srch_rng_y = mSearchRangeY; + + sMeParamsIp.u4_timestamp_high = -1; + sMeParamsIp.u4_timestamp_low = -1; + + sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t); + sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t); + + ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp); + return; +} + +void Codec::setGopParams() { + ive_ctl_set_gop_params_ip_t sGopParamsIp{}; + ive_ctl_set_gop_params_op_t sGopParamsOp{}; + + sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; + + sGopParamsIp.u4_i_frm_interval = mIInterval; + sGopParamsIp.u4_idr_frm_interval = mIDRInterval; + + sGopParamsIp.u4_timestamp_high = -1; + sGopParamsIp.u4_timestamp_low = -1; + + sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t); + sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t); + + ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp); + return; +} + +void Codec::setProfileParams() { + ive_ctl_set_profile_params_ip_t sProfileParamsIp{}; + ive_ctl_set_profile_params_op_t sProfileParamsOp{}; + + sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; + + sProfileParamsIp.e_profile = mProfile; + if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) { + sProfileParamsIp.u4_entropy_coding_mode = 0; + } else { + sProfileParamsIp.u4_entropy_coding_mode = 1; + } + sProfileParamsIp.u4_timestamp_high = -1; + sProfileParamsIp.u4_timestamp_low = -1; + + sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t); + sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t); + + ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp); + return; +} + +void Codec::setDeblockParams() { + ive_ctl_set_deblock_params_ip_t sDeblockParamsIp{}; + ive_ctl_set_deblock_params_op_t sDeblockParamsOp{}; + + sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; + + sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel; + + sDeblockParamsIp.u4_timestamp_high = -1; + sDeblockParamsIp.u4_timestamp_low = -1; + + sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t); + sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t); + + ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp); + return; +} + +void Codec::setVuiParams() { + ih264e_vui_ip_t sVuiParamsIp{}; + ih264e_vui_op_t sVuiParamsOp{}; + + sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVuiParamsIp.e_sub_cmd = IVE_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 = 1; + 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(ih264e_vui_ip_t); + sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t); + + ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp); + return; +} + +void Codec::setSeiMdcvParams() { + ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{}; + ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{}; + + sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS; + sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag; + if (mSeiMdcvFlag) { + for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++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 = -1; + sSeiMdcvParamsIp.u4_timestamp_low = -1; + + sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t); + sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t); + ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp); + return; +} + +void Codec::setSeiCllParams() { + ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{}; + ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{}; + + sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCllParamsIp.e_sub_cmd = IVE_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 = -1; + sSeiCllParamsIp.u4_timestamp_low = -1; + + sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t); + sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp); + return; +} + +void Codec::setSeiAveParams() { + ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{}; + ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{}; + + sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiAveParamsIp.e_sub_cmd = IVE_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 = -1; + sSeiAveParamsIp.u4_timestamp_low = -1; + + sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t); + sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp); + return; +} + +void Codec::setSeiCcvParams() { + ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{}; + ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{}; + + sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCcvParamsIp.e_sub_cmd = IVE_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 < NUM_SEI_CCV_PRIMARIES; ++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 = -1; + sSeiCcvParamsIp.u4_timestamp_low = -1; + + sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t); + sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp); + return; +} + +void Codec::logVersion() { + ive_ctl_getversioninfo_ip_t sCtlIp{}; + ive_ctl_getversioninfo_op_t sCtlOp{}; + UWORD8 au1Buf[512]; + + sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL; + sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION; + + sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t); + sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t); + sCtlIp.pu1_version = au1Buf; + sCtlIp.u4_version_bufsize = sizeof(au1Buf); + + ive_api_function(mCodecCtx, (void *)&sCtlIp, (void *)&sCtlOp); + return; +} + +void Codec::encodeFrames(const uint8_t *data, size_t size) { + size_t frameSize = (mIvVideoColorFormat == IV_YUV_422ILE) ? (mWidth * mHeight * 2) + : ((mWidth * mHeight * 3) / 2); + ive_video_encode_ip_t sEncodeIp{}; + ive_video_encode_op_t sEncodeOp{}; + uint8_t header[kHeaderLength]; + iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf; + sEncodeIp.s_out_buf.pv_buf = header; + sEncodeIp.s_out_buf.u4_bytes = 0; + sEncodeIp.s_out_buf.u4_bufsize = kHeaderLength; + sEncodeIp.u4_size = sizeof(ive_video_encode_ip_t); + sEncodeOp.u4_size = sizeof(ive_video_encode_op_t); + + sEncodeIp.e_cmd = IVE_CMD_VIDEO_ENCODE; + sEncodeIp.pv_bufs = nullptr; + sEncodeIp.pv_mb_info = nullptr; + sEncodeIp.pv_pic_info = nullptr; + sEncodeIp.u4_mb_info_type = 0; + sEncodeIp.u4_pic_info_type = 0; + sEncodeIp.u4_is_last = 0; + sEncodeOp.s_out_buf.pv_buf = nullptr; + + /* Initialize color formats */ + memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t)); + psInpRawBuf->u4_size = sizeof(iv_raw_buf_t); + psInpRawBuf->e_color_fmt = mIvVideoColorFormat; + + ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); + size_t numFrame = 0; + while (size > 0) { + uint8_t *tmpData = (uint8_t *)malloc(frameSize); + size_t bytesConsumed = std::min(size, frameSize); + if (bytesConsumed < frameSize) { + memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed); + } + memcpy(tmpData, data, bytesConsumed); + setEncParams(psInpRawBuf, tmpData); + uint64_t OutputBufferSize = (frameSize / kCompressionRatio); + uint8_t *OutputBuffer = (uint8_t *)malloc(OutputBufferSize); + sEncodeIp.s_out_buf.pv_buf = OutputBuffer; + sEncodeIp.s_out_buf.u4_bufsize = OutputBufferSize; + if (mIsForceIdrEnabled) { + if (numFrame == mForceIdrInterval) { + setFrameType(IV_IDR_FRAME); + } + } + if (mIsDynamicBitRateChangeEnabled) { + if (numFrame == mDynamicBitRateInterval) { + if (data[0] & 0x01) { + mBitrate *= 2; + } else { + mBitrate /= 2; + } + setBitRate(); + } + } + if (mIsDynamicFrameRateChangeEnabled) { + if (numFrame == mDynamicFrameRateInterval) { + if (size > 1 && data[1] & 0x01) { + mFrameRate *= 2; + } else { + mFrameRate /= 2; + } + setFrameRate(); + } + } + ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); + ++numFrame; + data += bytesConsumed; + size -= bytesConsumed; + free(tmpData); + free(OutputBuffer); + } +} + +void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { + switch (mIvVideoColorFormat) { + case IV_YUV_420SP_UV: + [[fallthrough]]; + case IV_YUV_420SP_VU: { + uint8_t *yPlane = const_cast(data); + uint8_t *uPlane = const_cast(data + (mWidth * mHeight)); + int32_t yStride = mWidth; + int32_t uStride = mWidth / 2; + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + + psInpRawBuf->au4_wd[0] = mWidth; + psInpRawBuf->au4_wd[1] = mWidth; + + psInpRawBuf->au4_ht[0] = mHeight; + psInpRawBuf->au4_ht[1] = mHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + break; + } + case IV_YUV_422ILE: { + uint8_t *yPlane = const_cast(data); + psInpRawBuf->apv_bufs[0] = yPlane; + + psInpRawBuf->au4_wd[0] = mWidth * 2; + + psInpRawBuf->au4_ht[0] = mHeight; + + psInpRawBuf->au4_strd[0] = mWidth * 2; + break; + } + case IV_YUV_420P: + [[fallthrough]]; + default: { + uint8_t *yPlane = const_cast(data); + uint8_t *uPlane = const_cast(data + (mWidth * mHeight)); + uint8_t *vPlane = const_cast(data + ((mWidth * mHeight) * 5) / 4); + int32_t yStride = mWidth; + int32_t uStride = mWidth / 2; + int32_t vStride = mWidth / 2; + + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + psInpRawBuf->apv_bufs[2] = vPlane; + + psInpRawBuf->au4_wd[0] = mWidth; + psInpRawBuf->au4_wd[1] = mWidth / 2; + psInpRawBuf->au4_wd[2] = mWidth / 2; + + psInpRawBuf->au4_ht[0] = mHeight; + psInpRawBuf->au4_ht[1] = mHeight / 2; + psInpRawBuf->au4_ht[2] = mHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + psInpRawBuf->au4_strd[2] = vStride; + break; + } + } + return; +} + +void Codec::deInitEncoder() { + iv_mem_rec_t *ps_mem_rec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + if (ps_mem_rec) { + free(ps_mem_rec->pv_base); + } + ++ps_mem_rec; + } + if (mMemRecords) { + free(mMemRecords); + } + mCodecCtx = nullptr; + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size < IDX_LAST) { + return 0; + } + Codec *codec = new Codec(); + if (codec->initEncoder(&data, &size)) { + codec->encodeFrames(data, size); + } + delete codec; + return 0; +} -- cgit v1.2.3 From cd1928dca16d263e47c61625f3f2c55a3a48d57f Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 3 Feb 2016 10:56:25 +0530 Subject: Encoder: Fix in returning recon buffers with smaller IDR interval For every IDR generated after the first one, one recon buffer was not released from the buffer manager, when recon was enabled. This resulted in encoder returning with an error after couple of IDRs when recon was enabled. This is fixed by calling recon buffer release based on pic_cnt instead of frm_num. frm_num is reset to 0 for every IDR where as pic_cnt is not. Bug: 173150684 Test: avcenc -i qcif.yuv -w 176 -h 144 -o out.h264 \ --bframes 2 --idr_interval 4 --recon_enable 1 \ --recon recon.yuv Change-Id: I8b72e5aedc6a460292388e4e46f56c07486db4a6 --- encoder/ih264e_encode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index fb37765..9210b3e 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -545,16 +545,16 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) * 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_frame_num > 1 - * 2) When the input buffer is null [ ie we are not consuming any inp] + * 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_frame_num > 1 || s_inp_buf.u4_is_last) - && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last)) + if (ps_codec->s_cfg.u4_enable_recon + && (ps_codec->i4_pic_cnt > (WORD32)ps_codec->s_cfg.u4_num_bframes || + s_inp_buf.u4_is_last)) { /* error status */ IH264_ERROR_T ret = IH264_SUCCESS; -- cgit v1.2.3 From 29393d25cdc676571e110105671ac76f92849c35 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 3 Feb 2016 11:06:18 +0530 Subject: avcenc: Fix PSNR computation for 420 semi-planar output in test PSNR computation for 420 Semi-planar recon was incorrect. Bug: 173151765 Test: avcenc -i qcif.yuv -w 176 -h 144 --bitrate 512000 \ -o out.h264 --recon_enable 1 --recon recon.yuv \ --input_chroma_format YUV_420SP_VU --recon_chroma_format \ YUV_420SP_VU --num_frames 4 --psnr 1 Change-Id: I8de628107894bfdef6027f865b235aa01349bc4d --- test/encoder/psnr.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/test/encoder/psnr.c b/test/encoder/psnr.c index d5a953c..87a03b0 100644 --- a/test/encoder/psnr.c +++ b/test/encoder/psnr.c @@ -111,13 +111,13 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * 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]; - strd2 = ps_buf2->au4_strd[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_UV == ps_buf1->e_color_fmt)) + || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt)) { switch(comp) { @@ -130,6 +130,8 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * 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) @@ -137,11 +139,14 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * 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_UV == ps_buf2->e_color_fmt)) + || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt)) { switch(comp) { @@ -153,14 +158,21 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * pu1_buf2 = ps_buf2->apv_bufs[1]; else pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; - incr1 = 2; + 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]; - incr1 = 2; + 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; } } @@ -175,8 +187,8 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * pu1_buf2 += incr2; df_psnr[comp] += diff * diff; } - pu1_buf1 += strd1 - ps_buf1->au4_wd[comp]; - pu1_buf2 += strd2 - ps_buf2->au4_wd[comp]; + pu1_buf1 += strd1; + pu1_buf2 += strd2; } df_psnr[comp] /= (wd * ht); if(df_psnr[comp]) -- cgit v1.2.3 From 6efeedf0633e1965a4d4e17d64f14215e9b6d48f Mon Sep 17 00:00:00 2001 From: Shivaansh Agrawal Date: Tue, 17 Nov 2020 20:56:42 +0530 Subject: Decoder: Fix integer overflow in parse slice Bug: 165976727 Test: POC in bug description Change-Id: Ia2c8ad5fe6e212d3910a9c91cda52c19f3fac120 --- decoder/ih264d_error_handler.h | 3 +- decoder/ih264d_parse_slice.c | 14 ++++++- decoder/ih264d_utils.c | 88 +++++++++++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h index 6cdbc81..a651c46 100644 --- a/decoder/ih264d_error_handler.h +++ b/decoder/ih264d_error_handler.h @@ -122,7 +122,8 @@ typedef enum ERROR_INV_SEI_MDCV_PARAMS = 0x9C, ERROR_INV_SEI_CLL_PARAMS = 0x9D, ERROR_INV_SEI_AVE_PARAMS = 0x9E, - ERROR_INV_SEI_CCV_PARAMS = 0x9F + ERROR_INV_SEI_CCV_PARAMS = 0x9F, + ERROR_INV_FRAME_NUM = 0xA0 } h264_decoder_error_code_t; diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index d807f11..97c47d3 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1472,10 +1472,20 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, else i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; - ps_dec->ps_cur_pic->i4_top_field_order_cnt = i4_temp_poc + WORD64 i8_result = (WORD64)i4_temp_poc - ps_dec->ps_cur_pic->i4_top_field_order_cnt; - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i4_temp_poc + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + ps_dec->ps_cur_pic->i4_top_field_order_cnt = 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 = i8_result; ps_dec->ps_cur_pic->i4_poc = i4_temp_poc; ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc; } diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index b7e68b1..93c379b 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -161,7 +161,7 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, UWORD8 u1_field_pic_flag, WORD32 *pi4_poc) { - WORD16 i1_pic_msb; + WORD64 i8_pic_msb; WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0; dec_seq_params_t *ps_seq = ps_pps->ps_sps; WORD32 i4_prev_frame_num_ofst; @@ -197,7 +197,7 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, >= (ps_seq->i4_max_pic_order_cntLsb >> 1))) { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + 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 @@ -207,29 +207,49 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, >= (ps_seq->i4_max_pic_order_cntLsb >> 1))) { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + i8_pic_msb = (WORD64)ps_prev_poc->i4_pic_order_cnt_msb - ps_seq->i4_max_pic_order_cntLsb; } else { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb; + i8_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb; } if(!u1_field_pic_flag || !u1_bottom_field_flag) - i4_top_field_order_cnt = i1_pic_msb - + ps_cur_poc->i4_pic_order_cnt_lsb; + { + 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 = i8_result; + } if(!u1_field_pic_flag) { - i4_bottom_field_order_cnt = i4_top_field_order_cnt - + ps_cur_poc->i4_delta_pic_order_cnt_bottom; + 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 = i8_result; } else if(u1_bottom_field_flag) { - i4_bottom_field_order_cnt = i1_pic_msb - + ps_cur_poc->i4_pic_order_cnt_lsb; + 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 = i8_result; + } + + if(IS_OUT_OF_RANGE_S32(i8_pic_msb)) + { + return ERROR_INV_POC; } - ps_cur_poc->i4_pic_order_cnt_msb = i1_pic_msb; + ps_cur_poc->i4_pic_order_cnt_msb = i8_pic_msb; break; case 1: @@ -269,15 +289,27 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, } else if(prev_frame_num > ((WORD32)u2_frame_num)) { - frame_num_ofst = i4_prev_frame_num_ofst - + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1; + 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 = 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) - abs_frm_num = frame_num_ofst + (WORD32)u2_frame_num; + { + 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 = i8_result; + } else abs_frm_num = 0; if((u1_nal_ref_idc == 0) && (abs_frm_num > 0)) @@ -405,8 +437,13 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, } else if(prev_frame_num > ((WORD32)u2_frame_num)) { - frame_num_ofst = i4_prev_frame_num_ofst - + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1; + 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 = i8_result; } else frame_num_ofst = i4_prev_frame_num_ofst; @@ -415,10 +452,23 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, if(u1_is_idr_slice) tmp_poc = 0; else if(u1_nal_ref_idc == 0) - tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1) - - 1; + { + 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 = i8_result; + } else - tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1); + { + 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 = i8_result; + } /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */ if(!u1_field_pic_flag) -- cgit v1.2.3 From 06c30b33c400afcf175916dea34f8b09599b58e5 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Tue, 17 Nov 2020 06:44:57 +0530 Subject: Validate input dimensions in process() Input dimensions are checked for supported range in set_dimensions control call. Encoder returns an error for unsupported values in this control call. But if the caller ignores this error and proceeds to call process(), encoder wasn't checking the dimensions again. Unsupported dimensions are now checked in process() call as well. Bug: 172908358 Test: Poc in bug Test: atest android.mediav2.cts Test: atest android.media.cts Change-Id: I677049afdd0fc4a7d7975c024d0a5a8d7758dc91 --- encoder/ih264e_api.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 61ef6b5..53067e0 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -138,6 +138,101 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, /* Function Definitions */ /*****************************************************************************/ +/** +******************************************************************************* +* +* @brief +* Used to test validity of input dimensions +* +* @par Description: +* Dimensions of the input buffer passed to encode call are validated +* +* @param[in] ps_codec +* Codec context +* +* @param[in] ps_ip +* Pointer to input structure +* +* @param[out] ps_op +* Pointer to output structure +* +* @returns error status +* +* @remarks none +* +******************************************************************************* +*/ +static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec, + ih264e_video_encode_ip_t *ps_ip, + ih264e_video_encode_op_t *ps_op) +{ + UWORD32 u4_wd, u4_ht; + cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; + iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf; + + u4_wd = ps_inp_buf->au4_wd[0]; + u4_ht = ps_inp_buf->au4_ht[0]; + switch (ps_inp_buf->e_color_fmt) + { + case IV_YUV_420P: + if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) || + ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) || + (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2])) + { + 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_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) || + ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) || + (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2])) + { + 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 IV_YUV_420SP_UV: + case IV_YUV_420SP_VU: + if ((ps_inp_buf->au4_wd[0] / 2) != 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; + return (IV_FAIL); + } + if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_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 IV_YUV_422ILE: + u4_wd = ps_inp_buf->au4_wd[0] / 2; + break; + default: + 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 (u4_wd != ps_curr_cfg->u4_disp_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 (u4_ht != ps_curr_cfg->u4_disp_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); + } + + return IV_SUCCESS; +} + /** ******************************************************************************* * @@ -818,6 +913,7 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, case IVE_CMD_VIDEO_ENCODE: { + codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); ih264e_video_encode_ip_t *ps_ip = pv_api_ip; ih264e_video_encode_op_t *ps_op = pv_api_op; @@ -836,6 +932,15 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; return (IV_FAIL); } + + if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] && + ps_codec->i4_header_mode != 1 && + IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op)) + { + 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; } @@ -4059,6 +4164,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, /* Update config params as per input */ ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); + + /* Initialize dimensions to max dimensions during init */ + ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd; + ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_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; -- cgit v1.2.3 From fd7e28588f149c1683c4f7a0a1c543f51b1cd41a Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 2 Dec 2020 11:54:47 -0800 Subject: decoder: Update check for first mb in slice first_mb_in_slice shouldn't be >= mbs in the picture. Test: poc in bugs Bug: b/174238784 Bug: b/174507022 Bug: oss-fuzz:27856 Bug: oss-fuzz:28039 Change-Id: Id3a41c8c2ddf814910fc2d5dd4f57bdd84d28fec (cherry picked from commit 7e06940dce7245f03fd950edf7f72ff321b2b451) --- decoder/ih264d_parse_slice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 927f1c0..cc1d90f 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1100,7 +1100,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, 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)) + >= (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)) { return ERROR_CORRUPTED_SLICE; -- cgit v1.2.3 From 91b4a017ed4a6fe055fc268ab9401df18fd767d1 Mon Sep 17 00:00:00 2001 From: Cindy Zhou Date: Wed, 2 Dec 2020 10:20:30 -0800 Subject: Enable cfi for libavc Bug: 158010610 Bug: 173497308 Test: Ran atest with DecoderConformanceTest, ImageReaderDecoderTest, VideoDecoderPerfTest, VideoEncoderTest. Compare the before and after enabling CFI results since there was a number of tests that were initially failing. Change-Id: Ib6b0871809e89bf26c426c5616dea6238f2a02ce --- Android.bp | 32 ++++++++++++++++++++++++++++---- libavc_blocklist.txt | 1 - 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Android.bp b/Android.bp index 5ba9c7a..59b45ea 100644 --- a/Android.bp +++ b/Android.bp @@ -225,11 +225,23 @@ cc_library_static { }, }, + target: { + android: { + sanitize: { + diag: { + cfi: true, + }, + }, + }, + }, + sanitize: { integer_overflow: true, misc_undefined: ["bounds"], - // Enable CFI if this becomes a shared library. - // cfi: true, + cfi: true, + config: { + cfi_assembly_support: true, + }, blocklist: "libavc_blocklist.txt", }, apex_available: [ @@ -486,11 +498,23 @@ cc_library_static { }, }, + target: { + android: { + sanitize: { + diag: { + cfi: true, + }, + }, + }, + }, + sanitize: { integer_overflow: true, misc_undefined: ["bounds"], - // Enable CFI if this becomes a shared library. - // cfi: true, + cfi: true, + config: { + cfi_assembly_support: true, + }, blocklist: "libavc_blocklist.txt", }, apex_available: [ diff --git a/libavc_blocklist.txt b/libavc_blocklist.txt index 5bb3630..30a2cef 100644 --- a/libavc_blocklist.txt +++ b/libavc_blocklist.txt @@ -1,5 +1,4 @@ [cfi] -src:*external/libavc/* [integer] # decoder/ih264d_dpb_mgr.c:1174: 2 - 3 cannot be represented in type 'unsigned int' -- cgit v1.2.3 From 5429105538e10f40547b1265b395a01847a84720 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Mon, 21 Dec 2020 17:24:42 +0000 Subject: Revert "Validate input dimensions in process()" This reverts commit 06c30b33c400afcf175916dea34f8b09599b58e5. Reason for revert: buildcop flagged test failure in mediatranscoding Bug: 176041187 Bug: 172908358 Change-Id: If813107ea7a2c9f3a87886504c7e36b4473c37db --- encoder/ih264e_api.c | 110 --------------------------------------------------- 1 file changed, 110 deletions(-) diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 53067e0..61ef6b5 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -138,101 +138,6 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, /* Function Definitions */ /*****************************************************************************/ -/** -******************************************************************************* -* -* @brief -* Used to test validity of input dimensions -* -* @par Description: -* Dimensions of the input buffer passed to encode call are validated -* -* @param[in] ps_codec -* Codec context -* -* @param[in] ps_ip -* Pointer to input structure -* -* @param[out] ps_op -* Pointer to output structure -* -* @returns error status -* -* @remarks none -* -******************************************************************************* -*/ -static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec, - ih264e_video_encode_ip_t *ps_ip, - ih264e_video_encode_op_t *ps_op) -{ - UWORD32 u4_wd, u4_ht; - cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; - iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf; - - u4_wd = ps_inp_buf->au4_wd[0]; - u4_ht = ps_inp_buf->au4_ht[0]; - switch (ps_inp_buf->e_color_fmt) - { - case IV_YUV_420P: - if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) || - ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) || - (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2])) - { - 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_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) || - ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) || - (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2])) - { - 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 IV_YUV_420SP_UV: - case IV_YUV_420SP_VU: - if ((ps_inp_buf->au4_wd[0] / 2) != 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; - return (IV_FAIL); - } - if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_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 IV_YUV_422ILE: - u4_wd = ps_inp_buf->au4_wd[0] / 2; - break; - default: - 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 (u4_wd != ps_curr_cfg->u4_disp_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 (u4_ht != ps_curr_cfg->u4_disp_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); - } - - return IV_SUCCESS; -} - /** ******************************************************************************* * @@ -913,7 +818,6 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, case IVE_CMD_VIDEO_ENCODE: { - codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); ih264e_video_encode_ip_t *ps_ip = pv_api_ip; ih264e_video_encode_op_t *ps_op = pv_api_op; @@ -932,15 +836,6 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; return (IV_FAIL); } - - if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] && - ps_codec->i4_header_mode != 1 && - IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op)) - { - 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; } @@ -4164,11 +4059,6 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, /* Update config params as per input */ ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); - - /* Initialize dimensions to max dimensions during init */ - ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd; - ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_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; -- cgit v1.2.3 From 6ce43b0dd799cd2aa5113797dbbd95f5e00a8000 Mon Sep 17 00:00:00 2001 From: Anuj Joshi Date: Wed, 18 Nov 2020 09:55:39 +0530 Subject: Free input buffers only when released by encoder in avc_enc_fuzzer Test: ./avc_enc_fuzzer Bug: 172952772 Change-Id: I9d2eb407c73e289b7d88d47d87fb36b68b5dfc69 --- fuzzer/avc_enc_fuzzer.cpp | 150 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 46 deletions(-) diff --git a/fuzzer/avc_enc_fuzzer.cpp b/fuzzer/avc_enc_fuzzer.cpp index e01f6a5..426eedb 100644 --- a/fuzzer/avc_enc_fuzzer.cpp +++ b/fuzzer/avc_enc_fuzzer.cpp @@ -19,13 +19,16 @@ */ #include #include +#include #include "ih264_defs.h" #include "ih264_typedefs.h" #include "ih264e.h" #include "ih264e_error.h" #define ive_api_function ih264e_api_function +typedef std::tuple bufferPtrs; +constexpr static int kMaxNumEncodeCalls = 100; constexpr uint32_t kHeaderLength = 0x800; constexpr int16_t kCompressionRatio = 1; @@ -93,6 +96,7 @@ enum { IDX_FORCE_IDR_INTERVAL, IDX_DYNAMIC_BITRATE_INTERVAL, IDX_DYNAMIC_FRAME_RATE_INTERVAL, + IDX_SEND_EOS_WITH_LAST_FRAME, IDX_LAST }; @@ -105,7 +109,7 @@ class Codec { void deInitEncoder(); private: - void setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data); + bufferPtrs setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize); void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType); void setQp(); void setEncMode(IVE_ENC_MODE_T eEncMode); @@ -144,6 +148,7 @@ class Codec { bool mIsForceIdrEnabled = false; bool mIsDynamicBitRateChangeEnabled = false; bool mIsDynamicFrameRateChangeEnabled = false; + bool mSendEosWithLastFrame = false; uint32_t mWidth = 2560; uint32_t mHeight = 2560; uint32_t mAvcEncLevel = 41; @@ -218,6 +223,7 @@ bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) { mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01; mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01; mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01; + mSendEosWithLastFrame = data[IDX_SEND_EOS_WITH_LAST_FRAME] & 0x01; mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07; mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07; mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07; @@ -840,6 +846,7 @@ void Codec::encodeFrames(const uint8_t *data, size_t size) { ive_video_encode_ip_t sEncodeIp{}; ive_video_encode_op_t sEncodeOp{}; uint8_t header[kHeaderLength]; + int32_t numEncodeCalls = 0; iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf; sEncodeIp.s_out_buf.pv_buf = header; sEncodeIp.s_out_buf.u4_bytes = 0; @@ -853,7 +860,6 @@ void Codec::encodeFrames(const uint8_t *data, size_t size) { sEncodeIp.pv_pic_info = nullptr; sEncodeIp.u4_mb_info_type = 0; sEncodeIp.u4_pic_info_type = 0; - sEncodeIp.u4_is_last = 0; sEncodeOp.s_out_buf.pv_buf = nullptr; /* Initialize color formats */ @@ -863,59 +869,103 @@ void Codec::encodeFrames(const uint8_t *data, size_t size) { ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); size_t numFrame = 0; - while (size > 0) { - uint8_t *tmpData = (uint8_t *)malloc(frameSize); - size_t bytesConsumed = std::min(size, frameSize); - if (bytesConsumed < frameSize) { - memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed); - } - memcpy(tmpData, data, bytesConsumed); - setEncParams(psInpRawBuf, tmpData); - uint64_t OutputBufferSize = (frameSize / kCompressionRatio); - uint8_t *OutputBuffer = (uint8_t *)malloc(OutputBufferSize); - sEncodeIp.s_out_buf.pv_buf = OutputBuffer; - sEncodeIp.s_out_buf.u4_bufsize = OutputBufferSize; - if (mIsForceIdrEnabled) { - if (numFrame == mForceIdrInterval) { - setFrameType(IV_IDR_FRAME); + std::vector inBuffers; + uint64_t outputBufferSize = (frameSize / kCompressionRatio); + while (!sEncodeOp.u4_is_last && numEncodeCalls < kMaxNumEncodeCalls) { + uint8_t *outputBuffer = (uint8_t *)malloc(outputBufferSize); + sEncodeIp.s_out_buf.pv_buf = outputBuffer; + sEncodeIp.s_out_buf.u4_bufsize = outputBufferSize; + if (size > 0) { + uint8_t *tmpData = (uint8_t *)malloc(frameSize); + size_t bytesConsumed = std::min(size, frameSize); + if (bytesConsumed < frameSize) { + memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed); } - } - if (mIsDynamicBitRateChangeEnabled) { - if (numFrame == mDynamicBitRateInterval) { - if (data[0] & 0x01) { - mBitrate *= 2; - } else { - mBitrate /= 2; + memcpy(tmpData, data, bytesConsumed); + bufferPtrs inBuffer = setEncParams(psInpRawBuf, tmpData, frameSize); + inBuffers.push_back(inBuffer); + free(tmpData); + sEncodeIp.u4_is_last = 0; + if (mSendEosWithLastFrame && size == bytesConsumed) { + sEncodeIp.u4_is_last = 1; + } + if (mIsForceIdrEnabled) { + if (numFrame == mForceIdrInterval) { + setFrameType(IV_IDR_FRAME); } - setBitRate(); } - } - if (mIsDynamicFrameRateChangeEnabled) { - if (numFrame == mDynamicFrameRateInterval) { - if (size > 1 && data[1] & 0x01) { - mFrameRate *= 2; - } else { - mFrameRate /= 2; + if (mIsDynamicBitRateChangeEnabled) { + if (numFrame == mDynamicBitRateInterval) { + if (data[0] & 0x01) { + mBitrate *= 2; + } else { + mBitrate /= 2; + } + setBitRate(); } - setFrameRate(); } + if (mIsDynamicFrameRateChangeEnabled) { + if (numFrame == mDynamicFrameRateInterval) { + if (size > 1 && data[1] & 0x01) { + mFrameRate *= 2; + } else { + mFrameRate /= 2; + } + setFrameRate(); + } + } + ++numFrame; + data += bytesConsumed; + size -= bytesConsumed; + } else { + sEncodeIp.u4_is_last = 1; + psInpRawBuf->apv_bufs[0] = nullptr; + psInpRawBuf->apv_bufs[1] = nullptr; + psInpRawBuf->apv_bufs[2] = nullptr; } ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); - ++numFrame; - data += bytesConsumed; - size -= bytesConsumed; - free(tmpData); - free(OutputBuffer); + if (sEncodeOp.s_inp_buf.apv_bufs[0]) { + std::vector::iterator iter; + uint8_t *inputbuf = (uint8_t *)sEncodeOp.s_inp_buf.apv_bufs[0]; + iter = std::find_if( + inBuffers.begin(), inBuffers.end(), + [=, &inputbuf](const bufferPtrs &buf) { return std::get<0>(buf) == inputbuf; }); + if (iter != inBuffers.end()) { + inBuffers.erase(iter); + free(sEncodeOp.s_inp_buf.apv_bufs[0]); + if (sEncodeOp.s_inp_buf.apv_bufs[1]) { + free(sEncodeOp.s_inp_buf.apv_bufs[1]); + } + if (sEncodeOp.s_inp_buf.apv_bufs[2]) { + free(sEncodeOp.s_inp_buf.apv_bufs[2]); + } + } + } + ++numEncodeCalls; + free(outputBuffer); } + for (const auto &buffer : inBuffers) { + free(std::get<0>(buffer)); + if (std::get<1>(buffer)) { + free(std::get<1>(buffer)); + } + if (std::get<2>(buffer)) { + free(std::get<2>(buffer)); + } + } + inBuffers.clear(); } -void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { +bufferPtrs Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize) { + bufferPtrs inBuffer; switch (mIvVideoColorFormat) { case IV_YUV_420SP_UV: [[fallthrough]]; case IV_YUV_420SP_VU: { - uint8_t *yPlane = const_cast(data); - uint8_t *uPlane = const_cast(data + (mWidth * mHeight)); + uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight); + uint8_t *uPlane = (uint8_t *)malloc(frameSize - (mWidth * mHeight)); + memcpy(yPlane, data, mWidth * mHeight); + memcpy(uPlane, data + (mWidth * mHeight), frameSize - (mWidth * mHeight)); int32_t yStride = mWidth; int32_t uStride = mWidth / 2; psInpRawBuf->apv_bufs[0] = yPlane; @@ -929,10 +979,12 @@ void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { psInpRawBuf->au4_strd[0] = yStride; psInpRawBuf->au4_strd[1] = uStride; + inBuffer = std::make_tuple(yPlane, uPlane, nullptr); break; } case IV_YUV_422ILE: { - uint8_t *yPlane = const_cast(data); + uint8_t *yPlane = (uint8_t *)malloc(frameSize); + memcpy(yPlane, data, frameSize); psInpRawBuf->apv_bufs[0] = yPlane; psInpRawBuf->au4_wd[0] = mWidth * 2; @@ -940,14 +992,19 @@ void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { psInpRawBuf->au4_ht[0] = mHeight; psInpRawBuf->au4_strd[0] = mWidth * 2; + inBuffer = std::make_tuple(yPlane, nullptr, nullptr); break; } case IV_YUV_420P: [[fallthrough]]; default: { - uint8_t *yPlane = const_cast(data); - uint8_t *uPlane = const_cast(data + (mWidth * mHeight)); - uint8_t *vPlane = const_cast(data + ((mWidth * mHeight) * 5) / 4); + uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight); + uint8_t *uPlane = (uint8_t *)malloc((mWidth * mHeight) / 4); + uint8_t *vPlane = (uint8_t *)malloc(frameSize - ((mWidth * mHeight) * 5) / 4); + memcpy(yPlane, data, mWidth * mHeight); + memcpy(uPlane, data + (mWidth * mHeight), (mWidth * mHeight) / 4); + memcpy(vPlane, data + ((mWidth * mHeight) * 5) / 4, + frameSize - ((mWidth * mHeight) * 5) / 4); int32_t yStride = mWidth; int32_t uStride = mWidth / 2; int32_t vStride = mWidth / 2; @@ -967,10 +1024,11 @@ void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { psInpRawBuf->au4_strd[0] = yStride; psInpRawBuf->au4_strd[1] = uStride; psInpRawBuf->au4_strd[2] = vStride; + inBuffer = std::make_tuple(yPlane, uPlane, vPlane); break; } } - return; + return inBuffer; } void Codec::deInitEncoder() { -- cgit v1.2.3 From bb48f971895b38333ba39f0f206c51652a4a40fa Mon Sep 17 00:00:00 2001 From: Cindy Zhou Date: Wed, 13 Jan 2021 11:39:38 -0800 Subject: Libavc remove diag Removing diag mode since it's only required for debugging purposes. Bug: 158010610 Test: n/a Change-Id: I8f87913ab14bcd97ec8e6975893726e3ee92e399 --- Android.bp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/Android.bp b/Android.bp index 59b45ea..b49674c 100644 --- a/Android.bp +++ b/Android.bp @@ -225,16 +225,6 @@ cc_library_static { }, }, - target: { - android: { - sanitize: { - diag: { - cfi: true, - }, - }, - }, - }, - sanitize: { integer_overflow: true, misc_undefined: ["bounds"], @@ -498,16 +488,6 @@ cc_library_static { }, }, - target: { - android: { - sanitize: { - diag: { - cfi: true, - }, - }, - }, - }, - sanitize: { integer_overflow: true, misc_undefined: ["bounds"], -- cgit v1.2.3 From c0aae295eddb7ab6fd91b73cbe1d581944725435 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Fri, 12 Feb 2021 15:15:50 -0800 Subject: [LSC] Add LOCAL_LICENSE_KINDS to external/libavc Added SPDX-license-identifier-Apache-2.0 to: Android.bp fuzzer/Android.bp test/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Exempt-From-Owner-Approval: janitorial work Change-Id: I3ad48ae634869eb3486d5c68962c992be83b2003 --- Android.bp | 17 +++++++++++++++++ fuzzer/Android.bp | 9 +++++++++ test/Android.bp | 9 +++++++++ 3 files changed, 35 insertions(+) diff --git a/Android.bp b/Android.bp index b49674c..602a94b 100644 --- a/Android.bp +++ b/Android.bp @@ -1,3 +1,20 @@ +package { + default_applicable_licenses: ["external_libavc_license"], +} + +// Added automatically by a large-scale-change +// See: http://go/android-license-faq +license { + name: "external_libavc_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + ], + license_text: [ + "NOTICE", + ], +} + cc_library_static { name: "libavcdec", vendor_available: true, diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index cb9d246..4c83461 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_libavc_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_libavc_license"], +} + cc_fuzz { name: "avc_dec_fuzzer", host_supported: true, diff --git a/test/Android.bp b/test/Android.bp index a62b56c..b859f49 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_libavc_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_libavc_license"], +} + cc_test { name: "avcdec", gtest: false, -- cgit v1.2.3 From 2205f2da33bf5c37942e95c9505ace60a0864b3e Mon Sep 17 00:00:00 2001 From: Shivaansh Agrawal Date: Fri, 18 Dec 2020 00:25:54 +0530 Subject: Decoder: add support to use ih264d instead of ivd structures Bug: 175759733 Test: avcdec -c dec.cfg Change-Id: I410bb2213cb375c5eabcb3e23499d6ad43cf1c96 --- decoder/ih264d_api.c | 18 ++- test/decoder/main.c | 357 +++++++++++++++++++++++++++------------------------ 2 files changed, 202 insertions(+), 173 deletions(-) diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 3dfcbf2..2508d7b 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -1972,18 +1972,22 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) WORD32 ret = 0,api_ret_value = IV_SUCCESS; WORD32 header_data_left = 0,frame_data_left = 0; UWORD8 *pu1_bitstrm_buf; + ih264d_video_decode_ip_t *ps_h264d_dec_ip; + ih264d_video_decode_op_t *ps_h264d_dec_op; ivd_video_decode_ip_t *ps_dec_ip; ivd_video_decode_op_t *ps_dec_op; ithread_set_name((void*)"Parse_thread"); - ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; - ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; + ps_h264d_dec_ip = (ih264d_video_decode_ip_t *)pv_api_ip; + ps_h264d_dec_op = (ih264d_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_dec_op, 0, sizeof(ivd_video_decode_op_t)); + memset(ps_h264d_dec_op, 0, sizeof(ih264d_video_decode_op_t)); ps_dec_op->u4_size = u4_size; } @@ -3236,10 +3240,14 @@ WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) dec_struct_t * ps_dec; WORD32 ret = IV_SUCCESS; + 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;; ivd_ctl_set_config_ip_t *ps_ctl_ip = - (ivd_ctl_set_config_ip_t *)pv_api_ip; + &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t; ivd_ctl_set_config_op_t *ps_ctl_op = - (ivd_ctl_set_config_op_t *)pv_api_op; + &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t; ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); diff --git a/test/decoder/main.c b/test/decoder/main.c index 533f72a..046c689 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -553,22 +553,24 @@ IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics) IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_B; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_B; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - 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_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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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) { @@ -603,22 +605,24 @@ IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_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_FRAME; - 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_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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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) { @@ -654,22 +658,24 @@ IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_PB; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_PB; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - 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_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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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"); @@ -704,22 +710,24 @@ IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_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_FRAME; - 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_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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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"); @@ -1657,39 +1665,41 @@ 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] = + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_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(ih264d_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(ih264d_video_decode_op_t); /*****************************************************************************/ /* API Call: Video Decode */ /*****************************************************************************/ - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_decode_ip, + (void *)&s_h264d_decode_op); - if(1 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { CHAR cur_fname[1000]; CHAR *extn = NULL; @@ -1701,7 +1711,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI MDCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_mdcv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag) { ih264d_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip; ih264d_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op; @@ -1732,7 +1742,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI CLL parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_cll_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag) { ih264d_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip; ih264d_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op; @@ -1763,7 +1773,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI AVE parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ave_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag) { ih264d_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip; ih264d_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op; @@ -1794,7 +1804,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI CCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ccv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag) { ih264d_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip; ih264d_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op; @@ -1845,8 +1855,8 @@ void flush_output(iv_obj_t *codec_obj, } } - dump_output(ps_app_ctx, &(s_video_decode_op.s_disp_frm_buf), - s_video_decode_op.u4_disp_buf_id, ps_op_file, + dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_op_chksum_file, *pu4_op_frm_ts, ps_app_ctx->u4_file_save_flag, ps_app_ctx->u4_chksum_save_flag); @@ -2275,24 +2285,26 @@ int main(WORD32 argc, CHAR *argv[]) /* set stride */ /*****************************************************************************/ { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - 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(); - - 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); - - ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_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, @@ -2366,30 +2378,34 @@ int main(WORD32 argc, CHAR *argv[]) /* 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; + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_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; { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - 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(); - - 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); - - ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + 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(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_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, @@ -2436,36 +2452,36 @@ 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(ih264d_video_decode_ip_t); + ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); /*****************************************************************************/ /* API Call: Header Decode */ /*****************************************************************************/ - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + 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", s_video_decode_op.u4_error_code); + printf("Error in header decode 0x%x\n", 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); @@ -2767,23 +2783,26 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_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; - 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(); - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride(); + ps_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_FRAME; - 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); + 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(ih264d_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != ret) { @@ -2947,8 +2966,10 @@ int main(WORD32 argc, CHAR *argv[]) { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_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; @@ -2956,27 +2977,27 @@ 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(ih264d_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(ih264d_video_decode_op_t); /* Get display buffer pointers */ if(1 == s_app_ctx.display) @@ -2989,9 +3010,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]); } /*****************************************************************************/ @@ -3000,8 +3021,8 @@ int main(WORD32 argc, CHAR *argv[]) GETTIME(&s_start_timer); - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_decode_ip, + (void *)&s_h264d_decode_op); GETTIME(&s_end_timer); @@ -3024,12 +3045,12 @@ int main(WORD32 argc, CHAR *argv[]) 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); + 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; @@ -3041,17 +3062,17 @@ 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; @@ -3129,7 +3150,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI MDCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_mdcv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag) { ih264d_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip; ih264d_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op; @@ -3160,7 +3181,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI CLL parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_cll_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag) { ih264d_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip; @@ -3192,7 +3213,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI AVE parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ave_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag) { ih264d_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip; ih264d_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op; @@ -3223,7 +3244,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI CCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ccv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag) { ih264d_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip; ih264d_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op; @@ -3253,22 +3274,22 @@ 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) { CHAR cur_fname[1000]; @@ -3298,10 +3319,10 @@ int main(WORD32 argc, CHAR *argv[]) } } - 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, + 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), + ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_op_chksum_file, u4_op_frm_ts, s_app_ctx.u4_file_save_flag, s_app_ctx.u4_chksum_save_flag); @@ -3313,7 +3334,7 @@ int main(WORD32 argc, CHAR *argv[]) } 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; -- cgit v1.2.3 From d0123b8c5f38793a24e064cf508f4af1689ee998 Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Thu, 4 Mar 2021 19:25:56 -0800 Subject: Rename OWNERS-codecs to match naming policies Bug: 181751857 Test: upload/gerrit Change-Id: I658d832547c144e5c4a6918085685fcc7bf26abb --- OWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OWNERS b/OWNERS index b2faa25..d5edff2 100644 --- a/OWNERS +++ b/OWNERS @@ -1,4 +1,4 @@ # owners for external/libavc -include platform/frameworks/av:/media/janitors/OWNERS-codecs +include platform/frameworks/av:/media/janitors/codec_OWNERS essick@google.com -hkuang@google.com \ No newline at end of file +hkuang@google.com -- cgit v1.2.3 From a073696092f26e5060af792b917738602d85686d Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Tue, 17 Nov 2020 06:44:57 +0530 Subject: Validate input dimensions in process() Input dimensions are checked for supported range in set_dimensions control call. Encoder returns an error for unsupported values in this control call. But if the caller ignores this error and proceeds to call process(), encoder wasn't checking the dimensions again. Unsupported dimensions are now checked in process() call as well. Note: This is relanding previously reverted commit 06c30b33c400afcf175916dea34f8b09599b58e5 Bug: 172908358 Test: Poc in bug Test: atest android.mediav2.cts Test: atest android.media.cts Change-Id: Icf3f296ab24432c680427a82da3505491acca3bd --- encoder/ih264e_api.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 61ef6b5..53067e0 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -138,6 +138,101 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, /* Function Definitions */ /*****************************************************************************/ +/** +******************************************************************************* +* +* @brief +* Used to test validity of input dimensions +* +* @par Description: +* Dimensions of the input buffer passed to encode call are validated +* +* @param[in] ps_codec +* Codec context +* +* @param[in] ps_ip +* Pointer to input structure +* +* @param[out] ps_op +* Pointer to output structure +* +* @returns error status +* +* @remarks none +* +******************************************************************************* +*/ +static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec, + ih264e_video_encode_ip_t *ps_ip, + ih264e_video_encode_op_t *ps_op) +{ + UWORD32 u4_wd, u4_ht; + cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; + iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf; + + u4_wd = ps_inp_buf->au4_wd[0]; + u4_ht = ps_inp_buf->au4_ht[0]; + switch (ps_inp_buf->e_color_fmt) + { + case IV_YUV_420P: + if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) || + ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) || + (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2])) + { + 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_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) || + ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) || + (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2])) + { + 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 IV_YUV_420SP_UV: + case IV_YUV_420SP_VU: + if ((ps_inp_buf->au4_wd[0] / 2) != 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; + return (IV_FAIL); + } + if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_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 IV_YUV_422ILE: + u4_wd = ps_inp_buf->au4_wd[0] / 2; + break; + default: + 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 (u4_wd != ps_curr_cfg->u4_disp_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 (u4_ht != ps_curr_cfg->u4_disp_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); + } + + return IV_SUCCESS; +} + /** ******************************************************************************* * @@ -818,6 +913,7 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, case IVE_CMD_VIDEO_ENCODE: { + codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); ih264e_video_encode_ip_t *ps_ip = pv_api_ip; ih264e_video_encode_op_t *ps_op = pv_api_op; @@ -836,6 +932,15 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; return (IV_FAIL); } + + if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] && + ps_codec->i4_header_mode != 1 && + IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op)) + { + 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; } @@ -4059,6 +4164,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, /* Update config params as per input */ ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); + + /* Initialize dimensions to max dimensions during init */ + ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd; + ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_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; -- cgit v1.2.3 From 3139d13ccdd1a1c41e8cbdd335fba2f1194d854a Mon Sep 17 00:00:00 2001 From: Aayush Soni Date: Thu, 25 Mar 2021 16:59:10 +0530 Subject: encoder: fix null buffer dereferencing Do not set the picture type as NA for the last frame in encoding order. Bug: 180219345 Test: POC in bug descriptions Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I57ee7db9e2e55fba2666a6aaa4002ef31276e4b9 --- encoder/ih264e_utils.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index 2196a64..239271e 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -445,11 +445,6 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, } } - if (ps_enc_buff->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++) { -- cgit v1.2.3 From e88c22c34cd93eef75ae473c4a35af775546b8fe Mon Sep 17 00:00:00 2001 From: Aayush Soni Date: Thu, 25 Mar 2021 16:59:10 +0530 Subject: encoder: fix null buffer dereferencing Do not set the picture type as NA for the last frame in encoding order. Bug: 180219345 Test: POC in bug descriptions Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I57ee7db9e2e55fba2666a6aaa4002ef31276e4b9 --- encoder/ih264e_utils.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index 2196a64..239271e 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -445,11 +445,6 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, } } - if (ps_enc_buff->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++) { -- cgit v1.2.3 From 954f023c74425d097c7ee45c1d9a37a7fafe778c Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Fri, 12 Mar 2021 10:15:49 +0530 Subject: encoder: fix invalid free of raw buffers Return current input buffer as buffer to be freed in case of errors that are seen before picking up the input buffer to be from the input queue. Once a buffer is picked up from the queue, that is returned as the buffer to be freed. There is no need to return a buffer from ps_proc context Bug: 180643802 Test: poc in the bug description Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I1671ca1e82f522004d1f070df89b256b856f75b8 --- encoder/ih264e_encode.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index 9210b3e..6a4e3a2 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -228,6 +228,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 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; + /* By default set the current input buffer as the buffer to be freed */ + /* This will later be updated to the actual input that gets encoded */ + ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; /* Check for output memory allocation size */ if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) @@ -474,6 +477,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) s_out_buf.u4_is_last = s_inp_buf.u4_is_last; ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last; + /* Send the input to application so that it can free it */ + ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; + /* Only encode if the current frame is not pre-encode skip */ if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0]) { @@ -774,12 +780,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } else { - /* proc ctxt base idx */ - WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS; - - /* proc ctxt */ - process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select]; - /* receive output back from codec */ s_out_buf = ps_codec->as_out_buf[ctxt_sel]; @@ -790,18 +790,11 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.u4_timestamp_low = 0; ps_video_encode_op->s_ive_op.u4_timestamp_high = 0; - /* receive input back from codec and send it to app */ - s_inp_buf = ps_proc->s_inp_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.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 = s_out_buf.s_bits_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; - if (1 == s_inp_buf.u4_is_last) { -- cgit v1.2.3 From 3e73f0d56298ba6256927928669d0cc6e4b1c9ee Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Fri, 12 Mar 2021 10:15:49 +0530 Subject: encoder: fix invalid free of raw buffers Return current input buffer as buffer to be freed in case of errors that are seen before picking up the input buffer to be from the input queue. Once a buffer is picked up from the queue, that is returned as the buffer to be freed. There is no need to return a buffer from ps_proc context Bug: 180643802 Test: poc in the bug description Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I1671ca1e82f522004d1f070df89b256b856f75b8 --- encoder/ih264e_encode.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index e7057dc..c7e3717 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -225,6 +225,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 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; + /* By default set the current input buffer as the buffer to be freed */ + /* This will later be updated to the actual input that gets encoded */ + ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; /* Check for output memory allocation size */ if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) @@ -394,6 +397,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) s_out_buf.u4_is_last = s_inp_buf.u4_is_last; ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last; + /* Send the input to application so that it can free it */ + ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; + /* Only encode if the current frame is not pre-encode skip */ if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0]) { @@ -694,12 +700,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } else { - /* proc ctxt base idx */ - WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS; - - /* proc ctxt */ - process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select]; - /* receive output back from codec */ s_out_buf = ps_codec->as_out_buf[ctxt_sel]; @@ -710,18 +710,11 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.u4_timestamp_low = 0; ps_video_encode_op->s_ive_op.u4_timestamp_high = 0; - /* receive input back from codec and send it to app */ - s_inp_buf = ps_proc->s_inp_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.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 = s_out_buf.s_bits_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; - if (1 == s_inp_buf.u4_is_last) { -- cgit v1.2.3 From e1fce24788ad7dfa6619c205c660e0be03281ffc Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Fri, 12 Mar 2021 10:15:49 +0530 Subject: encoder: fix invalid free of raw buffers Return current input buffer as buffer to be freed in case of errors that are seen before picking up the input buffer to be from the input queue. Once a buffer is picked up from the queue, that is returned as the buffer to be freed. There is no need to return a buffer from ps_proc context Bug: 180643802 Test: poc in the bug description Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I1671ca1e82f522004d1f070df89b256b856f75b8 --- encoder/ih264e_encode.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index fb37765..fe23841 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -228,6 +228,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 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; + /* By default set the current input buffer as the buffer to be freed */ + /* This will later be updated to the actual input that gets encoded */ + ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; /* Check for output memory allocation size */ if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) @@ -474,6 +477,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) s_out_buf.u4_is_last = s_inp_buf.u4_is_last; ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last; + /* Send the input to application so that it can free it */ + ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; + /* Only encode if the current frame is not pre-encode skip */ if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0]) { @@ -774,12 +780,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } else { - /* proc ctxt base idx */ - WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS; - - /* proc ctxt */ - process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select]; - /* receive output back from codec */ s_out_buf = ps_codec->as_out_buf[ctxt_sel]; @@ -790,18 +790,11 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.u4_timestamp_low = 0; ps_video_encode_op->s_ive_op.u4_timestamp_high = 0; - /* receive input back from codec and send it to app */ - s_inp_buf = ps_proc->s_inp_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.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 = s_out_buf.s_bits_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; - if (1 == s_inp_buf.u4_is_last) { -- cgit v1.2.3 From 646a58ccf1cfbf191d0a3e247664f30c48fdee4d Mon Sep 17 00:00:00 2001 From: Neelkamal Semwal Date: Thu, 1 Apr 2021 12:52:14 +0530 Subject: encoder: Use intermediate buffer for accessing last MB row few SIMD modules read few more bytes from the input buffer at the end of frame. To avoid OOB read, intermediate buffer is used while processing last MB row. Bug: 180505809 Test: poc in bug Test: atest CtsMediaTestCases:VideoEncoderTest Test: atest CtsMediaV2TestCases:CodecEncoderTest Test: atest VtsHalMediaC2V1_0TargetVideoEncTest Change-Id: I11ca65937c7dfaf623f3535c02158ceec0dcc6ee --- encoder/ih264e_process.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index 289053f..bf4c1e7 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -1259,7 +1259,8 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) /* init buffer pointers */ 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.e_inp_color_fmt == IV_YUV_422ILE || + ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) { if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) u2_num_rows = (UWORD16) MB_SIZE - u4_pad_bottom_sz; @@ -1311,7 +1312,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) case IV_YUV_420SP_UV: case IV_YUV_420SP_VU: /* In case of 420 semi-planar input, copy last few rows to intermediate - buffer as chroma trans functions access one extra byte due to interleaved input. + buffer as few SIMD functions access upto 16 more bytes. This data will be padded if required */ if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) || u4_pad_bottom_sz || u4_pad_right_sz) { @@ -1324,16 +1325,13 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) pu1_dst = ps_proc->pu1_src_buf_luma; - /* If padding is required, we always copy luma, if padding isn't required we never copy luma. */ - if (u4_pad_bottom_sz || u4_pad_right_sz) { - if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) - num_rows = MB_SIZE - u4_pad_bottom_sz; - for (i = 0; i < num_rows; i++) - { - memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); - pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; - pu1_dst += ps_proc->i4_src_strd; - } + if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) + num_rows = MB_SIZE - u4_pad_bottom_sz; + for (i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); + pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; + pu1_dst += ps_proc->i4_src_strd; } pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) + ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE); @@ -1414,6 +1412,18 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->i4_src_chroma_strd, u4_pad_ht / 2, u4_pad_wd); } + if (ps_proc->i4_mb_y && ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) { + UWORD8 *pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE) - + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; + UWORD8 *pu1_dst = ps_proc->pu1_src_buf_luma - ps_proc->i4_src_strd; + memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); + if (u4_pad_right_sz && (ps_proc->i4_mb_x == 0)) { + pu1_dst += ps_codec->s_cfg.u4_disp_wd; + memset(pu1_dst, pu1_dst[-1], u4_pad_right_sz); + } + } + /* pad bottom edge */ if (u4_pad_bottom_sz && (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) && ps_proc->i4_mb_x == 0) { -- cgit v1.2.3 From 4a22b5d1055ae2c3cf5699579c2c363a58ce81d0 Mon Sep 17 00:00:00 2001 From: Rakesh Kumar Date: Wed, 28 Apr 2021 23:44:50 +0530 Subject: Decoder: Update check for increment u2_cur_slice_num Increment u2_cur_slice_num only if current slice had atleast one MB of memory left. Test: clusterfuzz generated poc in bug Bug: b/182152757 Bug: b/179938345 Bug: b/185112718 Change-Id: Ic5eb07e961bccb7fde954bcfd791fd879804e335 --- decoder/ih264d_parse_slice.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index f4413c7..266c69b 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1435,17 +1435,20 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, i1_is_end_of_poc = 0; } - if (ps_dec->u4_first_slice_in_pic == 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++; + } } - // in the case of single core increment ps_decode_cur_slice - if((ps_dec->u1_separate_parse == 0) && (ps_dec->u4_first_slice_in_pic == 0)) - { - ps_dec->ps_decode_cur_slice++; - } ps_dec->u1_slice_header_done = 0; -- cgit v1.2.3 From a88e0683a420d7ee9aa4b6f41f94cb8dc0c5e040 Mon Sep 17 00:00:00 2001 From: Rakesh Kumar Date: Wed, 28 Apr 2021 23:44:50 +0530 Subject: Decoder: Update check for increment u2_cur_slice_num Increment u2_cur_slice_num only if current slice had atleast one MB of memory left. Test: clusterfuzz generated poc in bug Bug: b/182152757 Bug: b/179938345 Bug: b/185112718 Change-Id: Ic5eb07e961bccb7fde954bcfd791fd879804e335 --- decoder/ih264d_parse_slice.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index cf2dda9..ffe7f2b 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1476,17 +1476,20 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, i1_is_end_of_poc = 0; } - if (ps_dec->u4_first_slice_in_pic == 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++; + } } - // in the case of single core increment ps_decode_cur_slice - if((ps_dec->u1_separate_parse == 0) && (ps_dec->u4_first_slice_in_pic == 0)) - { - ps_dec->ps_decode_cur_slice++; - } ps_dec->u1_slice_header_done = 0; -- cgit v1.2.3