/****************************************************************************** * * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * 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 "iv_datatypedef.h" #include "iv.h" #include "ivd.h" #include "impeg2d.h" #include "impeg2_buf_mgr.h" #include "impeg2_disp_mgr.h" #include "impeg2_macros.h" #include "impeg2_defs.h" #include "impeg2_platform_macros.h" #include "impeg2_inter_pred.h" #include "impeg2_idct.h" #include "impeg2_format_conv.h" #include "impeg2_mem_func.h" #include "impeg2_globals.h" #include "impeg2d_bitstream.h" #include "impeg2d_api.h" #include "impeg2d_structs.h" #include "impeg2d_debug.h" #if STATISTICS WORD32 gai4_impeg2d_idct_inp_last_nonzero_histogram[64] = {0}; WORD32 gai4_impeg2d_idct_inp_num_nonzero_histogram[64] = {0}; WORD32 gai4_impeg2d_idct_inp_last_non_zero_row_histogram[8] = {0}; WORD32 gai4_impeg2d_iqnt_inp_last_nonzero_histogram[64] = {0}; WORD32 gai4_impeg2d_iqnt_inp_num_nonzero_histogram[64] = {0}; WORD32 gai4_impeg2d_iqnt_inp_last_non_zero_row_histogram[8] = {0}; WORD32 gi4_impeg2d_idct_inp_only_first_coeff = 0; WORD32 gi4_impeg2d_idct_inp_only_last_coeff = 0; WORD32 gi4_impeg2d_idct_inp_only_first_n_last_coeff = 0; WORD32 gi4_impeg2d_idct_cnt = 0; WORD32 gi4_impeg2d_iqnt_inp_only_first_coeff = 0; WORD32 gi4_impeg2d_iqnt_inp_only_last_coeff = 0; WORD32 gi4_impeg2d_iqnt_inp_only_first_n_last_coeff = 0; WORD32 gi4_impeg2d_iqnt_cnt = 0; void impeg2d_iqnt_inp_statistics(WORD16 *pi2_iqnt_inp, WORD32 i4_non_zero_cols, WORD32 i4_non_zero_rows) { WORD32 i, j; WORD32 i4_last_row = 0, i4_last_col = 0; WORD32 i4_num_non_zero = 0; WORD32 i4_non_zero_cols_computed = 0; WORD32 i4_non_zero_rows_computed = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { if(pi2_iqnt_inp[i * 8 + j]) { i4_non_zero_cols_computed |= (1 << j); i4_non_zero_rows_computed |= (1 << i); } } } if(i4_non_zero_cols_computed != i4_non_zero_cols) { printf("IQ Input: Invalid non_zero_cols 0x%x non_zero_cols_computed 0x%x\n", i4_non_zero_cols, i4_non_zero_cols_computed); } if(i4_non_zero_rows_computed != i4_non_zero_rows) { printf("IQ Input: Invalid non_zero_rows 0x%x non_zero_rows_computed 0x%x\n", i4_non_zero_rows, i4_non_zero_rows_computed); } { WORD32 last_non_zero_row = 32 - CLZ(i4_non_zero_rows); gai4_impeg2d_iqnt_inp_last_non_zero_row_histogram[last_non_zero_row - 1]++; } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { if(pi2_iqnt_inp[i * 8 + j]) { i4_last_col = MAX(i4_last_col, j); i4_last_row = MAX(i4_last_row, i); i4_num_non_zero++; } } } gai4_impeg2d_iqnt_inp_last_nonzero_histogram[i4_last_row * 8 + i4_last_col]++; gai4_impeg2d_iqnt_inp_num_nonzero_histogram[i4_num_non_zero]++; gi4_impeg2d_iqnt_cnt++; /* Check if only (0,0) and (7,7) are non zero */ if(i4_num_non_zero == 1) { if(pi2_iqnt_inp[7 * 8 + 7]) gi4_impeg2d_iqnt_inp_only_last_coeff++; } if(i4_num_non_zero == 1) { if(pi2_iqnt_inp[0]) gi4_impeg2d_iqnt_inp_only_first_coeff++; } if(i4_num_non_zero == 2) { if((pi2_iqnt_inp[0]) && (1 == pi2_iqnt_inp[7 * 8 + 7])) gi4_impeg2d_iqnt_inp_only_first_n_last_coeff++; } } void impeg2d_idct_inp_statistics(WORD16 *pi2_idct_inp, WORD32 i4_non_zero_cols, WORD32 i4_non_zero_rows) { WORD32 i, j; WORD32 i4_last_row = 0, i4_last_col = 0; WORD32 i4_num_non_zero = 0; WORD32 i4_non_zero_cols_computed = 0; WORD32 i4_non_zero_rows_computed = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { if(pi2_idct_inp[i * 8 + j]) { i4_non_zero_cols_computed |= (1 << j); i4_non_zero_rows_computed |= (1 << i); } } } if(i4_non_zero_cols_computed != i4_non_zero_cols) { printf("IDCT Input: Invalid non_zero_cols 0x%x non_zero_cols_computed 0x%x\n", i4_non_zero_cols, i4_non_zero_cols_computed); } if(i4_non_zero_rows_computed != i4_non_zero_rows) { printf("IDCT Input: Invalid non_zero_rows 0x%x non_zero_rows_computed 0x%x\n", i4_non_zero_rows, i4_non_zero_rows_computed); } { WORD32 last_non_zero_row = 32 - CLZ(i4_non_zero_rows); gai4_impeg2d_idct_inp_last_non_zero_row_histogram[last_non_zero_row - 1]++; } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { if(pi2_idct_inp[i * 8 + j]) { i4_last_col = MAX(i4_last_col, j); i4_last_row = MAX(i4_last_row, i); i4_num_non_zero++; } } } gai4_impeg2d_idct_inp_last_nonzero_histogram[i4_last_row * 8 + i4_last_col]++; gai4_impeg2d_idct_inp_num_nonzero_histogram[i4_num_non_zero]++; gi4_impeg2d_idct_cnt++; /* Check if only (0,0) and (7,7) are non zero */ if(i4_num_non_zero == 1) { if(pi2_idct_inp[7 * 8 + 7]) gi4_impeg2d_idct_inp_only_last_coeff++; } if(i4_num_non_zero == 1) { if(pi2_idct_inp[0]) gi4_impeg2d_idct_inp_only_first_coeff++; } if(i4_num_non_zero == 2) { if((pi2_idct_inp[0]) && (1 == pi2_idct_inp[7 * 8 + 7])) gi4_impeg2d_idct_inp_only_first_n_last_coeff++; } } void impeg2d_print_idct_inp_statistics() { WORD32 i, j; WORD32 i4_sum; WORD32 i4_accumulator; i4_sum = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { i4_sum += gai4_impeg2d_idct_inp_last_nonzero_histogram[i * 8 + j]; } } printf("IDCT input : Only last coeff non-zero %8.2f\n", (gi4_impeg2d_idct_inp_only_last_coeff * 100.0) / gi4_impeg2d_idct_cnt); printf("IDCT input : Only first coeff non-zero (Includes DC + mismatch) %8.2f\n", (gi4_impeg2d_idct_inp_only_first_coeff * 100.0) / gi4_impeg2d_idct_cnt); printf("IDCT input : Last non-zero coeff histogram\n"); for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val = gai4_impeg2d_idct_inp_last_nonzero_histogram[i * 8 + j] * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IDCT input : Cumulative Last non-zero coeff histogram\n"); i4_accumulator = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val; i4_accumulator += gai4_impeg2d_idct_inp_last_nonzero_histogram[i * 8 + j]; val = i4_accumulator * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IDCT input : Number of non-zero coeff histogram\n"); i4_sum = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { i4_sum += gai4_impeg2d_idct_inp_num_nonzero_histogram[i * 8 + j]; } } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val = gai4_impeg2d_idct_inp_num_nonzero_histogram[i * 8 + j] * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IDCT input : Cumulative number of non-zero coeffs histogram\n"); i4_accumulator = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val; i4_accumulator += gai4_impeg2d_idct_inp_num_nonzero_histogram[i * 8 + j]; val = i4_accumulator * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IDCT input : Last non-zero row histogram\n"); { i4_accumulator = 0; for(i = 0; i < 8; i++) { i4_accumulator += gai4_impeg2d_idct_inp_last_non_zero_row_histogram[i]; } for(i = 0; i < 8; i++) { double val = gai4_impeg2d_idct_inp_last_non_zero_row_histogram[i] * 100.0 / i4_accumulator; printf("%8.2f \t", val); } printf("\n"); } } void impeg2d_print_iqnt_inp_statistics() { WORD32 i, j; WORD32 i4_sum; WORD32 i4_accumulator; i4_sum = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { i4_sum += gai4_impeg2d_iqnt_inp_last_nonzero_histogram[i * 8 + j]; } } printf("IQnt input : Only last coeff non-zero %8.2f\n", (gi4_impeg2d_iqnt_inp_only_last_coeff * 100.0) / gi4_impeg2d_iqnt_cnt); printf("IQnt input : Only first coeff non-zero (Includes DC + mismatch) %8.2f\n", (gi4_impeg2d_iqnt_inp_only_first_coeff * 100.0) / gi4_impeg2d_idct_cnt); printf("IQnt input : Last non-zero coeff histogram\n"); for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val = gai4_impeg2d_iqnt_inp_last_nonzero_histogram[i * 8 + j] * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IQnt input : Cumulative Last non-zero coeff histogram\n"); i4_accumulator = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val; i4_accumulator += gai4_impeg2d_iqnt_inp_last_nonzero_histogram[i * 8 + j]; val = i4_accumulator * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IQnt input : Number of non-zero coeff histogram\n"); i4_sum = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { i4_sum += gai4_impeg2d_iqnt_inp_num_nonzero_histogram[i * 8 + j]; } } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val = gai4_impeg2d_iqnt_inp_num_nonzero_histogram[i * 8 + j] * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IQnt input : Cumulative number of non-zero coeffs histogram\n"); i4_accumulator = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { double val; i4_accumulator += gai4_impeg2d_iqnt_inp_num_nonzero_histogram[i * 8 + j]; val = i4_accumulator * 100.0 / i4_sum; printf("%8.2f \t", val); } printf("\n"); } printf("IQnt input : Last non-zero row histogram\n"); { i4_accumulator = 0; for(i = 0; i < 8; i++) { i4_accumulator += gai4_impeg2d_iqnt_inp_last_non_zero_row_histogram[i]; } for(i = 0; i < 8; i++) { double val = gai4_impeg2d_iqnt_inp_last_non_zero_row_histogram[i] * 100.0 / i4_accumulator; printf("%8.2f \t", val); } printf("\n"); } } void impeg2d_print_statistics() { impeg2d_print_idct_inp_statistics(); impeg2d_print_iqnt_inp_statistics(); } #endif #if DEBUG_MB static UWORD32 u4_debug_frm = 12; static UWORD32 u4_debug_mb_x = 3; static UWORD32 u4_debug_mb_y = 0; static UWORD32 u4_debug_frm_num = 0; /*****************************************************************************/ /* */ /* Function Name : example_of_a_function */ /* */ /* Description : This function illustrates the use of C coding standards. */ /* switch/case, if, for, block comments have been shown */ /* here. */ /* Inputs : */ /* Globals : */ /* Processing : */ /* Outputs : */ /* Returns : */ /* */ /* Issues : */ /* */ /* Revision History: */ /* */ /* DD MM YYYY Author(s) Changes (Describe the changes made) */ /* 13 07 2002 Ittiam Draft */ /* */ /*****************************************************************************/ void impeg2d_trace_mb_start(UWORD32 u4_mb_x, UWORD32 u4_mb_y) { UWORD32 u4_frm_num = impeg2d_frm_num_get(); if(u4_frm_num == u4_debug_frm && u4_mb_x == u4_debug_mb_x && u4_mb_y == u4_debug_mb_y) { // printf(""); } } /*****************************************************************************/ /* */ /* Function Name : example_of_a_function */ /* */ /* Description : This function illustrates the use of C coding standards. */ /* switch/case, if, for, block comments have been shown */ /* here. */ /* Inputs : */ /* Globals : */ /* Processing : */ /* Outputs : */ /* Returns : */ /* */ /* Issues : */ /* */ /* Revision History: */ /* */ /* DD MM YYYY Author(s) Changes (Describe the changes made) */ /* 13 07 2002 Ittiam Draft */ /* */ /*****************************************************************************/ void impeg2d_frm_num_set(void) { u4_debug_frm_num++; } /*****************************************************************************/ /* */ /* Function Name : example_of_a_function */ /* */ /* Description : This function illustrates the use of C coding standards. */ /* switch/case, if, for, block comments have been shown */ /* here. */ /* Inputs : */ /* Globals : */ /* Processing : */ /* Outputs : */ /* Returns : */ /* */ /* Issues : */ /* */ /* Revision History: */ /* */ /* DD MM YYYY Author(s) Changes (Describe the changes made) */ /* 13 07 2002 Ittiam Draft */ /* */ /*****************************************************************************/ UWORD32 impeg2d_frm_num_get(void) { return(u4_debug_frm_num); } #endif