| /** |
| * 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. |
| */ |
| #define _GNU_SOURCE |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <sys/time.h> |
| #include <stdlib.h> |
| #include "iv_datatypedef.h" |
| #include "iv.h" |
| #include "ivd.h" |
| #include "impeg2d.h" |
| |
| typedef struct timeval TIMER; |
| #define GETTIME(timer) gettimeofday(timer,NULL); |
| #define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time) \ |
| s_elapsed_time = (s_end_timer.tv_sec - s_start_timer.tv_sec); |
| |
| #define MAX_FRAME_WIDTH 2560 |
| #define MAX_FRAME_HEIGHT 1600 |
| #define NEW_FILE_LEN 2095752 |
| |
| FILE *ps_inarg_file = NULL; |
| FILE *ps_ip_file = NULL; |
| UWORD8 *pu1_bs_buf = NULL; |
| UWORD8 *buffer = NULL; |
| ivd_out_bufdesc_t *ps_out_buf = NULL; |
| |
| #define WAIT_TIMEOUT (8 * 60) |
| |
| void free_resources() { |
| if (ps_inarg_file) { |
| fclose(ps_inarg_file); |
| } |
| |
| if (ps_ip_file) { |
| fclose(ps_ip_file); |
| } |
| |
| if (buffer) { |
| free(buffer); |
| } |
| |
| if (pu1_bs_buf) { |
| free(pu1_bs_buf); |
| } |
| |
| if (ps_out_buf) { |
| if (ps_out_buf->pu1_bufs[0]) { |
| free(ps_out_buf->pu1_bufs[0]); |
| } |
| free(ps_out_buf); |
| } |
| } |
| |
| void exit_on_error(WORD32 status) { |
| if (status != IV_SUCCESS) { |
| free_resources(); |
| exit (EXIT_FAILURE); |
| } |
| } |
| |
| void * app_aligned_malloc(WORD32 alignment, WORD32 i4_size) { |
| return memalign(alignment, i4_size); |
| } |
| |
| void app_aligned_free(void *pv_buf) { |
| free(pv_buf); |
| return; |
| } |
| |
| void flush_output(iv_obj_t *codec_obj, ivd_out_bufdesc_t *ps_out_buf, |
| UWORD8 *pu1_bs_buf, UWORD32 *pu4_op_frm_ts, |
| UWORD32 u4_ip_frm_ts, UWORD32 u4_bytes_remaining) { |
| WORD32 ret; |
| |
| do { |
| ivd_ctl_flush_ip_t s_ctl_ip; |
| ivd_ctl_flush_op_t s_ctl_op; |
| |
| if (*pu4_op_frm_ts >= (10000)) |
| break; |
| |
| s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH; |
| s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t); |
| s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t); |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, |
| (void *) &s_ctl_op); |
| |
| 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] = |
| (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT); |
| s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = |
| ((MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT) / 2); |
| s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 0; |
| s_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_out_buf->pu1_bufs[1]; |
| s_video_decode_ip.s_out_buffer.pu1_bufs[2] = NULL; |
| s_video_decode_ip.s_out_buffer.u4_num_bufs = 2; |
| s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); |
| |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_video_decode_ip, |
| (void *) &s_video_decode_op); |
| |
| if (1 == s_video_decode_op.u4_output_present) { |
| (*pu4_op_frm_ts)++; |
| } |
| } |
| } while (IV_SUCCESS == ret); |
| } |
| |
| int main(WORD32 argc, CHAR *argv[]) { |
| WORD32 ret = 0; |
| UWORD32 file_pos = 0; |
| UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0; |
| WORD32 u4_bytes_remaining = 0; |
| UWORD32 u4_ip_buf_len = 0; |
| UWORD32 s_elapsed_time = 0; |
| UWORD32 u4_num_mem_recs = 0; |
| UWORD32 i = 0; |
| UWORD32 u4_inarg_file_size = 0; |
| iv_obj_t *codec_obj = NULL; |
| void *pv_mem_rec_location = NULL; |
| TIMER s_start_timer; |
| TIMER s_end_timer; |
| |
| GETTIME(&s_start_timer); |
| |
| if (argc < 2) { |
| return EXIT_FAILURE; |
| } |
| |
| ps_inarg_file = fopen(argv[1], "rb"); |
| if (ps_inarg_file == NULL) { |
| return EXIT_FAILURE; |
| } |
| |
| char *buffer = malloc(NEW_FILE_LEN); |
| if (buffer == NULL) { |
| exit_on_error(IV_FAIL); |
| } |
| memset(buffer, 0, NEW_FILE_LEN); |
| |
| ps_ip_file = tmpfile(); |
| if (ps_ip_file < 0) { |
| exit_on_error(IV_FAIL); |
| } |
| |
| fseek(ps_inarg_file, 0, SEEK_END); |
| u4_inarg_file_size = ftell(ps_inarg_file); |
| fseek(ps_inarg_file, 0, SEEK_SET); |
| |
| /* Create final media file */ |
| fread(buffer, u4_inarg_file_size, 1, ps_inarg_file); |
| fwrite(buffer, 1, NEW_FILE_LEN, ps_ip_file); |
| |
| /* Create decoder instance */ |
| { |
| ps_out_buf = (ivd_out_bufdesc_t *) malloc(sizeof(ivd_out_bufdesc_t)); |
| |
| { |
| iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip; |
| iv_num_mem_rec_op_t s_no_of_mem_rec_query_op; |
| |
| s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip); |
| s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op); |
| s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; |
| |
| /* API Call: Get Number of Mem Records */ |
| ret = impeg2d_api_function(NULL, (void *) &s_no_of_mem_rec_query_ip, |
| (void *) &s_no_of_mem_rec_query_op); |
| exit_on_error(ret); |
| u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec; |
| } |
| |
| pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t)); |
| if (pv_mem_rec_location == NULL) { |
| exit_on_error(IV_FAIL); |
| } |
| |
| { |
| impeg2d_fill_mem_rec_ip_t s_fill_mem_rec_ip; |
| impeg2d_fill_mem_rec_op_t s_fill_mem_rec_op; |
| iv_mem_rec_t *ps_mem_rec; |
| UWORD32 total_size = 0; |
| |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = |
| IV_CMD_FILL_NUM_MEM_REC; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = |
| (iv_mem_rec_t *) pv_mem_rec_location; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = |
| MAX_FRAME_WIDTH; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = |
| MAX_FRAME_HEIGHT; |
| s_fill_mem_rec_ip.u4_share_disp_buf = 0; |
| s_fill_mem_rec_ip.u4_deinterlace = 0; |
| s_fill_mem_rec_ip.e_output_format = IV_YUV_420SP_UV; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size = |
| sizeof(impeg2d_fill_mem_rec_ip_t); |
| s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size = |
| sizeof(impeg2d_fill_mem_rec_op_t); |
| ps_mem_rec = (iv_mem_rec_t *) pv_mem_rec_location; |
| for (i = 0; i < u4_num_mem_recs; i++) |
| ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t); |
| |
| /* API Call: Fill Mem Records */ |
| ret = impeg2d_api_function(NULL, (void *) &s_fill_mem_rec_ip, |
| (void *) &s_fill_mem_rec_op); |
| exit_on_error(ret); |
| |
| u4_num_mem_recs = s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t |
| .u4_num_mem_rec_filled; |
| ps_mem_rec = (iv_mem_rec_t *) pv_mem_rec_location; |
| for (i = 0; i < u4_num_mem_recs; i++) { |
| ps_mem_rec->pv_base = app_aligned_malloc( |
| ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size); |
| if (ps_mem_rec->pv_base == NULL) { |
| exit_on_error(IV_FAIL); |
| } |
| total_size += ps_mem_rec->u4_mem_size; |
| ps_mem_rec++; |
| } |
| } |
| |
| { |
| impeg2d_init_ip_t s_init_ip; |
| impeg2d_init_op_t s_init_op; |
| void *fxns = &impeg2d_api_function; |
| iv_mem_rec_t *mem_tab; |
| |
| mem_tab = (iv_mem_rec_t *) pv_mem_rec_location; |
| s_init_ip.s_ivd_init_ip_t.e_cmd = |
| (IVD_API_COMMAND_TYPE_T) IV_CMD_INIT; |
| s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab; |
| s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = MAX_FRAME_WIDTH; |
| s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = MAX_FRAME_HEIGHT; |
| s_init_ip.u4_share_disp_buf = 0; |
| s_init_ip.u4_deinterlace = 0; |
| s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs; |
| s_init_ip.s_ivd_init_ip_t.e_output_format = IV_YUV_420SP_UV; |
| s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(impeg2d_init_ip_t); |
| s_init_op.s_ivd_init_op_t.u4_size = sizeof(impeg2d_init_op_t); |
| |
| codec_obj = (iv_obj_t *) mem_tab[0].pv_base; |
| codec_obj->pv_fxns = fxns; |
| codec_obj->u4_size = sizeof(iv_obj_t); |
| |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_init_ip, |
| (void *) &s_init_op); |
| exit_on_error(ret); |
| } |
| } |
| |
| { |
| ivd_ctl_getbufinfo_ip_t s_ctl_ip; |
| ivd_ctl_getbufinfo_op_t s_ctl_op; |
| |
| s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO; |
| s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t); |
| s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t); |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, |
| (void *) &s_ctl_op); |
| exit_on_error(ret); |
| u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0]; |
| } |
| /* set num of cores */ |
| { |
| impeg2d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; |
| impeg2d_ctl_set_num_cores_op_t s_ctl_set_cores_op; |
| |
| s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_set_cores_ip.e_sub_cmd = |
| (IVD_CONTROL_API_COMMAND_TYPE_T) IMPEG2D_CMD_CTL_SET_NUM_CORES; |
| s_ctl_set_cores_ip.u4_num_cores = 2; |
| s_ctl_set_cores_ip.u4_size = sizeof(impeg2d_ctl_set_num_cores_ip_t); |
| s_ctl_set_cores_op.u4_size = sizeof(impeg2d_ctl_set_num_cores_op_t); |
| |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_ctl_set_cores_ip, |
| (void *) &s_ctl_set_cores_op); |
| exit_on_error(ret); |
| } |
| |
| /* Allocate input and output buffers for IV_YUV_420SP_UV */ |
| { |
| pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len); |
| ps_out_buf->pu1_bufs[0] = (UWORD8 *) malloc( |
| (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3) / 2); |
| if ((ps_out_buf->pu1_bufs[0] == NULL) || (pu1_bs_buf == NULL)) { |
| exit_on_error(IV_FAIL); |
| } |
| |
| ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0] |
| + (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT); |
| } |
| |
| /* Set the decoder in frame decode mode */ |
| { |
| ivd_ctl_set_config_ip_t s_ctl_ip; |
| ivd_ctl_set_config_op_t s_ctl_op; |
| |
| s_ctl_ip.u4_disp_wd = 0; |
| s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; |
| s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; |
| s_ctl_ip.e_vid_dec_mode = 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); |
| |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, |
| (void *) &s_ctl_op); |
| } |
| |
| while ((s_elapsed_time < WAIT_TIMEOUT)) { |
| u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), u4_ip_buf_len, |
| ps_ip_file); |
| if (u4_bytes_remaining == 0) { |
| fseek(ps_ip_file, 0, SEEK_SET); |
| u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), |
| u4_ip_buf_len, ps_ip_file); |
| } |
| |
| { |
| 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] = |
| (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT); |
| s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = |
| ((MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT) / 2); |
| s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 0; |
| s_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_out_buf->pu1_bufs[1]; |
| s_video_decode_ip.s_out_buffer.pu1_bufs[2] = NULL; |
| s_video_decode_ip.s_out_buffer.u4_num_bufs = 2; |
| s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); |
| /* API Call: Video Decode */ |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_video_decode_ip, |
| (void *) &s_video_decode_op); |
| |
| if (IV_SUCCESS != ret) { |
| if ((s_video_decode_op.u4_error_code & 0xFF) |
| == IVD_RES_CHANGED) { |
| ivd_ctl_reset_ip_t s_ctl_ip; |
| ivd_ctl_reset_op_t s_ctl_op; |
| |
| flush_output(codec_obj, ps_out_buf, pu1_bs_buf, |
| &u4_op_frm_ts, u4_ip_frm_ts, |
| u4_bytes_remaining); |
| |
| s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; |
| s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t); |
| s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t); |
| |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_ctl_ip, |
| (void *) &s_ctl_op); |
| exit_on_error(ret); |
| |
| /* set num of cores */ |
| { |
| impeg2d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; |
| impeg2d_ctl_set_num_cores_op_t s_ctl_set_cores_op; |
| |
| s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_set_cores_ip.e_sub_cmd = |
| (IVD_CONTROL_API_COMMAND_TYPE_T) IMPEG2D_CMD_CTL_SET_NUM_CORES; |
| s_ctl_set_cores_ip.u4_num_cores = 2; |
| s_ctl_set_cores_ip.u4_size = |
| sizeof(impeg2d_ctl_set_num_cores_ip_t); |
| s_ctl_set_cores_op.u4_size = |
| sizeof(impeg2d_ctl_set_num_cores_op_t); |
| |
| ret = impeg2d_api_function( |
| (iv_obj_t *) codec_obj, |
| (void *) &s_ctl_set_cores_ip, |
| (void *) &s_ctl_set_cores_op); |
| exit_on_error(ret); |
| |
| } |
| /* set processsor */ |
| { |
| impeg2d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip; |
| impeg2d_ctl_set_processor_op_t s_ctl_set_num_processor_op; |
| |
| s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL; |
| s_ctl_set_num_processor_ip.e_sub_cmd = |
| (IVD_CONTROL_API_COMMAND_TYPE_T) IMPEG2D_CMD_CTL_SET_PROCESSOR; |
| s_ctl_set_num_processor_ip.u4_size = |
| sizeof(impeg2d_ctl_set_processor_ip_t); |
| s_ctl_set_num_processor_op.u4_size = |
| sizeof(impeg2d_ctl_set_processor_op_t); |
| |
| ret = impeg2d_api_function( |
| (iv_obj_t *) codec_obj, |
| (void *) &s_ctl_set_num_processor_ip, |
| (void *) &s_ctl_set_num_processor_op); |
| exit_on_error(ret); |
| |
| } |
| |
| } else if (IMPEG2D_UNSUPPORTED_DIMENSIONS |
| == (IMPEG2D_ERROR_CODES_T) s_video_decode_op |
| .u4_error_code) { |
| flush_output(codec_obj, ps_out_buf, pu1_bs_buf, |
| &u4_op_frm_ts, u4_ip_frm_ts, |
| u4_bytes_remaining); |
| break; |
| } else if (IVD_DISP_FRM_ZERO_OP_BUF_SIZE |
| == (IMPEG2D_ERROR_CODES_T) s_video_decode_op |
| .u4_error_code) { |
| break; |
| } |
| } |
| file_pos += s_video_decode_op.u4_num_bytes_consumed; |
| fseek(ps_ip_file, file_pos, SEEK_SET); |
| u4_ip_frm_ts++; |
| |
| if (1 == s_video_decode_op.u4_output_present) { |
| u4_op_frm_ts++; |
| } else { |
| if ((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) { |
| break; |
| } |
| } |
| } |
| GETTIME(&s_end_timer); |
| ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time); |
| } |
| |
| /* To get the last decoded frames, call process with NULL input */ |
| flush_output(codec_obj, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, u4_ip_frm_ts, |
| u4_bytes_remaining); |
| |
| /* Delete decoder and close all the files and free all the memory */ |
| { |
| iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip; |
| iv_retrieve_mem_rec_op_t s_retrieve_dec_op; |
| s_retrieve_dec_ip.pv_mem_rec_location = |
| (iv_mem_rec_t *) pv_mem_rec_location; |
| s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; |
| s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t); |
| s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t); |
| ret = impeg2d_api_function((iv_obj_t *) codec_obj, |
| (void *) &s_retrieve_dec_ip, |
| (void *) &s_retrieve_dec_op); |
| exit_on_error(ret); |
| |
| u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled; |
| iv_mem_rec_t *ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location; |
| for (UWORD16 u2_i = 0; u2_i < u4_num_mem_recs; u2_i++) { |
| app_aligned_free(ps_mem_rec->pv_base); |
| ps_mem_rec++; |
| } |
| free(s_retrieve_dec_ip.pv_mem_rec_location); |
| } |
| |
| free_resources(); |
| return EXIT_SUCCESS; |
| } |